More tests
This commit is contained in:
@@ -68,7 +68,7 @@ func NewWithState(s *SymbolTable, constants []object.Object) *Compiler {
|
||||
func (c *Compiler) Compile(node ast.Node) error {
|
||||
if c.Debug {
|
||||
log.Printf(
|
||||
"%s Compiling %T: %s\n",
|
||||
"%sCompiling %T: %s\n",
|
||||
strings.Repeat(" ", c.l), node, node.String(),
|
||||
)
|
||||
}
|
||||
|
||||
@@ -479,7 +479,6 @@ func TestArrayIndexExpressions(t *testing.T) {
|
||||
}
|
||||
|
||||
for _, tt := range tests {
|
||||
t.Log(tt.input)
|
||||
evaluated := testEval(tt.input)
|
||||
|
||||
integer, ok := tt.expected.(int)
|
||||
|
||||
@@ -9,6 +9,7 @@ import (
|
||||
"unicode/utf8"
|
||||
)
|
||||
|
||||
// Builtins ...
|
||||
var Builtins = map[string]*Builtin{
|
||||
"len": {Name: "len", Fn: Len},
|
||||
"input": {Name: "input", Fn: Input},
|
||||
@@ -21,6 +22,7 @@ var Builtins = map[string]*Builtin{
|
||||
"exit": {Name: "exit", Fn: Exit},
|
||||
}
|
||||
|
||||
// BuiltinsIndex ...
|
||||
var BuiltinsIndex []*Builtin
|
||||
|
||||
func init() {
|
||||
@@ -39,6 +41,7 @@ func newError(format string, a ...interface{}) *Error {
|
||||
return &Error{Message: fmt.Sprintf(format, a...)}
|
||||
}
|
||||
|
||||
// Len ...
|
||||
func Len(args ...Object) Object {
|
||||
if len(args) != 1 {
|
||||
return newError("wrong number of arguments. got=%d, want=1",
|
||||
@@ -56,6 +59,7 @@ func Len(args ...Object) Object {
|
||||
}
|
||||
}
|
||||
|
||||
// Input ...
|
||||
func Input(args ...Object) Object {
|
||||
if len(args) > 0 {
|
||||
obj, ok := args[0].(*String)
|
||||
@@ -77,6 +81,7 @@ func Input(args ...Object) Object {
|
||||
return &String{Value: string(line)}
|
||||
}
|
||||
|
||||
// Print ...
|
||||
func Print(args ...Object) Object {
|
||||
for _, arg := range args {
|
||||
fmt.Println(arg.Inspect())
|
||||
@@ -85,6 +90,7 @@ func Print(args ...Object) Object {
|
||||
return nil
|
||||
}
|
||||
|
||||
// First ...
|
||||
func First(args ...Object) Object {
|
||||
if len(args) != 1 {
|
||||
return newError("wrong number of arguments. got=%d, want=1",
|
||||
@@ -103,6 +109,7 @@ func First(args ...Object) Object {
|
||||
return nil
|
||||
}
|
||||
|
||||
// Last ...
|
||||
func Last(args ...Object) Object {
|
||||
if len(args) != 1 {
|
||||
return newError("wrong number of arguments. got=%d, want=1",
|
||||
@@ -122,6 +129,7 @@ func Last(args ...Object) Object {
|
||||
return nil
|
||||
}
|
||||
|
||||
// Rest ...
|
||||
func Rest(args ...Object) Object {
|
||||
if len(args) != 1 {
|
||||
return newError("wrong number of arguments. got=%d, want=1",
|
||||
@@ -143,6 +151,7 @@ func Rest(args ...Object) Object {
|
||||
return nil
|
||||
}
|
||||
|
||||
// Push ...
|
||||
func Push(args ...Object) Object {
|
||||
if len(args) != 2 {
|
||||
return newError("wrong number of arguments. got=%d, want=2",
|
||||
@@ -167,6 +176,7 @@ func Push(args ...Object) Object {
|
||||
return &Array{Elements: newElements}
|
||||
}
|
||||
|
||||
// Pop ...
|
||||
func Pop(args ...Object) Object {
|
||||
if len(args) != 1 {
|
||||
return newError("wrong number of arguments. got=%d, want=1",
|
||||
@@ -190,6 +200,7 @@ func Pop(args ...Object) Object {
|
||||
return element
|
||||
}
|
||||
|
||||
// Exit ...
|
||||
func Exit(args ...Object) Object {
|
||||
if len(args) == 1 {
|
||||
if args[0].Type() != INTEGER_OBJ {
|
||||
|
||||
2
testdata/arrays.monkey
vendored
Normal file
2
testdata/arrays.monkey
vendored
Normal file
@@ -0,0 +1,2 @@
|
||||
let xs = [1, 2, 3]
|
||||
xs[0] + xs[1] + xs[2]
|
||||
3
testdata/assign.monkey
vendored
Normal file
3
testdata/assign.monkey
vendored
Normal file
@@ -0,0 +1,3 @@
|
||||
let x = 1
|
||||
x = 2
|
||||
x = x + 1
|
||||
13
testdata/builtins.monkey
vendored
Normal file
13
testdata/builtins.monkey
vendored
Normal file
@@ -0,0 +1,13 @@
|
||||
let xs = [1, 2, 3]
|
||||
len(xs)
|
||||
|
||||
first(xs)
|
||||
rest(xs)
|
||||
last(xs)
|
||||
push(xs, 5)
|
||||
pop(xs)
|
||||
|
||||
len("foo")
|
||||
|
||||
let x = input()
|
||||
print(x)
|
||||
2
testdata/closures.monkey
vendored
Normal file
2
testdata/closures.monkey
vendored
Normal file
@@ -0,0 +1,2 @@
|
||||
let f = fn(x) { fn() { x + 1 } }
|
||||
f(2)
|
||||
2
testdata/expressions.monkey
vendored
Normal file
2
testdata/expressions.monkey
vendored
Normal file
@@ -0,0 +1,2 @@
|
||||
1 + 2;
|
||||
(1 + 2) * 3;
|
||||
2
testdata/functions.monkey
vendored
Normal file
2
testdata/functions.monkey
vendored
Normal file
@@ -0,0 +1,2 @@
|
||||
let f = fn(x, y) { x * y };
|
||||
f(2, 4)
|
||||
2
testdata/hashes.monkey
vendored
Normal file
2
testdata/hashes.monkey
vendored
Normal file
@@ -0,0 +1,2 @@
|
||||
let d = {"a": 1, "b": 2}
|
||||
d["a"] + d["b"]
|
||||
5
testdata/if.monkey
vendored
Normal file
5
testdata/if.monkey
vendored
Normal file
@@ -0,0 +1,5 @@
|
||||
let x = 1
|
||||
if (x == 1) {
|
||||
x = 2
|
||||
x
|
||||
}
|
||||
3
testdata/let.monkey
vendored
Normal file
3
testdata/let.monkey
vendored
Normal file
@@ -0,0 +1,3 @@
|
||||
let x = 1
|
||||
let y = 2
|
||||
let z = x
|
||||
2
testdata/strings.monkey
vendored
Normal file
2
testdata/strings.monkey
vendored
Normal file
@@ -0,0 +1,2 @@
|
||||
let s = "hello"
|
||||
s + " " + "world"
|
||||
7
vm/vm.go
7
vm/vm.go
@@ -316,6 +316,13 @@ func (vm *VM) Run() error {
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
if vm.Debug {
|
||||
log.Printf(
|
||||
"%-25s [ip=%02d fp=%02d, sp=%02d]",
|
||||
"", ip, vm.framesIndex-1, vm.sp,
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
return nil
|
||||
|
||||
@@ -8,7 +8,9 @@ import (
|
||||
"monkey/object"
|
||||
"monkey/parser"
|
||||
"os"
|
||||
"path"
|
||||
"path/filepath"
|
||||
"strings"
|
||||
"testing"
|
||||
)
|
||||
|
||||
@@ -831,13 +833,17 @@ func TestAssignmentStatements(t *testing.T) {
|
||||
runVmTests(t, tests)
|
||||
}
|
||||
|
||||
func TestExamples(t *testing.T) {
|
||||
matches, err := filepath.Glob("../examples/*.monkey")
|
||||
func TestIntegration(t *testing.T) {
|
||||
matches, err := filepath.Glob("../testdata/*.monkey")
|
||||
if err != nil {
|
||||
t.Error(err)
|
||||
}
|
||||
|
||||
for _, match := range matches {
|
||||
basename := path.Base(match)
|
||||
name := strings.TrimSuffix(basename, filepath.Ext(basename))
|
||||
|
||||
t.Run(name, func(t *testing.T) {
|
||||
b, err := os.ReadFile(match)
|
||||
if err != nil {
|
||||
t.Error(err)
|
||||
@@ -860,10 +866,51 @@ func TestExamples(t *testing.T) {
|
||||
t.Log(input)
|
||||
t.Fatalf("vm error: %s", err)
|
||||
}
|
||||
|
||||
if vm.sp != 0 {
|
||||
t.Log(input)
|
||||
t.Fatal("vm stack pointer non-zero")
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func TestExamples(t *testing.T) {
|
||||
matches, err := filepath.Glob("../examples/*.monkey")
|
||||
if err != nil {
|
||||
t.Error(err)
|
||||
}
|
||||
|
||||
for _, match := range matches {
|
||||
basename := path.Base(match)
|
||||
name := strings.TrimSuffix(basename, filepath.Ext(basename))
|
||||
|
||||
t.Run(name, func(t *testing.T) {
|
||||
b, err := os.ReadFile(match)
|
||||
if err != nil {
|
||||
t.Error(err)
|
||||
}
|
||||
|
||||
input := string(b)
|
||||
program := parse(input)
|
||||
|
||||
c := compiler.New()
|
||||
err = c.Compile(program)
|
||||
if err != nil {
|
||||
t.Log(input)
|
||||
t.Fatalf("compiler error: %s", err)
|
||||
}
|
||||
|
||||
vm := New(c.Bytecode())
|
||||
|
||||
err = vm.Run()
|
||||
if err != nil {
|
||||
t.Log(input)
|
||||
t.Fatalf("vm error: %s", err)
|
||||
}
|
||||
if vm.sp != 0 {
|
||||
t.Log(input)
|
||||
t.Fatal("vm stack pointer non-zero")
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user