From 04d0f4b61b8e8b92cf992caf733deec81dadf3c3 Mon Sep 17 00:00:00 2001 From: Marvin Blum Date: Fri, 23 Oct 2015 20:09:26 +0200 Subject: [PATCH] Fixed function call and buildin function call, all tests are green. Still need to solve special cases and sqf: ... sqf blocks. --- README.md | 2 +- in/simple.asl | 9 ++--- src/asl/parser.go | 67 +++++++++++++++++++----------------- src/asl/parser_test.go | 15 +++++--- src/asl/tokenizer.go | 1 - test/parser_buildin_func.asl | 1 + 6 files changed, 52 insertions(+), 43 deletions(-) create mode 100644 test/parser_buildin_func.asl diff --git a/README.md b/README.md index 1264f0e..fbdf0e4 100644 --- a/README.md +++ b/README.md @@ -122,7 +122,7 @@ someUnit addItem "NVGoogles"; is equivalent to: ``` -$addItem(someUnit)("NVGoogles"); +addItem(someUnit)("NVGoogles"); ``` ## Contribute diff --git a/in/simple.asl b/in/simple.asl index 64411ab..3d59463 100644 --- a/in/simple.asl +++ b/in/simple.asl @@ -1,7 +1,4 @@ -func myFunc(a, b) { - return a > b; -} - -myFunc(1+3/4, 2-(66*22)/3-((123))); - +// TODO: +//var _x = setHitIndex(vehicle()(player))(1, 1); +var _x = setHit(player)("head"); foo(); diff --git a/src/asl/parser.go b/src/asl/parser.go index 81ff07f..a334e96 100644 --- a/src/asl/parser.go +++ b/src/asl/parser.go @@ -261,13 +261,10 @@ func parseStatement() { if accept("=") { appendOut(name, false) parseAssignment() - } else if name == "$" { - name = get().token - next() - parseBuildinFunctionCall(name) } else { - parseFunctionCall(true) - appendOut(name + ";", true) + parseFunctionCall(true, name) + expect(";") + appendOut(";", true) } if !end() { @@ -277,20 +274,41 @@ func parseStatement() { func parseAssignment() { expect("=") - appendOut(" = " + get().token, false) - next() + appendOut(" = ", false) + parseExpression(true) expect(";") appendOut(";", true) } -func parseFunctionCall(out bool) string { - output := "[" +func parseFunctionCall(out bool, name string) string { + output := "" expect("(") - output += parseParameter(false) + leftParams, leftParamCount := parseParameter(false) expect(")") - expect(";") - output += "] call " + + if accept("(") { + // buildin function + next() + rightParams, rightParamCount := parseParameter(false) + expect(")") + + if leftParamCount > 1 { + leftParams = "["+leftParams+"]" + } + + if rightParamCount > 1 { + rightParams = "["+rightParams+"]" + } + + if leftParamCount > 1 { + output = leftParams+" "+name+" "+rightParams + } else { + output = name+" "+rightParams + } + } else { + output = "["+leftParams+"] call "+name + } if out { appendOut(output, false) @@ -299,26 +317,13 @@ func parseFunctionCall(out bool) string { return output } -func parseBuildinFunctionCall(name string) { - // FIXME: does not work for all kind of commands - expect("(") - appendOut("[", false) - parseParameter(true) - expect(")") - appendOut("] ", false) - expect("(") - appendOut(name + " [", false) - parseParameter(true) - expect(")") - expect(";") - appendOut("];", true) -} - -func parseParameter(out bool) string { +func parseParameter(out bool) (string, int) { output := "" + count := 0 for !accept(")") { output += parseExpression(out) + count++ if !accept(")") { expect(",") @@ -330,7 +335,7 @@ func parseParameter(out bool) string { appendOut(output, false) } - return output + return output, count } func parseExpression(out bool) string { @@ -377,7 +382,7 @@ func parseIdentifier() string { if seek("(") { name := get().token next() - output = "("+parseFunctionCall(false)+name+")" + output = "("+parseFunctionCall(false, name)+")" } else { output = get().token next() diff --git a/src/asl/parser_test.go b/src/asl/parser_test.go index 45c8514..e97f241 100644 --- a/src/asl/parser_test.go +++ b/src/asl/parser_test.go @@ -61,32 +61,39 @@ func TestParserFunction(t *testing.T) { func TestParserAssignResult(t *testing.T) { got := getCompiled(t, "test/parser_assign_result.asl") - want := "x = [1, 2, 3] call foo;\ny = [1, 2, 3] call bar;" + want := "x = ([1, 2, 3] call foo);\ny = ([1, 2, 3] call bar);\n" equal(t, got, want) } -func TestExpression(t *testing.T) { +func TestParserExpression(t *testing.T) { got := getCompiled(t, "test/parser_expression.asl") want := "x = (1+(2+3))/(6*(someVariable+99-100))-(20)+anotherVariable+([] call foo);\n" equal(t, got, want) } -func TestExpression2(t *testing.T) { +func TestParserExpression2(t *testing.T) { got := getCompiled(t, "test/parser_expression2.asl") want := "x = true||(3>=4&&5<8);\n" equal(t, got, want) } -func TestFunctionCall(t *testing.T) { +func TestParserFunctionCall(t *testing.T) { got := getCompiled(t, "test/parser_func_call.asl") want := "myFunc = {\na = _this select 0;\nb = _this select 1;\nreturn a>b;\n};\n[1+3/4, 2-(66*22)/3-((123))] call myFunc;\n" equal(t, got, want) } +func TestParserBuildinFunctionCall(t *testing.T) { + got := getCompiled(t, "test/parser_buildin_func.asl") + want := "_x = (setHit \"head\");\n" + + equal(t, got, want) +} + func getCompiled(t *testing.T, file string) string { code, err := ioutil.ReadFile(file) diff --git a/src/asl/tokenizer.go b/src/asl/tokenizer.go index 1f2d383..a67d544 100644 --- a/src/asl/tokenizer.go +++ b/src/asl/tokenizer.go @@ -24,7 +24,6 @@ var delimiter = []byte{ ':', '&', '|', - '$', '+', '-', '*', diff --git a/test/parser_buildin_func.asl b/test/parser_buildin_func.asl new file mode 100644 index 0000000..3f34ff2 --- /dev/null +++ b/test/parser_buildin_func.asl @@ -0,0 +1 @@ +var _x = setHit(player)("head");