84 lines
2.0 KiB
Go
84 lines
2.0 KiB
Go
package expression
|
|
|
|
import (
|
|
"math"
|
|
|
|
"git.akyoto.dev/cli/q/src/token"
|
|
)
|
|
|
|
// Operator represents an operator for mathematical expressions.
|
|
type Operator struct {
|
|
Symbol string
|
|
Precedence int8
|
|
Operands int8
|
|
}
|
|
|
|
// Operators defines the operators used in the language.
|
|
// The number corresponds to the operator priority and can not be zero.
|
|
var Operators = [64]Operator{
|
|
token.Period: {".", 13, 2},
|
|
token.Call: {"λ", 12, 1},
|
|
token.Array: {"@", 12, 2},
|
|
token.Negate: {"-", 11, 1},
|
|
token.Not: {"!", 11, 1},
|
|
token.Mul: {"*", 10, 2},
|
|
token.Div: {"/", 10, 2},
|
|
token.Mod: {"%", 10, 2},
|
|
token.Add: {"+", 9, 2},
|
|
token.Sub: {"-", 9, 2},
|
|
token.Shr: {">>", 8, 2},
|
|
token.Shl: {"<<", 8, 2},
|
|
token.And: {"&", 7, 2},
|
|
token.Xor: {"^", 6, 2},
|
|
token.Or: {"|", 5, 2},
|
|
|
|
token.Greater: {">", 4, 2},
|
|
token.Less: {"<", 4, 2},
|
|
token.GreaterEqual: {">=", 4, 2},
|
|
token.LessEqual: {"<=", 4, 2},
|
|
token.Equal: {"==", 3, 2},
|
|
token.NotEqual: {"!=", 3, 2},
|
|
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},
|
|
}
|
|
|
|
func isComplete(expr *Expression) bool {
|
|
if expr == nil {
|
|
return false
|
|
}
|
|
|
|
if expr.Token.Kind == token.Identifier || expr.Token.Kind == token.Number || expr.Token.Kind == token.String {
|
|
return true
|
|
}
|
|
|
|
if expr.Token.Kind == token.Call {
|
|
return true
|
|
}
|
|
|
|
if expr.Token.IsOperator() && len(expr.Children) == numOperands(expr.Token.Kind) {
|
|
return true
|
|
}
|
|
|
|
return false
|
|
}
|
|
|
|
func numOperands(symbol token.Kind) int {
|
|
return int(Operators[symbol].Operands)
|
|
}
|
|
|
|
func precedence(symbol token.Kind) int8 {
|
|
return Operators[symbol].Precedence
|
|
}
|