about summary refs log tree commit diff
path: root/pkg/lang/ast/op.go
diff options
context:
space:
mode:
Diffstat (limited to 'pkg/lang/ast/op.go')
-rw-r--r--pkg/lang/ast/op.go102
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
+}