Implemented an abstract syntax tree

This commit is contained in:
2024-06-30 22:54:59 +02:00
parent 27c707b6ff
commit f479b5a03a
28 changed files with 422 additions and 315 deletions

View File

@ -8,22 +8,22 @@ import (
// Expression is a binary tree with an operator on each node.
type Expression struct {
Token token.Token
Parent *Expression
Children []*Expression
Precedence int
Token token.Token
Precedence int8
}
// New creates a new expression.
func New() *Expression {
return pool.Get().(*Expression)
return &Expression{}
}
// NewLeaf creates a new leaf node.
func NewLeaf(t token.Token) *Expression {
expr := New()
expr.Token = t
return expr
return &Expression{
Token: t,
}
}
// AddChild adds a child to the expression.
@ -32,17 +32,16 @@ func (expr *Expression) AddChild(child *Expression) {
child.Parent = expr
}
// Close puts the expression back into the memory pool.
func (expr *Expression) Close() {
// Reset resets all values to the default.
func (expr *Expression) Reset() {
for _, child := range expr.Children {
child.Close()
child.Reset()
}
expr.Token.Reset()
expr.Parent = nil
expr.Children = expr.Children[:0]
expr.Precedence = 0
pool.Put(expr)
}
// EachLeaf iterates through all leaves in the tree.

View File

@ -88,7 +88,7 @@ func TestExpressionParse(t *testing.T) {
src := []byte(test.Expression)
tokens := token.Tokenize(src)
expr := expression.Parse(tokens)
defer expr.Close()
defer expr.Reset()
assert.NotNil(t, expr)
assert.Equal(t, expr.String(), test.Result)

View File

@ -9,7 +9,7 @@ import (
// Operator represents an operator for mathematical expressions.
type Operator struct {
Symbol string
Precedence int
Precedence int8
Operands int
}
@ -39,14 +39,14 @@ var Operators = map[string]*Operator{
"&&": {"&&", 2, 2},
"||": {"||", 1, 2},
"=": {"=", math.MinInt, 2},
":=": {":=", math.MinInt, 2},
"+=": {"+=", math.MinInt, 2},
"-=": {"-=", math.MinInt, 2},
"*=": {"*=", math.MinInt, 2},
"/=": {"/=", math.MinInt, 2},
">>=": {">>=", math.MinInt, 2},
"<<=": {"<<=", math.MinInt, 2},
"=": {"=", math.MinInt8, 2},
":=": {":=", math.MinInt8, 2},
"+=": {"+=", math.MinInt8, 2},
"-=": {"-=", math.MinInt8, 2},
"*=": {"*=", math.MinInt8, 2},
"/=": {"/=", math.MinInt8, 2},
">>=": {">>=", math.MinInt8, 2},
"<<=": {"<<=", math.MinInt8, 2},
}
func isComplete(expr *Expression) bool {
@ -75,7 +75,7 @@ func numOperands(symbol string) int {
return operator.Operands
}
func precedence(symbol string) int {
func precedence(symbol string) int8 {
operator, exists := Operators[symbol]
if !exists {

View File

@ -70,7 +70,7 @@ func Parse(tokens token.List) *Expression {
continue
}
group.Precedence = math.MaxInt
group.Precedence = math.MaxInt8
if cursor == nil {
cursor = group

View File

@ -12,7 +12,6 @@ func BenchmarkExpression(b *testing.B) {
tokens := token.Tokenize(src)
for i := 0; i < b.N; i++ {
expr := expression.Parse(tokens)
expr.Close()
expression.Parse(tokens)
}
}

View File

@ -1,9 +0,0 @@
package expression
import "sync"
var pool = sync.Pool{
New: func() interface{} {
return &Expression{}
},
}