package ast import ( "fmt" "jinx/pkg/lang/scanner/token" ) type BinOp int const ( BinOpPlus BinOp = iota BinOpMinus BinOpStar BinOpSlash BinOpPercent BinOpAssign BinOpEq BinOpNeq BinOpLt BinOpLte BinOpGt 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 BinOpAssign: return 1 case BinOpEq, BinOpNeq, BinOpLt, BinOpLte, BinOpGt, BinOpGte: return 2 case BinOpPlus, BinOpMinus: return 3 case BinOpStar, BinOpSlash, BinOpPercent: 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 ( 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 }