umx_compiler

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

commit 5cbae63c67263f473fbfb7a5ec45e0d11a144c12
parent 70b2cc1df065a909998e5db015454daa8d591c44
Author: bsandro <email@bsandro.tech>
Date:   Thu, 23 Jun 2022 04:04:42 +0300

primitive integer eval

Diffstat:
Aeval/eval.go | 26++++++++++++++++++++++++++
Aeval/eval_test.go | 42++++++++++++++++++++++++++++++++++++++++++
Aobject/object.go | 32++++++++++++++++++++++++++++++++
3 files changed, 100 insertions(+), 0 deletions(-)

diff --git a/eval/eval.go b/eval/eval.go @@ -0,0 +1,26 @@ +package eval + +import ( + "interp/ast" + "interp/object" +) + +func Eval(node ast.Node) object.Object { + switch node := node.(type) { + case *ast.Program: + return evalStatements(node.Statements) + case *ast.ExpressionStatement: + return Eval(node.Expression) + case *ast.IntegerLiteral: + return &object.Integer{Value: node.Value} + } + return nil +} + +func evalStatements(statements []ast.Statement) object.Object { + var result object.Object + for _,statement := range statements { + result = Eval(statement) + } + return result +} diff --git a/eval/eval_test.go b/eval/eval_test.go @@ -0,0 +1,42 @@ +package eval + +import ( + "interp/lexer" + "interp/parser" + "interp/object" + "testing" +) + +func TestEvalIntegerExpression(t *testing.T) { + tests := []struct{ + input string + expected int64 + }{ + {"6", 6}, + {"10", 10}, + } + for _, tt := range tests { + evaluated := testEval(tt.input) + testIntegerObject(t, evaluated, tt.expected) + } +} + +func testEval(input string) object.Object { + l := lexer.New(input) + p := parser.New(l) + prg := p.ParseProgram() + return Eval(prg) +} + +func testIntegerObject(t *testing.T, obj object.Object, expected int64) bool { + result, ok := obj.(*object.Integer) + if !ok { + t.Errorf("obj is not integer (%T %+v)", obj, obj) + return false + } + if result.Value != expected { + t.Errorf("obj has wrong value (%d instead of %d)", result.Value, expected) + return false + } + return true +} diff --git a/object/object.go b/object/object.go @@ -0,0 +1,32 @@ +package object + +import "fmt" + +type ObjectType string + +const ( + INTEGER_OBJ = "INTEGER" + BOOLEAN_OBJ = "BOOLEAN" + NULL_OBJ = "NULL" +) + +type Object interface { + Type() ObjectType + Inspect() string +} + +type Integer struct { + Value int64 +} +func (i *Integer) Inspect() string { return fmt.Sprintf("%d", i.Value) } +func (i *Integer) Type() ObjectType { return INTEGER_OBJ } + +type Boolean struct { + Value bool +} +func (b *Boolean) Inspect() string { return fmt.Sprintf("%t", b.Value) } +func (b *Boolean) Type() ObjectType { return BOOLEAN_OBJ } + +type Null struct {} +func (n *Null) Inspect() string { return "null" } +func (n *Null) Type() ObjectType { return NULL_OBJ }