Browse Source

feat: Adding statement support

Matthias Ladkau 3 years ago
parent
commit
f25a1bb761

+ 5 - 3
lang/ecal/parser/helper.go

@@ -109,9 +109,11 @@ func (n *ASTNode) equalsPath(path string, other *ASTNode, ignoreTokenPosition bo
 		msg = fmt.Sprintf("Name is different %v vs %v\n", n.Name, other.Name)
 	}
 
-	if ok, tokenMSG := n.Token.Equals(*other.Token, ignoreTokenPosition); !ok {
-		res = false
-		msg += fmt.Sprintf("Token is different:\n%v\n", tokenMSG)
+	if n.Token != nil && other.Token != nil {
+		if ok, tokenMSG := n.Token.Equals(*other.Token, ignoreTokenPosition); !ok {
+			res = false
+			msg += fmt.Sprintf("Token is different:\n%v\n", tokenMSG)
+		}
 	}
 
 	if len(n.Meta) != len(other.Meta) {

+ 25 - 0
lang/ecal/parser/parser_main_test.go

@@ -14,6 +14,31 @@ import (
 	"testing"
 )
 
+func TestStatementParsing(t *testing.T) {
+
+	// Comment parsing without statements
+
+	input := `a := 1
+	b := 2; c:= 3`
+	expectedOutput := `
+statements
+  :=
+    identifier: a
+    number: 1
+  :=
+    identifier: b
+    number: 2
+  :=
+    identifier: c
+    number: 3
+`[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 TestCommentParsing(t *testing.T) {
 
 	// Comment parsing without statements

+ 29 - 5
lang/ecal/parser/prettyprinter.go

@@ -16,6 +16,7 @@ import (
 	"text/template"
 
 	"devt.de/krotik/common/errorutil"
+	"devt.de/krotik/common/stringutil"
 )
 
 /*
@@ -35,9 +36,12 @@ func init() {
 		NodeNUMBER:     template.Must(template.New(NodeTRUE).Parse("{{.val}}")),
 		NodeIDENTIFIER: template.Must(template.New(NodeTRUE).Parse("{{.val}}")),
 
+		// Constructed tokens
+
+		// NodeSTATEMENTS - Special case (handled in code)
+
 		/*
 
-			// Constructed tokens
 
 			NodeSTATEMENTS = "statements" // List of statements
 
@@ -103,13 +107,14 @@ func PrettyPrint(ast *ASTNode) (string, error) {
 
 	visit = func(ast *ASTNode, level int) (string, error) {
 		var buf bytes.Buffer
+		var numChildren = len(ast.Children)
 
 		tempKey := ast.Name
 		tempParam := make(map[string]string)
 
 		// First pretty print children
 
-		if len(ast.Children) > 0 {
+		if numChildren > 0 {
 			for i, child := range ast.Children {
 				res, err := visit(child, level+1)
 				if err != nil {
@@ -130,10 +135,29 @@ func PrettyPrint(ast *ASTNode) (string, error) {
 			tempKey += fmt.Sprint("_", len(tempParam))
 		}
 
-		// Adding node value to template parameters
+		// Handle special cases requiring children
+
+		if ast.Name == NodeSTATEMENTS {
+
+			// For statements just concat all children
+
+			for i := 0; i < numChildren; i++ {
+				buf.WriteString(stringutil.GenerateRollingString(" ", level*4))
+				buf.WriteString(tempParam[fmt.Sprint("c", i+1)])
+				buf.WriteString("\n")
+			}
+
+			return buf.String(), nil
+
+		}
+
+		if ast.Token != nil {
+
+			// Adding node value to template parameters
 
-		tempParam["val"] = ast.Token.Val
-		tempParam["qval"] = strconv.Quote(ast.Token.Val)
+			tempParam["val"] = ast.Token.Val
+			tempParam["qval"] = strconv.Quote(ast.Token.Val)
+		}
 
 		// Retrieve the template