浏览代码

Default grammar is part of PEG VM frame. RULE2 and CALL2 change the default grammar for the duration of the rule being called.

master
Ian Piumarta 10 个月前
父节点
当前提交
1acd725af0
共有 1 个文件被更改,包括 30 次插入9 次删除
  1. +30
    -9
      minproto.leg

+ 30
- 9
minproto.leg 查看文件

@ -1,6 +1,6 @@
# minproto.leg -- minimal prototype langauge for semantic experiments # 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 unsigned char byte;
typedef enum op_t { 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, SUCCEED, FAIL, ACTION, BEGIN, END, UNEND, SET,
} op_t; } op_t;
char *op_n[] = { 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", "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", printf("%03d %-7s %p %2d %2d %2d\n",
pc, op_n[i->op], i->arg.code, i->arg2.len, i->ok, i->ko); pc, op_n[i->op], i->arg.code, i->arg2.len, i->ok, i->ko);
break; 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: default:
printf("%03d %-7s %s %2d %2d %2d\n", 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); 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); valueError("__match__", "program contains explicit CALL opcode", program);
break; break;
} }
case CALL2: {
valueError("__match__", "program contains explicit CALL2 opcode", program);
break;
}
case ACTION: { case ACTION: {
if (!isClosure(code[cpc].arg.obj)) valueError("__match__", "ACTION argument must be a closure", program); if (!isClosure(code[cpc].arg.obj)) valueError("__match__", "ACTION argument must be a closure", program);
break; break;
@ -4944,12 +4952,10 @@ vmInsn *vmCacheGet(oop grammar, oop symbol)
return vmCompile(grammar, 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); vmCache = new(pObject);
vmInsn *code = vmCacheGet(grammar, symbol);
int maxactions = 32; int maxactions = 32;
struct Action { 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 }; \ actions[context.nactions++] = (struct Action){ ACT, OBJ, BEG, LEN }; \
} }
//vmInsn *code = vmCacheGet(frame.grammar, symbol);
struct Frame { struct Frame {
oop grammar;
oop symbol; oop symbol;
vmInsn *code; vmInsn *code;
int pc; int pc;
@ -4986,8 +4995,9 @@ int vmRun(oop grammar, oop symbol, char *text, int start, int length)
int rsp = 0, nrstack = 32; int rsp = 0, nrstack = 32;
rstack = xmalloc(sizeof(*rstack) * nrstack); rstack = xmalloc(sizeof(*rstack) * nrstack);
frame.grammar = grammar0;
frame.symbol = symbol; frame.symbol = symbol;
frame.code = vmCacheGet(grammar, symbol);
frame.code = vmCacheGet(grammar0, symbol);
frame.pc = 0; frame.pc = 0;
frame.nactions = context.nactions; frame.nactions = context.nactions;
@ -5054,8 +5064,19 @@ int vmRun(oop grammar, oop symbol, char *text, int start, int length)
continue; continue;
} }
case RULE2: { case RULE2: {
i->op = CALL;
i->op = CALL2;
i->arg.code = vmCacheGet(i->arg2.obj, i->arg.obj); 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; goto doCall;
} }
case RULE: { 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->arglen = ((Node *)i->arg)->Symbol.nvars;
//i->arg = ((Node *)i->arg)->Symbol.code; assert(i->arg); //i->arg = ((Node *)i->arg)->Symbol.code; assert(i->arg);
i->op = CALL; 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 ;-)) goto doCall; // (just in case they are not consecutive ;-))
} }
case CALL: { doCall: case CALL: { doCall:

正在加载...
取消
保存