Skip to content

Commit

Permalink
👷 Evaluate number literals
Browse files Browse the repository at this point in the history
  • Loading branch information
ChmielewskiKamil committed Sep 8, 2024
1 parent 3007fd6 commit 1775525
Show file tree
Hide file tree
Showing 2 changed files with 109 additions and 0 deletions.
55 changes: 55 additions & 0 deletions evaluator/evaluator.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
package evaluator

import (
"solbot/ast"
"solbot/object"
)

func Eval(node ast.Node) object.Object {
switch node := node.(type) {
// File

case *ast.File:
return evalDeclarations(node.Declarations)

// Declarations

case *ast.FunctionDeclaration:
// TODO: Hacky way to eval other parts in tests, fix later.
return Eval(node.Body)

// Statements

case *ast.ExpressionStatement:
return Eval(node.Expression)
case *ast.BlockStatement:
return evalStatements(node.Statements)

// Expressions

case *ast.NumberLiteral:
return &object.Integer{Value: node.Value}
}

return nil
}

func evalDeclarations(decls []ast.Declaration) object.Object {
var result object.Object

for _, decl := range decls {
result = Eval(decl)
}

return result
}

func evalStatements(stmts []ast.Statement) object.Object {
var result object.Object

for _, stmt := range stmts {
result = Eval(stmt)
}

return result
}
54 changes: 54 additions & 0 deletions evaluator/evaluator_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
package evaluator

import (
"math/big"
"solbot/object"
"solbot/parser"
"solbot/token"
"testing"
)

func TestEvalIntegerExpression(t *testing.T) {
tests := []struct {
input string
expected *big.Int
}{
{"1", big.NewInt(1)},
{"50", big.NewInt(50)},
}

for _, tt := range tests {
evaluated := testEval(tt.input, true)
testIntegerObject(t, evaluated, tt.expected)
}
}

func testEval(input string, boilerplate bool) object.Object {
p := parser.Parser{}

if boilerplate {
input = "function test() { " + input + " }"
}

handle := token.NewFile("test.sol", input)
p.Init(handle)

file := p.ParseFile()

return Eval(file)
}

func testIntegerObject(t *testing.T, obj object.Object, expected *big.Int) bool {
result, ok := obj.(*object.Integer)
if !ok {
t.Errorf("Expected object.Integer, got %T (%+v)", obj, obj)
return false
}

if result.Value.Cmp(expected) != 0 {
t.Errorf("Expected %s, got %s", expected.String(), result.Value.String())
return false
}

return true
}

0 comments on commit 1775525

Please sign in to comment.