X-Git-Url: https://git.josue.xyz/?a=blobdiff_plain;f=compiler.go;h=e928218affb8275dac9a52a98f29b6c603c29b4e;hb=refs%2Fremotes%2Forigin%2Fmaster;hp=ec17a44ee24a6738ed662608bcef72ef0ed40d3d;hpb=05081b20e8fd940323137692ba21ba095bfedd6c;p=TinyThreePassCompiler%2F.git diff --git a/compiler.go b/compiler.go index ec17a44..e928218 100644 --- a/compiler.go +++ b/compiler.go @@ -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 }