Momo: stack machine, part 2
This commit is contained in:
parent
2320106f73
commit
a4e634ecd6
146
src/momo/momo.c
146
src/momo/momo.c
|
@ -204,16 +204,16 @@ unsigned int runStackMachine(struct StackData* data, size_t count, unsigned int
|
||||||
|
|
||||||
#define FINISH_OP \
|
#define FINISH_OP \
|
||||||
/* push identifier */ \
|
/* push identifier */ \
|
||||||
if (curIdent[0]) { \
|
if (state[curState].curIdent[0]) { \
|
||||||
if (strcmp(curIdent,"n")==0) { \
|
if (strcmp(state[curState].curIdent,"n")==0) { \
|
||||||
data[*pc].ins=MOMO_STACK_PUSH_N; \
|
data[*pc].ins=MOMO_STACK_PUSH_N; \
|
||||||
data[*pc].param=0; \
|
data[*pc].param=0; \
|
||||||
printf("PENDING IDENT: %s\n",curIdent); \
|
printf("PENDING IDENT: %s\n",state[curState].curIdent); \
|
||||||
} else { \
|
} else { \
|
||||||
data[*pc].ins=MOMO_STACK_PUSH; \
|
data[*pc].ins=MOMO_STACK_PUSH; \
|
||||||
printf("PENDING IDENT: %s\n",curIdent); \
|
printf("PENDING IDENT: %s\n",state[curState].curIdent); \
|
||||||
if (sscanf(curIdent,"%u",&data[*pc].param)!=1) { \
|
if (sscanf(state[curState].curIdent,"%u",&data[*pc].param)!=1) { \
|
||||||
printf("ERROR: invalid identifier %s\n",curIdent); \
|
printf("ERROR: invalid identifier %s\n",state[curState].curIdent); \
|
||||||
return 3; \
|
return 3; \
|
||||||
} \
|
} \
|
||||||
} \
|
} \
|
||||||
|
@ -221,58 +221,58 @@ unsigned int runStackMachine(struct StackData* data, size_t count, unsigned int
|
||||||
} \
|
} \
|
||||||
\
|
\
|
||||||
/* push operation if pending */ \
|
/* push operation if pending */ \
|
||||||
if (curOp[0]) { \
|
if (state[curState].curOp[0]) { \
|
||||||
printf("PENDING OP: %s\n",curOp); \
|
printf("PENDING OP: %s\n",state[curState].curOp); \
|
||||||
if (strcmp(curOp,"+")==0) { \
|
if (strcmp(state[curState].curOp,"+")==0) { \
|
||||||
data[*pc].ins=MOMO_STACK_ADD; \
|
data[*pc].ins=MOMO_STACK_ADD; \
|
||||||
data[*pc].param=0; \
|
data[*pc].param=0; \
|
||||||
(*pc)++; \
|
(*pc)++; \
|
||||||
} else if (strcmp(curOp,"-")==0) { \
|
} else if (strcmp(state[curState].curOp,"-")==0) { \
|
||||||
data[*pc].ins=MOMO_STACK_SUB; \
|
data[*pc].ins=MOMO_STACK_SUB; \
|
||||||
data[*pc].param=0; \
|
data[*pc].param=0; \
|
||||||
(*pc)++; \
|
(*pc)++; \
|
||||||
} else if (strcmp(curOp,"*")==0) { \
|
} else if (strcmp(state[curState].curOp,"*")==0) { \
|
||||||
data[*pc].ins=MOMO_STACK_MUL; \
|
data[*pc].ins=MOMO_STACK_MUL; \
|
||||||
data[*pc].param=0; \
|
data[*pc].param=0; \
|
||||||
(*pc)++; \
|
(*pc)++; \
|
||||||
} else if (strcmp(curOp,"/")==0) { \
|
} else if (strcmp(state[curState].curOp,"/")==0) { \
|
||||||
data[*pc].ins=MOMO_STACK_DIV; \
|
data[*pc].ins=MOMO_STACK_DIV; \
|
||||||
data[*pc].param=0; \
|
data[*pc].param=0; \
|
||||||
(*pc)++; \
|
(*pc)++; \
|
||||||
} else if (strcmp(curOp,"%")==0) { \
|
} else if (strcmp(state[curState].curOp,"%")==0) { \
|
||||||
data[*pc].ins=MOMO_STACK_MOD; \
|
data[*pc].ins=MOMO_STACK_MOD; \
|
||||||
data[*pc].param=0; \
|
data[*pc].param=0; \
|
||||||
(*pc)++; \
|
(*pc)++; \
|
||||||
} else if (strcmp(curOp,"&&")==0) { \
|
} else if (strcmp(state[curState].curOp,"&&")==0) { \
|
||||||
data[*pc].ins=MOMO_STACK_CMP_AND; \
|
data[*pc].ins=MOMO_STACK_CMP_AND; \
|
||||||
data[*pc].param=0; \
|
data[*pc].param=0; \
|
||||||
(*pc)++; \
|
(*pc)++; \
|
||||||
} else if (strcmp(curOp,"||")==0) { \
|
} else if (strcmp(state[curState].curOp,"||")==0) { \
|
||||||
data[*pc].ins=MOMO_STACK_CMP_OR; \
|
data[*pc].ins=MOMO_STACK_CMP_OR; \
|
||||||
data[*pc].param=0; \
|
data[*pc].param=0; \
|
||||||
(*pc)++; \
|
(*pc)++; \
|
||||||
} else if (strcmp(curOp,">")==0) { \
|
} else if (strcmp(state[curState].curOp,">")==0) { \
|
||||||
data[*pc].ins=MOMO_STACK_CMP_GT; \
|
data[*pc].ins=MOMO_STACK_CMP_GT; \
|
||||||
data[*pc].param=0; \
|
data[*pc].param=0; \
|
||||||
(*pc)++; \
|
(*pc)++; \
|
||||||
} else if (strcmp(curOp,"<")==0) { \
|
} else if (strcmp(state[curState].curOp,"<")==0) { \
|
||||||
data[*pc].ins=MOMO_STACK_CMP_LT; \
|
data[*pc].ins=MOMO_STACK_CMP_LT; \
|
||||||
data[*pc].param=0; \
|
data[*pc].param=0; \
|
||||||
(*pc)++; \
|
(*pc)++; \
|
||||||
} else if (strcmp(curOp,">=")==0) { \
|
} else if (strcmp(state[curState].curOp,">=")==0) { \
|
||||||
data[*pc].ins=MOMO_STACK_CMP_GE; \
|
data[*pc].ins=MOMO_STACK_CMP_GE; \
|
||||||
data[*pc].param=0; \
|
data[*pc].param=0; \
|
||||||
(*pc)++; \
|
(*pc)++; \
|
||||||
} else if (strcmp(curOp,"<=")==0) { \
|
} else if (strcmp(state[curState].curOp,"<=")==0) { \
|
||||||
data[*pc].ins=MOMO_STACK_CMP_LE; \
|
data[*pc].ins=MOMO_STACK_CMP_LE; \
|
||||||
data[*pc].param=0; \
|
data[*pc].param=0; \
|
||||||
(*pc)++; \
|
(*pc)++; \
|
||||||
} else if (strcmp(curOp,"<=")==0) { \
|
} else if (strcmp(state[curState].curOp,"<=")==0) { \
|
||||||
} else if (strcmp(curOp,"==")==0) { \
|
} else if (strcmp(state[curState].curOp,"==")==0) { \
|
||||||
data[*pc].ins=MOMO_STACK_CMP_EQ; \
|
data[*pc].ins=MOMO_STACK_CMP_EQ; \
|
||||||
data[*pc].param=0; \
|
data[*pc].param=0; \
|
||||||
(*pc)++; \
|
(*pc)++; \
|
||||||
} else if (strcmp(curOp,"!=")==0) { \
|
} else if (strcmp(state[curState].curOp,"!=")==0) { \
|
||||||
data[*pc].ins=MOMO_STACK_CMP_NE; \
|
data[*pc].ins=MOMO_STACK_CMP_NE; \
|
||||||
data[*pc].param=0; \
|
data[*pc].param=0; \
|
||||||
(*pc)++; \
|
(*pc)++; \
|
||||||
|
@ -282,8 +282,8 @@ unsigned int runStackMachine(struct StackData* data, size_t count, unsigned int
|
||||||
} \
|
} \
|
||||||
} \
|
} \
|
||||||
\
|
\
|
||||||
memset(curOp,0,8); \
|
memset(state[curState].curOp,0,8); \
|
||||||
curOpLen=0;
|
state[curState].curOpLen=0;
|
||||||
|
|
||||||
// errors:
|
// errors:
|
||||||
// 0: success
|
// 0: success
|
||||||
|
@ -293,121 +293,129 @@ unsigned int runStackMachine(struct StackData* data, size_t count, unsigned int
|
||||||
// 4: unknown operation
|
// 4: unknown operation
|
||||||
// 5: program too long
|
// 5: program too long
|
||||||
unsigned char compileExprSub(const char** ptr, struct StackData* data, size_t* pc, size_t count) {
|
unsigned char compileExprSub(const char** ptr, struct StackData* data, size_t* pc, size_t count) {
|
||||||
unsigned char isOp=0;
|
struct ExprState {
|
||||||
unsigned char oldIsOp=0;
|
unsigned char isOp;
|
||||||
char curIdent[32];
|
unsigned char oldIsOp;
|
||||||
char curOp[8];
|
char curIdent[32];
|
||||||
unsigned char curIdentLen=0;
|
char curOp[8];
|
||||||
unsigned char curOpLen=0;
|
unsigned char curIdentLen;
|
||||||
unsigned char startBranch=0;
|
unsigned char curOpLen;
|
||||||
|
unsigned char startBranch;
|
||||||
|
size_t pendingBranch;
|
||||||
|
} state[8];
|
||||||
|
unsigned char curState=0;
|
||||||
|
|
||||||
memset(curIdent,0,32);
|
memset(state,0,sizeof(struct ExprState)*8);
|
||||||
memset(curOp,0,8);
|
|
||||||
|
|
||||||
for (; *(*ptr); (*ptr)++) {
|
for (; *(*ptr); (*ptr)++) {
|
||||||
char next=**ptr;
|
char next=**ptr;
|
||||||
unsigned char doNotPush=0;
|
unsigned char doNotPush=0;
|
||||||
printf("%c\n",next);
|
printf("%c\n",next);
|
||||||
if (curIdentLen>30) return 1;
|
if (state[curState].curIdentLen>30) return 1;
|
||||||
if (curOpLen>6) return 2;
|
if (state[curState].curOpLen>6) return 2;
|
||||||
if (*pc>=count) return 5;
|
if (*pc>=count) return 5;
|
||||||
switch (next) {
|
switch (next) {
|
||||||
case '+':
|
case '+':
|
||||||
isOp=1;
|
state[curState].isOp=1;
|
||||||
break;
|
break;
|
||||||
case '-':
|
case '-':
|
||||||
isOp=1;
|
state[curState].isOp=1;
|
||||||
break;
|
break;
|
||||||
case '*':
|
case '*':
|
||||||
isOp=1;
|
state[curState].isOp=1;
|
||||||
break;
|
break;
|
||||||
case '/':
|
case '/':
|
||||||
isOp=1;
|
state[curState].isOp=1;
|
||||||
break;
|
break;
|
||||||
case '%':
|
case '%':
|
||||||
isOp=1;
|
state[curState].isOp=1;
|
||||||
break;
|
break;
|
||||||
case '!':
|
case '!':
|
||||||
isOp=1;
|
state[curState].isOp=1;
|
||||||
break;
|
break;
|
||||||
case '=':
|
case '=':
|
||||||
isOp=1;
|
state[curState].isOp=1;
|
||||||
break;
|
break;
|
||||||
case '|':
|
case '|':
|
||||||
isOp=1;
|
state[curState].isOp=1;
|
||||||
break;
|
break;
|
||||||
case '&':
|
case '&':
|
||||||
isOp=1;
|
state[curState].isOp=1;
|
||||||
break;
|
break;
|
||||||
case '>':
|
case '>':
|
||||||
isOp=1;
|
state[curState].isOp=1;
|
||||||
break;
|
break;
|
||||||
case '<':
|
case '<':
|
||||||
isOp=1;
|
state[curState].isOp=1;
|
||||||
break;
|
break;
|
||||||
case '?':
|
case '?':
|
||||||
// special case
|
// special case
|
||||||
startBranch=1;
|
state[curState].startBranch=1;
|
||||||
doNotPush=1;
|
doNotPush=1;
|
||||||
isOp=1;
|
state[curState].isOp=1;
|
||||||
break;
|
break;
|
||||||
case ':':
|
case ':':
|
||||||
// special case
|
// special case
|
||||||
doNotPush=1;
|
doNotPush=1;
|
||||||
startBranch=2;
|
state[curState].startBranch=2;
|
||||||
isOp=1;
|
state[curState].isOp=1;
|
||||||
break;
|
break;
|
||||||
case '(':
|
case '(':
|
||||||
// special case
|
// start a new state
|
||||||
doNotPush=1;
|
curState++;
|
||||||
|
memset(&state[curState],0,sizeof(struct ExprState));
|
||||||
|
continue;
|
||||||
break;
|
break;
|
||||||
case ')':
|
case ')':
|
||||||
// special case
|
// pop last state
|
||||||
doNotPush=1;
|
curState--;
|
||||||
|
continue;
|
||||||
break;
|
break;
|
||||||
case ' ':
|
case ' ':
|
||||||
// ignore
|
// ignore
|
||||||
doNotPush=1;
|
doNotPush=1;
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
isOp=0;
|
state[curState].isOp=0;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
if (isOp!=oldIsOp) {
|
if (state[curState].isOp!=state[curState].oldIsOp) {
|
||||||
oldIsOp=isOp;
|
state[curState].oldIsOp=state[curState].isOp;
|
||||||
if (isOp) {
|
if (state[curState].isOp) {
|
||||||
printf("OP MODE\n");
|
printf("OP MODE\n");
|
||||||
FINISH_OP;
|
FINISH_OP;
|
||||||
} else {
|
} else {
|
||||||
printf("IDENT MODE\n");
|
printf("IDENT MODE\n");
|
||||||
// prepare
|
// prepare
|
||||||
memset(curIdent,0,32);
|
memset(state[curState].curIdent,0,32);
|
||||||
curIdentLen=0;
|
state[curState].curIdentLen=0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (!doNotPush) {
|
if (!doNotPush) {
|
||||||
if (isOp) {
|
if (state[curState].isOp) {
|
||||||
curOp[curOpLen++]=next;
|
state[curState].curOp[state[curState].curOpLen++]=next;
|
||||||
} else {
|
} else {
|
||||||
curIdent[curIdentLen++]=next;
|
state[curState].curIdent[state[curState].curIdentLen++]=next;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (startBranch) {
|
if (state[curState].startBranch) {
|
||||||
printf("START BRANCH: %d\n",startBranch);
|
printf("START BRANCH: %d\n",state[curState].startBranch);
|
||||||
if (startBranch==2) {
|
if (state[curState].startBranch==2) {
|
||||||
data[*pc].ins=MOMO_STACK_EXIT;
|
data[*pc].ins=MOMO_STACK_EXIT;
|
||||||
data[*pc].param=0;
|
data[*pc].param=0;
|
||||||
|
data[state[curState].pendingBranch].param=*pc-state[curState].pendingBranch;
|
||||||
|
state[curState].pendingBranch=0;
|
||||||
} else {
|
} else {
|
||||||
|
state[curState].pendingBranch=*pc;
|
||||||
data[*pc].ins=MOMO_STACK_BEQ;
|
data[*pc].ins=MOMO_STACK_BEQ;
|
||||||
// TODO offset
|
|
||||||
data[*pc].param=0;
|
data[*pc].param=0;
|
||||||
}
|
}
|
||||||
startBranch=0;
|
state[curState].startBranch=0;
|
||||||
(*pc)++;
|
(*pc)++;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!isOp) {
|
if (!state[curState].isOp) {
|
||||||
FINISH_OP;
|
FINISH_OP;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue