[Lua] Property access and function call fixes
parent
b2ff858f1d
commit
69c1da3dfb
|
@ -70,6 +70,12 @@ Deno.test("Evaluator test", async () => {
|
||||||
assertEquals(singleResult(evalExpr(`test(3)`, env)), 3);
|
assertEquals(singleResult(evalExpr(`test(3)`, env)), 3);
|
||||||
assertEquals(singleResult(await evalExpr(`asyncTest(3) + 1`, env)), 4);
|
assertEquals(singleResult(await evalExpr(`asyncTest(3) + 1`, env)), 4);
|
||||||
|
|
||||||
|
// Function expressions and table access
|
||||||
|
assertEquals(
|
||||||
|
await evalExpr(`(function() return {name="John"} end)().name`),
|
||||||
|
"John",
|
||||||
|
);
|
||||||
|
|
||||||
// Function definitions
|
// Function definitions
|
||||||
const fn = evalExpr(`function(a, b) return a + b end`);
|
const fn = evalExpr(`function(a, b) return a + b end`);
|
||||||
assertEquals(fn.body.parameters, ["a", "b"]);
|
assertEquals(fn.body.parameters, ["a", "b"]);
|
||||||
|
|
|
@ -104,6 +104,26 @@ export function evalExpression(
|
||||||
return luaGet(singleResult(values[0]), singleResult(values[1]));
|
return luaGet(singleResult(values[0]), singleResult(values[1]));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
case "PropertyAccess": {
|
||||||
|
const obj = evalPrefixExpression(e.object, env);
|
||||||
|
if (obj instanceof Promise) {
|
||||||
|
return obj.then((obj) => {
|
||||||
|
if (!obj.get) {
|
||||||
|
throw new Error(
|
||||||
|
`Not a gettable object: ${obj}`,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
return obj.get(e.property);
|
||||||
|
});
|
||||||
|
} else {
|
||||||
|
if (!obj.get) {
|
||||||
|
throw new Error(
|
||||||
|
`Not a gettable object: ${obj}`,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
return obj.get(e.property);
|
||||||
|
}
|
||||||
|
}
|
||||||
case "Variable":
|
case "Variable":
|
||||||
case "FunctionCall":
|
case "FunctionCall":
|
||||||
return evalPrefixExpression(e, env);
|
return evalPrefixExpression(e, env);
|
||||||
|
|
|
@ -27,6 +27,7 @@ Deno.test("Test Lua parser", () => {
|
||||||
parse(`e({[3] = 1, [10 * 10] = "sup"})`);
|
parse(`e({[3] = 1, [10 * 10] = "sup"})`);
|
||||||
parse(`e(tbl.name)`);
|
parse(`e(tbl.name)`);
|
||||||
parse(`e(tbl["name" + 10])`);
|
parse(`e(tbl["name" + 10])`);
|
||||||
|
parse(`e(test().bla)`);
|
||||||
|
|
||||||
// Function calls
|
// Function calls
|
||||||
parse(`e(func(), func(1, 2, 3), a.b(), a.b.c:hello(), (a.b)(7))`);
|
parse(`e(func(), func(1, 2, 3), a.b(), a.b.c:hello(), (a.b)(7))`);
|
||||||
|
|
|
@ -184,14 +184,7 @@ function parseStatement(t: ParseTree): LuaStatement {
|
||||||
case "FunctionCall":
|
case "FunctionCall":
|
||||||
return {
|
return {
|
||||||
type: "FunctionCallStatement",
|
type: "FunctionCallStatement",
|
||||||
call: parseExpression(
|
call: parseFunctionCall(t),
|
||||||
{
|
|
||||||
type: "FunctionCall",
|
|
||||||
children: t.children!,
|
|
||||||
from: t.from,
|
|
||||||
to: t.to,
|
|
||||||
},
|
|
||||||
) as LuaFunctionCallExpression,
|
|
||||||
};
|
};
|
||||||
case "Assign":
|
case "Assign":
|
||||||
return {
|
return {
|
||||||
|
@ -223,6 +216,26 @@ function parseStatement(t: ParseTree): LuaStatement {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function parseFunctionCall(t: ParseTree): LuaFunctionCallExpression {
|
||||||
|
if (t.children![1].type === ":") {
|
||||||
|
return {
|
||||||
|
type: "FunctionCall",
|
||||||
|
prefix: parsePrefixExpression(t.children![0]),
|
||||||
|
name: t.children![2].children![0].text!,
|
||||||
|
args: parseFunctionArgs(t.children!.slice(3)),
|
||||||
|
from: t.from,
|
||||||
|
to: t.to,
|
||||||
|
};
|
||||||
|
}
|
||||||
|
return {
|
||||||
|
type: "FunctionCall",
|
||||||
|
prefix: parsePrefixExpression(t.children![0]),
|
||||||
|
args: parseFunctionArgs(t.children!.slice(1)),
|
||||||
|
from: t.from,
|
||||||
|
to: t.to,
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
function parseAttNames(t: ParseTree): LuaAttName[] {
|
function parseAttNames(t: ParseTree): LuaAttName[] {
|
||||||
if (t.type !== "AttNameList") {
|
if (t.type !== "AttNameList") {
|
||||||
throw new Error(`Expected AttNameList, got ${t.type}`);
|
throw new Error(`Expected AttNameList, got ${t.type}`);
|
||||||
|
@ -373,23 +386,7 @@ function parseExpression(t: ParseTree): LuaExpression {
|
||||||
case "Parens":
|
case "Parens":
|
||||||
return parseExpression(t.children![1]);
|
return parseExpression(t.children![1]);
|
||||||
case "FunctionCall": {
|
case "FunctionCall": {
|
||||||
if (t.children![1].type === ":") {
|
return parseFunctionCall(t);
|
||||||
return {
|
|
||||||
type: "FunctionCall",
|
|
||||||
prefix: parsePrefixExpression(t.children![0]),
|
|
||||||
name: t.children![2].children![0].text!,
|
|
||||||
args: parseFunctionArgs(t.children!.slice(3)),
|
|
||||||
from: t.from,
|
|
||||||
to: t.to,
|
|
||||||
};
|
|
||||||
}
|
|
||||||
return {
|
|
||||||
type: "FunctionCall",
|
|
||||||
prefix: parsePrefixExpression(t.children![0]),
|
|
||||||
args: parseFunctionArgs(t.children!.slice(1)),
|
|
||||||
from: t.from,
|
|
||||||
to: t.to,
|
|
||||||
};
|
|
||||||
}
|
}
|
||||||
case "FunctionDef": {
|
case "FunctionDef": {
|
||||||
const body = parseFunctionBody(t.children![1]);
|
const body = parseFunctionBody(t.children![1]);
|
||||||
|
@ -484,6 +481,9 @@ function parsePrefixExpression(t: ParseTree): LuaPrefixExpression {
|
||||||
from: t.from,
|
from: t.from,
|
||||||
to: t.to,
|
to: t.to,
|
||||||
};
|
};
|
||||||
|
case "FunctionCall": {
|
||||||
|
return parseFunctionCall(t);
|
||||||
|
}
|
||||||
default:
|
default:
|
||||||
console.error(t);
|
console.error(t);
|
||||||
throw new Error(`Unknown prefix expression type: ${t.type}`);
|
throw new Error(`Unknown prefix expression type: ${t.type}`);
|
||||||
|
|
Loading…
Reference in New Issue