From: Oscar J Rodriguez Date: Sat, 6 May 2023 02:28:30 +0000 (-0700) Subject: Completed part 3, need clone X-Git-Url: https://git.josue.xyz/?p=TinyThreePassCompiler%2F.git;a=commitdiff_plain;h=dae1584bd3bccdc6d0e02dc6bd5302e445184add Completed part 3, need clone --- diff --git a/compiler.go b/compiler.go index ec17a44..75d4d8f 100644 --- a/compiler.go +++ b/compiler.go @@ -29,7 +29,8 @@ 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)" + input := "[ a b ] ((a*b) + (5*5))-3" + //input := "[ a b ] (a*a) + (5*5)" variables, program := extractVariables(input) @@ -38,6 +39,8 @@ func main() { firstPass(variables, program, &Tree) fmt.Println(Tree) secondPass(&Tree) + slices.Sort(variables) + thirdPass(&Tree, variables) printer(&Tree) } @@ -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] { @@ -104,7 +109,7 @@ func firstPass(variables, program []rune, node *AST) { } } 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 { @@ -121,6 +126,9 @@ func firstPass(variables, program []rune, node *AST) { 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 @@ -153,6 +161,79 @@ func secondPass(node *AST) { } } +func thirdPass(node *AST, variables []rune) { + /////////////////////////////////////////THINKING SPACE///////////////////// + // + // If I am a imm I just load to R0 + // If I am an arg I just load to R0 + // + // + // If I am an operator then I put my answer to my father on R0 + // If my left child is a imm or arg just call it and then SW + // If my right child is a imm or arg just call it then SW then operate + // If my left is an operand then call it(not sure about this one) + // If my right is an operand PU then call it then SW then PO then SW + // If i am an operand at the end always just operate AD MU DI SU + // + //////////////////////////////////////////////////////////////////////////// + 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") + } + + //need to think about which kind of child nodes make me want to PU & 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 diff --git a/sim.js b/sim.js new file mode 100644 index 0000000..533ca28 --- /dev/null +++ b/sim.js @@ -0,0 +1,52 @@ +function simulate(asm, args) { + var r0 = undefined; + var r1 = undefined; + var stack = []; + asm.forEach(function (instruct) { + var match = instruct.match(/(IM|AR)\s+(\d+)/) || [0, instruct, 0]; + var ins = match[1]; + var n = match[2] | 0; + + if (ins == "IM") { + r0 = n; + } else if (ins == "AR") { + r0 = args[n]; + } else if (ins == "SW") { + var tmp = r0; + r0 = r1; + r1 = tmp; + } else if (ins == "PU") { + stack.push(r0); + } else if (ins == "PO") { + r0 = stack.pop(); + } else if (ins == "AD") { + r0 += r1; + } else if (ins == "SU") { + r0 -= r1; + } else if (ins == "MU") { + r0 *= r1; + } else if (ins == "DI") { + r0 /= r1; + } + }); + return r0; +} + +asm = [ + "AR 0", + "SW", + "AR 1", + "SW", + "MU", + "SW", + "IM 25", + "SW", + "AD", + "SW", + "IM 3", + "SW", + "SU", +]; + +var total = simulate(asm, [4, 5]); +console.log(total);