umx_compiler

UMX virtual machine "Monkey" interpreter / bytecode compiler
git clone git://bsandro.tech/umx_compiler
Log | Files | Refs

commit 7b8cd20ca0804b40f3621fea353739f8214c8055
parent 5cbae63c67263f473fbfb7a5ec45e0d11a144c12
Author: bsandro <email@bsandro.tech>
Date:   Thu, 23 Jun 2022 22:54:32 +0300

eval boolean

Diffstat:
Meval/eval.go | 18+++++++++++++++++-
Meval/eval_test.go | 33++++++++++++++++++++++++++++++---
Mrepl/repl.go | 8++++++--
3 files changed, 53 insertions(+), 6 deletions(-)

diff --git a/eval/eval.go b/eval/eval.go @@ -5,6 +5,12 @@ import ( "interp/object" ) +var ( + TRUE = &object.Boolean{Value: true} + FALSE = &object.Boolean{Value: false} + NULL = &object.Null{} +) + func Eval(node ast.Node) object.Object { switch node := node.(type) { case *ast.Program: @@ -13,14 +19,24 @@ func Eval(node ast.Node) object.Object { return Eval(node.Expression) case *ast.IntegerLiteral: return &object.Integer{Value: node.Value} + case *ast.Boolean: + return nativeBoolToBooleanObject(node.Value) } return nil } func evalStatements(statements []ast.Statement) object.Object { var result object.Object - for _,statement := range statements { + for _, statement := range statements { result = Eval(statement) } return result } + +func nativeBoolToBooleanObject(input bool) *object.Boolean { + if input { + return TRUE + } else { + return FALSE + } +} diff --git a/eval/eval_test.go b/eval/eval_test.go @@ -2,14 +2,14 @@ package eval import ( "interp/lexer" - "interp/parser" "interp/object" + "interp/parser" "testing" ) func TestEvalIntegerExpression(t *testing.T) { - tests := []struct{ - input string + tests := []struct { + input string expected int64 }{ {"6", 6}, @@ -40,3 +40,30 @@ func testIntegerObject(t *testing.T, obj object.Object, expected int64) bool { } return true } + +func TestEvalBooleanExpression(t *testing.T) { + tests := []struct { + input string + expected bool + }{ + {"true", true}, + {"false", false}, + } + for _, tt := range tests { + evaluated := testEval(tt.input) + testBooleanObject(t, evaluated, tt.expected) + } +} + +func testBooleanObject(t *testing.T, obj object.Object, expected bool) bool { + result, ok := obj.(*object.Boolean) + if !ok { + t.Errorf("obj is not boolean (%T %+v)", obj, obj) + return false + } + if result.Value != expected { + t.Errorf("obj has wrong value (%t instead of %t)", result.Value, expected) + return false + } + return true +} diff --git a/repl/repl.go b/repl/repl.go @@ -3,6 +3,7 @@ package repl import ( "bufio" "fmt" + "interp/eval" "interp/lexer" "interp/parser" "io" @@ -26,8 +27,11 @@ func Start(in io.Reader, out io.Writer) { if len(p.Errors()) != 0 { printParserErrors(out, p.Errors()) } - io.WriteString(out, prg.String()) - io.WriteString(out, "\n") + evaluated := eval.Eval(prg) + if evaluated != nil { + io.WriteString(out, evaluated.Inspect()) + io.WriteString(out, "\n") + } } }