diff --git a/minproto.leg b/minproto.leg index 48a77e4..1b1e525 100644 --- a/minproto.leg +++ b/minproto.leg @@ -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: