7 "golang.org/x/exp/slices"
30 //a := &AST{Op: imm, N: 5
31 //b := &AST{Op: plus, A: a, B: &AST{Op: arg, N: 0}}
32 input := "[ a b ] ((a*b) + (5*5))-3"
33 //input := "[ a b ] (a*a) + (5*5)"
35 variables, program := extractVariables(input)
37 fmt.Println(variables, program)
39 firstPass(variables, program, &Tree)
42 slices.Sort(variables)
43 thirdPass(&Tree, variables)
48 func printer(tree *AST) {
53 fmt.Printf("%c", tree.Value)
75 // firstPass Is a function that makes the first pass of the compiler,
76 // it converts the variable and program into an AST
77 func firstPass(variables, program []rune, node *AST) {
91 node.Left.Parent = node
95 node.Right.Parent = node
102 if program[0] > 47 && program[0] < 58 {
104 if node.Op == zeroOp {
105 node.Left = &AST{Op: imm, Value: int(program[0]) - 48}
106 //a := &AST{Op: imm, N: 5
108 node.Right = &AST{Op: imm, Value: int(program[0]) - 48}
110 } else if slices.Contains(variables, program[0]) {
112 if node.Op != plus && node.Op != min && node.Op != mul && node.Op != div {
113 node.Left = &AST{Op: arg, Value: int(program[0])}
114 //a := &AST{Op: imm, N: 5
116 node.Right = &AST{Op: arg, Value: int(program[0])}
122 if len(program) > 1 {
123 firstPass(variables, program[1:], pass)
130 // secondPass takes an AST and reduces the operations that only include imm
131 // values so the program results in a more compact one with precalculated imms
132 func secondPass(node *AST) {
139 if node.Right.Op == imm && node.Left.Op == imm {
143 node.Value = node.Left.Value - node.Right.Value
145 node.Value = node.Left.Value + node.Right.Value
147 node.Value = node.Left.Value * node.Right.Value
149 node.Value = node.Left.Value / node.Right.Value
156 if node.Left.Op != arg && node.Left.Op != imm {
157 secondPass(node.Left)
159 if node.Right.Op != arg && node.Right.Op != imm {
160 secondPass(node.Right)
164 func thirdPass(node *AST, variables []rune) {
165 /////////////////////////////////////////THINKING SPACE/////////////////////
167 // If I am a imm I just load to R0
168 // If I am an arg I just load to R0
171 // If I am an operator then I put my answer to my father on R0
172 // If my left child is a imm or arg just call it and then SW
173 // If my right child is a imm or arg just call it then SW then operate
174 // If my left is an operand then call it(not sure about this one)
175 // If my right is an operand PU then call it then SW then PO then SW
176 // If i am an operand at the end always just operate AD MU DI SU
178 ////////////////////////////////////////////////////////////////////////////
181 number, found := slices.BinarySearch(variables, rune(node.Value))
183 fmt.Printf("AR %d\n", number)
187 fmt.Printf("IM %d\n", node.Value)
189 switch node.Left.Op {
191 number, valid := slices.BinarySearch(variables, rune(node.Left.Value))
193 fmt.Printf("AR %d\n", number)
196 fmt.Printf("IM %d\n", node.Left.Value)
198 thirdPass(node.Left, variables)
201 switch node.Right.Op {
204 number, valid := slices.BinarySearch(variables, rune(node.Right.Value))
206 fmt.Printf("AR %d\n", number)
211 fmt.Printf("IM %d\n", node.Right.Value)
215 thirdPass(node.Right, variables)
220 //need to think about which kind of child nodes make me want to PU & PO
237 // extractVariables receives the original program string and converts it in
238 // two rune slices, the first containing the variables and a second containing
239 // the trimmed program
240 func extractVariables(input string) ([]rune, []rune) {
241 variables := strings.Split(input, "]")
242 // Cleaning out the variables that are gettting extracted
243 variables[0] = strings.Split(variables[0], "[")[1]
244 variables[0] = strings.Trim(variables[0], " ")
245 cleanVariables := []rune(variables[0])
246 var resultVariables []rune
247 for _, v := range cleanVariables {
249 resultVariables = append(resultVariables, v)
253 //Cleaning out the program that is getting extracted
254 variables[1] = strings.Trim(variables[1], " ")
255 cleanProgram := []rune(variables[1])
256 var resultProgram []rune
257 for _, v := range cleanProgram {
259 resultProgram = append(resultProgram, v)
265 return resultVariables, resultProgram