Преглед на файлове

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
#
# 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:

Зареждане…
Отказ
Запис