Parcourir la source

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 il y a 10 mois
Parent
révision
1acd725af0
1 fichiers modifiés avec 30 ajouts et 9 suppressions
  1. +30
    -9
      minproto.leg

+ 30
- 9
minproto.leg Voir le fichier

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

Chargement…
Annuler
Enregistrer