Clean up of some of the comments or unnecesary debugging things
[TinyThreePassCompiler/.git] / compiler.go
index ec17a44ee24a6738ed662608bcef72ef0ed40d3d..e928218affb8275dac9a52a98f29b6c603c29b4e 100644 (file)
@@ -27,21 +27,24 @@ type AST struct {
 }
 
 func main() {
-       //a := &AST{Op: imm, N: 5
-       //b := &AST{Op: plus, A: a, B: &AST{Op: arg, N: 0}}
-       input := "[ a b ] (a*a) + (5*5)"
+       //TODO(josuer08): Change this for a argv reader and all of the printing can
+       // be moved to writing to a file or just use standalone with redirection not
+       //quite sure about it.
+       input := "[ a b ] ((a*b) + (5*5))-3"
 
        variables, program := extractVariables(input)
-
-       fmt.Println(variables, program)
+       //fmt.Println(variables, program)
        Tree := AST{}
        firstPass(variables, program, &Tree)
-       fmt.Println(Tree)
+       //fmt.Println(Tree)
        secondPass(&Tree)
-       printer(&Tree)
+       slices.Sort(variables)
+       thirdPass(&Tree, variables)
+       //printer(&Tree)
 
 }
 
+// printer si a function that prints in Reverse Pollish Notation the AST
 func printer(tree *AST) {
        switch {
        case tree.Op == imm:
@@ -69,6 +72,8 @@ func printer(tree *AST) {
        }
 }
 
+// firstPass Is a function that makes the first pass of the compiler,
+// it converts the variable and program into an AST
 func firstPass(variables, program []rune, node *AST) {
        pass := node
        switch program[0] {
@@ -98,29 +103,24 @@ func firstPass(variables, program []rune, node *AST) {
                        var zeroOp op
                        if node.Op == zeroOp {
                                node.Left = &AST{Op: imm, Value: int(program[0]) - 48}
-                               //a := &AST{Op: imm, N: 5
                        } else {
                                node.Right = &AST{Op: imm, Value: int(program[0]) - 48}
                        }
                } else if slices.Contains(variables, program[0]) {
-                       //var zeroOp op
-                       if node.Op != 2 && node.Op != 3 && node.Op != 4 && node.Op != 5 {
+                       if node.Op != plus && node.Op != min && node.Op != mul && node.Op != div {
                                node.Left = &AST{Op: arg, Value: int(program[0])}
-                               //a := &AST{Op: imm, N: 5
                        } else {
                                node.Right = &AST{Op: arg, Value: int(program[0])}
                        }
-
                }
-
        }
        if len(program) > 1 {
                firstPass(variables, program[1:], pass)
-
        }
-       return
-
 }
+
+// secondPass takes an AST and reduces the operations that only include imm
+// values so the program results in a more compact one with precalculated imms
 func secondPass(node *AST) {
        if node.Op == arg {
                return
@@ -129,7 +129,6 @@ func secondPass(node *AST) {
                return
        }
        if node.Right.Op == imm && node.Left.Op == imm {
-
                switch node.Op {
                case min:
                        node.Value = node.Left.Value - node.Right.Value
@@ -153,6 +152,61 @@ func secondPass(node *AST) {
        }
 }
 
+func thirdPass(node *AST, variables []rune) {
+       switch node.Op {
+       case arg:
+               number, found := slices.BinarySearch(variables, rune(node.Value))
+               if found {
+                       fmt.Printf("AR %d\n", number)
+               }
+       case imm:
+               fmt.Printf("IM %d\n", node.Value)
+       default:
+               switch node.Left.Op {
+               case arg:
+                       number, valid := slices.BinarySearch(variables, rune(node.Left.Value))
+                       if valid {
+                               fmt.Printf("AR %d\n", number)
+                       }
+               case imm:
+                       fmt.Printf("IM %d\n", node.Left.Value)
+               default:
+                       thirdPass(node.Left, variables)
+               }
+               switch node.Right.Op {
+               case arg:
+                       fmt.Println("SW")
+                       number, valid := slices.BinarySearch(variables, rune(node.Right.Value))
+                       if valid {
+                               fmt.Printf("AR %d\n", number)
+                       }
+                       fmt.Println("SW")
+               case imm:
+                       fmt.Println("SW")
+                       fmt.Printf("IM %d\n", node.Right.Value)
+                       fmt.Println("SW")
+               default:
+                       fmt.Println("PU")
+                       thirdPass(node.Right, variables)
+                       fmt.Println("SW")
+                       fmt.Println("PO")
+               }
+               switch node.Op {
+               case mul:
+                       fmt.Println("MU")
+               case div:
+                       fmt.Println("DI")
+               case min:
+                       fmt.Println("SU")
+               case plus:
+                       fmt.Println("AD")
+
+               }
+
+       }
+
+}
+
 // extractVariables receives the original program string and converts it in
 // two rune slices, the first containing the variables and a second containing
 // the trimmed program
@@ -168,7 +222,6 @@ func extractVariables(input string) ([]rune, []rune) {
                        resultVariables = append(resultVariables, v)
                }
        }
-
        //Cleaning out the program that is getting extracted
        variables[1] = strings.Trim(variables[1], " ")
        cleanProgram := []rune(variables[1])
@@ -176,10 +229,7 @@ func extractVariables(input string) ([]rune, []rune) {
        for _, v := range cleanProgram {
                if v != ' ' {
                        resultProgram = append(resultProgram, v)
-
                }
-
        }
-
        return resultVariables, resultProgram
 }