85 lines
1.7 KiB
Go
85 lines
1.7 KiB
Go
package expression
|
|
|
|
import (
|
|
"math"
|
|
|
|
"git.akyoto.dev/cli/q/src/build/token"
|
|
)
|
|
|
|
// Operator represents an operator for mathematical expressions.
|
|
type Operator struct {
|
|
Symbol string
|
|
Precedence int
|
|
Operands int
|
|
}
|
|
|
|
// Operators defines the operators used in the language.
|
|
// The number corresponds to the operator priority and can not be zero.
|
|
var Operators = map[string]*Operator{
|
|
".": {".", 13, 2},
|
|
"λ": {"λ", 12, 1},
|
|
"!": {"!", 11, 1},
|
|
"*": {"*", 10, 2},
|
|
"/": {"/", 10, 2},
|
|
"%": {"%", 10, 2},
|
|
"+": {"+", 9, 2},
|
|
"-": {"-", 9, 2},
|
|
">>": {">>", 8, 2},
|
|
"<<": {"<<", 8, 2},
|
|
">": {">", 7, 2},
|
|
"<": {"<", 7, 2},
|
|
">=": {">=", 7, 2},
|
|
"<=": {"<=", 7, 2},
|
|
"==": {"==", 6, 2},
|
|
"!=": {"!=", 6, 2},
|
|
"&": {"&", 5, 2},
|
|
"^": {"^", 4, 2},
|
|
"|": {"|", 3, 2},
|
|
"&&": {"&&", 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},
|
|
}
|
|
|
|
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.Operator && len(expr.Children) >= numOperands(expr.Token.Text()) {
|
|
return true
|
|
}
|
|
|
|
return false
|
|
}
|
|
|
|
func numOperands(symbol string) int {
|
|
operator, exists := Operators[symbol]
|
|
|
|
if !exists {
|
|
return -1
|
|
}
|
|
|
|
return operator.Operands
|
|
}
|
|
|
|
func precedence(symbol string) int {
|
|
operator, exists := Operators[symbol]
|
|
|
|
if !exists {
|
|
return -1
|
|
}
|
|
|
|
return operator.Precedence
|
|
}
|