diff options
Diffstat (limited to 'pkg/lang/ast/op.go')
| -rw-r--r-- | pkg/lang/ast/op.go | 102 |
1 files changed, 95 insertions, 7 deletions
diff --git a/pkg/lang/ast/op.go b/pkg/lang/ast/op.go index a708c78..f5fce51 100644 --- a/pkg/lang/ast/op.go +++ b/pkg/lang/ast/op.go @@ -1,13 +1,18 @@ package ast +import ( + "fmt" + "jinx/pkg/lang/scanner/token" +) + type BinOp int const ( - BinOpAdd BinOp = iota - BinOpSub - BinOpMul - BinOpDiv - BinOpMod + BinOpPlus BinOp = iota + BinOpMinus + BinOpStar + BinOpSlash + BinOpPercent BinOpAssign BinOpEq @@ -18,9 +23,92 @@ const ( BinOpGte ) +func BinOpFromToken(tok token.Token) (BinOp, bool) { + var op BinOp + switch tok.Kind { + case token.Plus: + op = BinOpPlus + case token.Minus: + op = BinOpMinus + case token.Star: + op = BinOpStar + case token.Slash: + op = BinOpSlash + case token.Percent: + op = BinOpPercent + case token.Assign: + op = BinOpAssign + case token.Eq: + op = BinOpEq + case token.Neq: + op = BinOpNeq + case token.Lt: + op = BinOpLt + case token.Lte: + op = BinOpLte + case token.Gt: + op = BinOpGt + case token.Gte: + op = BinOpGte + default: + return 0, false + } + + return op, true +} + +func (op BinOp) Precedence() int { + switch op { + case BinOpPlus, BinOpMinus: + return 1 + case BinOpStar, BinOpSlash, BinOpPercent: + return 2 + case BinOpAssign: + return 3 + case BinOpEq, BinOpNeq, BinOpLt, BinOpLte, BinOpGt, BinOpGte: + return 4 + default: + panic(fmt.Sprintf("unknown binary operator: %d", op)) + } +} + +type Associativity int + +const ( + AssociativityLeft Associativity = iota + AssociativityRight +) + +func (op BinOp) Associativity() Associativity { + switch op { + case BinOpPlus, BinOpMinus, BinOpStar, BinOpSlash, BinOpPercent: + return AssociativityLeft + case BinOpAssign: + return AssociativityRight + case BinOpEq, BinOpNeq, BinOpLt, BinOpLte, BinOpGt, BinOpGte: + return AssociativityLeft + default: + panic(fmt.Sprintf("unknown binary operator: %d", op)) + } +} + type UnOp int const ( - UnOpNot UnOp = iota - UnOpNeg + UnOpBang UnOp = iota + UnOpMinus ) + +func UnOpFromToken(tok token.Token) (UnOp, bool) { + var op UnOp + switch tok.Kind { + case token.Bang: + op = UnOpBang + case token.Minus: + op = UnOpMinus + default: + return 0, false + } + + return op, true +} |
