|
|
@ -1,6 +1,6 @@ |
|
|
|
# minproto.leg -- minimal prototype langauge for semantic experiments |
|
|
|
# |
|
|
|
# last edited: 2024-07-05 17:16:16 by piumarta on zora-1034.local |
|
|
|
# last edited: 2024-07-10 11:28:02 by piumarta on zora-1034.local |
|
|
|
|
|
|
|
%{ |
|
|
|
; |
|
|
@ -4770,12 +4770,12 @@ oop applyThunkIn(oop func, oop env) |
|
|
|
typedef unsigned char byte; |
|
|
|
|
|
|
|
typedef enum op_t { |
|
|
|
PUSH, DROP, POP, DOT, CLASS, STRING, TEST, RULE2, RULE, CALL, |
|
|
|
PUSH, DROP, POP, DOT, CLASS, STRING, TEST, RULE2, RULE, CALL, CALL2, |
|
|
|
SUCCEED, FAIL, ACTION, BEGIN, END, UNEND, SET, |
|
|
|
} op_t; |
|
|
|
|
|
|
|
char *op_n[] = { |
|
|
|
"PUSH", "DROP", "POP", "DOT", "CLASS", "STRING", "TEST", "RULE2", "RULE", "CALL", |
|
|
|
"PUSH", "DROP", "POP", "DOT", "CLASS", "STRING", "TEST", "RULE2", "RULE", "CALL", "CALL2", |
|
|
|
"SUCCEED", "FAIL", "ACTION", "BEGIN", "END", "UNEND", "SET", |
|
|
|
}; |
|
|
|
|
|
|
@ -4838,6 +4838,10 @@ void vmDisassemble(vmInsn *code, int pc) |
|
|
|
printf("%03d %-7s %p %2d %2d %2d\n", |
|
|
|
pc, op_n[i->op], i->arg.code, i->arg2.len, i->ok, i->ko); |
|
|
|
break; |
|
|
|
case CALL2: |
|
|
|
printf("%03d %-7s %p %2d %2d %2d\n", |
|
|
|
pc, op_n[i->op], i->arg.code, i->arg2.len, i->ok, i->ko); |
|
|
|
break; |
|
|
|
default: |
|
|
|
printf("%03d %-7s %s %2d %2d %2d\n", |
|
|
|
pc, op_n[i->op], codeString(i->arg.obj, 0), i->arg2.len, i->ok, i->ko); |
|
|
@ -4906,6 +4910,10 @@ vmInsn *vmCompile(oop grammar, oop symbol) |
|
|
|
valueError("__match__", "program contains explicit CALL opcode", program); |
|
|
|
break; |
|
|
|
} |
|
|
|
case CALL2: { |
|
|
|
valueError("__match__", "program contains explicit CALL2 opcode", program); |
|
|
|
break; |
|
|
|
} |
|
|
|
case ACTION: { |
|
|
|
if (!isClosure(code[cpc].arg.obj)) valueError("__match__", "ACTION argument must be a closure", program); |
|
|
|
break; |
|
|
@ -4944,12 +4952,10 @@ vmInsn *vmCacheGet(oop grammar, oop symbol) |
|
|
|
return vmCompile(grammar, symbol); |
|
|
|
} |
|
|
|
|
|
|
|
int vmRun(oop grammar, oop symbol, char *text, int start, int length) |
|
|
|
int vmRun(oop grammar0, oop symbol, char *text, int start, int length) |
|
|
|
{ |
|
|
|
vmCache = new(pObject); |
|
|
|
|
|
|
|
vmInsn *code = vmCacheGet(grammar, symbol); |
|
|
|
|
|
|
|
int maxactions = 32; |
|
|
|
|
|
|
|
struct Action { |
|
|
@ -4977,7 +4983,10 @@ int vmRun(oop grammar, oop symbol, char *text, int start, int length) |
|
|
|
actions[context.nactions++] = (struct Action){ ACT, OBJ, BEG, LEN }; \ |
|
|
|
} |
|
|
|
|
|
|
|
//vmInsn *code = vmCacheGet(frame.grammar, symbol); |
|
|
|
|
|
|
|
struct Frame { |
|
|
|
oop grammar; |
|
|
|
oop symbol; |
|
|
|
vmInsn *code; |
|
|
|
int pc; |
|
|
@ -4986,8 +4995,9 @@ int vmRun(oop grammar, oop symbol, char *text, int start, int length) |
|
|
|
|
|
|
|
int rsp = 0, nrstack = 32; |
|
|
|
rstack = xmalloc(sizeof(*rstack) * nrstack); |
|
|
|
frame.grammar = grammar0; |
|
|
|
frame.symbol = symbol; |
|
|
|
frame.code = vmCacheGet(grammar, symbol); |
|
|
|
frame.code = vmCacheGet(grammar0, symbol); |
|
|
|
frame.pc = 0; |
|
|
|
frame.nactions = context.nactions; |
|
|
|
|
|
|
@ -5054,8 +5064,19 @@ int vmRun(oop grammar, oop symbol, char *text, int start, int length) |
|
|
|
continue; |
|
|
|
} |
|
|
|
case RULE2: { |
|
|
|
i->op = CALL; |
|
|
|
i->op = CALL2; |
|
|
|
i->arg.code = vmCacheGet(i->arg2.obj, i->arg.obj); |
|
|
|
goto doCall2; // (just in case they are not consecutive ;-)) |
|
|
|
case CALL2: { doCall2: |
|
|
|
frame.pc--; // save pc of call insn |
|
|
|
push(r, frame); |
|
|
|
frame.grammar = i->arg2.obj; |
|
|
|
frame.code = i->arg.code; |
|
|
|
frame.pc = 0; |
|
|
|
saveAction(vmEnter, nil, 0, 0); |
|
|
|
frame.nactions = context.nactions; |
|
|
|
continue; |
|
|
|
} |
|
|
|
goto doCall; |
|
|
|
} |
|
|
|
case RULE: { |
|
|
@ -5072,7 +5093,7 @@ int vmRun(oop grammar, oop symbol, char *text, int start, int length) |
|
|
|
//i->arglen = ((Node *)i->arg)->Symbol.nvars; |
|
|
|
//i->arg = ((Node *)i->arg)->Symbol.code; assert(i->arg); |
|
|
|
i->op = CALL; |
|
|
|
i->arg.code = vmCacheGet(grammar, i->arg.obj); |
|
|
|
i->arg.code = vmCacheGet(frame.grammar, i->arg.obj); |
|
|
|
goto doCall; // (just in case they are not consecutive ;-)) |
|
|
|
} |
|
|
|
case CALL: { doCall: |
|
|
|