Improved performance

This commit is contained in:
2024-08-01 23:41:39 +02:00
parent 3c70529015
commit 778c125d19
10 changed files with 112 additions and 124 deletions

View File

@ -15,7 +15,7 @@ type Operator struct {
// Operators defines the operators used in the language.
// The number corresponds to the operator priority and can not be zero.
var Operators = map[token.Kind]*Operator{
var Operators = [64]Operator{
token.Period: {".", 13, 2},
token.Call: {"λ", 12, 1},
token.Array: {"@", 12, 2},
@ -41,12 +41,15 @@ var Operators = map[token.Kind]*Operator{
token.LogicalAnd: {"&&", 2, 2},
token.LogicalOr: {"||", 1, 2},
token.Separator: {",", 0, 2},
token.Assign: {"=", math.MinInt8, 2},
token.Define: {":=", math.MinInt8, 2},
token.AddAssign: {"+=", math.MinInt8, 2},
token.SubAssign: {"-=", math.MinInt8, 2},
token.MulAssign: {"*=", math.MinInt8, 2},
token.DivAssign: {"/=", math.MinInt8, 2},
token.ModAssign: {"%=", math.MinInt8, 2},
token.ShrAssign: {">>=", math.MinInt8, 2},
token.ShlAssign: {"<<=", math.MinInt8, 2},
}
@ -68,21 +71,9 @@ func isComplete(expr *Expression) bool {
}
func numOperands(symbol token.Kind) int {
operator, exists := Operators[symbol]
if !exists {
return -1
}
return int(operator.Operands)
return int(Operators[symbol].Operands)
}
func precedence(symbol token.Kind) int8 {
operator, exists := Operators[symbol]
if !exists {
return -1
}
return operator.Precedence
return Operators[symbol].Precedence
}

View File

@ -101,63 +101,64 @@ func Parse(tokens []token.Token) *Expression {
continue
}
if t.IsOperator() {
if cursor == nil {
cursor = NewLeaf(t)
cursor.Precedence = precedence(t.Kind)
root = cursor
continue
}
node := NewLeaf(t)
node.Precedence = precedence(t.Kind)
if cursor.Token.IsOperator() {
oldPrecedence := cursor.Precedence
newPrecedence := node.Precedence
if newPrecedence > oldPrecedence {
if len(cursor.Children) == numOperands(cursor.Token.Kind) {
cursor.LastChild().Replace(node)
} else {
cursor.AddChild(node)
}
} else {
start := cursor
for start != nil {
precedence := start.Precedence
if precedence < newPrecedence {
start.LastChild().Replace(node)
break
}
if precedence == newPrecedence {
if start == root {
root = node
}
start.Replace(node)
break
}
start = start.Parent
}
if start == nil {
root.Replace(node)
root = node
}
}
} else {
node.AddChild(cursor)
root = node
}
cursor = node
if !t.IsOperator() {
continue
}
if cursor == nil {
cursor = NewLeaf(t)
cursor.Precedence = precedence(t.Kind)
root = cursor
continue
}
node := NewLeaf(t)
node.Precedence = precedence(t.Kind)
if cursor.Token.IsOperator() {
oldPrecedence := cursor.Precedence
newPrecedence := node.Precedence
if newPrecedence > oldPrecedence {
if len(cursor.Children) == numOperands(cursor.Token.Kind) {
cursor.LastChild().Replace(node)
} else {
cursor.AddChild(node)
}
} else {
start := cursor
for start != nil {
precedence := start.Precedence
if precedence < newPrecedence {
start.LastChild().Replace(node)
break
}
if precedence == newPrecedence {
if start == root {
root = node
}
start.Replace(node)
break
}
start = start.Parent
}
if start == nil {
root.Replace(node)
root = node
}
}
} else {
node.AddChild(cursor)
root = node
}
cursor = node
}
return root