extract variables function ready and implementing the first pass
authorOscar J Rodriguez <jrpc@google.com>
Sat, 18 Mar 2023 08:02:12 +0000 (01:02 -0700)
committerOscar J Rodriguez <jrpc@google.com>
Sat, 18 Mar 2023 08:02:12 +0000 (01:02 -0700)
compiler.go

index 1585cb3e53c5342dd0e3b4d158e639dfa9fd110c..4ad5e55090da421ad08fc1a97dd652d970657464 100644 (file)
 package main
 
-import "fmt"
+import (
+       "fmt"
+       "strings"
+
+       "golang.org/x/exp/slices"
+)
 
 type op int
 
 const (
-   imm op = iota
-   arg
-   plus
-   min
-   mul
-   div
+       imm op = iota
+       arg
+       plus
+       min
+       mul
+       div
 )
 
 type AST struct {
-   Op op
-   A  *AST
-   B  *AST
-   N  int
+       Op     op
+       Left   *AST
+       Right  *AST
+       Value  int
+       Parent *AST
 }
 
+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 + b*b"
+       //value := []rune(input)
 
+       variables, program := extractVariables(input)
 
-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 + b*b"
-    value := []rune(input)
-    for index, char := range value {
-        //make a stack and start pusing the [] to identify the start of a function and its end
-        //also check on a *-+/ for starting new operations with the last value and the next
-        //or can be a ( which pushes last value to a stack and picks up a new "first value" for this operation and ) indicating that order of operation is finish and
-        //you should pull again the last value that you pushed
-
-        //found [ start registering args to a map
-        // variable inside [] add to map of variables
-        // found ] stop registering new variables for the map
-        // found variable put to stack
-        // found inmmediate number put to stack
-        // found operation activate operation mode and upon next variable or inmediate add to the structure
-        // found ( can push another variable to stack and increment the indent counter
-        // found ) if no operation mode (that would be an error) then add the operations to the structure and decrement the indnet counter
-    }
+       fmt.Println(variables, program)
+       var Tree AST
+       firstPass(program, &Tree)
+       //si es una letra y el stack esta sin setear pon en el A del stack un AST arg
+       //si es una operacion setea la op en el stack
+       //si es un abrir parentesis apunta al lado que este disponible del AST
+       //si es una letra y ya esta seteada la op mete un AST arg a la otra letra
+       //si es un cerrar parentesis coge para el pai.
+
+       //los numeros se portan justo como las letras.
+
+}
+
+func firstPass(variables, program []rune, node *AST) {
+       switch program[0] {
+       case '-':
+               node.Op = min
+               firstPass(variables, program[1:], node)
+       case '+':
+               node.Op = plus
+               firstPass(variables, program[1:], node)
+       case '*':
+               node.Op = mul
+               firstPass(variables, program[1:], node)
+       case '/':
+               node.Op = div
+               firstPass(variables, program[1:], node)
+       case '(':
+               if node.Left != nil {
+                       firstPass(variables, program[1:], node.Left)
+               } else {
+                       firstPass(variables, program[1:], node.Right)
+               }
+       case ')':
+               return
+
+       default:
+               if program[0] > 47 && program[0] < 58 {
+                       var zeroOp op
+                       if node.Op == zeroOp {
+                               node.Left = &AST{Op: imm, Value: int(program[0]) - 48}
+                               firstPass(variables, program[1:], node)
+                               //a := &AST{Op: imm, N: 5
+                       } else {
+                               node.Right = &AST{Op: imm, Value: int(program[0]) - 48}
+                               firstPass(variables, program[1:], node)
+                       }
+               } else if slices.Contains(variables, program[0]) {
+                       var zeroOp op
+                       if node.Op == zeroOp {
+                               node.Left = &AST{Op: imm, Value: int(program[0]) - 48}
+                               firstPass(variables, program[1:], node)
+                               //a := &AST{Op: imm, N: 5
+                       } else {
+                               node.Right = &AST{Op: imm, Value: int(program[0]) - 48}
+                               firstPass(variables, program[1:], node)
+                       }
+
+               }
+
+       }
+       return
+
+}
+
+// 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
+func extractVariables(input string) ([]rune, []rune) {
+       variables := strings.Split(input, "]")
+       // Cleaning out the variables that are gettting extracted
+       variables[0] = strings.Split(variables[0], "[")[1]
+       variables[0] = strings.Trim(variables[0], " ")
+       cleanVariables := []rune(variables[0])
+       var resultVariables []rune
+       for _, v := range cleanVariables {
+               if v != ' ' {
+                       resultVariables = append(resultVariables, v)
+               }
+       }
+
+       //Cleaning out the program that is getting extracted
+       variables[1] = strings.Trim(variables[1], " ")
+       cleanProgram := []rune(variables[1])
+       var resultProgram []rune
+       for _, v := range cleanProgram {
+               if v != ' ' {
+                       resultProgram = append(resultProgram, v)
+
+               }
+
+       }
+
+       return resultVariables, resultProgram
 }