Browse Source

feat: ECAL supports anonymous functions

Matthias Ladkau 3 years ago
parent
commit
cef15c6833

+ 5 - 2
lang/ecal/parser/parser.go

@@ -438,10 +438,13 @@ ndFunc is used to parse function definitions.
 */
 func ndFunc(p *parser, self *ASTNode) (*ASTNode, error) {
 	var exp *ASTNode
+	var err error
 
-	// Must specify a function name
+	// Might specify a function name
 
-	err := acceptChild(p, self, TokenIDENTIFIER)
+	if p.node.Token.ID == TokenIDENTIFIER {
+		err = acceptChild(p, self, TokenIDENTIFIER)
+	}
 
 	// Read in parameters
 

+ 29 - 2
lang/ecal/parser/parser_func_test.go

@@ -37,7 +37,7 @@ statements
 func TestSinkParsing(t *testing.T) {
 
 	input := `
-	sink fooBar 
+	sink fooBar
     kindmatch [ "priority", "t.do.bla" ],
 	scopematch [ "data.read", "data.write" ],
 	statematch { "priority:" : 5, test: 1, "bla 1": null },
@@ -114,7 +114,7 @@ sink
 	}
 
 	input = `
-	sink fooBar 
+	sink fooBar
     ==
 	kindmatch [ "priority", "t.do.bla" ]
 	{
@@ -193,6 +193,33 @@ function
 		t.Error("Unexpected parser output:\n", res, "expected was:\n", expectedOutput, "Error:", err)
 		return
 	}
+
+	input = `
+func() {
+  a := 1
+  return
+  b := 2
+  return
+}
+`
+	expectedOutput = `
+function
+  params
+  statements
+    :=
+      identifier: a
+      number: 1
+    return
+    :=
+      identifier: b
+      number: 2
+    return
+`[1:]
+
+	if res, err := UnitTestParse("mytest", input); err != nil || fmt.Sprint(res) != expectedOutput {
+		t.Error("Unexpected parser output:\n", res, "expected was:\n", expectedOutput, "Error:", err)
+		return
+	}
 }
 
 func TestFunctionCalling(t *testing.T) {

+ 1 - 0
lang/ecal/parser/prettyprinter.go

@@ -90,6 +90,7 @@ func init() {
 
 		// Function definition
 
+		NodeFUNC + "_2":   template.Must(template.New(NodeFUNC).Parse("func {{.c1}} {\n{{.c2}}}")),
 		NodeFUNC + "_3":   template.Must(template.New(NodeFUNC).Parse("func {{.c1}}{{.c2}} {\n{{.c3}}}")),
 		NodeRETURN:        template.Must(template.New(NodeRETURN).Parse("return")),
 		NodeRETURN + "_1": template.Must(template.New(NodeRETURN).Parse("return {{.c1}}")),