pull/1102/head
Zef Hemel 2024-09-27 17:09:25 +02:00
parent aa712ed8f4
commit cdcce0d828
8 changed files with 94 additions and 12 deletions

View File

@ -93,7 +93,7 @@ export type LuaLocalFunctionStatement = {
export type LuaFunctionName = { export type LuaFunctionName = {
type: "FunctionName"; type: "FunctionName";
propNames?: string[]; propNames: string[];
colonName?: string; colonName?: string;
}; };

View File

@ -185,4 +185,17 @@ Deno.test("Statement evaluation", async () => {
env7, env7,
); );
assertEquals(env7.get("c"), 3); assertEquals(env7.get("c"), 3);
// Function definition and calling
const env8 = new LuaEnv();
env8.set("print", new LuaNativeJSFunction(console.log));
await evalBlock(
`
function test(a)
return a + 1
end
print("3 + 1 = " .. test(3))
`,
env8,
);
}); });

View File

@ -6,11 +6,15 @@ import type {
import { evalPromiseValues } from "$common/space_lua/util.ts"; import { evalPromiseValues } from "$common/space_lua/util.ts";
import { import {
type ILuaFunction, type ILuaFunction,
type ILuaGettable,
type ILuaSettable,
LuaBreak, LuaBreak,
LuaEnv, LuaEnv,
LuaFunction,
luaGet, luaGet,
luaLen, luaLen,
type LuaLValueContainer, type LuaLValueContainer,
LuaReturn,
LuaTable, LuaTable,
luaTruthy, luaTruthy,
type LuaValue, type LuaValue,
@ -356,6 +360,39 @@ export async function evalStatement(
case "FunctionCallStatement": { case "FunctionCallStatement": {
return evalExpression(s.call, env); return evalExpression(s.call, env);
} }
case "Function": {
let body = s.body;
let propNames = s.name.propNames;
if (s.name.colonName) {
// function hello:there() -> function hello.there(self) transformation
body = {
...s.body,
parameters: ["self", ...s.body.parameters],
};
propNames = [...s.name.propNames, s.name.colonName];
}
let settable: ILuaSettable & ILuaGettable = env;
for (let i = 0; i < propNames.length - 1; i++) {
settable = settable.get(propNames[i]);
if (!settable) {
throw new Error(
`Cannot find property ${propNames[i]}`,
);
}
}
settable.set(
propNames[propNames.length - 1],
new LuaFunction(body, env),
);
break;
}
case "Return": {
throw new LuaReturn(
await evalPromiseValues(
s.expressions.map((value) => evalExpression(value, env)),
),
);
}
default: default:
throw new Error(`Unknown statement type ${s.type}`); throw new Error(`Unknown statement type ${s.type}`);
} }

View File

@ -19,7 +19,7 @@
Block { statement* ReturnStatement? } Block { statement* ReturnStatement? }
ReturnStatement { kw<"return"> exp? ";"?} ReturnStatement { kw<"return"> ExpList? ";"?}
@skip { newline | space | Comment } @skip { newline | space | Comment }

View File

@ -3,9 +3,9 @@ import {LRParser} from "@lezer/lr"
const spec_identifier = {__proto__:null,break:16, goto:20, do:24, end:26, while:30, nil:32, true:34, false:36, or:80, and:82, not:104, function:114, repeat:122, until:124, if:128, then:130, elseif:132, else:134, for:138, in:146, local:156, return:172} const spec_identifier = {__proto__:null,break:16, goto:20, do:24, end:26, while:30, nil:32, true:34, false:36, or:80, and:82, not:104, function:114, repeat:122, until:124, if:128, then:130, elseif:132, else:134, for:138, in:146, local:156, return:172}
export const parser = LRParser.deserialize({ export const parser = LRParser.deserialize({
version: 14, version: 14,
states: ">`O!ZQPOOOOQO'#Cc'#CcO!UQPO'#CaO!bQPOOOOQO'#Ei'#EiO!vQQO'#CwO$]QPO'#EhOOQO'#Eh'#EhO$gQPO'#EhOOQO'#EO'#EOO%vQPO'#D}OOQO'#Ed'#EdOOQO'#EV'#EVO%{QPO'#C_OOQO'#C_'#C_QOQPOOO!UQPO'#CeO&`QPO'#CgO!vQQO'#CjO&gQPO'#DjO!vQQO'#DmO!UQPO'#DrO!UQPO'#DyO&nQPO'#EPO&vQQO'#ETO'^QPO,58{OOQO'#Cq'#CqO!UQPO,59^O!vQQO,59`O(gQQO'#C|O(nQQO'#EnOOQO'#Ej'#EjOOQO,59f,59fO!UQPO,59fO(uQPO'#EfO,eQPO,59cOOQO'#Dc'#DcOOQO'#Dd'#DdOOQO'#De'#DeO!vQQO'#DaOOQO'#Ef'#EfO,lQPO'#DfO,qQPO'#E^O,yQPO,5;kO!vQQO,5:iOOQO-E8T-E8TOOQO,58y,58yOOQO,59P,59PO-RQPO,59RO-WQPO,59UO-_QPO,5:UO-dQPO,5:XO-kQPO'#FOOOQO'#Dv'#DvO-vQPO'#DuO-{QPO,5:^O.QQPO'#DzO,lQPO,5:eO.]QQO'#ERO/sQPO'#FQOOQO'#EQ'#EQO!UQPO,5:gO1WQPO,5:kO2hQPO,5:oOOQO,5:o,5:oOOQO1G.g1G.gOOQO1G.x1G.xO3OQPO1G.zO3VQSO'#EfO4cQSO'#EiO!vQQO'#DOO7WQSO'#DQOOQO'#Ek'#EkOOQO,59h,59hO7bQSO,59hO7jQPO'#EoOOQO,5;Y,5;YO9PQPO,5;YO9UQPO1G/QOOQO1G.}1G.}OOQO'#DX'#DXOOQO'#DY'#DYOOQO'#DZ'#DZOOQO'#D['#D[OOQO'#D^'#D^OOQO'#D_'#D_OOQO'#D`'#D`O!vQQO,59oO!vQQO,59oO!vQQO,59oO!vQQO,59oO!vQQO,59oO!vQQO,59oO!vQQO,59oO!vQQO,59oO!vQQO,59oO:eQPO,59{O<QQQO'#DhOOQO,5:Q,5:QO<`QPO,5:xOOQO-E8[-E8[OOQO'#Dx'#DxOOQO1G0T1G0TOOQO1G.m1G.mO&`QPO1G.pO!vQQO1G/pO<jQPO1G/sO!vQQO,5:`O!UQPO'#E[O<wQPO,5;jO!vQQO,5:aO&`QPO1G/xO!UQPO'#E]O=PQPO,5:fO!UQPO,5:fOOQO1G0P1G0PO!UQPO'#ESOOQO,5:m,5:mO!UQPO'#E_O=[QPO,5;lO,lQPO1G0RO!vQQO1G0VOOQO1G0Z1G0ZOOQO7+$f7+$fO>oQQO,59kO?pQPO,59jO?wQQO1G/SO@OQSO1G/SOOQO1G/S1G/SO@WQSO,59{O!vQQO'#EXO@bQPO,5;ZOOQO1G0t1G0tOOQO7+$l7+$lOD_QPO1G/ZODfQPO1G/ZOGVQPO1G/ZOG^QPO1G/ZOIwQPO1G/ZOJUQPO1G/ZOLVQPO1G/ZO! lQPO1G/ZO! sQPO1G/ZO! zQPO'#EhO!!UQPO'#E}OOQO'#Di'#DiO!!^QPO,5:SO!!cQPO7+$[O!!hQPO7+%[O!#wQPO7+%_O!$SQPO1G/zOOQO,5:v,5:vOOQO-E8Y-E8YOOQO1G/{1G/{O!$ZQPO7+%dOOQO,5:w,5:wOOQO-E8Z-E8ZO!UQPO1G0QOOQO1G0Q1G0QO!$`QQO,5:nOOQO,5:y,5:yOOQO-E8]-E8]OOQO7+%m7+%mOOQO7+%q7+%qO!$eQSO1G/VO!$oQPO1G/UO!%{QSO1G/ZO!&SQSO1G/ZO!'bQSO1G/ZO!'iQSO1G/ZO!(qQSO1G/ZO!)OQSO1G/ZO!)nQSO1G/ZO!+rQSO1G/ZO!+yQSO1G/ZOOQO,5:r,5:rOOQO7+$n7+$nO!,QQQO7+$nOOQO-E8U-E8UO!,XQPO,5:sOOQO-E8V-E8VO!-nQQO'#EYO!-yQPO,5;iO&`QPO1G/nOOQO<<Gv<<GvO!.RQPO<<HyO!vQQO'#EZOOQO<<Hy<<HyO&`QPO<<HyO!vQQO7+%fOOQO<<IO<<IOOOQO7+%l7+%lOOQO1G0Y1G0YO>oQQO7+$pOOQO<<HY<<HYP'cQQO'#EWO!.^QPO,5:tOOQO,5:t,5:tOOQO-E8W-E8WO!.hQPO7+%YOOQO-E8X-E8XOOQOAN>eAN>eO&`QPOAN>eO!.mQPO,5:uO!.tQPOAN>eO!.yQPO<<IQO!/TQSO<<H[OOQO<<Ht<<HtO!/_QPOG24PO<jQPO1G0aOOQOG24PG24PO!vQQOAN>lOOQOLD)kLD)kOOQO7+%{7+%{O!/dQPOG24WO>oQQO'#DaO>oQQO,59oO>oQQO,59oO>oQQO,59oO>oQQO,59oO>oQQO,59oO>oQQO,59oO>oQQO,59oO>oQQO,59oO>oQQO,59o", states: ">`O!ZQPOOOOQO'#Cc'#CcO!UQPO'#CaO!bQPOOOOQO'#Ei'#EiO!vQQO'#CwO$]QPO'#EhOOQO'#Eh'#EhO$gQPO'#EhOOQO'#EO'#EOO%vQPO'#D}OOQO'#Ed'#EdOOQO'#EV'#EVO%{QPO'#C_OOQO'#C_'#C_QOQPOOO!UQPO'#CeO&`QPO'#CgO!vQQO'#CjO&gQPO'#DjO!vQQO'#DmO!UQPO'#DrO!UQPO'#DyO&nQPO'#EPO&vQQO'#ETO'^QPO,58{OOQO'#Cq'#CqO!UQPO,59^O!vQQO,59`O(gQQO'#C|O(nQQO'#EnOOQO'#Ej'#EjOOQO,59f,59fO!UQPO,59fO(uQPO'#EfO,eQPO,59cOOQO'#Dc'#DcOOQO'#Dd'#DdOOQO'#De'#DeO!vQQO'#DaOOQO'#Ef'#EfO,lQPO'#DfO,qQPO'#E^O,yQPO,5;kO!vQQO,5:iOOQO-E8T-E8TOOQO,58y,58yOOQO,59P,59PO-RQPO,59RO-WQPO,59UO-_QPO,5:UO-dQPO,5:XO-kQPO'#FOOOQO'#Dv'#DvO-vQPO'#DuO-{QPO,5:^O.QQPO'#DzO,lQPO,5:eO.]QQO'#ERO/sQPO'#FQOOQO'#EQ'#EQO!UQPO,5:gO1WQPO,5:kO2hQPO'#EoOOQO'#Dx'#DxOOQO,5:o,5:oO3}QPO,5:oOOQO1G.g1G.gOOQO1G.x1G.xO4cQPO1G.zO4jQSO'#EfO5vQSO'#EiO!vQQO'#DOO8kQSO'#DQOOQO'#Ek'#EkOOQO,59h,59hO8uQSO,59hOOQO,5;Y,5;YO8}QPO,5;YO9SQPO1G/QOOQO1G.}1G.}OOQO'#DX'#DXOOQO'#DY'#DYOOQO'#DZ'#DZOOQO'#D['#D[OOQO'#D^'#D^OOQO'#D_'#D_OOQO'#D`'#D`O!vQQO,59oO!vQQO,59oO!vQQO,59oO!vQQO,59oO!vQQO,59oO!vQQO,59oO!vQQO,59oO!vQQO,59oO!vQQO,59oO:cQPO,59{O<OQQO'#DhOOQO,5:Q,5:QO<^QPO,5:xOOQO-E8[-E8[OOQO1G0T1G0TOOQO1G.m1G.mO&`QPO1G.pO!vQQO1G/pO<hQPO1G/sO!vQQO,5:`O!UQPO'#E[O<uQPO,5;jO!vQQO,5:aO&`QPO1G/xO!UQPO'#E]O<}QPO,5:fO!UQPO,5:fOOQO1G0P1G0PO!UQPO'#ESOOQO,5:m,5:mO!UQPO'#E_O=YQPO,5;lO,lQPO1G0RO!vQQO1G0VO!vQQO'#EXO>mQPO,5;ZOOQO1G0Z1G0ZOOQO7+$f7+$fO@QQQO,59kOARQPO,59jOAYQQO1G/SOAaQSO1G/SOOQO1G/S1G/SOAiQSO,59{OOQO1G0t1G0tOOQO7+$l7+$lOD]QPO1G/ZODdQPO1G/ZOGTQPO1G/ZOG[QPO1G/ZOIuQPO1G/ZOJSQPO1G/ZOLTQPO1G/ZO! jQPO1G/ZO! qQPO1G/ZO! xQPO'#EhO!!SQPO'#E}OOQO'#Di'#DiO!![QPO,5:SO!!aQPO7+$[O!!fQPO7+%[O!#uQPO7+%_O!$QQPO1G/zOOQO,5:v,5:vOOQO-E8Y-E8YOOQO1G/{1G/{O!$XQPO7+%dOOQO,5:w,5:wOOQO-E8Z-E8ZO!UQPO1G0QOOQO1G0Q1G0QO!$^QQO,5:nOOQO,5:y,5:yOOQO-E8]-E8]OOQO7+%m7+%mOOQO7+%q7+%qO!$cQPO,5:sOOQO-E8V-E8VO!%xQSO1G/VO!&SQPO1G/UO!'`QSO1G/ZO!'gQSO1G/ZO!(uQSO1G/ZO!(|QSO1G/ZO!*UQSO1G/ZO!*cQSO1G/ZO!+RQSO1G/ZO!-VQSO1G/ZO!-^QSO1G/ZOOQO,5:r,5:rOOQO7+$n7+$nO!-eQQO7+$nOOQO-E8U-E8UO!-lQQO'#EYO!-wQPO,5;iO&`QPO1G/nOOQO<<Gv<<GvO!.PQPO<<HyO!vQQO'#EZOOQO<<Hy<<HyO&`QPO<<HyO!vQQO7+%fOOQO<<IO<<IOOOQO7+%l7+%lOOQO1G0Y1G0YO@QQQO7+$pOOQO<<HY<<HYP'cQQO'#EWO!.[QPO,5:tOOQO,5:t,5:tOOQO-E8W-E8WO!.fQPO7+%YOOQO-E8X-E8XOOQOAN>eAN>eO&`QPOAN>eO!.kQPO,5:uO!.rQPOAN>eO!.wQPO<<IQO!/RQSO<<H[OOQO<<Ht<<HtO!/]QPOG24PO<hQPO1G0aOOQOG24PG24PO!vQQOAN>lOOQOLD)kLD)kOOQO7+%{7+%{O!/bQPOG24WO@QQQO'#DaO@QQQO,59oO@QQQO,59oO@QQQO,59oO@QQQO,59oO@QQQO,59oO@QQQO,59oO@QQQO,59oO@QQQO,59oO@QQQO,59o",
stateData: "!/n~O#UOS#VOSPOS~OSZOUQOWZOY`O[aO_bOlTO!ZfO!_cO!bdO!geO!pgO!xhO#XPO~O#SRP~P]OgkOilOlnOoqOqmO#ZjO~O`xOaxObxOcxOdxOlTOqmO!UwO!ZyO#XPO#ZjO#fuO#itO#jtO#pvO~Og#[Xi#[Xl#[Xo#[Xq#[X#Z#[X~OvzO#`#sX~P#wOS#WXU#WXW#WXY#WX[#WX_#WXl#WX!Z#WX!_#WX!b#WX!g#WX!p#WX!x#WX#S#WX#X#WX]#WX!`#WX!d#WX!e#WX~P#wO#`|O~O#SRX]RX!`RX!dRX!eRX~P]O]RP~P]O!`RP~P]O!Z!_O#XPO~OS!bO#S!wX]!wX!`!wX!d!wX!e!wX~P!vOU!cO~O`xOaxObxOcxOdxOi!hOlTOqmO!U%oO!ZyO#XPO#ZjO#fuO#itO#jtO#pvO~Ou!kO~P'cOm!nO~P!vOm#YXx#YXy#YXz#YX!P#YX#d#YX#e#YX#f#YX#g#YX#h#YX#i#YX#j#YX#k#YX#l#YX#m#YX#n#YX#o#YX[#YX!c#YXS#YX#S#YXj#YXv#YXU#YXW#YXY#YX_#YX!Z#YX!_#YX!b#YX!g#YX!p#YX!x#YX#X#YX]#YX!`#YX!d#YX!e#YX~P!bOx#QOy#ROz!yO!P!}O#d!rO#e!sO#f!tO#g!uO#h!uO#i!vO#j!vO#k!wO#l!wO#m!wO#n!wO#o!xO~Om!qO~P+aOl#TO~OlTO#XPO~OvzO#`#sa~O]#ZO~O[#[O~P+aO!`#]O~O!c#^O~P+aOv#`O#`#_O!k#rX~O!k#bO~O[#cO~Og#dOo#fOl!nX~O#u#hOS!vPU!vPW!vPY!vP[!vP_!vPl!vPv!vP!Z!vP!_!vP!b!vP!g!vP!p!vP!x!vP#S!vP#X!vP#`!vP]!vP!`!vP!d!vP!e!vP~Ov#jOS#tXU#tXW#tXY#tX[#tX_#tXl#tX!Z#tX!_#tX!b#tX!g#tX!p#tX!x#tX#S#tX#X#tX#`#tX]#tX!`#tX!d#tX!e#tX~O#`#mOS!saU!saW!saY!sa[!sa_!sal!sa!Z!sa!_!sa!b!sa!g!sa!p!sa!x!sa#S!sa#X!sa]!sa!`!sa!d!sa!e!sa~OS#nO#S!wa]!wa!`!wa!d!wa!e!wa~P+aOj#oO~P+aOu#YXx#YXy#YXz#YX!P#YX#a#YX#d#YX#e#YX#f#YX#g#YX#h#YX#i#YX#j#YX#k#YX#l#YX#m#YX#n#YX#o#YX~P!bO#`#pOg#]Xi#]Xl#]Xo#]Xq#]Xu#]Xx#]Xy#]Xz#]X!P#]X#Z#]X#a#]X#d#]X#e#]X#f#]X#g#]X#h#]X#i#]X#j#]X#k#]X#l#]X#m#]X#n#]X#o#]X~Ox%wOy%xOz%pO!P%tO#d!rO#e!sO#f!tO#g!uO#h!uO#i!vO#j!vO#k!wO#l!wO#m!wO#n!wO#o!xO~OutX#atX~P6SOu#tO#a#rO~Ov#vOm#cXS#cXU#cXW#cXY#cX[#cX_#cXl#cX!Z#cX!_#cX!b#cX!g#cX!p#cX!x#cX#S#cX#X#cX]#cX!`#cX!d#cX!e#cX~P+aOm#xO~OlnOqmO#ZjO~O#o!xOx!Tay!Taz!Ta!P!Ta#d!Ta#e!Ta#f!Ta#g!Ta#h!Ta#i!Ta#j!Ta#k!Ta#l!Ta#m!Ta#n!Ta~Om!Ta[!Ta!c!TaS!Ta#S!Taj!Tav!TaU!TaW!TaY!Ta_!Tal!Ta!Z!Ta!_!Ta!b!Ta!g!Ta!p!Ta!x!Ta#X!Ta]!Ta!`!Ta!d!Ta!e!Ta~P9aOc$UOlTO#XPOm!]P~Ov#Qa#`#Qa~P#wO]RP!dRP!eRP~P]Ov#`O!k#ra~Og#dOo$cOl!na~Ov#jOS#taU#taW#taY#ta[#ta_#tal#ta!Z#ta!_#ta!b#ta!g#ta!p#ta!x#ta#S#ta#X#ta#`#ta]#ta!`#ta!d#ta!e#ta~O`xOaxObxOcxOdxOlTOqmO!U%oO!ZyO#XPO#ZjO#fuO#itO#jtO#pvO~Oj$kO~P+aOu$vO~P'cOu$vO#a$wO~Ou!Ta#a!Ta~P9aOv#vOm#caS#caU#caW#caY#ca[#ca_#cal#ca!Z#ca!_#ca!b#ca!g#ca!p#ca!x#ca#S#ca#X#ca]#ca!`#ca!d#ca!e#ca~O!P!}O#e!sO#f!tO#g!uO#h!uO#i!vO#j!vO#k!wO#l!wO#m!wO#n!wO#o!xOmwixwiywizwi[wi!cwiSwi#SwijwivwiUwiWwiYwi_wilwi!Zwi!_wi!bwi!gwi!pwi!xwi#Xwi]wi!`wi!dwi!ewi~O#d!rO~PAuO#dwi~PAuO!P!}O#g!uO#h!uO#i!vO#j!vO#k!wO#l!wO#m!wO#n!wO#o!xOmwixwiywizwi#dwi#fwi[wi!cwiSwi#SwijwivwiUwiWwiYwi_wilwi!Zwi!_wi!bwi!gwi!pwi!xwi#Xwi]wi!`wi!dwi!ewi~O#ewi~PDmO#e!sO~PDmO#k!wO#l!wO#m!wO#n!wO#o!xOmwixwiywizwi#dwi#ewi#fwi#gwi#hwi[wi!cwiSwi#SwijwivwiUwiWwiYwi_wilwi!Zwi!_wi!bwi!gwi!pwi!xwi#Xwi]wi!`wi!dwi!ewi~O!P!}O#i!vO#j!vO~PGeO!Pwi#iwi#jwi~PGeO#o!xOmwixwiywi[wi!cwiSwi#SwijwivwiUwiWwiYwi_wilwi!Zwi!_wi!bwi!gwi!pwi!xwi#Xwi]wi!`wi!dwi!ewi~Ozwi!Pwi#dwi#ewi#fwi#gwi#hwi#iwi#jwi#kwi#lwi#mwi#nwi~PJcOz!yO!P!}O#d!rO#e!sO#f!tO#g!uO#h!uO#i!vO#j!vO#k!wO#l!wO#m!wO#n!wO#o!xOmwixwi[wi!cwiSwi#SwijwivwiUwiWwiYwi_wilwi!Zwi!_wi!bwi!gwi!pwi!xwi#Xwi]wi!`wi!dwi!ewi~Oy#RO~PMSOywi~PMSOv${Om#qX~P#wOv${Om#qX~Om$}O~O]%OO~OS!^qU!^qW!^qY!^q[!^q_!^ql!^q!Z!^q!_!^q!b!^q!g!^q!p!^q!x!^q#S!^q#X!^q]!^q!`!^q!d!^q!e!^q~P+aO]%RO!d%QO!e%SO~Ov%TO~P+aO]%UO~O#v%WO~Ousi#asi~P6SO#`%XO~O!P%tO#e!sO#f!tO#g!uO#h!uO#i!vO#j!vO#k!wO#l!wO#m!wO#n!wO#o!xOuwixwiywizwi#awi~O#d!rO~P!$tO#dwi~P!$tO!P%tO#g!uO#h!uO#i!vO#j!vO#k!wO#l!wO#m!wO#n!wO#o!xOuwixwiywizwi#awi#dwi#fwi~O#ewi~P!&ZO#e!sO~P!&ZO#k!wO#l!wO#m!wO#n!wO#o!xOuwixwiywizwi#awi#dwi#ewi#fwi#gwi#hwi~O!P%tO#i!vO#j!vO~P!'pO!Pwi#iwi#jwi~P!'pO#o!xOuwixwiywi#awi~Ozwi!Pwi#dwi#ewi#fwi#gwi#hwi#iwi#jwi#kwi#lwi#mwi#nwi~P!)]Oz%pO!P%tO#d!rO#e!sO#f!tO#g!uO#h!uO#i!vO#j!vO#k!wO#l!wO#m!wO#n!wO#o!xOuwixwi#awi~Oy%xO~P!*kOywi~P!*kOu%YO~P'cOm!{av!{aS!{aU!{aW!{aY!{a[!{a_!{al!{a!Z!{a!_!{a!b!{a!g!{a!p!{a!x!{a#S!{a#X!{a]!{a!`!{a!d!{a!e!{a~P+aOc%]OlTO#XPO~Ov${Om#qa~O]%aO!d%QO!e%bO~Om!|av!|a~P#wO]%gO~O!c%iO~P+aO]%jO~Ov%kO[!hy~P+aOury#ary~P6SO]%lO~O[!h!Z~P+aOP#j~", stateData: "!/l~O#UOS#VOSPOS~OSZOUQOWZOY`O[aO_bOlTO!ZfO!_cO!bdO!geO!pgO!xhO#XPO~O#SRP~P]OgkOilOlnOoqOqmO#ZjO~O`xOaxObxOcxOdxOlTOqmO!UwO!ZyO#XPO#ZjO#fuO#itO#jtO#pvO~Og#[Xi#[Xl#[Xo#[Xq#[X#Z#[X~OvzO#`#sX~P#wOS#WXU#WXW#WXY#WX[#WX_#WXl#WX!Z#WX!_#WX!b#WX!g#WX!p#WX!x#WX#S#WX#X#WX]#WX!`#WX!d#WX!e#WX~P#wO#`|O~O#SRX]RX!`RX!dRX!eRX~P]O]RP~P]O!`RP~P]O!Z!_O#XPO~OS!cO#S!wX]!wX!`!wX!d!wX!e!wX~P!vOU!eO~O`xOaxObxOcxOdxOi!jOlTOqmO!U%oO!ZyO#XPO#ZjO#fuO#itO#jtO#pvO~Ou!mO~P'cOm!oO~P!vOm#YXx#YXy#YXz#YX!P#YX#d#YX#e#YX#f#YX#g#YX#h#YX#i#YX#j#YX#k#YX#l#YX#m#YX#n#YX#o#YX[#YX!c#YXS#YXv#YX#S#YXj#YXU#YXW#YXY#YX_#YX!Z#YX!_#YX!b#YX!g#YX!p#YX!x#YX#X#YX]#YX!`#YX!d#YX!e#YX~P!bOx#ROy#SOz!zO!P#OO#d!sO#e!tO#f!uO#g!vO#h!vO#i!wO#j!wO#k!xO#l!xO#m!xO#n!xO#o!yO~Om!rO~P+aOl#UO~OlTO#XPO~OvzO#`#sa~O]#ZO~O[#[O~P+aO!`#]O~O!c#^O~P+aOv#`O#`#_O!k#rX~O!k#bO~O[#cO~Og#dOo#fOl!nX~O#u#hOS!vPU!vPW!vPY!vP[!vP_!vPl!vPv!vP!Z!vP!_!vP!b!vP!g!vP!p!vP!x!vP#S!vP#X!vP#`!vP]!vP!`!vP!d!vP!e!vP~Ov#jOS#tXU#tXW#tXY#tX[#tX_#tXl#tX!Z#tX!_#tX!b#tX!g#tX!p#tX!x#tX#S#tX#X#tX#`#tX]#tX!`#tX!d#tX!e#tX~O#`#mOS!saU!saW!saY!sa[!sa_!sal!sa!Z!sa!_!sa!b!sa!g!sa!p!sa!x!sa#S!sa#X!sa]!sa!`!sa!d!sa!e!sa~Ov#nOS#cX#S#cXm#cXU#cXW#cXY#cX[#cX_#cXl#cX!Z#cX!_#cX!b#cX!g#cX!p#cX!x#cX#X#cX]#cX!`#cX!d#cX!e#cX~P+aOS#pO#S!wa]!wa!`!wa!d!wa!e!wa~Oj#qO~P+aOu#YXx#YXy#YXz#YX!P#YX#a#YX#d#YX#e#YX#f#YX#g#YX#h#YX#i#YX#j#YX#k#YX#l#YX#m#YX#n#YX#o#YX~P!bO#`#rOg#]Xi#]Xl#]Xo#]Xq#]Xu#]Xx#]Xy#]Xz#]X!P#]X#Z#]X#a#]X#d#]X#e#]X#f#]X#g#]X#h#]X#i#]X#j#]X#k#]X#l#]X#m#]X#n#]X#o#]X~Ox%wOy%xOz%pO!P%tO#d!sO#e!tO#f!uO#g!vO#h!vO#i!wO#j!wO#k!xO#l!xO#m!xO#n!xO#o!yO~OutX#atX~P7gOu#vO#a#tO~Om#xO~OlnOqmO#ZjO~O#o!yOx!Tay!Taz!Ta!P!Ta#d!Ta#e!Ta#f!Ta#g!Ta#h!Ta#i!Ta#j!Ta#k!Ta#l!Ta#m!Ta#n!Ta~Om!Ta[!Ta!c!TaS!Tav!Ta#S!Taj!TaU!TaW!TaY!Ta_!Tal!Ta!Z!Ta!_!Ta!b!Ta!g!Ta!p!Ta!x!Ta#X!Ta]!Ta!`!Ta!d!Ta!e!Ta~P9_Oc$UOlTO#XPOm!]P~Ov#Qa#`#Qa~P#wO]RP!dRP!eRP~P]Ov#`O!k#ra~Og#dOo$cOl!na~Ov#jOS#taU#taW#taY#ta[#ta_#tal#ta!Z#ta!_#ta!b#ta!g#ta!p#ta!x#ta#S#ta#X#ta#`#ta]#ta!`#ta!d#ta!e#ta~Ov#nOS#ca#S#cam#caU#caW#caY#ca[#ca_#cal#ca!Z#ca!_#ca!b#ca!g#ca!p#ca!x#ca#X#ca]#ca!`#ca!d#ca!e#ca~O`xOaxObxOcxOdxOlTOqmO!U%oO!ZyO#XPO#ZjO#fuO#itO#jtO#pvO~Oj$mO~P+aOu$xO~P'cOu$xO#a$yO~Ou!Ta#a!Ta~P9_O!P#OO#e!tO#f!uO#g!vO#h!vO#i!wO#j!wO#k!xO#l!xO#m!xO#n!xO#o!yOmwixwiywizwi[wi!cwiSwivwi#SwijwiUwiWwiYwi_wilwi!Zwi!_wi!bwi!gwi!pwi!xwi#Xwi]wi!`wi!dwi!ewi~O#d!sO~PAsO#dwi~PAsO!P#OO#g!vO#h!vO#i!wO#j!wO#k!xO#l!xO#m!xO#n!xO#o!yOmwixwiywizwi#dwi#fwi[wi!cwiSwivwi#SwijwiUwiWwiYwi_wilwi!Zwi!_wi!bwi!gwi!pwi!xwi#Xwi]wi!`wi!dwi!ewi~O#ewi~PDkO#e!tO~PDkO#k!xO#l!xO#m!xO#n!xO#o!yOmwixwiywizwi#dwi#ewi#fwi#gwi#hwi[wi!cwiSwivwi#SwijwiUwiWwiYwi_wilwi!Zwi!_wi!bwi!gwi!pwi!xwi#Xwi]wi!`wi!dwi!ewi~O!P#OO#i!wO#j!wO~PGcO!Pwi#iwi#jwi~PGcO#o!yOmwixwiywi[wi!cwiSwivwi#SwijwiUwiWwiYwi_wilwi!Zwi!_wi!bwi!gwi!pwi!xwi#Xwi]wi!`wi!dwi!ewi~Ozwi!Pwi#dwi#ewi#fwi#gwi#hwi#iwi#jwi#kwi#lwi#mwi#nwi~PJaOz!zO!P#OO#d!sO#e!tO#f!uO#g!vO#h!vO#i!wO#j!wO#k!xO#l!xO#m!xO#n!xO#o!yOmwixwi[wi!cwiSwivwi#SwijwiUwiWwiYwi_wilwi!Zwi!_wi!bwi!gwi!pwi!xwi#Xwi]wi!`wi!dwi!ewi~Oy#SO~PMQOywi~PMQOv${Om#qX~P#wOv${Om#qX~Om$}O~O]%OO~OS!^qU!^qW!^qY!^q[!^q_!^ql!^q!Z!^q!_!^q!b!^q!g!^q!p!^q!x!^q#S!^q#X!^q]!^q!`!^q!d!^q!e!^q~P+aO]%RO!d%QO!e%SO~Ov%TO~P+aO]%UO~O#v%WO~OS!{av!{a#S!{am!{aU!{aW!{aY!{a[!{a_!{al!{a!Z!{a!_!{a!b!{a!g!{a!p!{a!x!{a#X!{a]!{a!`!{a!d!{a!e!{a~P+aOusi#asi~P7gO#`%XO~O!P%tO#e!tO#f!uO#g!vO#h!vO#i!wO#j!wO#k!xO#l!xO#m!xO#n!xO#o!yOuwixwiywizwi#awi~O#d!sO~P!&XO#dwi~P!&XO!P%tO#g!vO#h!vO#i!wO#j!wO#k!xO#l!xO#m!xO#n!xO#o!yOuwixwiywizwi#awi#dwi#fwi~O#ewi~P!'nO#e!tO~P!'nO#k!xO#l!xO#m!xO#n!xO#o!yOuwixwiywizwi#awi#dwi#ewi#fwi#gwi#hwi~O!P%tO#i!wO#j!wO~P!)TO!Pwi#iwi#jwi~P!)TO#o!yOuwixwiywi#awi~Ozwi!Pwi#dwi#ewi#fwi#gwi#hwi#iwi#jwi#kwi#lwi#mwi#nwi~P!*pOz%pO!P%tO#d!sO#e!tO#f!uO#g!vO#h!vO#i!wO#j!wO#k!xO#l!xO#m!xO#n!xO#o!yOuwixwi#awi~Oy%xO~P!,OOywi~P!,OOu%YO~P'cOc%]OlTO#XPO~Ov${Om#qa~O]%aO!d%QO!e%bO~Om!|av!|a~P#wO]%gO~O!c%iO~P+aO]%jO~Ov%kO[!hy~P+aOury#ary~P7gO]%lO~O[!h!Z~P+aOP#j~",
goto: ";f#uPPP#vP$fP$sP$fP$fPP$fPPPPPP&{(PP(PPP)]PP*iP&{P+w+w+wPP'RPPP+},i-X-uP.g/Z0P'RP0y0y0y'RP1y2S$fPP$fPPPP$fP2V2V2YP2]$f2f$fP$f2i$f2v2y3P3SP3c3r3x4O4V4]4c4i4oPPPP4uP5SP7j8z:`:hPP:p:vPPPPPPPPPPPPP;O;R;U;cQ_OQ!QaQ!ScQ$X#[Q$Z#^Q$`#cQ%_$}Q%d%SQ%h%bR%m%igZO]ac#[#^#c$}%S%b%i#[SOT]abcdhlnwz|!h!y!z!{!|!}#O#P#Q#R#T#[#]#^#_#b#c#m#p#v${$}%Q%S%T%X%b%i%k%o%p%q%r%s%t%u%v%w%xQiQQ!P`Q!UeQ!YfS![g#jQ!dkW!gm#r$w%ZQ!pqQ#l!_Q$]#`Q$a#dQ$d#fQ$e#hR%V$cWoRr!f!p!wxTbdhlmnw|!h!y!z!{!|!}#O#P#Q#R#]#_#b#m#p#r#v$w%Q%T%X%Z%k%o%p%q%r%s%t%u%v%w%x#eSOT]abcdhlmnwz|!h!y!z!{!|!}#O#P#Q#R#T#[#]#^#_#b#c#m#p#r#v$w${$}%Q%S%T%X%Z%b%i%k%o%p%q%r%s%t%u%v%w%x#eVOT]abcdhlmnwz|!h!y!z!{!|!}#O#P#Q#R#T#[#]#^#_#b#c#m#p#r#v$w${$}%Q%S%T%X%Z%b%i%k%o%p%q%r%s%t%u%v%w%x!|VTbdhlmnwz|!h!y!z!{!|!}#O#P#Q#R#T#]#_#b#m#p#r#v$w${%Q%T%X%Z%k%o%p%q%r%s%t%u%v%w%xgWO]ac#[#^#c$}%S%b%iX!jm#r$w%Zp!zs!R!T!a!e!m#q#z$R$S$Y$[$y%c%e%n]%q!i$j$l$s$t%ft!{s!R!T!a!e!m#q#z#{#}$R$S$Y$[$y%c%e%na%r!i$j$l$m$o$s$t%fr!|s!R!T!a!e!m#q#z#{$R$S$Y$[$y%c%e%n_%s!i$j$l$m$s$t%fv!}s!R!T!a!e!m#q#z#{#|#}$R$S$Y$[$y%c%e%nc%t!i$j$l$m$n$o$s$t%fx#Os!R!T!a!e!m#q#z#{#|#}$O$R$S$Y$[$y%c%e%ne%u!i$j$l$m$n$o$p$s$t%fz#Ps!R!T!a!e!m#q#z#{#|#}$O$P$R$S$Y$[$y%c%e%ng%v!i$j$l$m$n$o$p$q$s$t%f!O#Ps!R!T!a!e!m#S#q#z#{#|#}$O$P$Q$R$S$Y$[$y%c%e%nk%v!i#u$j$l$m$n$o$p$q$r$s$t%f!UwTbdhlnw|!h!y!z!{!|!}#O#P#Q#R#]#_#b#m#v%Q%T%kq%om#p#r$w%X%Z%o%p%q%r%s%t%u%v%w%xQ#UyQ#g!ZR$h#lR$W#TR!XeR!WeQ#Y|Q$_#bR$i#mR!ZfgYO]ac#[#^#c$}%S%b%iR!`gQ!]gR$f#jR#i![d^Oac#[#^#c$}%S%b%iR!O]d]Oac#[#^#c$}%S%b%iR}]Q#s!lR$x#sQ#w!mR$z#wS$|$T$UR%^$|Q%P$ZR%`%PQ#a!UR$^#aQ#e!YR$b#eQ{UR#W{Q#k!]R$g#kg[O]ac#[#^#c$}%S%b%iQsTQ!RbQ!TdQ!ahQ!elW!im#r$w%ZW!mn|#b#mQ#SwQ#q!hQ#u%oQ#z!yQ#{!zQ#|!{Q#}!|Q$O!}Q$P#OQ$Q#PQ$R#QQ$S#RQ$Y#]Q$[#_Q$j#pQ$l%pQ$m%qQ$n%rQ$o%sQ$p%tQ$q%uQ$r%vQ$s%wQ$t%xQ$y#vQ%c%QQ%e%TQ%f%XR%n%klRO]acz#T#[#^#c${$}%S%b%i!UrTbdhlnw|!h!y!z!{!|!}#O#P#Q#R#]#_#b#m#v%Q%T%kq!fm#p#r$w%X%Z%o%p%q%r%s%t%u%v%w%xfUO]ac#[#^#c$}%S%b%i!vVTbdhlmnw|!h!y!z!{!|!}#O#P#Q#R#]#_#b#m#p#r#v$w%Q%T%X%Z%k%o%p%q%r%s%t%u%v%w%xQ#VzQ$T#TR%[${UpRr!fR#y!pQ!lmV$u#r$w%ZXoRr!f!pQ!onV#X|#b#mR$V#TR!VegXO]ac#[#^#c$}%S%b%iR!^g", goto: ";a#uPPP#vP$fP$sP$fP$fPP$fPPPPPP&{(PP(PPP)]PP*iP&{P+w+w+wPP'RPPP+},h-V-rP.c/U/y'RP0r0r0r'RP1r1{$fPP$fPPPP$fP2O2O2RP2U$f2b$fP$f2e$f2r2u2{3OP3_3n3t3z4R4X4_4e4kPPPP4qP5OP7d8t:Y:bPP:j:pPPPPPPPPPPPPP:y:|;P;^Q_OQ!QaQ!ScQ$X#[Q$Z#^Q$`#cQ%_$}Q%d%SQ%h%bR%m%igZO]ac#[#^#c$}%S%b%i#[SOT]abcdhlnwz|!j!z!{!|!}#O#P#Q#R#S#U#[#]#^#_#b#c#m#n#r${$}%Q%S%T%X%b%i%k%o%p%q%r%s%t%u%v%w%xQiQQ!P`Q!UeQ!YfS![g#jQ!fkW!im#t$y%ZQ!qqQ#l!_Q$]#`Q$a#dQ$d#fQ$e#hR%V$cWoRr!h!q!wxTbdhlmnw|!j!z!{!|!}#O#P#Q#R#S#]#_#b#m#n#r#t$y%Q%T%X%Z%k%o%p%q%r%s%t%u%v%w%x#eSOT]abcdhlmnwz|!j!z!{!|!}#O#P#Q#R#S#U#[#]#^#_#b#c#m#n#r#t$y${$}%Q%S%T%X%Z%b%i%k%o%p%q%r%s%t%u%v%w%x#eVOT]abcdhlmnwz|!j!z!{!|!}#O#P#Q#R#S#U#[#]#^#_#b#c#m#n#r#t$y${$}%Q%S%T%X%Z%b%i%k%o%p%q%r%s%t%u%v%w%x!|VTbdhlmnwz|!j!z!{!|!}#O#P#Q#R#S#U#]#_#b#m#n#r#t$y${%Q%T%X%Z%k%o%p%q%r%s%t%u%v%w%xgWO]ac#[#^#c$}%S%b%iX!lm#t$y%Zn!{s!R!T!a!g#s#z$R$S$Y$[$j%c%e%n]%q!k$l$n$u$v%fr!|s!R!T!a!g#s#z#{#}$R$S$Y$[$j%c%e%na%r!k$l$n$o$q$u$v%fp!}s!R!T!a!g#s#z#{$R$S$Y$[$j%c%e%n_%s!k$l$n$o$u$v%ft#Os!R!T!a!g#s#z#{#|#}$R$S$Y$[$j%c%e%nc%t!k$l$n$o$p$q$u$v%fv#Ps!R!T!a!g#s#z#{#|#}$O$R$S$Y$[$j%c%e%ne%u!k$l$n$o$p$q$r$u$v%fx#Qs!R!T!a!g#s#z#{#|#}$O$P$R$S$Y$[$j%c%e%ng%v!k$l$n$o$p$q$r$s$u$v%f|#Qs!R!T!a!g#T#s#z#{#|#}$O$P$Q$R$S$Y$[$j%c%e%nk%v!k#w$l$n$o$p$q$r$s$t$u$v%f!UwTbdhlnw|!j!z!{!|!}#O#P#Q#R#S#]#_#b#m#n%Q%T%kq%om#r#t$y%X%Z%o%p%q%r%s%t%u%v%w%xQ#VyQ#g!ZR$h#lR$W#UR!XeR!WeQ!dhQ#Y|Q$_#bR$i#mR!ZfgYO]ac#[#^#c$}%S%b%iR!`gQ!]gR$f#jR#i![d^Oac#[#^#c$}%S%b%iR!O]d]Oac#[#^#c$}%S%b%iR}]Q#u!nR$z#uQ#o!aR$k#oS$|$T$UR%^$|Q%P$ZR%`%PQ#a!UR$^#aQ#e!YR$b#eQ{UR#X{Q#k!]R$g#kg[O]ac#[#^#c$}%S%b%iQsTQ!RbQ!TdY!ahn|#b#mQ!glW!km#t$y%ZQ#TwQ#s!jQ#w%oQ#z!zQ#{!{Q#|!|Q#}!}Q$O#OQ$P#PQ$Q#QQ$R#RQ$S#SQ$Y#]Q$[#_Q$j#nQ$l#rQ$n%pQ$o%qQ$p%rQ$q%sQ$r%tQ$s%uQ$t%vQ$u%wQ$v%xQ%c%QQ%e%TQ%f%XR%n%klRO]acz#U#[#^#c${$}%S%b%i!UrTbdhlnw|!j!z!{!|!}#O#P#Q#R#S#]#_#b#m#n%Q%T%kq!hm#r#t$y%X%Z%o%p%q%r%s%t%u%v%w%xfUO]ac#[#^#c$}%S%b%i!vVTbdhlmnw|!j!z!{!|!}#O#P#Q#R#S#]#_#b#m#n#r#t$y%Q%T%X%Z%k%o%p%q%r%s%t%u%v%w%xQ#WzQ$T#UR%[${UpRr!hR#y!qQ!nmV$w#t$y%ZXoRr!h!qW!bh|#b#mR!pnR$V#UR!VegXO]ac#[#^#c$}%S%b%iR!^g",
nodeNames: "⚠ Comment Chunk Block ; Label :: Name break Goto goto Scope do end WhileStatement while nil true false Ellipsis Number LiteralString Property . MemberExpression [ ] Parens ( ) FunctionCall : TableConstructor { FieldDynamic FieldProp FieldExp } , BinaryExpression or and CompareOp BitOp BitOp BitOp BitOp Concat ArithOp ArithOp ArithOp UnaryExpression not ArithOp BitOp LenOp FunctionDef function FuncBody ArgList RepeatStatement repeat until IfStatement if then elseif else ForStatement for ForNumeric ForGeneric NameList in ExpList Function FuncName LocalFunction local Assign VarList Local AttNameList AttName Attrib ReturnStatement return", nodeNames: "⚠ Comment Chunk Block ; Label :: Name break Goto goto Scope do end WhileStatement while nil true false Ellipsis Number LiteralString Property . MemberExpression [ ] Parens ( ) FunctionCall : TableConstructor { FieldDynamic FieldProp FieldExp } , BinaryExpression or and CompareOp BitOp BitOp BitOp BitOp Concat ArithOp ArithOp ArithOp UnaryExpression not ArithOp BitOp LenOp FunctionDef function FuncBody ArgList RepeatStatement repeat until IfStatement if then elseif else ForStatement for ForNumeric ForGeneric NameList in ExpList Function FuncName LocalFunction local Assign VarList Local AttNameList AttName Attrib ReturnStatement return",
maxTerm: 130, maxTerm: 130,
nodeProps: [ nodeProps: [
@ -13,10 +13,10 @@ export const parser = LRParser.deserialize({
], ],
skippedNodes: [0,1], skippedNodes: [0,1],
repeatNodeCount: 9, repeatNodeCount: 9,
tokenData: "7O~RsXY#`YZ#z[]#`]^$Xpq#`rs$ast)duv)ivw)nwx)sxy.qyz.vz{.{{|/Q|}/V}!O/^!O!P0Q!P!Q0g!Q!R0|!R![2b![!]4f!]!^4s!^!_4z!_!`5^!`!a5f!c!}5x!}#O6W#O#P#q#P#Q6]#Q#R6b#T#o5x#o#p6g#p#q6l#q#r6q#r#s6v~#eS#V~XY#`[]#`pq#`#O#P#q~#tQYZ#`]^#`~$PP#U~]^$S~$XO#U~~$^P#U~YZ$S~$dWOY$|Z]$|^r$|s#O$|#O#P%q#P;'S$|;'S;=`(R<%lO$|~%PXOY$|Z]$|^r$|rs%ls#O$|#O#P%q#P;'S$|;'S;=`(R<%lO$|~%qO#Z~~%tZrs$|wx$|!Q![&g#O#P$|#T#U$|#U#V$|#Y#Z$|#b#c$|#i#j(X#l#m(z#n#o$|~&jZOY$|Z]$|^r$|rs%ls!Q$|!Q![']![#O$|#O#P%q#P;'S$|;'S;=`(R<%lO$|~'`ZOY$|Z]$|^r$|rs%ls!Q$|!Q![$|![#O$|#O#P%q#P;'S$|;'S;=`(R<%lO$|~(UP;=`<%l$|~([P#o#p(_~(bR!Q![(k!c!i(k#T#Z(k~(nS!Q![(k!c!i(k#T#Z(k#q#r$|~(}R!Q![)W!c!i)W#T#Z)W~)ZR!Q![$|!c!i$|#T#Z$|~)iO#p~~)nO#m~~)sO#e~~)vWOY*`Z]*`^w*`x#O*`#O#P+O#P;'S*`;'S;=`-`<%lO*`~*cXOY*`Z]*`^w*`wx%lx#O*`#O#P+O#P;'S*`;'S;=`-`<%lO*`~+RZrs*`wx*`!Q![+t#O#P*`#T#U*`#U#V*`#Y#Z*`#b#c*`#i#j-f#l#m.X#n#o*`~+wZOY*`Z]*`^w*`wx%lx!Q*`!Q![,j![#O*`#O#P+O#P;'S*`;'S;=`-`<%lO*`~,mZOY*`Z]*`^w*`wx%lx!Q*`!Q![*`![#O*`#O#P+O#P;'S*`;'S;=`-`<%lO*`~-cP;=`<%l*`~-iP#o#p-l~-oR!Q![-x!c!i-x#T#Z-x~-{S!Q![-x!c!i-x#T#Z-x#q#r*`~.[R!Q![.e!c!i.e#T#Z.e~.hR!Q![*`!c!i*`#T#Z*`~.vOl~~.{Om~~/QO#k~~/VO#i~V/^OvR#aS~/cP#j~}!O/f~/kTP~OY/fZ]/f^;'S/f;'S;=`/z<%lO/f~/}P;=`<%l/fV0VPgT!O!P0YV0_P!PT!O!P0bQ0gOcQ~0lQ#l~!P!Q0r!_!`0w~0wO#n~T0|OzT~1RUd~!O!P1e!Q![2b!g!h1y!z!{2s#X#Y1y#l#m2s~1hP!Q![1k~1pRd~!Q![1k!g!h1y#X#Y1y~1|Q{|2S}!O2S~2VP!Q![2Y~2_Pd~!Q![2Y~2gSd~!O!P1e!Q![2b!g!h1y#X#Y1y~2vR!Q![3P!c!i3P#T#Z3P~3UUd~!O!P3h!Q![3P!c!i3P!r!s4Y#T#Z3P#d#e4Y~3kR!Q![3t!c!i3t#T#Z3t~3yTd~!Q![3t!c!i3t!r!s4Y#T#Z3t#d#e4Y~4]R{|2S}!O2S!P!Q2S~4kPo~![!]4n~4sOU~V4zOSR#aSV5RQ#uQzT!^!_5X!_!`0wT5^O#gT~5cP#`~!_!`0wV5mQ#vQzT!_!`0w!`!a5sT5xO#hT~5}R#X~!Q![5x!c!}5x#T#o5x~6]Oi~~6bOj~~6gO#o~~6lOq~~6qO#d~~6vOu~~6{P#f~!_!`0w", tokenData: "7X~RtXY#cYZ#}[]#c]^$[pq#cqr$drs$ost)ruv)wvw)|wx*Rxy/Pyz/Uz{/Z{|/`|}/e}!O/l!O!P0`!P!Q0u!Q!R1V!R![2k![!]4o!]!^4|!^!_5T!_!`5g!`!a5o!c!}6R!}#O6a#O#P#t#P#Q6f#Q#R6k#T#o6R#o#p6p#p#q6u#q#r6z#r#s7P~#hS#V~XY#c[]#cpq#c#O#P#t~#wQYZ#c]^#c~$SP#U~]^$V~$[O#U~~$aP#U~YZ$VT$gP!_!`$jT$oOzT~$rWOY%[Z]%[^r%[s#O%[#O#P&P#P;'S%[;'S;=`(a<%lO%[~%_XOY%[Z]%[^r%[rs%zs#O%[#O#P&P#P;'S%[;'S;=`(a<%lO%[~&PO#Z~~&SZrs%[wx%[!Q![&u#O#P%[#T#U%[#U#V%[#Y#Z%[#b#c%[#i#j(g#l#m)Y#n#o%[~&xZOY%[Z]%[^r%[rs%zs!Q%[!Q!['k![#O%[#O#P&P#P;'S%[;'S;=`(a<%lO%[~'nZOY%[Z]%[^r%[rs%zs!Q%[!Q![%[![#O%[#O#P&P#P;'S%[;'S;=`(a<%lO%[~(dP;=`<%l%[~(jP#o#p(m~(pR!Q![(y!c!i(y#T#Z(y~(|S!Q![(y!c!i(y#T#Z(y#q#r%[~)]R!Q![)f!c!i)f#T#Z)f~)iR!Q![%[!c!i%[#T#Z%[~)wO#p~~)|O#m~~*RO#e~~*UWOY*nZ]*n^w*nx#O*n#O#P+^#P;'S*n;'S;=`-n<%lO*n~*qXOY*nZ]*n^w*nwx%zx#O*n#O#P+^#P;'S*n;'S;=`-n<%lO*n~+aZrs*nwx*n!Q![,S#O#P*n#T#U*n#U#V*n#Y#Z*n#b#c*n#i#j-t#l#m.g#n#o*n~,VZOY*nZ]*n^w*nwx%zx!Q*n!Q![,x![#O*n#O#P+^#P;'S*n;'S;=`-n<%lO*n~,{ZOY*nZ]*n^w*nwx%zx!Q*n!Q![*n![#O*n#O#P+^#P;'S*n;'S;=`-n<%lO*n~-qP;=`<%l*n~-wP#o#p-z~-}R!Q![.W!c!i.W#T#Z.W~.ZS!Q![.W!c!i.W#T#Z.W#q#r*n~.jR!Q![.s!c!i.s#T#Z.s~.vR!Q![*n!c!i*n#T#Z*n~/UOl~~/ZOm~~/`O#k~~/eO#i~V/lOvR#aS~/qP#j~}!O/t~/yTP~OY/tZ]/t^;'S/t;'S;=`0Y<%lO/t~0]P;=`<%l/tV0ePgT!O!P0hV0mP!PT!O!P0pQ0uOcQ~0zQ#l~!P!Q1Q!_!`$j~1VO#n~~1[Ud~!O!P1n!Q![2k!g!h2S!z!{2|#X#Y2S#l#m2|~1qP!Q![1t~1yRd~!Q![1t!g!h2S#X#Y2S~2VQ{|2]}!O2]~2`P!Q![2c~2hPd~!Q![2c~2pSd~!O!P1n!Q![2k!g!h2S#X#Y2S~3PR!Q![3Y!c!i3Y#T#Z3Y~3_Ud~!O!P3q!Q![3Y!c!i3Y!r!s4c#T#Z3Y#d#e4c~3tR!Q![3}!c!i3}#T#Z3}~4STd~!Q![3}!c!i3}!r!s4c#T#Z3}#d#e4c~4fR{|2]}!O2]!P!Q2]~4tPo~![!]4w~4|OU~V5TOSR#aSV5[Q#uQzT!^!_5b!_!`$jT5gO#gT~5lP#`~!_!`$jV5vQ#vQzT!_!`$j!`!a5|T6RO#hT~6WR#X~!Q![6R!c!}6R#T#o6R~6fOi~~6kOj~~6pO#o~~6uOq~~6zO#d~~7POu~~7UP#f~!_!`$j",
tokenizers: [0, 1, 2], tokenizers: [0, 1, 2],
topRules: {"Chunk":[0,2]}, topRules: {"Chunk":[0,2]},
dynamicPrecedences: {"110":1}, dynamicPrecedences: {"110":1},
specialized: [{term: 101, get: (value) => spec_identifier[value] || -1}], specialized: [{term: 101, get: (value) => spec_identifier[value] || -1}],
tokenPrec: 2787 tokenPrec: 2785
}) })

View File

@ -81,4 +81,9 @@ Deno.test("Test Lua parser", () => {
parse(`a(1, 2, 3)`); parse(`a(1, 2, 3)`);
parse(`print "Sup"`); parse(`print "Sup"`);
parse(`e(1 + print "8")`); parse(`e(1 + print "8")`);
// Return statements
parse(`return`);
parse(`return 1`);
parse(`return 1, 2, 3`);
}); });

View File

@ -165,6 +165,10 @@ function parseStatement(n: CrudeAST): LuaStatement {
names: parseAttNames(t[2]), names: parseAttNames(t[2]),
expressions: t[4] ? parseExpList(t[4]) : [], expressions: t[4] ? parseExpList(t[4]) : [],
}; };
case "ReturnStatement": {
const expressions = t[2] ? parseExpList(t[2]) : [];
return { type: "Return", expressions };
}
case "break": case "break":
return { type: "Break" }; return { type: "Break" };
default: default:

View File

@ -1,6 +1,7 @@
import type { LuaFunctionBody } from "./ast.ts"; import type { LuaFunctionBody } from "./ast.ts";
import { evalStatement } from "$common/space_lua/eval.ts";
export class LuaEnv implements ILuaSettable { export class LuaEnv implements ILuaSettable, ILuaGettable {
variables = new Map<string, LuaValue>(); variables = new Map<string, LuaValue>();
constructor(readonly parent?: LuaEnv) { constructor(readonly parent?: LuaEnv) {
@ -18,7 +19,7 @@ export class LuaEnv implements ILuaSettable {
} }
} }
get(name: string): LuaValue { get(name: string): LuaValue | undefined {
if (this.variables.has(name)) { if (this.variables.has(name)) {
return this.variables.get(name); return this.variables.get(name);
} }
@ -61,6 +62,10 @@ export interface ILuaSettable {
set(key: LuaValue, value: LuaValue): void; set(key: LuaValue, value: LuaValue): void;
} }
export interface ILuaGettable {
get(key: LuaValue): LuaValue | undefined;
}
export class LuaFunction implements ILuaFunction { export class LuaFunction implements ILuaFunction {
constructor(private body: LuaFunctionBody, private closure: LuaEnv) { constructor(private body: LuaFunctionBody, private closure: LuaEnv) {
} }
@ -76,7 +81,19 @@ export class LuaFunction implements ILuaFunction {
} }
env.set(this.body.parameters[i], arg); env.set(this.body.parameters[i], arg);
} }
throw new Error("Not yet implemented funciton call"); return evalStatement(this.body.block, env).catch((e: any) => {
if (e instanceof LuaReturn) {
if (e.values.length === 0) {
return;
} else if (e.values.length === 1) {
return e.values[0];
} else {
return new LuaMultiRes(e.values);
}
} else {
throw e;
}
});
} }
} }
@ -94,7 +111,7 @@ export class LuaNativeJSFunction implements ILuaFunction {
} }
} }
export class LuaTable implements ILuaSettable { export class LuaTable implements ILuaSettable, ILuaGettable {
// To optimize the table implementation we use a combination of different data structures // To optimize the table implementation we use a combination of different data structures
// When tables are used as maps, the common case is that they are string keys, so we use a simple object for that // When tables are used as maps, the common case is that they are string keys, so we use a simple object for that
private stringKeys: Record<string, any>; private stringKeys: Record<string, any>;
@ -131,7 +148,7 @@ export class LuaTable implements ILuaSettable {
} }
} }
get(key: LuaValue): LuaValue { get(key: LuaValue): LuaValue | undefined {
if (typeof key === "string") { if (typeof key === "string") {
return this.stringKeys[key]; return this.stringKeys[key];
} else if (Number.isInteger(key) && key >= 1) { } else if (Number.isInteger(key) && key >= 1) {
@ -202,6 +219,12 @@ export function luaLen(obj: any): number {
export class LuaBreak extends Error { export class LuaBreak extends Error {
} }
export class LuaReturn extends Error {
constructor(readonly values: LuaValue[]) {
super();
}
}
export function luaTruthy(value: any): boolean { export function luaTruthy(value: any): boolean {
if (value === undefined || value === null || value === false) { if (value === undefined || value === null || value === false) {
return false; return false;