moulo
Some checks failed
Build / build (push) Successful in 9m45s
Test / build (push) Failing after 15m53s

This commit is contained in:
Chuck Smith
2024-03-22 16:49:33 -04:00
parent 6282075e66
commit cbb430b47d
10 changed files with 29 additions and 3 deletions

View File

@@ -25,6 +25,7 @@ const (
OpSub
OpMul
OpDiv
OpMod
OpTrue
OpFalse
OpEqual
@@ -69,6 +70,7 @@ var definitions = map[Opcode]*Definition{
OpSub: {"OpSub", []int{}},
OpMul: {"OpMul", []int{}},
OpDiv: {"OpDiv", []int{}},
OpMod: {"OpMod", []int{}},
OpTrue: {"OpTrue", []int{}},
OpFalse: {"OpFalse", []int{}},
OpEqual: {"OpEqual", []int{}},

View File

@@ -139,6 +139,8 @@ func (c *Compiler) Compile(node ast.Node) error {
c.emit(code.OpMul)
case "/":
c.emit(code.OpDiv)
case "%":
c.emit(code.OpMod)
case ">":
c.emit(code.OpGreaterThan)
case ">=":

View File

@@ -77,6 +77,16 @@ func TestIntegerArithmetic(t *testing.T) {
code.Make(code.OpPop),
},
},
{
input: "5 % 2",
expectedConstants: []interface{}{5, 2},
expectedInstructions: []code.Instructions{
code.Make(code.OpConstant, 0),
code.Make(code.OpConstant, 1),
code.Make(code.OpMod),
code.Make(code.OpPop),
},
},
{
input: "-1",
expectedConstants: []interface{}{1},

View File

@@ -336,6 +336,8 @@ func evalIntegerInfixExpression(operator string, left, right object.Object) obje
return &object.Integer{Value: leftVal * rightVal}
case "/":
return &object.Integer{Value: leftVal / rightVal}
case "%":
return &object.Integer{Value: leftVal % rightVal}
case "<":
return nativeBoolToBooleanObject(leftVal < rightVal)
case "<=":

View File

@@ -30,6 +30,7 @@ func TestEvalIntegerExpression(t *testing.T) {
{"3 * 3 * 3 + 10", 37},
{"3 * (3 * 3) + 10", 37},
{"(5 + 10 * 2 + 15 / 3) * 2 + -10", 50},
{"5 % 2", 1},
}
for _, tt := range tests {

View File

@@ -87,6 +87,8 @@ func (l *Lexer) NextToken() token.Token {
}
case '*':
tok = newToken(token.ASTERISK, l.ch)
case '%':
tok = newToken(token.PERCENT, l.ch)
case '<':
if l.peekChar() == '=' {
l.readChar()

View File

@@ -14,8 +14,8 @@ const (
ASSIGN // := or =
EQUALS // ==
LESSGREATER // > or <
SUM // +
PRODUCT // *
SUM // + or -
PRODUCT // * or / or %
PREFIX // -X or !X
CALL // myFunction(X)
INDEX // array[index]
@@ -34,6 +34,7 @@ var precedences = map[token.TokenType]int{
token.MINUS: SUM,
token.SLASH: PRODUCT,
token.ASTERISK: PRODUCT,
token.PERCENT: PRODUCT,
token.LPAREN: CALL,
token.LBRACKET: INDEX,
token.DOT: INDEX,
@@ -82,6 +83,7 @@ func New(l *lexer.Lexer) *Parser {
p.registerInfix(token.MINUS, p.parseInfixExpression)
p.registerInfix(token.SLASH, p.parseInfixExpression)
p.registerInfix(token.ASTERISK, p.parseInfixExpression)
p.registerInfix(token.PERCENT, p.parseInfixExpression)
p.registerInfix(token.EQ, p.parseInfixExpression)
p.registerInfix(token.NOT_EQ, p.parseInfixExpression)
p.registerInfix(token.LT, p.parseInfixExpression)

View File

@@ -27,6 +27,7 @@ const (
BANG = "!"
ASTERISK = "*"
SLASH = "/"
PERCENT = "%"
LT = "<"
LTE = "<="

View File

@@ -112,7 +112,7 @@ func (vm *VM) Run() error {
return err
}
case code.OpAdd, code.OpSub, code.OpMul, code.OpDiv:
case code.OpAdd, code.OpSub, code.OpMul, code.OpDiv, code.OpMod:
err := vm.executeBinaryOperation(op)
if err != nil {
return err
@@ -543,6 +543,9 @@ func (vm *VM) executeBinaryIntegerOperation(op code.Opcode, left, right object.O
result = leftValue * rightValue
case code.OpDiv:
result = leftValue / rightValue
case code.OpMod:
result = leftValue % rightValue
default:
return fmt.Errorf("unknown integer operator: %d", op)
}

View File

@@ -224,6 +224,7 @@ func TestIntegerArithmetic(t *testing.T) {
{"-10", -10},
{"-50 + 100 + -50", 0},
{"(5 + 10 * 2 + 15 / 3) * 2 + -10", 50},
{"5 % 2", 1},
}
runVmTests(t, tests)