Improved performance
This commit is contained in:
@ -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
|
||||
}
|
||||
|
@ -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
|
||||
|
Reference in New Issue
Block a user