Evaluation - Integer evaluation now works, got basically a REPL going on.

git-svn-id: https://svn.tlawal.org/svn/monkey@44 f6afcba9-9ef1-4bdd-9b72-7484f5705bac
This commit is contained in:
Tijani Lawal 2022-08-07 14:44:11 +00:00
parent 7a319dc03b
commit 1b97196361
3 changed files with 130 additions and 0 deletions

32
evaluator/evaluator.go Normal file
View File

@ -0,0 +1,32 @@
package evaluator
import (
"monkey/ast"
"monkey/object"
)
func Eval(node ast.Node) object.Object {
switch node := node.(type) {
// Statements
case *ast.Program:
return eval_statements(node.Statements)
case *ast.ExpressionStatement:
return Eval(node.Expression)
// Expressions
case *ast.IntegerLiteral:
return &object.Integer{Value: node.Value}
}
return nil
}
func eval_statements(statements []ast.Statement) object.Object {
var result object.Object
for _, statement := range statements {
result = Eval(statement)
}
return result
}

View File

@ -0,0 +1,45 @@
package evaluator
import (
"monkey/lexer"
"monkey/object"
"monkey/parser"
"testing"
)
func TestEvalIntegerExpression(l_test *testing.T) {
tests := []struct {
input string
expected int64
}{
{"5", 5},
{"10", 10},
}
for _, tt := range tests {
evaluated := test_eval(tt.input)
test_integer_object(l_test, evaluated, tt.expected)
}
}
// Helpers
func test_eval(input string) object.Object {
l_lexer := lexer.New(input)
l_parser := parser.New(l_lexer)
program := l_parser.ParseProgram()
return Eval(program)
}
func test_integer_object(l_test *testing.T, l_object object.Object, expected int64) bool {
result, ok := l_object.(*object.Integer)
if !ok {
l_test.Errorf("object is not integer, got=%T (%+v)", l_object, l_object)
return false
}
if result.Value != expected {
l_test.Errorf("object has wrong value, got=%d, want=%d", result.Value, expected)
return false
}
return true
}

53
object/object.go Normal file
View File

@ -0,0 +1,53 @@
package object
import "fmt"
type ObjectType string
const (
INTEGER_OBJECT = "INTEGER"
BOOLEAN_OBJECT = "BOOLEAN"
NULL_OBJECT = "NULL"
)
type Object interface {
Type() ObjectType
Inspect() string
}
// Integer
type Integer struct {
Value int64
}
func (i *Integer) Type() ObjectType {
return INTEGER_OBJECT
}
func (i *Integer) Inspect() string {
return fmt.Sprintf("%d", i.Value)
}
// Booleans
type Boolean struct {
Value bool
}
func (b *Boolean) Type() ObjectType {
return BOOLEAN_OBJECT
}
func (b *Boolean) Inpect() string {
return fmt.Sprintf("%t", b.Value)
}
// Null
type Null struct{}
func (n *Null) Type() ObjectType {
return NULL_OBJECT
}
func (n *Null) Inpect() string {
return "null"
}