From 5567710476464f3273acec904450ca71c173c7a1 Mon Sep 17 00:00:00 2001 From: Evan Chng Xian Lin Date: Thu, 11 Apr 2024 15:04:40 +0800 Subject: [PATCH 01/28] Print AndOperation --- printer/ast/source_code_printer.go | 76 ++++++++++++++++++++++++++++++ 1 file changed, 76 insertions(+) create mode 100644 printer/ast/source_code_printer.go diff --git a/printer/ast/source_code_printer.go b/printer/ast/source_code_printer.go new file mode 100644 index 00000000..af844306 --- /dev/null +++ b/printer/ast/source_code_printer.go @@ -0,0 +1,76 @@ +package printer + +import ( + "strings" + + "github.com/unpackdev/solgo/ast" + "go.uber.org/zap" +) + +// Print is a function that prints the AST nodes to source code +func Print(node ast.Node[ast.NodeType]) (string, bool) { + sb := strings.Builder{} + success := PrintRecursive(node, &sb, 0) + return sb.String(), success +} + +// PrintRecursive is a function that prints the AST nodes to source code recursively +func PrintRecursive(node ast.Node[ast.NodeType], sb *strings.Builder, depth int) bool { + if node == nil { + zap.S().Error("Node is nil") + return false + } + switch node := node.(type) { + case *ast.AndOperation: + return printAndOperation(node, sb, depth) + default: + zap.S().Errorf("Unknown node type: %T\n", node) + return false + } +} + +func printAndOperation(node *ast.AndOperation, sb *strings.Builder, depth int) bool { + expressions := []string{} + success := true + for _, exp := range node.GetExpressions() { + s, ok := Print(exp) + success = success && ok + expressions = append(expressions, s) + } + writeSeperatedList(sb, " && ", expressions) + return success +} + +func writeSeperatedStrings(sb *strings.Builder, seperator string, s ...string) { + count := 0 + for _, item := range s { + // Skip empty strings + if item == "" { + continue + } + + if count > 0 { + sb.WriteString(seperator) + sb.WriteString(item) + } else { + sb.WriteString(item) + } + } +} + +func writeSeperatedList(sb *strings.Builder, seperator string, s []string) { + count := 0 + for _, item := range s { + // Skip empty strings + if item == "" { + continue + } + + if count > 0 { + sb.WriteString(seperator) + sb.WriteString(item) + } else { + sb.WriteString(item) + } + } +} From 78507872e32ff770e240ca5568c55aef852ea0aa Mon Sep 17 00:00:00 2001 From: Evan Chng Xian Lin Date: Thu, 11 Apr 2024 15:18:39 +0800 Subject: [PATCH 02/28] Print Assignment --- printer/ast/and_operation.go | 19 +++++++++ printer/ast/assignment.go | 64 ++++++++++++++++++++++++++++++ printer/ast/source_code_printer.go | 18 +++------ 3 files changed, 89 insertions(+), 12 deletions(-) create mode 100644 printer/ast/and_operation.go create mode 100644 printer/ast/assignment.go diff --git a/printer/ast/and_operation.go b/printer/ast/and_operation.go new file mode 100644 index 00000000..993f0721 --- /dev/null +++ b/printer/ast/and_operation.go @@ -0,0 +1,19 @@ +package printer + +import ( + "strings" + + "github.com/unpackdev/solgo/ast" +) + +func printAndOperation(node *ast.AndOperation, sb *strings.Builder, depth int) bool { + expressions := []string{} + success := true + for _, exp := range node.GetExpressions() { + s, ok := Print(exp) + success = success && ok + expressions = append(expressions, s) + } + writeSeperatedList(sb, " && ", expressions) + return success +} diff --git a/printer/ast/assignment.go b/printer/ast/assignment.go new file mode 100644 index 00000000..8b79b270 --- /dev/null +++ b/printer/ast/assignment.go @@ -0,0 +1,64 @@ +package printer + +import ( + "fmt" + "strings" + + ast_pb "github.com/unpackdev/protos/dist/go/ast" + "github.com/unpackdev/solgo/ast" +) + +func getOperatorString(op ast_pb.Operator) string { + switch op { + case ast_pb.Operator_EQUAL: + return "=" + case ast_pb.Operator_PLUS_EQUAL: + return "+=" + case ast_pb.Operator_MINUS_EQUAL: + return "-=" + case ast_pb.Operator_MUL_EQUAL: + return "*=" + case ast_pb.Operator_DIVISION: + return "/=" + case ast_pb.Operator_MOD_EQUAL: + return "%=" + case ast_pb.Operator_AND_EQUAL: + return "&=" + case ast_pb.Operator_OR_EQUAL: + return "|=" + case ast_pb.Operator_XOR_EQUAL: + return "^=" + case ast_pb.Operator_SHIFT_LEFT_EQUAL: + return "<<=" + case ast_pb.Operator_SHIFT_RIGHT_EQUAL: + return ">>=" + case ast_pb.Operator_BIT_AND_EQUAL: + return "&=" + case ast_pb.Operator_BIT_OR_EQUAL: + return "|=" + case ast_pb.Operator_BIT_XOR_EQUAL: + return "^=" + case ast_pb.Operator_POW_EQUAL: + return "**=" + default: + return "" + } +} + +func printAssignment(node *ast.Assignment, sb *strings.Builder, depth int) bool { + success := true + if node.Expression != nil { + return PrintRecursive(node.Expression, sb, depth) + } + if node.LeftExpression == nil || node.RightExpression == nil { + return false + } + op := getOperatorString(node.Operator) + if op == "" { + success = false + } + PrintRecursive(node.LeftExpression, sb, depth) + sb.WriteString(fmt.Sprintf(" %s ", op)) + PrintRecursive(node.RightExpression, sb, depth) + return success +} diff --git a/printer/ast/source_code_printer.go b/printer/ast/source_code_printer.go index af844306..00ad8e36 100644 --- a/printer/ast/source_code_printer.go +++ b/printer/ast/source_code_printer.go @@ -29,18 +29,6 @@ func PrintRecursive(node ast.Node[ast.NodeType], sb *strings.Builder, depth int) } } -func printAndOperation(node *ast.AndOperation, sb *strings.Builder, depth int) bool { - expressions := []string{} - success := true - for _, exp := range node.GetExpressions() { - s, ok := Print(exp) - success = success && ok - expressions = append(expressions, s) - } - writeSeperatedList(sb, " && ", expressions) - return success -} - func writeSeperatedStrings(sb *strings.Builder, seperator string, s ...string) { count := 0 for _, item := range s { @@ -74,3 +62,9 @@ func writeSeperatedList(sb *strings.Builder, seperator string, s []string) { } } } + +func writeStrings(sb *strings.Builder, s ...string) { + for _, item := range s { + sb.WriteString(item) + } +} From e2fda85b229531850676f6234e81e39451845de6 Mon Sep 17 00:00:00 2001 From: Evan Chng Xian Lin Date: Thu, 11 Apr 2024 15:30:50 +0800 Subject: [PATCH 03/28] Print BinaryOperation --- printer/ast/assignment.go | 11 ++++---- printer/ast/binary.go | 57 +++++++++++++++++++++++++++++++++++++++ 2 files changed, 63 insertions(+), 5 deletions(-) create mode 100644 printer/ast/binary.go diff --git a/printer/ast/assignment.go b/printer/ast/assignment.go index 8b79b270..3654be95 100644 --- a/printer/ast/assignment.go +++ b/printer/ast/assignment.go @@ -1,14 +1,13 @@ package printer import ( - "fmt" "strings" ast_pb "github.com/unpackdev/protos/dist/go/ast" "github.com/unpackdev/solgo/ast" ) -func getOperatorString(op ast_pb.Operator) string { +func getAssignOperatorString(op ast_pb.Operator) string { switch op { case ast_pb.Operator_EQUAL: return "=" @@ -18,7 +17,7 @@ func getOperatorString(op ast_pb.Operator) string { return "-=" case ast_pb.Operator_MUL_EQUAL: return "*=" - case ast_pb.Operator_DIVISION: + case ast_pb.Operator_DIV_EQUAL: return "/=" case ast_pb.Operator_MOD_EQUAL: return "%=" @@ -53,12 +52,14 @@ func printAssignment(node *ast.Assignment, sb *strings.Builder, depth int) bool if node.LeftExpression == nil || node.RightExpression == nil { return false } - op := getOperatorString(node.Operator) + op := getAssignOperatorString(node.Operator) if op == "" { success = false } PrintRecursive(node.LeftExpression, sb, depth) - sb.WriteString(fmt.Sprintf(" %s ", op)) + sb.WriteString(" ") + sb.WriteString(op) + sb.WriteString(" ") PrintRecursive(node.RightExpression, sb, depth) return success } diff --git a/printer/ast/binary.go b/printer/ast/binary.go new file mode 100644 index 00000000..306bbefd --- /dev/null +++ b/printer/ast/binary.go @@ -0,0 +1,57 @@ +package printer + +import ( + "strings" + + ast_pb "github.com/unpackdev/protos/dist/go/ast" + "github.com/unpackdev/solgo/ast" +) + +func getBinaryOperatorString(op ast_pb.Operator) string { + switch op { + case ast_pb.Operator_ADDITION: + return "+" + case ast_pb.Operator_SUBTRACTION: + return "-" + case ast_pb.Operator_MULTIPLICATION: + return "*" + case ast_pb.Operator_DIVISION: + return "/" + case ast_pb.Operator_MODULO: + return "%" + case ast_pb.Operator_EQUAL: + return "==" + case ast_pb.Operator_NOT_EQUAL: + return "!=" + case ast_pb.Operator_GREATER_THAN: + return ">" + case ast_pb.Operator_GREATER_THAN_OR_EQUAL: + return ">=" + case ast_pb.Operator_LESS_THAN: + return "<" + case ast_pb.Operator_LESS_THAN_OR_EQUAL: + return "<=" + case ast_pb.Operator_OR: + return "||" + // not sure where is the AND operator in ast_pb? + default: + return "" + } +} + +func printBinaryOperation(node *ast.BinaryOperation, sb *strings.Builder, depth int) bool { + success := true + if node.LeftExpression == nil || node.RightExpression == nil { + return false + } + op := getBinaryOperatorString(node.Operator) + if op == "" { + success = false + } + PrintRecursive(node.LeftExpression, sb, depth) + sb.WriteString(" ") + sb.WriteString(op) + sb.WriteString(" ") + PrintRecursive(node.RightExpression, sb, depth) + return success +} From 0304c6134e26b00ebe17ee9aaa3a00bc94f70fc9 Mon Sep 17 00:00:00 2001 From: Evan Chng Xian Lin Date: Thu, 11 Apr 2024 15:40:14 +0800 Subject: [PATCH 04/28] print BodyNode --- printer/ast/body.go | 19 +++++++++++++++++++ printer/ast/source_code_printer.go | 6 ++++++ 2 files changed, 25 insertions(+) create mode 100644 printer/ast/body.go diff --git a/printer/ast/body.go b/printer/ast/body.go new file mode 100644 index 00000000..3c5c0a69 --- /dev/null +++ b/printer/ast/body.go @@ -0,0 +1,19 @@ +package printer + +import ( + "strings" + + "github.com/unpackdev/solgo/ast" +) + +func printBody(node *ast.BodyNode, sb *strings.Builder, depth int) bool { + success := true + stmts := []string{} + for _, stmt := range node.GetStatements() { + s, ok := Print(stmt) + success = success && ok + stmts = append(stmts, indentString(s, depth+1)) + } + writeSeperatedList(sb, "\n;", stmts) + return success +} diff --git a/printer/ast/source_code_printer.go b/printer/ast/source_code_printer.go index 00ad8e36..a19c28a4 100644 --- a/printer/ast/source_code_printer.go +++ b/printer/ast/source_code_printer.go @@ -7,6 +7,8 @@ import ( "go.uber.org/zap" ) +const INDENT_SIZE = 4 + // Print is a function that prints the AST nodes to source code func Print(node ast.Node[ast.NodeType]) (string, bool) { sb := strings.Builder{} @@ -68,3 +70,7 @@ func writeStrings(sb *strings.Builder, s ...string) { sb.WriteString(item) } } + +func indentString(s string, depth int) string { + return strings.Repeat(" ", depth*INDENT_SIZE) +} From a1bae10972c0eded0dc825ba607a07096c53b419 Mon Sep 17 00:00:00 2001 From: Evan Chng Xian Lin Date: Thu, 11 Apr 2024 15:47:53 +0800 Subject: [PATCH 05/28] Print Conditional --- printer/ast/and_operation.go | 2 +- printer/ast/assignment.go | 4 ++-- printer/ast/binary.go | 10 +++++----- printer/ast/body.go | 2 +- printer/ast/conditional.go | 22 ++++++++++++++++++++++ 5 files changed, 31 insertions(+), 9 deletions(-) create mode 100644 printer/ast/conditional.go diff --git a/printer/ast/and_operation.go b/printer/ast/and_operation.go index 993f0721..d1022885 100644 --- a/printer/ast/and_operation.go +++ b/printer/ast/and_operation.go @@ -11,7 +11,7 @@ func printAndOperation(node *ast.AndOperation, sb *strings.Builder, depth int) b success := true for _, exp := range node.GetExpressions() { s, ok := Print(exp) - success = success && ok + success = ok && success expressions = append(expressions, s) } writeSeperatedList(sb, " && ", expressions) diff --git a/printer/ast/assignment.go b/printer/ast/assignment.go index 3654be95..550eceb9 100644 --- a/printer/ast/assignment.go +++ b/printer/ast/assignment.go @@ -56,10 +56,10 @@ func printAssignment(node *ast.Assignment, sb *strings.Builder, depth int) bool if op == "" { success = false } - PrintRecursive(node.LeftExpression, sb, depth) + success = PrintRecursive(node.LeftExpression, sb, depth) && success sb.WriteString(" ") sb.WriteString(op) sb.WriteString(" ") - PrintRecursive(node.RightExpression, sb, depth) + success = PrintRecursive(node.RightExpression, sb, depth) && success return success } diff --git a/printer/ast/binary.go b/printer/ast/binary.go index 306bbefd..63997806 100644 --- a/printer/ast/binary.go +++ b/printer/ast/binary.go @@ -40,18 +40,18 @@ func getBinaryOperatorString(op ast_pb.Operator) string { } func printBinaryOperation(node *ast.BinaryOperation, sb *strings.Builder, depth int) bool { - success := true + ok := true if node.LeftExpression == nil || node.RightExpression == nil { return false } op := getBinaryOperatorString(node.Operator) if op == "" { - success = false + ok = false } - PrintRecursive(node.LeftExpression, sb, depth) + ok = PrintRecursive(node.LeftExpression, sb, depth) && ok sb.WriteString(" ") sb.WriteString(op) sb.WriteString(" ") - PrintRecursive(node.RightExpression, sb, depth) - return success + ok = PrintRecursive(node.RightExpression, sb, depth) && ok + return ok } diff --git a/printer/ast/body.go b/printer/ast/body.go index 3c5c0a69..57a49706 100644 --- a/printer/ast/body.go +++ b/printer/ast/body.go @@ -11,7 +11,7 @@ func printBody(node *ast.BodyNode, sb *strings.Builder, depth int) bool { stmts := []string{} for _, stmt := range node.GetStatements() { s, ok := Print(stmt) - success = success && ok + success = ok && success stmts = append(stmts, indentString(s, depth+1)) } writeSeperatedList(sb, "\n;", stmts) diff --git a/printer/ast/conditional.go b/printer/ast/conditional.go new file mode 100644 index 00000000..e972731c --- /dev/null +++ b/printer/ast/conditional.go @@ -0,0 +1,22 @@ +package printer + +import ( + "strings" + + "github.com/unpackdev/solgo/ast" + "go.uber.org/zap" +) + +func printConditional(node ast.Conditional, sb *strings.Builder, depth int) bool { + success := true + if len(node.GetExpressions()) < 3 { + zap.S().Error("Conditional node must have at least 3 expressions") + return false + } + success = PrintRecursive(node.GetExpressions()[0], sb, depth) && success + sb.WriteString(" ? ") + success = PrintRecursive(node.GetExpressions()[1], sb, depth) && success + sb.WriteString(" : ") + success = PrintRecursive(node.GetExpressions()[2], sb, depth) && success + return success +} From 89482cf04a177931e952fe10c2574110eb0f02e4 Mon Sep 17 00:00:00 2001 From: Evan Chng Xian Lin Date: Thu, 11 Apr 2024 16:48:04 +0800 Subject: [PATCH 06/28] Print contract, Parameter, ParameterList, SourceUnit --- ast/source_unit.go | 3 +- printer/{ast => ast_printer}/and_operation.go | 2 +- printer/{ast => ast_printer}/assignment.go | 2 +- printer/ast_printer/ast_printer.go | 2 ++ printer/{ast => ast_printer}/binary.go | 2 +- printer/{ast => ast_printer}/body.go | 2 +- printer/{ast => ast_printer}/conditional.go | 4 +-- printer/ast_printer/constructor.go | 16 +++++++++ printer/ast_printer/contract.go | 28 +++++++++++++++ printer/ast_printer/parameter.go | 34 +++++++++++++++++++ printer/ast_printer/parameter_list.go | 20 +++++++++++ printer/ast_printer/pragma.go | 13 +++++++ .../source_code_printer.go | 16 ++++++++- printer/ast_printer/source_unit.go | 20 +++++++++++ 14 files changed, 156 insertions(+), 8 deletions(-) rename printer/{ast => ast_printer}/and_operation.go (95%) rename printer/{ast => ast_printer}/assignment.go (98%) create mode 100644 printer/ast_printer/ast_printer.go rename printer/{ast => ast_printer}/binary.go (98%) rename printer/{ast => ast_printer}/body.go (94%) rename printer/{ast => ast_printer}/conditional.go (82%) create mode 100644 printer/ast_printer/constructor.go create mode 100644 printer/ast_printer/contract.go create mode 100644 printer/ast_printer/parameter.go create mode 100644 printer/ast_printer/parameter_list.go create mode 100644 printer/ast_printer/pragma.go rename printer/{ast => ast_printer}/source_code_printer.go (76%) create mode 100644 printer/ast_printer/source_unit.go diff --git a/ast/source_unit.go b/ast/source_unit.go index 9aff89b6..2ff5c8b7 100644 --- a/ast/source_unit.go +++ b/ast/source_unit.go @@ -2,10 +2,11 @@ package ast import ( "fmt" - "github.com/goccy/go-json" "path/filepath" "regexp" + "github.com/goccy/go-json" + v3 "github.com/cncf/xds/go/xds/type/v3" ast_pb "github.com/unpackdev/protos/dist/go/ast" "github.com/unpackdev/solgo" diff --git a/printer/ast/and_operation.go b/printer/ast_printer/and_operation.go similarity index 95% rename from printer/ast/and_operation.go rename to printer/ast_printer/and_operation.go index d1022885..44ed2b8e 100644 --- a/printer/ast/and_operation.go +++ b/printer/ast_printer/and_operation.go @@ -1,4 +1,4 @@ -package printer +package ast_printer import ( "strings" diff --git a/printer/ast/assignment.go b/printer/ast_printer/assignment.go similarity index 98% rename from printer/ast/assignment.go rename to printer/ast_printer/assignment.go index 550eceb9..8537aed1 100644 --- a/printer/ast/assignment.go +++ b/printer/ast_printer/assignment.go @@ -1,4 +1,4 @@ -package printer +package ast_printer import ( "strings" diff --git a/printer/ast_printer/ast_printer.go b/printer/ast_printer/ast_printer.go new file mode 100644 index 00000000..094e7980 --- /dev/null +++ b/printer/ast_printer/ast_printer.go @@ -0,0 +1,2 @@ +package ast_printer + diff --git a/printer/ast/binary.go b/printer/ast_printer/binary.go similarity index 98% rename from printer/ast/binary.go rename to printer/ast_printer/binary.go index 63997806..e0475817 100644 --- a/printer/ast/binary.go +++ b/printer/ast_printer/binary.go @@ -1,4 +1,4 @@ -package printer +package ast_printer import ( "strings" diff --git a/printer/ast/body.go b/printer/ast_printer/body.go similarity index 94% rename from printer/ast/body.go rename to printer/ast_printer/body.go index 57a49706..1b9a0335 100644 --- a/printer/ast/body.go +++ b/printer/ast_printer/body.go @@ -1,4 +1,4 @@ -package printer +package ast_printer import ( "strings" diff --git a/printer/ast/conditional.go b/printer/ast_printer/conditional.go similarity index 82% rename from printer/ast/conditional.go rename to printer/ast_printer/conditional.go index e972731c..eb5a25b2 100644 --- a/printer/ast/conditional.go +++ b/printer/ast_printer/conditional.go @@ -1,4 +1,4 @@ -package printer +package ast_printer import ( "strings" @@ -7,7 +7,7 @@ import ( "go.uber.org/zap" ) -func printConditional(node ast.Conditional, sb *strings.Builder, depth int) bool { +func printConditional(node *ast.Conditional, sb *strings.Builder, depth int) bool { success := true if len(node.GetExpressions()) < 3 { zap.S().Error("Conditional node must have at least 3 expressions") diff --git a/printer/ast_printer/constructor.go b/printer/ast_printer/constructor.go new file mode 100644 index 00000000..777f4a02 --- /dev/null +++ b/printer/ast_printer/constructor.go @@ -0,0 +1,16 @@ +package ast_printer + +import ( + "strings" + + "github.com/unpackdev/solgo/ast" +) + +func printConstructor(node *ast.Constructor, sb *strings.Builder, depth int) bool { + success := true + sb.WriteString("constructor(") + success = printParameterList(node.GetParameters(), sb, depth) && success + sb.WriteString(") \n") + success = PrintRecursive(node.GetBody(), sb, depth) && success + return success +} diff --git a/printer/ast_printer/contract.go b/printer/ast_printer/contract.go new file mode 100644 index 00000000..f4325bdd --- /dev/null +++ b/printer/ast_printer/contract.go @@ -0,0 +1,28 @@ +package ast_printer + +import ( + "strings" + + "github.com/unpackdev/solgo/ast" +) + +func printContract(node *ast.Contract, sb *strings.Builder, depth int) bool { + success := true + sb.WriteString("contract ") + sb.WriteString(node.GetName()) + baseContracts := []string{} + for _, base := range node.GetBaseContracts() { + baseContracts = append(baseContracts, base.BaseName.GetName()) + } + if len(baseContracts) > 0 { + sb.WriteString(" is ") + writeSeperatedStrings(sb, ", ", baseContracts...) + } + + sb.WriteString(" {\n") + for _, child := range node.GetNodes() { + success = PrintRecursive(child, sb, depth+1) && success + } + sb.WriteString("}\n") + return success +} diff --git a/printer/ast_printer/parameter.go b/printer/ast_printer/parameter.go new file mode 100644 index 00000000..071d9144 --- /dev/null +++ b/printer/ast_printer/parameter.go @@ -0,0 +1,34 @@ +package ast_printer + +import ( + "strings" + + ast_pb "github.com/unpackdev/protos/dist/go/ast" + "github.com/unpackdev/solgo/ast" +) + +func getStorageLocationString(storage ast_pb.StorageLocation) string { + switch storage { + case ast_pb.StorageLocation_DEFAULT: + return "" + case ast_pb.StorageLocation_MEMORY: + return "memory" + case ast_pb.StorageLocation_STORAGE: + return "storage" + case ast_pb.StorageLocation_CALLDATA: + return "calldata" + default: + return "" + } +} + +func printParamter(node *ast.Parameter, sb *strings.Builder, depth int) bool { + success := true + sb.WriteString(node.GetName()) + typeName, ok := Print(node.GetTypeName()) + success = ok && success + ident := node.GetName() + storage := getStorageLocationString(node.GetStorageLocation()) + writeSeperatedStrings(sb, " ", typeName, storage, ident) + return success +} diff --git a/printer/ast_printer/parameter_list.go b/printer/ast_printer/parameter_list.go new file mode 100644 index 00000000..8b5723f9 --- /dev/null +++ b/printer/ast_printer/parameter_list.go @@ -0,0 +1,20 @@ +package ast_printer + +import ( + "strings" + + "github.com/unpackdev/solgo/ast" +) + +// parameterList does not have the correct Node interface, we handle it separately +func printParameterList(node *ast.ParameterList, sb *strings.Builder, depth int) bool { + success := true + params := []string{} + for _, param := range node.GetParameters() { + s, ok := Print(param) + success = ok && success + params = append(params, s) + } + writeSeperatedList(sb, ", ", params) + return success +} diff --git a/printer/ast_printer/pragma.go b/printer/ast_printer/pragma.go new file mode 100644 index 00000000..cc4a41f9 --- /dev/null +++ b/printer/ast_printer/pragma.go @@ -0,0 +1,13 @@ +package ast_printer + +import ( + "strings" + + "github.com/unpackdev/solgo/ast" +) + +func printPragma(node *ast.Pragma, sb *strings.Builder, depth int) bool { + sb.WriteString(node.GetText()) + sb.WriteString("\n") + return true +} diff --git a/printer/ast/source_code_printer.go b/printer/ast_printer/source_code_printer.go similarity index 76% rename from printer/ast/source_code_printer.go rename to printer/ast_printer/source_code_printer.go index a19c28a4..0ca7bdcf 100644 --- a/printer/ast/source_code_printer.go +++ b/printer/ast_printer/source_code_printer.go @@ -1,8 +1,9 @@ -package printer +package ast_printer import ( "strings" + ast_pb "github.com/unpackdev/protos/dist/go/ast" "github.com/unpackdev/solgo/ast" "go.uber.org/zap" ) @@ -25,7 +26,20 @@ func PrintRecursive(node ast.Node[ast.NodeType], sb *strings.Builder, depth int) switch node := node.(type) { case *ast.AndOperation: return printAndOperation(node, sb, depth) + case *ast.BodyNode: + return printBody(node, sb, depth) + case *ast.Conditional: + return printConditional(node, sb, depth) + case *ast.Constructor: + return printConstructor(node, sb, depth) + case *ast.Pragma: + return printPragma(node, sb, depth) + case *ast.Contract: + return printContract(node, sb, depth) default: + if node.GetType() == ast_pb.NodeType_SOURCE_UNIT { + return printSourceUnit(node, sb, depth) + } zap.S().Errorf("Unknown node type: %T\n", node) return false } diff --git a/printer/ast_printer/source_unit.go b/printer/ast_printer/source_unit.go new file mode 100644 index 00000000..09ac96a0 --- /dev/null +++ b/printer/ast_printer/source_unit.go @@ -0,0 +1,20 @@ +package ast_printer + +import ( + "fmt" + "strings" + + "github.com/unpackdev/solgo/ast" +) + +func printSourceUnit(node ast.Node[ast.NodeType], sb *strings.Builder, depth int) bool { + success := true + for _, child := range node.GetNodes() { + fmt.Printf("%T\n", child) + s, ok := Print(child.(ast.Node[ast.NodeType])) + success = ok && success + sb.WriteString(s) + sb.WriteString("\n") + } + return success +} From 74d3a24ebe18e41f2ffc361c3b820410fa3ef0a2 Mon Sep 17 00:00:00 2001 From: Evan Chng Xian Lin Date: Thu, 11 Apr 2024 17:39:31 +0800 Subject: [PATCH 07/28] Print typename, Function --- ast/parameter.go | 2 +- printer/ast_printer/body.go | 7 ++-- printer/ast_printer/contract.go | 1 + printer/ast_printer/function.go | 37 ++++++++++++++++++++++ printer/ast_printer/parameter.go | 32 ++++++++++++++++++- printer/ast_printer/source_code_printer.go | 15 +++++++-- printer/ast_printer/type_name.go | 27 ++++++++++++++++ 7 files changed, 112 insertions(+), 9 deletions(-) create mode 100644 printer/ast_printer/function.go create mode 100644 printer/ast_printer/type_name.go diff --git a/ast/parameter.go b/ast/parameter.go index 3827fe72..e3428ab5 100644 --- a/ast/parameter.go +++ b/ast/parameter.go @@ -438,5 +438,5 @@ func (p *Parameter) getStorageLocationFromCtx(ctx *parser.ParameterDeclarationCo } } - return ast_pb.StorageLocation_MEMORY + return ast_pb.StorageLocation_DEFAULT } diff --git a/printer/ast_printer/body.go b/printer/ast_printer/body.go index 1b9a0335..2a6460d1 100644 --- a/printer/ast_printer/body.go +++ b/printer/ast_printer/body.go @@ -8,12 +8,9 @@ import ( func printBody(node *ast.BodyNode, sb *strings.Builder, depth int) bool { success := true - stmts := []string{} for _, stmt := range node.GetStatements() { - s, ok := Print(stmt) - success = ok && success - stmts = append(stmts, indentString(s, depth+1)) + success = PrintRecursive(stmt, sb, depth+1) && success + writeStrings(sb, ";\n") } - writeSeperatedList(sb, "\n;", stmts) return success } diff --git a/printer/ast_printer/contract.go b/printer/ast_printer/contract.go index f4325bdd..9e3706bb 100644 --- a/printer/ast_printer/contract.go +++ b/printer/ast_printer/contract.go @@ -21,6 +21,7 @@ func printContract(node *ast.Contract, sb *strings.Builder, depth int) bool { sb.WriteString(" {\n") for _, child := range node.GetNodes() { + sb.WriteString(indentString("", depth+1)) success = PrintRecursive(child, sb, depth+1) && success } sb.WriteString("}\n") diff --git a/printer/ast_printer/function.go b/printer/ast_printer/function.go new file mode 100644 index 00000000..50e2d55c --- /dev/null +++ b/printer/ast_printer/function.go @@ -0,0 +1,37 @@ +package ast_printer + +import ( + "strings" + + "github.com/unpackdev/solgo/ast" +) + +func printFunction(node *ast.Function, sb *strings.Builder, depth int) bool { + success := true + visibility := getVisibilityString(node.GetVisibility()) + funcName := node.GetName() + mutability := getStateMutabilityString(node.GetStateMutability()) + virtual := "" + if node.IsVirtual() { + virtual = "virtual " + } + + writeStrings(sb, "function ", funcName, "(") + printParameterList(node.GetParameters(), sb, depth) + writeSeperatedStrings(sb, " ", ")", visibility, virtual, mutability) + + paramBuilder := strings.Builder{} + printParameterList(node.GetReturnParameters(), ¶mBuilder, depth) + + if paramBuilder.String() != "" { + writeStrings(sb, " returns (", paramBuilder.String(), ")") + } + + sb.WriteString(" {\n") + if node.GetBody() != nil { + success = PrintRecursive(node.GetBody(), sb, depth) && success + } + sb.WriteString("}\n") + + return success +} diff --git a/printer/ast_printer/parameter.go b/printer/ast_printer/parameter.go index 071d9144..df60b291 100644 --- a/printer/ast_printer/parameter.go +++ b/printer/ast_printer/parameter.go @@ -22,7 +22,37 @@ func getStorageLocationString(storage ast_pb.StorageLocation) string { } } -func printParamter(node *ast.Parameter, sb *strings.Builder, depth int) bool { +func getVisibilityString(visibility ast_pb.Visibility) string { + switch visibility { + case ast_pb.Visibility_INTERNAL: + return "internal" + case ast_pb.Visibility_PUBLIC: + return "public" + case ast_pb.Visibility_EXTERNAL: + return "external" + case ast_pb.Visibility_PRIVATE: + return "private" + default: + return "" + } +} + +func getStateMutabilityString(mut ast_pb.Mutability) string { + switch mut { + case ast_pb.Mutability_PURE: + return "pure" + case ast_pb.Mutability_VIEW: + return "view" + case ast_pb.Mutability_NONPAYABLE: + return "nonpayable" + case ast_pb.Mutability_PAYABLE: + return "payable" + default: + return "" + } +} + +func printParameter(node *ast.Parameter, sb *strings.Builder, depth int) bool { success := true sb.WriteString(node.GetName()) typeName, ok := Print(node.GetTypeName()) diff --git a/printer/ast_printer/source_code_printer.go b/printer/ast_printer/source_code_printer.go index 0ca7bdcf..1142bb9c 100644 --- a/printer/ast_printer/source_code_printer.go +++ b/printer/ast_printer/source_code_printer.go @@ -8,7 +8,7 @@ import ( "go.uber.org/zap" ) -const INDENT_SIZE = 4 +const INDENT_SIZE = 2 // Print is a function that prints the AST nodes to source code func Print(node ast.Node[ast.NodeType]) (string, bool) { @@ -36,6 +36,15 @@ func PrintRecursive(node ast.Node[ast.NodeType], sb *strings.Builder, depth int) return printPragma(node, sb, depth) case *ast.Contract: return printContract(node, sb, depth) + case *ast.Function: + return printFunction(node, sb, depth) + case *ast.Parameter: + return printParameter(node, sb, depth) + case *ast.Assignment: + return printAssignment(node, sb, depth) + case *ast.TypeName: + return printTypeName(node, sb, depth) + default: if node.GetType() == ast_pb.NodeType_SOURCE_UNIT { return printSourceUnit(node, sb, depth) @@ -59,6 +68,7 @@ func writeSeperatedStrings(sb *strings.Builder, seperator string, s ...string) { } else { sb.WriteString(item) } + count++ } } @@ -76,6 +86,7 @@ func writeSeperatedList(sb *strings.Builder, seperator string, s []string) { } else { sb.WriteString(item) } + count++ } } @@ -86,5 +97,5 @@ func writeStrings(sb *strings.Builder, s ...string) { } func indentString(s string, depth int) string { - return strings.Repeat(" ", depth*INDENT_SIZE) + return strings.Repeat(" ", depth*INDENT_SIZE) + s } diff --git a/printer/ast_printer/type_name.go b/printer/ast_printer/type_name.go new file mode 100644 index 00000000..55f5c46f --- /dev/null +++ b/printer/ast_printer/type_name.go @@ -0,0 +1,27 @@ +package ast_printer + +import ( + "fmt" + "strings" + + "github.com/unpackdev/solgo/ast" +) + +func printTypeName(node *ast.TypeName, sb *strings.Builder, depth int) bool { + success := true + if node.ValueType != nil { + keyType, ok := Print(node.KeyType) + if !ok { + success = false + } + valueType, ok := Print(node.ValueType) + if !ok { + success = false + } + typeName := fmt.Sprintf("mapping(%s => %s)", keyType, valueType) + sb.WriteString(typeName) + } else { + sb.WriteString(node.GetName()) + } + return success +} From f226fc3de549419739c8ea7526e122c23c83914f Mon Sep 17 00:00:00 2001 From: Evan Chng Xian Lin Date: Thu, 11 Apr 2024 18:01:12 +0800 Subject: [PATCH 08/28] Print declarations --- ast/state_variable.go | 5 + printer/ast_printer/ast_printer.go | 102 +++++++++++++++++++++ printer/ast_printer/declaration.go | 18 ++++ printer/ast_printer/parameter.go | 3 +- printer/ast_printer/source_code_printer.go | 101 -------------------- printer/ast_printer/state_variable.go | 27 ++++++ 6 files changed, 153 insertions(+), 103 deletions(-) create mode 100644 printer/ast_printer/declaration.go delete mode 100644 printer/ast_printer/source_code_printer.go create mode 100644 printer/ast_printer/state_variable.go diff --git a/ast/state_variable.go b/ast/state_variable.go index 40f2f3d1..6ec062ae 100644 --- a/ast/state_variable.go +++ b/ast/state_variable.go @@ -22,6 +22,7 @@ type StateVariableDeclaration struct { Visibility ast_pb.Visibility `json:"visibility"` // Visibility of the state variable declaration StorageLocation ast_pb.StorageLocation `json:"storage_location"` // Storage location of the state variable declaration StateMutability ast_pb.Mutability `json:"mutability"` // State mutability of the state variable declaration + Override bool `json:"is_override"` // Indicates if the state variable is an override TypeName *TypeName `json:"type_name"` // Type name of the state variable InitialValue Node[NodeType] `json:"initial_value"` // Initial value of the state variable } @@ -207,6 +208,8 @@ func (v *StateVariableDeclaration) Parse( v.Constant = constantCtx != nil } + v.Override = ctx.GetOverrideSpecifierSet() + typeName := NewTypeName(v.ASTBuilder) typeName.Parse(unit, nil, v.Id, ctx.GetType_()) @@ -270,6 +273,8 @@ func (v *StateVariableDeclaration) ParseGlobal( v.Constant = constantCtx != nil } + v.Override = ctx.GetOverrideSpecifierSet() + typeName := NewTypeName(v.ASTBuilder) typeName.Parse(nil, nil, v.Id, ctx.GetType_()) v.TypeName = typeName diff --git a/printer/ast_printer/ast_printer.go b/printer/ast_printer/ast_printer.go index 094e7980..dcc2eae3 100644 --- a/printer/ast_printer/ast_printer.go +++ b/printer/ast_printer/ast_printer.go @@ -1,2 +1,104 @@ package ast_printer +import ( + "strings" + + ast_pb "github.com/unpackdev/protos/dist/go/ast" + "github.com/unpackdev/solgo/ast" + "go.uber.org/zap" +) + +const INDENT_SIZE = 2 + +// Print is a function that prints the AST nodes to source code +func Print(node ast.Node[ast.NodeType]) (string, bool) { + sb := strings.Builder{} + success := PrintRecursive(node, &sb, 0) + return sb.String(), success +} + +// PrintRecursive is a function that prints the AST nodes to source code recursively +func PrintRecursive(node ast.Node[ast.NodeType], sb *strings.Builder, depth int) bool { + if node == nil { + zap.S().Error("Node is nil") + return false + } + switch node := node.(type) { + case *ast.AndOperation: + return printAndOperation(node, sb, depth) + case *ast.BodyNode: + return printBody(node, sb, depth) + case *ast.Conditional: + return printConditional(node, sb, depth) + case *ast.Constructor: + return printConstructor(node, sb, depth) + case *ast.Pragma: + return printPragma(node, sb, depth) + case *ast.Contract: + return printContract(node, sb, depth) + case *ast.Function: + return printFunction(node, sb, depth) + case *ast.Parameter: + return printParameter(node, sb, depth) + case *ast.Assignment: + return printAssignment(node, sb, depth) + case *ast.TypeName: + return printTypeName(node, sb, depth) + case *ast.BinaryOperation: + return printBinaryOperation(node, sb, depth) + case *ast.StateVariableDeclaration: + return printStateVariableDeclaration(node, sb, depth) + default: + if node.GetType() == ast_pb.NodeType_SOURCE_UNIT { + return printSourceUnit(node, sb, depth) + } + zap.S().Errorf("Unknown node type: %T\n", node) + return false + } +} + +func writeSeperatedStrings(sb *strings.Builder, seperator string, s ...string) { + count := 0 + for _, item := range s { + // Skip empty strings + if item == "" { + continue + } + + if count > 0 { + sb.WriteString(seperator) + sb.WriteString(item) + } else { + sb.WriteString(item) + } + count++ + } +} + +func writeSeperatedList(sb *strings.Builder, seperator string, s []string) { + count := 0 + for _, item := range s { + // Skip empty strings + if item == "" { + continue + } + + if count > 0 { + sb.WriteString(seperator) + sb.WriteString(item) + } else { + sb.WriteString(item) + } + count++ + } +} + +func writeStrings(sb *strings.Builder, s ...string) { + for _, item := range s { + sb.WriteString(item) + } +} + +func indentString(s string, depth int) string { + return strings.Repeat(" ", depth*INDENT_SIZE) + s +} diff --git a/printer/ast_printer/declaration.go b/printer/ast_printer/declaration.go new file mode 100644 index 00000000..60cd8f84 --- /dev/null +++ b/printer/ast_printer/declaration.go @@ -0,0 +1,18 @@ +package ast_printer + +import ( + "strings" + + "github.com/unpackdev/solgo/ast" +) + +func printDeclaration(node *ast.Declaration, sb *strings.Builder, depth int) bool { + success := true + typeName, ok := Print(node.GetTypeName()) + success = ok && success + ident := node.GetName() + storage := getStorageLocationString(node.GetStorageLocation()) + writeSeperatedStrings(sb, " ", typeName, storage, ident) + + return success +} diff --git a/printer/ast_printer/parameter.go b/printer/ast_printer/parameter.go index df60b291..dc521c94 100644 --- a/printer/ast_printer/parameter.go +++ b/printer/ast_printer/parameter.go @@ -44,7 +44,7 @@ func getStateMutabilityString(mut ast_pb.Mutability) string { case ast_pb.Mutability_VIEW: return "view" case ast_pb.Mutability_NONPAYABLE: - return "nonpayable" + return "" case ast_pb.Mutability_PAYABLE: return "payable" default: @@ -54,7 +54,6 @@ func getStateMutabilityString(mut ast_pb.Mutability) string { func printParameter(node *ast.Parameter, sb *strings.Builder, depth int) bool { success := true - sb.WriteString(node.GetName()) typeName, ok := Print(node.GetTypeName()) success = ok && success ident := node.GetName() diff --git a/printer/ast_printer/source_code_printer.go b/printer/ast_printer/source_code_printer.go deleted file mode 100644 index 1142bb9c..00000000 --- a/printer/ast_printer/source_code_printer.go +++ /dev/null @@ -1,101 +0,0 @@ -package ast_printer - -import ( - "strings" - - ast_pb "github.com/unpackdev/protos/dist/go/ast" - "github.com/unpackdev/solgo/ast" - "go.uber.org/zap" -) - -const INDENT_SIZE = 2 - -// Print is a function that prints the AST nodes to source code -func Print(node ast.Node[ast.NodeType]) (string, bool) { - sb := strings.Builder{} - success := PrintRecursive(node, &sb, 0) - return sb.String(), success -} - -// PrintRecursive is a function that prints the AST nodes to source code recursively -func PrintRecursive(node ast.Node[ast.NodeType], sb *strings.Builder, depth int) bool { - if node == nil { - zap.S().Error("Node is nil") - return false - } - switch node := node.(type) { - case *ast.AndOperation: - return printAndOperation(node, sb, depth) - case *ast.BodyNode: - return printBody(node, sb, depth) - case *ast.Conditional: - return printConditional(node, sb, depth) - case *ast.Constructor: - return printConstructor(node, sb, depth) - case *ast.Pragma: - return printPragma(node, sb, depth) - case *ast.Contract: - return printContract(node, sb, depth) - case *ast.Function: - return printFunction(node, sb, depth) - case *ast.Parameter: - return printParameter(node, sb, depth) - case *ast.Assignment: - return printAssignment(node, sb, depth) - case *ast.TypeName: - return printTypeName(node, sb, depth) - - default: - if node.GetType() == ast_pb.NodeType_SOURCE_UNIT { - return printSourceUnit(node, sb, depth) - } - zap.S().Errorf("Unknown node type: %T\n", node) - return false - } -} - -func writeSeperatedStrings(sb *strings.Builder, seperator string, s ...string) { - count := 0 - for _, item := range s { - // Skip empty strings - if item == "" { - continue - } - - if count > 0 { - sb.WriteString(seperator) - sb.WriteString(item) - } else { - sb.WriteString(item) - } - count++ - } -} - -func writeSeperatedList(sb *strings.Builder, seperator string, s []string) { - count := 0 - for _, item := range s { - // Skip empty strings - if item == "" { - continue - } - - if count > 0 { - sb.WriteString(seperator) - sb.WriteString(item) - } else { - sb.WriteString(item) - } - count++ - } -} - -func writeStrings(sb *strings.Builder, s ...string) { - for _, item := range s { - sb.WriteString(item) - } -} - -func indentString(s string, depth int) string { - return strings.Repeat(" ", depth*INDENT_SIZE) + s -} diff --git a/printer/ast_printer/state_variable.go b/printer/ast_printer/state_variable.go new file mode 100644 index 00000000..34cd827d --- /dev/null +++ b/printer/ast_printer/state_variable.go @@ -0,0 +1,27 @@ +package ast_printer + +import ( + "strings" + + "github.com/unpackdev/solgo/ast" +) + +func printStateVariableDeclaration(node *ast.StateVariableDeclaration, sb *strings.Builder, depth int) bool { + success := true + typeName, ok := Print(node.GetTypeName()) + success = ok && success + ident := node.GetName() + storage := getStorageLocationString(node.GetStorageLocation()) + visibility := getVisibilityString(node.GetVisibility()) + override := "" + if node.Override { + override = "override" + } + writeSeperatedStrings(sb, " ", visibility, storage, typeName, override, ident) + if node.GetInitialValue != nil { + sb.WriteString(" = ") + success = PrintRecursive(node.GetInitialValue(), sb, depth) && success + } + sb.WriteString(";\n") + return success +} From e95e1d64aab802f401f09b44b11edda41ea05be4 Mon Sep 17 00:00:00 2001 From: Evan Chng Xian Lin Date: Thu, 11 Apr 2024 18:21:25 +0800 Subject: [PATCH 09/28] Print Emit --- printer/ast_printer/ast_printer.go | 47 ++++++++++++++++++++++++++++++ printer/ast_printer/emit.go | 23 +++++++++++++++ printer/ast_printer/parameter.go | 46 ----------------------------- 3 files changed, 70 insertions(+), 46 deletions(-) create mode 100644 printer/ast_printer/emit.go diff --git a/printer/ast_printer/ast_printer.go b/printer/ast_printer/ast_printer.go index dcc2eae3..fd95504d 100644 --- a/printer/ast_printer/ast_printer.go +++ b/printer/ast_printer/ast_printer.go @@ -48,6 +48,8 @@ func PrintRecursive(node ast.Node[ast.NodeType], sb *strings.Builder, depth int) return printBinaryOperation(node, sb, depth) case *ast.StateVariableDeclaration: return printStateVariableDeclaration(node, sb, depth) + case *ast.Emit: + return printEmit(node, sb, depth) default: if node.GetType() == ast_pb.NodeType_SOURCE_UNIT { return printSourceUnit(node, sb, depth) @@ -102,3 +104,48 @@ func writeStrings(sb *strings.Builder, s ...string) { func indentString(s string, depth int) string { return strings.Repeat(" ", depth*INDENT_SIZE) + s } + +func getStorageLocationString(storage ast_pb.StorageLocation) string { + switch storage { + case ast_pb.StorageLocation_DEFAULT: + return "" + case ast_pb.StorageLocation_MEMORY: + return "memory" + case ast_pb.StorageLocation_STORAGE: + return "storage" + case ast_pb.StorageLocation_CALLDATA: + return "calldata" + default: + return "" + } +} + +func getVisibilityString(visibility ast_pb.Visibility) string { + switch visibility { + case ast_pb.Visibility_INTERNAL: + return "internal" + case ast_pb.Visibility_PUBLIC: + return "public" + case ast_pb.Visibility_EXTERNAL: + return "external" + case ast_pb.Visibility_PRIVATE: + return "private" + default: + return "" + } +} + +func getStateMutabilityString(mut ast_pb.Mutability) string { + switch mut { + case ast_pb.Mutability_PURE: + return "pure" + case ast_pb.Mutability_VIEW: + return "view" + case ast_pb.Mutability_NONPAYABLE: + return "" + case ast_pb.Mutability_PAYABLE: + return "payable" + default: + return "" + } +} diff --git a/printer/ast_printer/emit.go b/printer/ast_printer/emit.go new file mode 100644 index 00000000..ffddcde1 --- /dev/null +++ b/printer/ast_printer/emit.go @@ -0,0 +1,23 @@ +package ast_printer + +import ( + "strings" + + "github.com/unpackdev/solgo/ast" +) + +func printEmit(node *ast.Emit, sb *strings.Builder, depth int) bool { + success := true + args := []string{} + for _, arg := range node.GetArguments() { + s, ok := Print(arg) + success = ok && success + args = append(args, s) + } + sb.WriteString("emit ") + success = PrintRecursive(node.GetExpression(), sb, depth) && success + sb.WriteString("(") + writeSeperatedList(sb, ", ", args) + sb.WriteString(")") + return success +} diff --git a/printer/ast_printer/parameter.go b/printer/ast_printer/parameter.go index dc521c94..fb2954e3 100644 --- a/printer/ast_printer/parameter.go +++ b/printer/ast_printer/parameter.go @@ -3,55 +3,9 @@ package ast_printer import ( "strings" - ast_pb "github.com/unpackdev/protos/dist/go/ast" "github.com/unpackdev/solgo/ast" ) -func getStorageLocationString(storage ast_pb.StorageLocation) string { - switch storage { - case ast_pb.StorageLocation_DEFAULT: - return "" - case ast_pb.StorageLocation_MEMORY: - return "memory" - case ast_pb.StorageLocation_STORAGE: - return "storage" - case ast_pb.StorageLocation_CALLDATA: - return "calldata" - default: - return "" - } -} - -func getVisibilityString(visibility ast_pb.Visibility) string { - switch visibility { - case ast_pb.Visibility_INTERNAL: - return "internal" - case ast_pb.Visibility_PUBLIC: - return "public" - case ast_pb.Visibility_EXTERNAL: - return "external" - case ast_pb.Visibility_PRIVATE: - return "private" - default: - return "" - } -} - -func getStateMutabilityString(mut ast_pb.Mutability) string { - switch mut { - case ast_pb.Mutability_PURE: - return "pure" - case ast_pb.Mutability_VIEW: - return "view" - case ast_pb.Mutability_NONPAYABLE: - return "" - case ast_pb.Mutability_PAYABLE: - return "payable" - default: - return "" - } -} - func printParameter(node *ast.Parameter, sb *strings.Builder, depth int) bool { success := true typeName, ok := Print(node.GetTypeName()) From e72e982b0396183d9a40989630c42f4e35609367 Mon Sep 17 00:00:00 2001 From: Evan Chng Xian Lin Date: Thu, 11 Apr 2024 18:25:13 +0800 Subject: [PATCH 10/28] Print For --- printer/ast_printer/ast_printer.go | 2 ++ printer/ast_printer/for.go | 29 +++++++++++++++++++++++++++++ 2 files changed, 31 insertions(+) create mode 100644 printer/ast_printer/for.go diff --git a/printer/ast_printer/ast_printer.go b/printer/ast_printer/ast_printer.go index fd95504d..7b77a803 100644 --- a/printer/ast_printer/ast_printer.go +++ b/printer/ast_printer/ast_printer.go @@ -50,6 +50,8 @@ func PrintRecursive(node ast.Node[ast.NodeType], sb *strings.Builder, depth int) return printStateVariableDeclaration(node, sb, depth) case *ast.Emit: return printEmit(node, sb, depth) + case *ast.ForStatement: + return printFor(node, sb, depth) default: if node.GetType() == ast_pb.NodeType_SOURCE_UNIT { return printSourceUnit(node, sb, depth) diff --git a/printer/ast_printer/for.go b/printer/ast_printer/for.go new file mode 100644 index 00000000..e72dc606 --- /dev/null +++ b/printer/ast_printer/for.go @@ -0,0 +1,29 @@ +package ast_printer + +import ( + "strings" + + "github.com/unpackdev/solgo/ast" +) + +func printFor(node *ast.ForStatement, sb *strings.Builder, depth int) bool { + success := true + sb.WriteString("for ") + if node.GetInitialiser() != nil { + success = PrintRecursive(node.GetInitialiser(), sb, depth) && success + } + sb.WriteString("; ") + if node.GetCondition() != nil { + success = PrintRecursive(node.GetCondition(), sb, depth) && success + } + sb.WriteString("; ") + if node.GetClosure() != nil { + success = PrintRecursive(node.GetClosure(), sb, depth) && success + } + sb.WriteString(" {\n") + if node.GetBody() != nil { + success = PrintRecursive(node.GetBody(), sb, depth) && success + } + sb.WriteString("}") + return success +} From 49d2ec470bd0be31f9f57ba0bca5eac11bc0164c Mon Sep 17 00:00:00 2001 From: Evan Chng Xian Lin Date: Thu, 11 Apr 2024 18:31:28 +0800 Subject: [PATCH 11/28] Print PrimaryExpression --- printer/ast_printer/ast_printer.go | 2 ++ printer/ast_printer/primary_expression.go | 18 ++++++++++++++++++ 2 files changed, 20 insertions(+) create mode 100644 printer/ast_printer/primary_expression.go diff --git a/printer/ast_printer/ast_printer.go b/printer/ast_printer/ast_printer.go index 7b77a803..12c9fc70 100644 --- a/printer/ast_printer/ast_printer.go +++ b/printer/ast_printer/ast_printer.go @@ -52,6 +52,8 @@ func PrintRecursive(node ast.Node[ast.NodeType], sb *strings.Builder, depth int) return printEmit(node, sb, depth) case *ast.ForStatement: return printFor(node, sb, depth) + case *ast.PrimaryExpression: + return printPrimaryExpression(node, sb, depth) default: if node.GetType() == ast_pb.NodeType_SOURCE_UNIT { return printSourceUnit(node, sb, depth) diff --git a/printer/ast_printer/primary_expression.go b/printer/ast_printer/primary_expression.go new file mode 100644 index 00000000..86418e1a --- /dev/null +++ b/printer/ast_printer/primary_expression.go @@ -0,0 +1,18 @@ +package ast_printer + +import ( + "strings" + + "github.com/unpackdev/solgo/ast" +) + +func printPrimaryExpression(node *ast.PrimaryExpression, sb *strings.Builder, depth int) bool { + s := "" + if node.GetValue() == "" { + s = node.GetName() + } else { + s = node.GetValue() + } + sb.WriteString(s) + return true +} From 7077282e37c605319071fe4be2d4a3019816fb57 Mon Sep 17 00:00:00 2001 From: Evan Chng Xian Lin Date: Thu, 11 Apr 2024 23:54:32 +0800 Subject: [PATCH 12/28] Print FunctionCall --- printer/ast_printer/ast_printer.go | 2 ++ printer/ast_printer/body.go | 1 + printer/ast_printer/constructor.go | 2 +- printer/ast_printer/function.go | 4 ++-- printer/ast_printer/function_call.go | 26 ++++++++++++++++++++++++++ printer/ast_printer/state_variable.go | 2 +- 6 files changed, 33 insertions(+), 4 deletions(-) create mode 100644 printer/ast_printer/function_call.go diff --git a/printer/ast_printer/ast_printer.go b/printer/ast_printer/ast_printer.go index 12c9fc70..e9dc2904 100644 --- a/printer/ast_printer/ast_printer.go +++ b/printer/ast_printer/ast_printer.go @@ -54,6 +54,8 @@ func PrintRecursive(node ast.Node[ast.NodeType], sb *strings.Builder, depth int) return printFor(node, sb, depth) case *ast.PrimaryExpression: return printPrimaryExpression(node, sb, depth) + case *ast.FunctionCall: + return printFunctionCall(node, sb, depth) default: if node.GetType() == ast_pb.NodeType_SOURCE_UNIT { return printSourceUnit(node, sb, depth) diff --git a/printer/ast_printer/body.go b/printer/ast_printer/body.go index 2a6460d1..83c9218f 100644 --- a/printer/ast_printer/body.go +++ b/printer/ast_printer/body.go @@ -9,6 +9,7 @@ import ( func printBody(node *ast.BodyNode, sb *strings.Builder, depth int) bool { success := true for _, stmt := range node.GetStatements() { + sb.WriteString(indentString("", depth)) success = PrintRecursive(stmt, sb, depth+1) && success writeStrings(sb, ";\n") } diff --git a/printer/ast_printer/constructor.go b/printer/ast_printer/constructor.go index 777f4a02..69782101 100644 --- a/printer/ast_printer/constructor.go +++ b/printer/ast_printer/constructor.go @@ -11,6 +11,6 @@ func printConstructor(node *ast.Constructor, sb *strings.Builder, depth int) boo sb.WriteString("constructor(") success = printParameterList(node.GetParameters(), sb, depth) && success sb.WriteString(") \n") - success = PrintRecursive(node.GetBody(), sb, depth) && success + success = PrintRecursive(node.GetBody(), sb, depth+1) && success return success } diff --git a/printer/ast_printer/function.go b/printer/ast_printer/function.go index 50e2d55c..14ef9adf 100644 --- a/printer/ast_printer/function.go +++ b/printer/ast_printer/function.go @@ -29,9 +29,9 @@ func printFunction(node *ast.Function, sb *strings.Builder, depth int) bool { sb.WriteString(" {\n") if node.GetBody() != nil { - success = PrintRecursive(node.GetBody(), sb, depth) && success + success = PrintRecursive(node.GetBody(), sb, depth+1) && success } - sb.WriteString("}\n") + sb.WriteString(indentString("}\n", depth)) return success } diff --git a/printer/ast_printer/function_call.go b/printer/ast_printer/function_call.go new file mode 100644 index 00000000..ef147900 --- /dev/null +++ b/printer/ast_printer/function_call.go @@ -0,0 +1,26 @@ +package ast_printer + +import ( + "strings" + + "github.com/unpackdev/solgo/ast" +) + +func printFunctionCall(node *ast.FunctionCall, sb *strings.Builder, depth int) bool { + success := true + if node.GetExpression() != nil { + success = PrintRecursive(node.GetExpression(), sb, depth) && success + } + args := []string{} + if node.GetArguments() != nil { + for _, arg := range node.GetArguments() { + s, ok := Print(arg) + success = ok && success + args = append(args, s) + } + } + sb.WriteString("(") + writeSeperatedList(sb, ", ", args) + sb.WriteString(")") + return success +} diff --git a/printer/ast_printer/state_variable.go b/printer/ast_printer/state_variable.go index 34cd827d..9da7df57 100644 --- a/printer/ast_printer/state_variable.go +++ b/printer/ast_printer/state_variable.go @@ -18,7 +18,7 @@ func printStateVariableDeclaration(node *ast.StateVariableDeclaration, sb *strin override = "override" } writeSeperatedStrings(sb, " ", visibility, storage, typeName, override, ident) - if node.GetInitialValue != nil { + if node.GetInitialValue() != nil { sb.WriteString(" = ") success = PrintRecursive(node.GetInitialValue(), sb, depth) && success } From adb19ed86de2ff3cb79805da55ac8b2a308769ca Mon Sep 17 00:00:00 2001 From: Evan Chng Xian Lin Date: Fri, 12 Apr 2024 00:01:16 +0800 Subject: [PATCH 13/28] Print Import --- printer/ast_printer/ast_printer.go | 2 ++ printer/ast_printer/imports.go | 21 +++++++++++++++++++++ 2 files changed, 23 insertions(+) create mode 100644 printer/ast_printer/imports.go diff --git a/printer/ast_printer/ast_printer.go b/printer/ast_printer/ast_printer.go index e9dc2904..92ce372b 100644 --- a/printer/ast_printer/ast_printer.go +++ b/printer/ast_printer/ast_printer.go @@ -56,6 +56,8 @@ func PrintRecursive(node ast.Node[ast.NodeType], sb *strings.Builder, depth int) return printPrimaryExpression(node, sb, depth) case *ast.FunctionCall: return printFunctionCall(node, sb, depth) + case *ast.Import: + return printImport(node, sb, depth) default: if node.GetType() == ast_pb.NodeType_SOURCE_UNIT { return printSourceUnit(node, sb, depth) diff --git a/printer/ast_printer/imports.go b/printer/ast_printer/imports.go new file mode 100644 index 00000000..870a3261 --- /dev/null +++ b/printer/ast_printer/imports.go @@ -0,0 +1,21 @@ +package ast_printer + +import ( + "strings" + + "github.com/unpackdev/solgo/ast" +) + +func printImport(node *ast.Import, sb *strings.Builder, depth int) bool { + success := true + sb.WriteString("import ") + if node.UnitAlias != "" { + writeStrings(sb, node.GetFile(), " as ", node.UnitAlias) + } else if len(node.UnitAliases) > 0 { + sb.WriteString("{") + writeSeperatedList(sb, ", ", node.UnitAliases) + writeStrings(sb, "} from ", node.GetFile()) + } + writeStrings(sb, ";\n") + return success +} From b34296e8bf667f7465485c6cf2efe99da39b809c Mon Sep 17 00:00:00 2001 From: Evan Chng Xian Lin Date: Fri, 12 Apr 2024 00:17:11 +0800 Subject: [PATCH 14/28] Print Unary Prefix and Suffix --- printer/ast_printer/ast_printer.go | 11 ++++++++++ printer/ast_printer/for.go | 4 ++-- printer/ast_printer/member_access.go | 15 ++++++++++++++ printer/ast_printer/unary_prefix.go | 13 ++++++++++++ printer/ast_printer/unary_suffix.go | 31 ++++++++++++++++++++++++++++ printer/ast_printer/variable.go | 26 +++++++++++++++++++++++ 6 files changed, 98 insertions(+), 2 deletions(-) create mode 100644 printer/ast_printer/member_access.go create mode 100644 printer/ast_printer/unary_prefix.go create mode 100644 printer/ast_printer/unary_suffix.go create mode 100644 printer/ast_printer/variable.go diff --git a/printer/ast_printer/ast_printer.go b/printer/ast_printer/ast_printer.go index 92ce372b..c99d9ff7 100644 --- a/printer/ast_printer/ast_printer.go +++ b/printer/ast_printer/ast_printer.go @@ -58,6 +58,17 @@ func PrintRecursive(node ast.Node[ast.NodeType], sb *strings.Builder, depth int) return printFunctionCall(node, sb, depth) case *ast.Import: return printImport(node, sb, depth) + case *ast.MemberAccessExpression: + return printMemberAccessExpression(node, sb, depth) + case *ast.VariableDeclaration: + return printVariableDeclaration(node, sb, depth) + case *ast.Declaration: + return printDeclaration(node, sb, depth) + case *ast.UnaryPrefix: + return printUnaryPrefix(node, sb, depth) + case *ast.UnarySuffix: + return printUnarySuffix(node, sb, depth) + default: if node.GetType() == ast_pb.NodeType_SOURCE_UNIT { return printSourceUnit(node, sb, depth) diff --git a/printer/ast_printer/for.go b/printer/ast_printer/for.go index e72dc606..f7999ad9 100644 --- a/printer/ast_printer/for.go +++ b/printer/ast_printer/for.go @@ -8,7 +8,7 @@ import ( func printFor(node *ast.ForStatement, sb *strings.Builder, depth int) bool { success := true - sb.WriteString("for ") + sb.WriteString("for (") if node.GetInitialiser() != nil { success = PrintRecursive(node.GetInitialiser(), sb, depth) && success } @@ -20,7 +20,7 @@ func printFor(node *ast.ForStatement, sb *strings.Builder, depth int) bool { if node.GetClosure() != nil { success = PrintRecursive(node.GetClosure(), sb, depth) && success } - sb.WriteString(" {\n") + sb.WriteString(") {\n") if node.GetBody() != nil { success = PrintRecursive(node.GetBody(), sb, depth) && success } diff --git a/printer/ast_printer/member_access.go b/printer/ast_printer/member_access.go new file mode 100644 index 00000000..10a699c3 --- /dev/null +++ b/printer/ast_printer/member_access.go @@ -0,0 +1,15 @@ +package ast_printer + +import ( + "strings" + + "github.com/unpackdev/solgo/ast" +) + +func printMemberAccessExpression(node *ast.MemberAccessExpression, sb *strings.Builder, depth int) bool { + success := true + success = PrintRecursive(node.GetExpression(), sb, depth) && success + sb.WriteString(".") + sb.WriteString(node.GetMemberName()) + return success +} diff --git a/printer/ast_printer/unary_prefix.go b/printer/ast_printer/unary_prefix.go new file mode 100644 index 00000000..58f7d1db --- /dev/null +++ b/printer/ast_printer/unary_prefix.go @@ -0,0 +1,13 @@ +package ast_printer + +import ( + "strings" + + "github.com/unpackdev/solgo/ast" +) + +func printUnaryPrefix(node *ast.UnaryPrefix, sb *strings.Builder, depth int) bool { + sb.WriteString(getUnaryOperatorString(node.GetOperator())) + success := PrintRecursive(node.GetExpression(), sb, depth) + return success +} diff --git a/printer/ast_printer/unary_suffix.go b/printer/ast_printer/unary_suffix.go new file mode 100644 index 00000000..427bc927 --- /dev/null +++ b/printer/ast_printer/unary_suffix.go @@ -0,0 +1,31 @@ +package ast_printer + +import ( + "strings" + + ast_pb "github.com/unpackdev/protos/dist/go/ast" + "github.com/unpackdev/solgo/ast" +) + +func getUnaryOperatorString(op ast_pb.Operator) string { + switch op { + case ast_pb.Operator_NOT: + return "!" + case ast_pb.Operator_BIT_NOT: + return "~" + case ast_pb.Operator_SUBTRACT: + return "-" + case ast_pb.Operator_INCREMENT: + return "++" + case ast_pb.Operator_DECREMENT: + return "--" + default: + return "" + } +} + +func printUnarySuffix(node *ast.UnarySuffix, sb *strings.Builder, depth int) bool { + success := PrintRecursive(node.GetExpression(), sb, depth) + sb.WriteString(getUnaryOperatorString(node.GetOperator())) + return success +} diff --git a/printer/ast_printer/variable.go b/printer/ast_printer/variable.go new file mode 100644 index 00000000..1e5afe25 --- /dev/null +++ b/printer/ast_printer/variable.go @@ -0,0 +1,26 @@ +package ast_printer + +import ( + "strings" + + "github.com/unpackdev/solgo/ast" +) + +func printVariableDeclaration(node *ast.VariableDeclaration, sb *strings.Builder, depth int) bool { + success := true + isTuple := len(node.GetDeclarations()) > 1 + if isTuple { + decls := []string{} + for _, decl := range node.GetDeclarations() { + s, ok := Print(decl) + success = ok && success + decls = append(decls, s) + } + writeSeperatedList(sb, ", ", decls) + } else { + PrintRecursive(node.GetDeclarations()[0], sb, depth) + } + sb.WriteString(" = ") + PrintRecursive(node.GetInitialValue(), sb, depth) + return success +} From 9711c185d96f2ccebd23f1830c4db2ab60c7cb3b Mon Sep 17 00:00:00 2001 From: Evan Chng Xian Lin Date: Fri, 12 Apr 2024 00:25:19 +0800 Subject: [PATCH 15/28] Print IndexAccess and Return --- printer/ast_printer/ast_printer.go | 5 ++++- printer/ast_printer/for.go | 2 +- printer/ast_printer/index_access.go | 16 ++++++++++++++++ printer/ast_printer/return.go | 17 +++++++++++++++++ printer/ast_printer/source_unit.go | 2 -- 5 files changed, 38 insertions(+), 4 deletions(-) create mode 100644 printer/ast_printer/index_access.go create mode 100644 printer/ast_printer/return.go diff --git a/printer/ast_printer/ast_printer.go b/printer/ast_printer/ast_printer.go index c99d9ff7..aa6d86a8 100644 --- a/printer/ast_printer/ast_printer.go +++ b/printer/ast_printer/ast_printer.go @@ -68,7 +68,10 @@ func PrintRecursive(node ast.Node[ast.NodeType], sb *strings.Builder, depth int) return printUnaryPrefix(node, sb, depth) case *ast.UnarySuffix: return printUnarySuffix(node, sb, depth) - + case *ast.IndexAccess: + return printIndexAccess(node, sb, depth) + case *ast.ReturnStatement: + return printReturn(node, sb, depth) default: if node.GetType() == ast_pb.NodeType_SOURCE_UNIT { return printSourceUnit(node, sb, depth) diff --git a/printer/ast_printer/for.go b/printer/ast_printer/for.go index f7999ad9..2eca9035 100644 --- a/printer/ast_printer/for.go +++ b/printer/ast_printer/for.go @@ -24,6 +24,6 @@ func printFor(node *ast.ForStatement, sb *strings.Builder, depth int) bool { if node.GetBody() != nil { success = PrintRecursive(node.GetBody(), sb, depth) && success } - sb.WriteString("}") + sb.WriteString(indentString("}", depth-1)) return success } diff --git a/printer/ast_printer/index_access.go b/printer/ast_printer/index_access.go new file mode 100644 index 00000000..66d88c38 --- /dev/null +++ b/printer/ast_printer/index_access.go @@ -0,0 +1,16 @@ +package ast_printer + +import ( + "strings" + + "github.com/unpackdev/solgo/ast" +) + +func printIndexAccess(node *ast.IndexAccess, sb *strings.Builder, depth int) bool { + success := true + success = PrintRecursive(node.GetBaseExpression(), sb, depth) && success + sb.WriteString("[") + success = PrintRecursive(node.GetIndexExpression(), sb, depth) && success + sb.WriteString("]") + return success +} diff --git a/printer/ast_printer/return.go b/printer/ast_printer/return.go new file mode 100644 index 00000000..52f675ab --- /dev/null +++ b/printer/ast_printer/return.go @@ -0,0 +1,17 @@ +package ast_printer + +import ( + "strings" + + "github.com/unpackdev/solgo/ast" +) + +func printReturn(node *ast.ReturnStatement, sb *strings.Builder, depth int) bool { + success := true + sb.WriteString("return") + if node.GetExpression() != nil { + sb.WriteString(" ") + success = PrintRecursive(node.GetExpression(), sb, depth) && success + } + return success +} diff --git a/printer/ast_printer/source_unit.go b/printer/ast_printer/source_unit.go index 09ac96a0..0a5525cf 100644 --- a/printer/ast_printer/source_unit.go +++ b/printer/ast_printer/source_unit.go @@ -1,7 +1,6 @@ package ast_printer import ( - "fmt" "strings" "github.com/unpackdev/solgo/ast" @@ -10,7 +9,6 @@ import ( func printSourceUnit(node ast.Node[ast.NodeType], sb *strings.Builder, depth int) bool { success := true for _, child := range node.GetNodes() { - fmt.Printf("%T\n", child) s, ok := Print(child.(ast.Node[ast.NodeType])) success = ok && success sb.WriteString(s) From ec75618cfb45bcb51f794802b809ba218bd12e03 Mon Sep 17 00:00:00 2001 From: Evan Chng Xian Lin Date: Fri, 12 Apr 2024 00:33:43 +0800 Subject: [PATCH 16/28] Print tuple --- printer/ast_printer/ast_printer.go | 2 ++ printer/ast_printer/constructor.go | 3 ++- printer/ast_printer/tuple.go | 21 +++++++++++++++++++++ 3 files changed, 25 insertions(+), 1 deletion(-) create mode 100644 printer/ast_printer/tuple.go diff --git a/printer/ast_printer/ast_printer.go b/printer/ast_printer/ast_printer.go index aa6d86a8..1536da67 100644 --- a/printer/ast_printer/ast_printer.go +++ b/printer/ast_printer/ast_printer.go @@ -72,6 +72,8 @@ func PrintRecursive(node ast.Node[ast.NodeType], sb *strings.Builder, depth int) return printIndexAccess(node, sb, depth) case *ast.ReturnStatement: return printReturn(node, sb, depth) + case *ast.TupleExpression: + return printTupleExpression(node, sb, depth) default: if node.GetType() == ast_pb.NodeType_SOURCE_UNIT { return printSourceUnit(node, sb, depth) diff --git a/printer/ast_printer/constructor.go b/printer/ast_printer/constructor.go index 69782101..7d92b46d 100644 --- a/printer/ast_printer/constructor.go +++ b/printer/ast_printer/constructor.go @@ -10,7 +10,8 @@ func printConstructor(node *ast.Constructor, sb *strings.Builder, depth int) boo success := true sb.WriteString("constructor(") success = printParameterList(node.GetParameters(), sb, depth) && success - sb.WriteString(") \n") + sb.WriteString(") {\n") success = PrintRecursive(node.GetBody(), sb, depth+1) && success + sb.WriteString(indentString("}\n", depth)) return success } diff --git a/printer/ast_printer/tuple.go b/printer/ast_printer/tuple.go new file mode 100644 index 00000000..b7678b45 --- /dev/null +++ b/printer/ast_printer/tuple.go @@ -0,0 +1,21 @@ +package ast_printer + +import ( + "strings" + + "github.com/unpackdev/solgo/ast" +) + +func printTupleExpression(node *ast.TupleExpression, sb *strings.Builder, depth int) bool { + success := true + sb.WriteString("(") + components := []string{} + for _, component := range node.GetComponents() { + s, ok := Print(component) + success = ok && success + components = append(components, s) + } + sb.WriteString(strings.Join(components, ", ")) + sb.WriteString(")") + return success +} From 8808357b30aa5dd1afc2c52c6ed580799409554b Mon Sep 17 00:00:00 2001 From: Evan Chng Xian Lin Date: Fri, 12 Apr 2024 10:26:21 +0800 Subject: [PATCH 17/28] Print imports fix --- printer/ast_printer/imports.go | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/printer/ast_printer/imports.go b/printer/ast_printer/imports.go index 870a3261..dd84f3b5 100644 --- a/printer/ast_printer/imports.go +++ b/printer/ast_printer/imports.go @@ -1,6 +1,7 @@ package ast_printer import ( + "fmt" "strings" "github.com/unpackdev/solgo/ast" @@ -9,13 +10,16 @@ import ( func printImport(node *ast.Import, sb *strings.Builder, depth int) bool { success := true sb.WriteString("import ") + file := fmt.Sprintf("'%s'", node.GetFile()) if node.UnitAlias != "" { - writeStrings(sb, node.GetFile(), " as ", node.UnitAlias) + writeStrings(sb, file, " as ", node.UnitAlias) } else if len(node.UnitAliases) > 0 { sb.WriteString("{") writeSeperatedList(sb, ", ", node.UnitAliases) - writeStrings(sb, "} from ", node.GetFile()) + writeStrings(sb, "} from ", file) + } else { + writeStrings(sb, file) } - writeStrings(sb, ";\n") + writeStrings(sb, ";") return success } From dc7e7c7ae8d6ed98ce136d38d17a88f40a738f5c Mon Sep 17 00:00:00 2001 From: Evan Chng Xian Lin Date: Fri, 12 Apr 2024 10:55:26 +0800 Subject: [PATCH 18/28] Print struct --- printer/ast_printer/ast_printer.go | 2 ++ printer/ast_printer/struct.go | 21 +++++++++++++++++++++ 2 files changed, 23 insertions(+) create mode 100644 printer/ast_printer/struct.go diff --git a/printer/ast_printer/ast_printer.go b/printer/ast_printer/ast_printer.go index 1536da67..f3bf6eb5 100644 --- a/printer/ast_printer/ast_printer.go +++ b/printer/ast_printer/ast_printer.go @@ -74,6 +74,8 @@ func PrintRecursive(node ast.Node[ast.NodeType], sb *strings.Builder, depth int) return printReturn(node, sb, depth) case *ast.TupleExpression: return printTupleExpression(node, sb, depth) + case *ast.StructDefinition: + return printStructDefinition(node, sb, depth) default: if node.GetType() == ast_pb.NodeType_SOURCE_UNIT { return printSourceUnit(node, sb, depth) diff --git a/printer/ast_printer/struct.go b/printer/ast_printer/struct.go new file mode 100644 index 00000000..e230b35f --- /dev/null +++ b/printer/ast_printer/struct.go @@ -0,0 +1,21 @@ +package ast_printer + +import ( + "strings" + + "github.com/unpackdev/solgo/ast" +) + +func printStructDefinition(node *ast.StructDefinition, sb *strings.Builder, depth int) bool { + success := true + sb.WriteString("struct ") + sb.WriteString(node.GetName()) + sb.WriteString(" {\n") + for _, member := range node.GetMembers() { + sb.WriteString(indentString("", depth+1)) + success = PrintRecursive(member, sb, depth) && success + sb.WriteString(";\n") + } + sb.WriteString(indentString("}\n", depth)) + return success +} From be5144bfb07cc5427e06661245801e07455fd07b Mon Sep 17 00:00:00 2001 From: Evan Chng Xian Lin Date: Fri, 12 Apr 2024 12:01:02 +0800 Subject: [PATCH 19/28] Print Enum and If --- printer/ast_printer/ast_printer.go | 4 ++++ printer/ast_printer/enum.go | 23 +++++++++++++++++++++++ printer/ast_printer/if.go | 25 +++++++++++++++++++++++++ 3 files changed, 52 insertions(+) create mode 100644 printer/ast_printer/enum.go create mode 100644 printer/ast_printer/if.go diff --git a/printer/ast_printer/ast_printer.go b/printer/ast_printer/ast_printer.go index f3bf6eb5..da92b460 100644 --- a/printer/ast_printer/ast_printer.go +++ b/printer/ast_printer/ast_printer.go @@ -76,6 +76,10 @@ func PrintRecursive(node ast.Node[ast.NodeType], sb *strings.Builder, depth int) return printTupleExpression(node, sb, depth) case *ast.StructDefinition: return printStructDefinition(node, sb, depth) + case *ast.IfStatement: + return printIfStatement(node, sb, depth) + case *ast.EnumDefinition: + return printEnumDefinition(node, sb, depth) default: if node.GetType() == ast_pb.NodeType_SOURCE_UNIT { return printSourceUnit(node, sb, depth) diff --git a/printer/ast_printer/enum.go b/printer/ast_printer/enum.go new file mode 100644 index 00000000..6078b332 --- /dev/null +++ b/printer/ast_printer/enum.go @@ -0,0 +1,23 @@ +package ast_printer + +import ( + "strings" + + "github.com/unpackdev/solgo/ast" +) + +func printEnumDefinition(node *ast.EnumDefinition, sb *strings.Builder, depth int) bool { + success := true + sb.WriteString("enum ") + sb.WriteString(node.GetName()) + sb.WriteString(" {") + members := []string{} + for _, member := range node.GetMembers() { + s, ok := Print(member) + success = ok && success + members = append(members, s) + } + writeSeperatedList(sb, ", ", members) + sb.WriteString("}\n") + return success +} diff --git a/printer/ast_printer/if.go b/printer/ast_printer/if.go new file mode 100644 index 00000000..82fc7225 --- /dev/null +++ b/printer/ast_printer/if.go @@ -0,0 +1,25 @@ +package ast_printer + +import ( + "strings" + + "github.com/unpackdev/solgo/ast" +) + +func printIfStatement(node *ast.IfStatement, sb *strings.Builder, depth int) bool { + success := true + sb.WriteString("if (") + if node.GetCondition() != nil { + success = PrintRecursive(node.GetCondition(), sb, depth) && success + } + sb.WriteString(") {\n") + if node.GetBody() != nil { + success = PrintRecursive(node.GetBody(), sb, depth+1) && success + } + // if node.GetElse() != nil { + // sb.WriteString(indentString("} else ", depth-1)) + // success = PrintRecursive(node.GetElse(), sb, depth) && success + // } + sb.WriteString(indentString("}", depth-1)) + return success +} From ab6a4a8b41aa4c17a77b51ea46bda536af6948ea Mon Sep 17 00:00:00 2001 From: Evan Chng Xian Lin Date: Fri, 12 Apr 2024 12:01:23 +0800 Subject: [PATCH 20/28] Handle "addresspayable" edge case --- printer/ast_printer/parameter.go | 6 +++++- printer/ast_printer/state_variable.go | 6 ++++++ 2 files changed, 11 insertions(+), 1 deletion(-) diff --git a/printer/ast_printer/parameter.go b/printer/ast_printer/parameter.go index fb2954e3..08120c9c 100644 --- a/printer/ast_printer/parameter.go +++ b/printer/ast_printer/parameter.go @@ -8,7 +8,11 @@ import ( func printParameter(node *ast.Parameter, sb *strings.Builder, depth int) bool { success := true - typeName, ok := Print(node.GetTypeName()) + typeName := "" + ok := true + if node.GetTypeName() != nil { + typeName, ok = Print(node.GetTypeName()) + } success = ok && success ident := node.GetName() storage := getStorageLocationString(node.GetStorageLocation()) diff --git a/printer/ast_printer/state_variable.go b/printer/ast_printer/state_variable.go index 9da7df57..ba576020 100644 --- a/printer/ast_printer/state_variable.go +++ b/printer/ast_printer/state_variable.go @@ -1,6 +1,7 @@ package ast_printer import ( + "fmt" "strings" "github.com/unpackdev/solgo/ast" @@ -14,9 +15,14 @@ func printStateVariableDeclaration(node *ast.StateVariableDeclaration, sb *strin storage := getStorageLocationString(node.GetStorageLocation()) visibility := getVisibilityString(node.GetVisibility()) override := "" + if typeName == "addresspayable" { + typeName = "address" + storage = "payable" + } if node.Override { override = "override" } + fmt.Println(visibility, storage, typeName, override, ident) writeSeperatedStrings(sb, " ", visibility, storage, typeName, override, ident) if node.GetInitialValue() != nil { sb.WriteString(" = ") From 9e0b00a613a6a60b611bf904d8f2528beef6a5fd Mon Sep 17 00:00:00 2001 From: Evan Chng Xian Lin Date: Fri, 12 Apr 2024 13:11:25 +0800 Subject: [PATCH 21/28] Print Modifier --- printer/ast_printer/ast_printer.go | 2 ++ printer/ast_printer/modifier.go | 31 ++++++++++++++++++++++++++++++ 2 files changed, 33 insertions(+) create mode 100644 printer/ast_printer/modifier.go diff --git a/printer/ast_printer/ast_printer.go b/printer/ast_printer/ast_printer.go index da92b460..0823210c 100644 --- a/printer/ast_printer/ast_printer.go +++ b/printer/ast_printer/ast_printer.go @@ -80,6 +80,8 @@ func PrintRecursive(node ast.Node[ast.NodeType], sb *strings.Builder, depth int) return printIfStatement(node, sb, depth) case *ast.EnumDefinition: return printEnumDefinition(node, sb, depth) + case *ast.ModifierDefinition: + return printModifierDefinition(node, sb, depth) default: if node.GetType() == ast_pb.NodeType_SOURCE_UNIT { return printSourceUnit(node, sb, depth) diff --git a/printer/ast_printer/modifier.go b/printer/ast_printer/modifier.go new file mode 100644 index 00000000..fe791170 --- /dev/null +++ b/printer/ast_printer/modifier.go @@ -0,0 +1,31 @@ +package ast_printer + +import ( + "strings" + + "github.com/unpackdev/solgo/ast" +) + +func printModifierDefinition(node *ast.ModifierDefinition, sb *strings.Builder, depth int) bool { + success := true + sb.WriteString("modifier ") + sb.WriteString(node.GetName()) + sb.WriteString("(") + printParameterList(node.GetParameters(), sb, depth) + sb.WriteString(") ") + visibility := getVisibilityString(node.GetVisibility()) + virtual := "" + if node.IsVirtual() { + virtual = "virtual" + } + writeSeperatedStrings(sb, " ", visibility, virtual) + + if node.GetBody() == nil { + sb.WriteString(";\n") + } else { + sb.WriteString(" {\n") + success = PrintRecursive(node.GetBody(), sb, depth+1) && success + sb.WriteString(indentString("}\n", depth)) + } + return success +} From 03d551e3f3af1f2ad273ef16012cfba4df0e7d43 Mon Sep 17 00:00:00 2001 From: Evan Chng Xian Lin Date: Fri, 12 Apr 2024 13:16:20 +0800 Subject: [PATCH 22/28] Print Event --- printer/ast_printer/ast_printer.go | 2 ++ printer/ast_printer/event.go | 18 ++++++++++++++++++ 2 files changed, 20 insertions(+) create mode 100644 printer/ast_printer/event.go diff --git a/printer/ast_printer/ast_printer.go b/printer/ast_printer/ast_printer.go index 0823210c..97766b0c 100644 --- a/printer/ast_printer/ast_printer.go +++ b/printer/ast_printer/ast_printer.go @@ -82,6 +82,8 @@ func PrintRecursive(node ast.Node[ast.NodeType], sb *strings.Builder, depth int) return printEnumDefinition(node, sb, depth) case *ast.ModifierDefinition: return printModifierDefinition(node, sb, depth) + case *ast.EventDefinition: + return printEventDefinition(node, sb, depth) default: if node.GetType() == ast_pb.NodeType_SOURCE_UNIT { return printSourceUnit(node, sb, depth) diff --git a/printer/ast_printer/event.go b/printer/ast_printer/event.go new file mode 100644 index 00000000..70b8d694 --- /dev/null +++ b/printer/ast_printer/event.go @@ -0,0 +1,18 @@ +package ast_printer + +import ( + "strings" + + "github.com/unpackdev/solgo/ast" +) + +func printEventDefinition(node *ast.EventDefinition, sb *strings.Builder, depth int) bool { + success := true + sb.WriteString("event ") + sb.WriteString(node.GetName()) + sb.WriteString("(") + printParameterList(node.GetParameters(), sb, depth) + sb.WriteString(")") + sb.WriteString(";\n") + return success +} From 6582c55264dcd8e14fe50e40afc54eb1f8d6e8cd Mon Sep 17 00:00:00 2001 From: Evan Chng Xian Lin Date: Fri, 12 Apr 2024 13:40:04 +0800 Subject: [PATCH 23/28] Print Error and handle enum type --- printer/ast_printer/ast_printer.go | 2 ++ printer/ast_printer/error.go | 18 ++++++++++++++++++ printer/ast_printer/state_variable.go | 2 +- printer/ast_printer/type_name.go | 8 +++++++- 4 files changed, 28 insertions(+), 2 deletions(-) create mode 100644 printer/ast_printer/error.go diff --git a/printer/ast_printer/ast_printer.go b/printer/ast_printer/ast_printer.go index 97766b0c..62f9d429 100644 --- a/printer/ast_printer/ast_printer.go +++ b/printer/ast_printer/ast_printer.go @@ -84,6 +84,8 @@ func PrintRecursive(node ast.Node[ast.NodeType], sb *strings.Builder, depth int) return printModifierDefinition(node, sb, depth) case *ast.EventDefinition: return printEventDefinition(node, sb, depth) + case *ast.ErrorDefinition: + return printErrorDefinition(node, sb, depth) default: if node.GetType() == ast_pb.NodeType_SOURCE_UNIT { return printSourceUnit(node, sb, depth) diff --git a/printer/ast_printer/error.go b/printer/ast_printer/error.go new file mode 100644 index 00000000..9e08345c --- /dev/null +++ b/printer/ast_printer/error.go @@ -0,0 +1,18 @@ +package ast_printer + +import ( + "strings" + + "github.com/unpackdev/solgo/ast" +) + +func printErrorDefinition(node *ast.ErrorDefinition, sb *strings.Builder, depth int) bool { + success := true + sb.WriteString("error ") + sb.WriteString(node.GetName()) + sb.WriteString("(") + success = printParameterList(node.GetParameters(), sb, depth) && success + sb.WriteString(")") + sb.WriteString(";\n") + return success +} diff --git a/printer/ast_printer/state_variable.go b/printer/ast_printer/state_variable.go index ba576020..499ebf81 100644 --- a/printer/ast_printer/state_variable.go +++ b/printer/ast_printer/state_variable.go @@ -9,6 +9,7 @@ import ( func printStateVariableDeclaration(node *ast.StateVariableDeclaration, sb *strings.Builder, depth int) bool { success := true + fmt.Printf("%+v\n\n", node.GetTypeName()) typeName, ok := Print(node.GetTypeName()) success = ok && success ident := node.GetName() @@ -22,7 +23,6 @@ func printStateVariableDeclaration(node *ast.StateVariableDeclaration, sb *strin if node.Override { override = "override" } - fmt.Println(visibility, storage, typeName, override, ident) writeSeperatedStrings(sb, " ", visibility, storage, typeName, override, ident) if node.GetInitialValue() != nil { sb.WriteString(" = ") diff --git a/printer/ast_printer/type_name.go b/printer/ast_printer/type_name.go index 55f5c46f..376a81ea 100644 --- a/printer/ast_printer/type_name.go +++ b/printer/ast_printer/type_name.go @@ -4,6 +4,7 @@ import ( "fmt" "strings" + ast_pb "github.com/unpackdev/protos/dist/go/ast" "github.com/unpackdev/solgo/ast" ) @@ -21,7 +22,12 @@ func printTypeName(node *ast.TypeName, sb *strings.Builder, depth int) bool { typeName := fmt.Sprintf("mapping(%s => %s)", keyType, valueType) sb.WriteString(typeName) } else { - sb.WriteString(node.GetName()) + if node.NodeType == ast_pb.NodeType_USER_DEFINED_PATH_NAME { + userType := node.GetTree().GetById(node.GetReferencedDeclaration()).(*ast.EnumDefinition) + sb.WriteString(userType.GetName()) + } else { + sb.WriteString(node.GetName()) + } } return success } From 08eb0e2a9cf798f6308606785f0216eb82d67137 Mon Sep 17 00:00:00 2001 From: Evan Chng Xian Lin Date: Fri, 12 Apr 2024 13:49:41 +0800 Subject: [PATCH 24/28] Print payable conversion --- printer/ast_printer/ast_printer.go | 2 ++ printer/ast_printer/payable_conversion.go | 21 +++++++++++++++++++++ printer/ast_printer/state_variable.go | 2 -- 3 files changed, 23 insertions(+), 2 deletions(-) create mode 100644 printer/ast_printer/payable_conversion.go diff --git a/printer/ast_printer/ast_printer.go b/printer/ast_printer/ast_printer.go index 62f9d429..d011761d 100644 --- a/printer/ast_printer/ast_printer.go +++ b/printer/ast_printer/ast_printer.go @@ -86,6 +86,8 @@ func PrintRecursive(node ast.Node[ast.NodeType], sb *strings.Builder, depth int) return printEventDefinition(node, sb, depth) case *ast.ErrorDefinition: return printErrorDefinition(node, sb, depth) + case *ast.PayableConversion: + return printPayableConversion(node, sb, depth) default: if node.GetType() == ast_pb.NodeType_SOURCE_UNIT { return printSourceUnit(node, sb, depth) diff --git a/printer/ast_printer/payable_conversion.go b/printer/ast_printer/payable_conversion.go new file mode 100644 index 00000000..e17a4e39 --- /dev/null +++ b/printer/ast_printer/payable_conversion.go @@ -0,0 +1,21 @@ +package ast_printer + +import ( + "strings" + + "github.com/unpackdev/solgo/ast" +) + +func printPayableConversion(node *ast.PayableConversion, sb *strings.Builder, depth int) bool { + success := true + sb.WriteString("payable(") + args := []string{} + for _, arg := range node.GetArguments() { + s, ok := Print(arg) + success = ok && success + args = append(args, s) + } + sb.WriteString(strings.Join(args, ", ")) + sb.WriteString(")") + return success +} diff --git a/printer/ast_printer/state_variable.go b/printer/ast_printer/state_variable.go index 499ebf81..6abafd5d 100644 --- a/printer/ast_printer/state_variable.go +++ b/printer/ast_printer/state_variable.go @@ -1,7 +1,6 @@ package ast_printer import ( - "fmt" "strings" "github.com/unpackdev/solgo/ast" @@ -9,7 +8,6 @@ import ( func printStateVariableDeclaration(node *ast.StateVariableDeclaration, sb *strings.Builder, depth int) bool { success := true - fmt.Printf("%+v\n\n", node.GetTypeName()) typeName, ok := Print(node.GetTypeName()) success = ok && success ident := node.GetName() From 87b65765ed0f5a26b0b1904c65a1bc2c9b69cd67 Mon Sep 17 00:00:00 2001 From: Evan Chng Xian Lin Date: Fri, 12 Apr 2024 14:59:41 +0800 Subject: [PATCH 25/28] Print Revert and fix bugs --- ast/if.go | 3 +++ printer/ast_printer/ast_printer.go | 4 ++++ printer/ast_printer/body.go | 30 ++++++++++++++++++++++++++++-- printer/ast_printer/constructor.go | 5 ++--- printer/ast_printer/continue.go | 12 ++++++++++++ printer/ast_printer/for.go | 3 +-- printer/ast_printer/function.go | 5 ++--- printer/ast_printer/if.go | 9 ++------- printer/ast_printer/modifier.go | 5 ++--- printer/ast_printer/revert.go | 26 ++++++++++++++++++++++++++ printer/ast_printer/type_name.go | 12 ++++++++++-- printer/ast_printer/variable.go | 6 ++++-- 12 files changed, 96 insertions(+), 24 deletions(-) create mode 100644 printer/ast_printer/continue.go create mode 100644 printer/ast_printer/revert.go diff --git a/ast/if.go b/ast/if.go index e63c90c1..5bfb6765 100644 --- a/ast/if.go +++ b/ast/if.go @@ -186,6 +186,9 @@ func (i *IfStatement) Parse( body.ParseBlock(unit, contractNode, fnNode, statementCtx.Block()) break } + // Edge case for single statement if + // Eg: if (a) b; + body.parseStatements(unit, contractNode, fnNode, statementCtx.GetChild(0)) i.Body = body } diff --git a/printer/ast_printer/ast_printer.go b/printer/ast_printer/ast_printer.go index d011761d..e3c9f912 100644 --- a/printer/ast_printer/ast_printer.go +++ b/printer/ast_printer/ast_printer.go @@ -88,6 +88,10 @@ func PrintRecursive(node ast.Node[ast.NodeType], sb *strings.Builder, depth int) return printErrorDefinition(node, sb, depth) case *ast.PayableConversion: return printPayableConversion(node, sb, depth) + case *ast.RevertStatement: + return printRevertStatement(node, sb, depth) + case *ast.ContinueStatement: + return printContinueStatement(node, sb, depth) default: if node.GetType() == ast_pb.NodeType_SOURCE_UNIT { return printSourceUnit(node, sb, depth) diff --git a/printer/ast_printer/body.go b/printer/ast_printer/body.go index 83c9218f..f8f587ef 100644 --- a/printer/ast_printer/body.go +++ b/printer/ast_printer/body.go @@ -3,15 +3,41 @@ package ast_printer import ( "strings" + ast_pb "github.com/unpackdev/protos/dist/go/ast" "github.com/unpackdev/solgo/ast" ) +var blocks []ast_pb.NodeType = []ast_pb.NodeType{ + ast_pb.NodeType_IF_STATEMENT, + ast_pb.NodeType_FOR_STATEMENT, + ast_pb.NodeType_WHILE_STATEMENT, + ast_pb.NodeType_DO_WHILE_STATEMENT, + ast_pb.NodeType_FUNCTION_DEFINITION, + ast_pb.NodeType_MODIFIER_DEFINITION, + ast_pb.NodeType_CONTRACT_DEFINITION, + ast_pb.NodeType_STRUCT_DEFINITION, + ast_pb.NodeType_ENUM_DEFINITION, +} + +func isBlock(nodeType ast_pb.NodeType) bool { + for _, block := range blocks { + if block == nodeType { + return true + } + } + return false +} + func printBody(node *ast.BodyNode, sb *strings.Builder, depth int) bool { success := true + sb.WriteString("{\n") for _, stmt := range node.GetStatements() { - sb.WriteString(indentString("", depth)) + sb.WriteString(indentString("", depth+1)) success = PrintRecursive(stmt, sb, depth+1) && success - writeStrings(sb, ";\n") + if !isBlock(stmt.GetType()) { + writeStrings(sb, ";\n") + } } + sb.WriteString(indentString("}\n", depth)) return success } diff --git a/printer/ast_printer/constructor.go b/printer/ast_printer/constructor.go index 7d92b46d..d44d642a 100644 --- a/printer/ast_printer/constructor.go +++ b/printer/ast_printer/constructor.go @@ -10,8 +10,7 @@ func printConstructor(node *ast.Constructor, sb *strings.Builder, depth int) boo success := true sb.WriteString("constructor(") success = printParameterList(node.GetParameters(), sb, depth) && success - sb.WriteString(") {\n") - success = PrintRecursive(node.GetBody(), sb, depth+1) && success - sb.WriteString(indentString("}\n", depth)) + sb.WriteString(") ") + success = PrintRecursive(node.GetBody(), sb, depth) && success return success } diff --git a/printer/ast_printer/continue.go b/printer/ast_printer/continue.go new file mode 100644 index 00000000..3e6fa60a --- /dev/null +++ b/printer/ast_printer/continue.go @@ -0,0 +1,12 @@ +package ast_printer + +import ( + "strings" + + "github.com/unpackdev/solgo/ast" +) + +func printContinueStatement(node *ast.ContinueStatement, sb *strings.Builder, depth int) bool { + sb.WriteString("continue") + return true +} diff --git a/printer/ast_printer/for.go b/printer/ast_printer/for.go index 2eca9035..788bfcd8 100644 --- a/printer/ast_printer/for.go +++ b/printer/ast_printer/for.go @@ -20,10 +20,9 @@ func printFor(node *ast.ForStatement, sb *strings.Builder, depth int) bool { if node.GetClosure() != nil { success = PrintRecursive(node.GetClosure(), sb, depth) && success } - sb.WriteString(") {\n") + sb.WriteString(") ") if node.GetBody() != nil { success = PrintRecursive(node.GetBody(), sb, depth) && success } - sb.WriteString(indentString("}", depth-1)) return success } diff --git a/printer/ast_printer/function.go b/printer/ast_printer/function.go index 14ef9adf..d651220f 100644 --- a/printer/ast_printer/function.go +++ b/printer/ast_printer/function.go @@ -26,12 +26,11 @@ func printFunction(node *ast.Function, sb *strings.Builder, depth int) bool { if paramBuilder.String() != "" { writeStrings(sb, " returns (", paramBuilder.String(), ")") } + sb.WriteString(" ") - sb.WriteString(" {\n") if node.GetBody() != nil { - success = PrintRecursive(node.GetBody(), sb, depth+1) && success + success = PrintRecursive(node.GetBody(), sb, depth) && success } - sb.WriteString(indentString("}\n", depth)) return success } diff --git a/printer/ast_printer/if.go b/printer/ast_printer/if.go index 82fc7225..8fb8502e 100644 --- a/printer/ast_printer/if.go +++ b/printer/ast_printer/if.go @@ -12,14 +12,9 @@ func printIfStatement(node *ast.IfStatement, sb *strings.Builder, depth int) boo if node.GetCondition() != nil { success = PrintRecursive(node.GetCondition(), sb, depth) && success } - sb.WriteString(") {\n") + sb.WriteString(") ") if node.GetBody() != nil { - success = PrintRecursive(node.GetBody(), sb, depth+1) && success + success = PrintRecursive(node.GetBody(), sb, depth) && success } - // if node.GetElse() != nil { - // sb.WriteString(indentString("} else ", depth-1)) - // success = PrintRecursive(node.GetElse(), sb, depth) && success - // } - sb.WriteString(indentString("}", depth-1)) return success } diff --git a/printer/ast_printer/modifier.go b/printer/ast_printer/modifier.go index fe791170..e0faa0cd 100644 --- a/printer/ast_printer/modifier.go +++ b/printer/ast_printer/modifier.go @@ -23,9 +23,8 @@ func printModifierDefinition(node *ast.ModifierDefinition, sb *strings.Builder, if node.GetBody() == nil { sb.WriteString(";\n") } else { - sb.WriteString(" {\n") - success = PrintRecursive(node.GetBody(), sb, depth+1) && success - sb.WriteString(indentString("}\n", depth)) + sb.WriteString(" ") + success = PrintRecursive(node.GetBody(), sb, depth) && success } return success } diff --git a/printer/ast_printer/revert.go b/printer/ast_printer/revert.go new file mode 100644 index 00000000..f4977461 --- /dev/null +++ b/printer/ast_printer/revert.go @@ -0,0 +1,26 @@ +package ast_printer + +import ( + "strings" + + "github.com/unpackdev/solgo/ast" +) + +func printRevertStatement(node *ast.RevertStatement, sb *strings.Builder, depth int) bool { + success := true + sb.WriteString("revert") + if node.GetExpression() != nil { + sb.WriteString(" ") + success = PrintRecursive(node.GetExpression(), sb, depth) && success + } + args := []string{} + for _, arg := range node.GetArguments() { + s, ok := Print(arg) + success = success && ok + args = append(args, s) + } + sb.WriteString("(") + writeSeperatedList(sb, ", ", args) + sb.WriteString(")") + return success +} diff --git a/printer/ast_printer/type_name.go b/printer/ast_printer/type_name.go index 376a81ea..172316ec 100644 --- a/printer/ast_printer/type_name.go +++ b/printer/ast_printer/type_name.go @@ -23,8 +23,16 @@ func printTypeName(node *ast.TypeName, sb *strings.Builder, depth int) bool { sb.WriteString(typeName) } else { if node.NodeType == ast_pb.NodeType_USER_DEFINED_PATH_NAME { - userType := node.GetTree().GetById(node.GetReferencedDeclaration()).(*ast.EnumDefinition) - sb.WriteString(userType.GetName()) + + ref := node.GetTree().GetById(node.GetReferencedDeclaration()) + if enumType, ok := ref.(*ast.EnumDefinition); ok { + enumName := enumType.GetName() + sb.WriteString(enumName) + } + if structType, ok := ref.(*ast.StructDefinition); ok { + structName := structType.GetName() + sb.WriteString(structName) + } } else { sb.WriteString(node.GetName()) } diff --git a/printer/ast_printer/variable.go b/printer/ast_printer/variable.go index 1e5afe25..b66547da 100644 --- a/printer/ast_printer/variable.go +++ b/printer/ast_printer/variable.go @@ -20,7 +20,9 @@ func printVariableDeclaration(node *ast.VariableDeclaration, sb *strings.Builder } else { PrintRecursive(node.GetDeclarations()[0], sb, depth) } - sb.WriteString(" = ") - PrintRecursive(node.GetInitialValue(), sb, depth) + if node.GetInitialValue() != nil { + sb.WriteString(" = ") + PrintRecursive(node.GetInitialValue(), sb, depth) + } return success } From 9855ea1d8efb40f0cbdc4b252d5f745c982bf993 Mon Sep 17 00:00:00 2001 From: Evan Chng Xian Lin Date: Fri, 12 Apr 2024 17:40:47 +0800 Subject: [PATCH 26/28] Modify state variable printing --- printer/ast_printer/state_variable.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/printer/ast_printer/state_variable.go b/printer/ast_printer/state_variable.go index 6abafd5d..6abc8bab 100644 --- a/printer/ast_printer/state_variable.go +++ b/printer/ast_printer/state_variable.go @@ -21,7 +21,7 @@ func printStateVariableDeclaration(node *ast.StateVariableDeclaration, sb *strin if node.Override { override = "override" } - writeSeperatedStrings(sb, " ", visibility, storage, typeName, override, ident) + writeSeperatedStrings(sb, " ", typeName, visibility, storage, override, ident) if node.GetInitialValue() != nil { sb.WriteString(" = ") success = PrintRecursive(node.GetInitialValue(), sb, depth) && success From e6bc02244fb2abec8a459e00ae43129759a343c5 Mon Sep 17 00:00:00 2001 From: Evan Chng Xian Lin Date: Sun, 14 Apr 2024 23:29:26 +0800 Subject: [PATCH 27/28] fix edge case in printing strings --- printer/ast_printer/primary_expression.go | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/printer/ast_printer/primary_expression.go b/printer/ast_printer/primary_expression.go index 86418e1a..a84231d9 100644 --- a/printer/ast_printer/primary_expression.go +++ b/printer/ast_printer/primary_expression.go @@ -3,11 +3,18 @@ package ast_printer import ( "strings" + ast_pb "github.com/unpackdev/protos/dist/go/ast" "github.com/unpackdev/solgo/ast" ) func printPrimaryExpression(node *ast.PrimaryExpression, sb *strings.Builder, depth int) bool { s := "" + if node.GetKind() == ast_pb.NodeType_UNICODE_STRING_LITERAL { + s = "\"" + node.GetValue() + "\"" + sb.WriteString(s) + return true + } + if node.GetValue() == "" { s = node.GetName() } else { From e6bf8ab6ebe7910a2c96f58a48979535436c3f7a Mon Sep 17 00:00:00 2001 From: Evan Chng Xian Lin Date: Fri, 19 Apr 2024 16:09:36 +0800 Subject: [PATCH 28/28] Print inline arrays --- ast/storage.go | 1 - printer/ast_printer/ast_printer.go | 2 ++ printer/ast_printer/inline_array.go | 28 ++++++++++++++++++++++++++++ 3 files changed, 30 insertions(+), 1 deletion(-) create mode 100644 printer/ast_printer/inline_array.go diff --git a/ast/storage.go b/ast/storage.go index 1de38773..7ad82da4 100644 --- a/ast/storage.go +++ b/ast/storage.go @@ -57,7 +57,6 @@ func (t *TypeName) StorageSize() (int64, bool) { // Add cases for other node types like struct, enum, etc., as needed. default: panic(fmt.Sprintf("Unhandled node type @ StorageSize: %s", t.NodeType)) - return 0, false // Type not recognized or not handled yet. } } diff --git a/printer/ast_printer/ast_printer.go b/printer/ast_printer/ast_printer.go index e3c9f912..bd05e85b 100644 --- a/printer/ast_printer/ast_printer.go +++ b/printer/ast_printer/ast_printer.go @@ -92,6 +92,8 @@ func PrintRecursive(node ast.Node[ast.NodeType], sb *strings.Builder, depth int) return printRevertStatement(node, sb, depth) case *ast.ContinueStatement: return printContinueStatement(node, sb, depth) + case *ast.InlineArray: + return printInlineArray(node, sb, depth) default: if node.GetType() == ast_pb.NodeType_SOURCE_UNIT { return printSourceUnit(node, sb, depth) diff --git a/printer/ast_printer/inline_array.go b/printer/ast_printer/inline_array.go new file mode 100644 index 00000000..4bea71b2 --- /dev/null +++ b/printer/ast_printer/inline_array.go @@ -0,0 +1,28 @@ +package ast_printer + +import ( + "strings" + + "github.com/unpackdev/solgo/ast" + "go.uber.org/zap" +) + +func printInlineArray(node *ast.InlineArray, sb *strings.Builder, depth int) bool { + success := true + if len(node.GetExpressions()) < 3 { + zap.S().Error("Conditional node must have at least 3 expressions") + return false + } + sb.WriteString("[") + items := []string{} + for _, item := range node.GetExpressions() { + s, ok := Print(item) + if !ok { + success = false + } + items = append(items, s) + } + writeSeperatedList(sb, ", ", items) + sb.WriteString("]") + return success +}