From abda5faff7e30dbbbd23244a9cc63a0616d2a06b Mon Sep 17 00:00:00 2001 From: Marvin Blum Date: Sun, 25 Oct 2015 15:10:29 +0100 Subject: [PATCH] Special cases for waitUntil and exitWith. --- README.md | 59 +++++++++++++++++++++++++++++++++++++++ ToDo.md | 4 +-- in/complex.asl | 2 +- in/simple.asl | 9 +++++- src/asl/parser.go | 30 ++++++++++++++++++++ src/asl/parser_test.go | 14 ++++++++++ src/asl/tokenizer.go | 4 ++- test/parser_exitwith.asl | 3 ++ test/parser_waituntil.asl | 1 + 9 files changed, 121 insertions(+), 5 deletions(-) create mode 100644 test/parser_exitwith.asl create mode 100644 test/parser_waituntil.asl diff --git a/README.md b/README.md index ab7800a..382c371 100644 --- a/README.md +++ b/README.md @@ -75,6 +75,12 @@ switch x { default: // ... } + +try { + // ... +} catch { + // ... +} ``` ### Functions @@ -115,6 +121,59 @@ foo(x, y, z)(1, 2, 3); [x, y, z] foo [1, 2, 3]; ``` +### Special functions + +There are some special functions in SQF, which also require special syntax in ASL. The examples presented here show how they are written in ASL and what the output will look like. Remember that ASL is case sensitive! + +**exitWith** + +``` +exitwith { + // your code +} + +// output: +if (true) exitWith { + // your code +}; +``` + +**waitUntil** + +``` +waituntil(condition); +// or +waituntil(expression;condition); + +// output: +waitUntil {condition}; +// or +waitUntil {expression;condition}; +``` + +## List of all keywords + +Keywords should not be used as identifiers. Here is a full list of all keywords in ASL. Remember that build in functions should not be used neither. + +| Keyword | +| - | +| var | +| if | +| while | +| witch | +| for | +| foreach | +| func | +| true | +| false | +| case | +| default | +| return | +| try | +| catch | +| exitwith | +| waituntil | + ## Contribute To contribute please create pull requests or explain your ideas in the issue section on GitHub. Report any bugs or incompatible ASL <-> SQF syntax you can find. diff --git a/ToDo.md b/ToDo.md index ab4d1f9..f877a60 100644 --- a/ToDo.md +++ b/ToDo.md @@ -14,6 +14,6 @@ ## Special cases -* exitWith... -* waitUntil... +* ~~exitWith...~~ +* ~~waitUntil...~~ * ~~!buildInFunc()()...~~ diff --git a/in/complex.asl b/in/complex.asl index 5c0eb52..2e28424 100644 --- a/in/complex.asl +++ b/in/complex.asl @@ -34,7 +34,7 @@ if !(isNil()(_getunit)) { if local()(_unit) { try { - execVM(_unit)(_file); + execVM(_unit)(_file); } catch { // do nothing } diff --git a/in/simple.asl b/in/simple.asl index cac616b..e69ad58 100644 --- a/in/simple.asl +++ b/in/simple.asl @@ -1 +1,8 @@ -var x = !foo(); +waituntil(x = x+1; x < 100); + +if timeIsOver { + exitwith { + foo(); + bar(); + } +} diff --git a/src/asl/parser.go b/src/asl/parser.go index e50bb25..d1d320d 100644 --- a/src/asl/parser.go +++ b/src/asl/parser.go @@ -37,6 +37,10 @@ func parseBlock() { parseReturn() } else if accept("try") { parseTryCatch() + } else if accept("exitwith") { + parseExitWith() + } else if accept("waituntil") { + parseWaitUntil() } else if accept("case") || accept("default") { return } else { @@ -248,6 +252,32 @@ func parseTryCatch() { appendOut("};", true) } +func parseExitWith() { + expect("exitwith") + expect("{") + appendOut("if (true) exitWith {", true) + parseBlock() + expect("}") + appendOut("};", true) +} + +func parseWaitUntil() { + expect("waituntil") + expect("(") + appendOut("waitUntil {", false) + parseExpression(true) + + if accept(";") { + next() + appendOut(";", false) + parseExpression(true) + } + + expect(")") + expect(";") + appendOut("};", true) +} + // Everything that does not start with a keyword. func parseStatement() { // empty block diff --git a/src/asl/parser_test.go b/src/asl/parser_test.go index 9bb246b..f6a8df4 100644 --- a/src/asl/parser_test.go +++ b/src/asl/parser_test.go @@ -115,6 +115,20 @@ func TestParserNegationFunctionCall(t *testing.T) { equal(t, got, want) } +func TestParserExitWith(t *testing.T) { + got := getCompiled(t, "test/parser_exitwith.asl") + want := "if (true) exitWith {\n};\n" + + equal(t, got, want) +} + +func TestParserWaitUntil(t *testing.T) { + got := getCompiled(t, "test/parser_waituntil.asl") + want := "waitUntil {x=x+1;x<100};\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 6d28c70..d54caa1 100644 --- a/src/asl/tokenizer.go +++ b/src/asl/tokenizer.go @@ -43,7 +43,9 @@ var keywords = []string{ "default", "return", "try", - "catch"} + "catch", + "exitwith", + "waituntil"} var whitespace = []byte{' ', '\n', '\t'} var identifier = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789_" diff --git a/test/parser_exitwith.asl b/test/parser_exitwith.asl new file mode 100644 index 0000000..ca29270 --- /dev/null +++ b/test/parser_exitwith.asl @@ -0,0 +1,3 @@ +exitwith { + // ... +} diff --git a/test/parser_waituntil.asl b/test/parser_waituntil.asl new file mode 100644 index 0000000..9ff443a --- /dev/null +++ b/test/parser_waituntil.asl @@ -0,0 +1 @@ +waituntil(x = x+1; x < 100);