Skip to content

Commit

Permalink
#12 Add some code regarding finalizing the compiler
Browse files Browse the repository at this point in the history
  • Loading branch information
thegodenage committed Mar 21, 2024
1 parent 708fc4d commit 60e0d52
Show file tree
Hide file tree
Showing 2 changed files with 108 additions and 3 deletions.
101 changes: 98 additions & 3 deletions internal/rule/factory.go
Original file line number Diff line number Diff line change
@@ -1,8 +1,12 @@
package rule

import (
"errors"
"fmt"
"reflect"
"sort"

"github.com/emirpasic/gods/stacks/arraystack"
)

var (
Expand All @@ -11,6 +15,11 @@ var (
adjustableNodes = []reflect.Type{
reflect.TypeOf(gt{}),
}

higherOrderNodes = []reflect.Type{
reflect.TypeOf(and{}),
reflect.TypeOf(or{}),
}
)

type NodeAdjuster interface {
Expand Down Expand Up @@ -46,11 +55,12 @@ func (e *expressionTreeFactory) CreateExpressionTree(tokens []Token) (expression
}
}

for _, nd := range nodes {

eTree, err := buildExpressionTree(nodes)
if err != nil {
return nil, fmt.Errorf("build expression tree: %w", err)
}

return nil, nil
return eTree, nil
}

func (e *expressionTreeFactory) adaptNode(base node, tokenMatch []Token) (node, error) {
Expand Down Expand Up @@ -96,3 +106,88 @@ func isAdjustableNode(nd node) bool {

return false
}

func buildExpressionTree(nodes []node) (expressionTree, error) {
sort.Slice(nodes, func(i, j int) bool {
if len(nodes) < 3 {
return false
}

first, second, third := reflect.TypeOf(nodes[i-1]), reflect.TypeOf(nodes[i]), reflect.TypeOf(nodes[j])

Check failure on line 116 in internal/rule/factory.go

View workflow job for this annotation

GitHub Actions / build

second declared and not used

Check failure on line 116 in internal/rule/factory.go

View workflow job for this annotation

GitHub Actions / build

third declared and not used

for _, t := range higherOrderNodes {
if first == t {

}
}
})

Check failure on line 123 in internal/rule/factory.go

View workflow job for this annotation

GitHub Actions / build

missing return

stack := arraystack.Stack{}

for i := 0; i < len(nodes); i++ {
switch nodes[i].(type) {
case and:
// after nth iteration it could be an and, we want then continue
// in order to add additional elements to the stack
if stack.Size() < 2 {
continue
}

if stack.Size() > 2 {
return nil, errors.New("expression is invalid, and can only evaluate 2 predicates")
}

nd := and{}

var childrenNodes []node

for j := 0; j < 2; j++ {
v, _ := stack.Pop()
vt, _ := v.(node)
childrenNodes = append(childrenNodes, vt)
}

// nodes are popped from the stack, therefore we need to change order of the children
nd.SetChild(childrenNodes[1], childrenNodes[0])

stack.Clear()

stack.Push(nd)
case or:
if stack.Size() < 2 {
continue
}

if stack.Size() > 2 {
return nil, errors.New("expression is invalid, and can only evaluate 2 predicates")
}

nd := or{}

var childrenNodes []node

for j := 0; j < 2; j++ {
v, _ := stack.Pop()
vt, _ := v.(node)
childrenNodes = append(childrenNodes, vt)
}

nd.SetChild(childrenNodes[1], childrenNodes[0])

stack.Clear()

stack.Push(nd)
default:
stack.Push(nodes[i])
}
}

v, ok := stack.Pop()
if !ok {
return nil, fmt.Errorf("empty expression stack")
}

vt, _ := v.(node)

return expressionTree(vt), nil
}
10 changes: 10 additions & 0 deletions internal/rule/node.go
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,11 @@ func (a and) Eval(r request.Wrapper) bool {
return a.left.Eval(r) && a.right.Eval(r)
}

func (a and) SetChild(left, right node) {
a.left = left
a.right = right
}

type or struct {
left, right node
}
Expand All @@ -22,6 +27,11 @@ func (o or) Eval(r request.Wrapper) bool {
return o.left.Eval(r) || o.right.Eval(r)
}

func (o or) SetChild(left, right node) {
o.left = left
o.right = right
}

type eq struct {
left, right node
}
Expand Down

0 comments on commit 60e0d52

Please sign in to comment.