mirror of
https://github.com/MorizzG/rlox.git
synced 2025-12-06 04:12:42 +00:00
added tests
This commit is contained in:
parent
1cca1494a4
commit
660464638f
255 changed files with 7220 additions and 3 deletions
|
|
@ -8,7 +8,10 @@ edition = "2021"
|
|||
[dependencies.rlox2-frontend]
|
||||
path = "../frontend"
|
||||
|
||||
[dev-dependencies]
|
||||
glob = "0.3"
|
||||
|
||||
[dependencies]
|
||||
thiserror = "1.0.38"
|
||||
itertools = "0.10.5"
|
||||
rustc-hash = "1.1.0"
|
||||
thiserror = "1"
|
||||
itertools = "0.13"
|
||||
rustc-hash = "2"
|
||||
|
|
|
|||
9
interpreter/tests/lox/assignment/associativity.lox
Normal file
9
interpreter/tests/lox/assignment/associativity.lox
Normal file
|
|
@ -0,0 +1,9 @@
|
|||
var a = "a";
|
||||
var b = "b";
|
||||
var c = "c";
|
||||
|
||||
// Assignment is right-associative.
|
||||
a = b = c;
|
||||
print a; // expect: c
|
||||
print b; // expect: c
|
||||
print c; // expect: c
|
||||
8
interpreter/tests/lox/assignment/global.lox
Normal file
8
interpreter/tests/lox/assignment/global.lox
Normal file
|
|
@ -0,0 +1,8 @@
|
|||
var a = "before";
|
||||
print a; // expect: before
|
||||
|
||||
a = "after";
|
||||
print a; // expect: after
|
||||
|
||||
print a = "arg"; // expect: arg
|
||||
print a; // expect: arg
|
||||
2
interpreter/tests/lox/assignment/grouping.lox
Normal file
2
interpreter/tests/lox/assignment/grouping.lox
Normal file
|
|
@ -0,0 +1,2 @@
|
|||
var a = "a";
|
||||
(a) = "value"; // Error at '=': Invalid assignment target.
|
||||
3
interpreter/tests/lox/assignment/infix_operator.lox
Normal file
3
interpreter/tests/lox/assignment/infix_operator.lox
Normal file
|
|
@ -0,0 +1,3 @@
|
|||
var a = "a";
|
||||
var b = "b";
|
||||
a + b = "value"; // Error at '=': Invalid assignment target.
|
||||
10
interpreter/tests/lox/assignment/local.lox
Normal file
10
interpreter/tests/lox/assignment/local.lox
Normal file
|
|
@ -0,0 +1,10 @@
|
|||
{
|
||||
var a = "before";
|
||||
print a; // expect: before
|
||||
|
||||
a = "after";
|
||||
print a; // expect: after
|
||||
|
||||
print a = "arg"; // expect: arg
|
||||
print a; // expect: arg
|
||||
}
|
||||
2
interpreter/tests/lox/assignment/prefix_operator.lox
Normal file
2
interpreter/tests/lox/assignment/prefix_operator.lox
Normal file
|
|
@ -0,0 +1,2 @@
|
|||
var a = "a";
|
||||
!a = "value"; // Error at '=': Invalid assignment target.
|
||||
5
interpreter/tests/lox/assignment/syntax.lox
Normal file
5
interpreter/tests/lox/assignment/syntax.lox
Normal file
|
|
@ -0,0 +1,5 @@
|
|||
// Assignment on RHS of variable.
|
||||
var a = "before";
|
||||
var c = a = "var";
|
||||
print a; // expect: var
|
||||
print c; // expect: var
|
||||
7
interpreter/tests/lox/assignment/to_this.lox
Normal file
7
interpreter/tests/lox/assignment/to_this.lox
Normal file
|
|
@ -0,0 +1,7 @@
|
|||
class Foo {
|
||||
Foo() {
|
||||
this = "value"; // Error at '=': Invalid assignment target.
|
||||
}
|
||||
}
|
||||
|
||||
Foo();
|
||||
1
interpreter/tests/lox/assignment/undefined.lox
Normal file
1
interpreter/tests/lox/assignment/undefined.lox
Normal file
|
|
@ -0,0 +1 @@
|
|||
unknown = "what"; // Error: Undefined variable 'unknown'.
|
||||
7
interpreter/tests/lox/block/empty.lox
Normal file
7
interpreter/tests/lox/block/empty.lox
Normal file
|
|
@ -0,0 +1,7 @@
|
|||
{} // By itself.
|
||||
|
||||
// In a statement.
|
||||
if (true) {}
|
||||
if (false) {} else {}
|
||||
|
||||
print "ok"; // expect: ok
|
||||
8
interpreter/tests/lox/block/scope.lox
Normal file
8
interpreter/tests/lox/block/scope.lox
Normal file
|
|
@ -0,0 +1,8 @@
|
|||
var a = "outer";
|
||||
|
||||
{
|
||||
var a = "inner";
|
||||
print a; // expect: inner
|
||||
}
|
||||
|
||||
print a; // expect: outer
|
||||
23
interpreter/tests/lox/bool/equality.lox
Normal file
23
interpreter/tests/lox/bool/equality.lox
Normal file
|
|
@ -0,0 +1,23 @@
|
|||
print true == true; // expect: true
|
||||
print true == false; // expect: false
|
||||
print false == true; // expect: false
|
||||
print false == false; // expect: true
|
||||
|
||||
// Not equal to other types.
|
||||
print true == 1; // expect: false
|
||||
print false == 0; // expect: false
|
||||
print true == "true"; // expect: false
|
||||
print false == "false"; // expect: false
|
||||
print false == ""; // expect: false
|
||||
|
||||
print true != true; // expect: false
|
||||
print true != false; // expect: true
|
||||
print false != true; // expect: true
|
||||
print false != false; // expect: false
|
||||
|
||||
// Not equal to other types.
|
||||
print true != 1; // expect: true
|
||||
print false != 0; // expect: true
|
||||
print true != "true"; // expect: true
|
||||
print false != "false"; // expect: true
|
||||
print false != ""; // expect: true
|
||||
3
interpreter/tests/lox/bool/not.lox
Normal file
3
interpreter/tests/lox/bool/not.lox
Normal file
|
|
@ -0,0 +1,3 @@
|
|||
print !true; // expect: false
|
||||
print !false; // expect: true
|
||||
print !!true; // expect: true
|
||||
11
interpreter/tests/lox/break/for.lox
Normal file
11
interpreter/tests/lox/break/for.lox
Normal file
|
|
@ -0,0 +1,11 @@
|
|||
for (var i = 0; i < 10; i = i + 1) {
|
||||
if (i == 5)
|
||||
break;
|
||||
|
||||
print i;
|
||||
}
|
||||
// expect: 0
|
||||
// expect: 1
|
||||
// expect: 2
|
||||
// expect: 3
|
||||
// expect: 4
|
||||
2
interpreter/tests/lox/break/outside_loop.lox
Normal file
2
interpreter/tests/lox/break/outside_loop.lox
Normal file
|
|
@ -0,0 +1,2 @@
|
|||
break;
|
||||
// expect: error
|
||||
15
interpreter/tests/lox/break/while.lox
Normal file
15
interpreter/tests/lox/break/while.lox
Normal file
|
|
@ -0,0 +1,15 @@
|
|||
var i = 0;
|
||||
|
||||
while (i < 10) {
|
||||
if (i == 5)
|
||||
break;
|
||||
|
||||
print i;
|
||||
|
||||
i = i + 1;
|
||||
}
|
||||
// expect: 0
|
||||
// expect: 1
|
||||
// expect: 2
|
||||
// expect: 3
|
||||
// expect: 4
|
||||
1
interpreter/tests/lox/call/bool.lox
Normal file
1
interpreter/tests/lox/call/bool.lox
Normal file
|
|
@ -0,0 +1 @@
|
|||
true(); // expect runtime error: Can only call functions and classes.
|
||||
1
interpreter/tests/lox/call/nil.lox
Normal file
1
interpreter/tests/lox/call/nil.lox
Normal file
|
|
@ -0,0 +1 @@
|
|||
nil(); // expect runtime error: Can only call functions and classes.
|
||||
1
interpreter/tests/lox/call/num.lox
Normal file
1
interpreter/tests/lox/call/num.lox
Normal file
|
|
@ -0,0 +1 @@
|
|||
123(); // expect runtime error: Can only call functions and classes.
|
||||
4
interpreter/tests/lox/call/object.lox
Normal file
4
interpreter/tests/lox/call/object.lox
Normal file
|
|
@ -0,0 +1,4 @@
|
|||
class Foo {}
|
||||
|
||||
var foo = Foo();
|
||||
foo(); // expect runtime error: Can only call functions and classes.
|
||||
1
interpreter/tests/lox/call/string.lox
Normal file
1
interpreter/tests/lox/call/string.lox
Normal file
|
|
@ -0,0 +1 @@
|
|||
"str"(); // expect runtime error: Can only call functions and classes.
|
||||
3
interpreter/tests/lox/class/empty.lox
Normal file
3
interpreter/tests/lox/class/empty.lox
Normal file
|
|
@ -0,0 +1,3 @@
|
|||
class Foo {}
|
||||
|
||||
print Foo; // expect: Foo
|
||||
1
interpreter/tests/lox/class/inherit_self.lox
Normal file
1
interpreter/tests/lox/class/inherit_self.lox
Normal file
|
|
@ -0,0 +1 @@
|
|||
class Foo < Foo {} // Error at 'Foo': A class can't inherit from itself.
|
||||
22
interpreter/tests/lox/class/inherited_method.lox
Normal file
22
interpreter/tests/lox/class/inherited_method.lox
Normal file
|
|
@ -0,0 +1,22 @@
|
|||
class Foo {
|
||||
inFoo() {
|
||||
print "in foo";
|
||||
}
|
||||
}
|
||||
|
||||
class Bar < Foo {
|
||||
inBar() {
|
||||
print "in bar";
|
||||
}
|
||||
}
|
||||
|
||||
class Baz < Bar {
|
||||
inBaz() {
|
||||
print "in baz";
|
||||
}
|
||||
}
|
||||
|
||||
var baz = Baz();
|
||||
baz.inFoo(); // expect: in foo
|
||||
baz.inBar(); // expect: in bar
|
||||
baz.inBaz(); // expect: in baz
|
||||
8
interpreter/tests/lox/class/local_inherit_other.lox
Normal file
8
interpreter/tests/lox/class/local_inherit_other.lox
Normal file
|
|
@ -0,0 +1,8 @@
|
|||
class A {}
|
||||
|
||||
fun f() {
|
||||
class B < A {}
|
||||
return B;
|
||||
}
|
||||
|
||||
print f(); // expect: B
|
||||
4
interpreter/tests/lox/class/local_inherit_self.lox
Normal file
4
interpreter/tests/lox/class/local_inherit_self.lox
Normal file
|
|
@ -0,0 +1,4 @@
|
|||
{
|
||||
class Foo < Foo {} // Error at 'Foo': A class can't inherit from itself.
|
||||
}
|
||||
// [c line 5] Error at end: Expect '}' after block.
|
||||
9
interpreter/tests/lox/class/local_reference_self.lox
Normal file
9
interpreter/tests/lox/class/local_reference_self.lox
Normal file
|
|
@ -0,0 +1,9 @@
|
|||
{
|
||||
class Foo {
|
||||
returnSelf() {
|
||||
return Foo;
|
||||
}
|
||||
}
|
||||
|
||||
print Foo().returnSelf(); // expect: Foo
|
||||
}
|
||||
7
interpreter/tests/lox/class/reference_self.lox
Normal file
7
interpreter/tests/lox/class/reference_self.lox
Normal file
|
|
@ -0,0 +1,7 @@
|
|||
class Foo {
|
||||
returnSelf() {
|
||||
return Foo;
|
||||
}
|
||||
}
|
||||
|
||||
print Foo().returnSelf(); // expect: Foo
|
||||
27
interpreter/tests/lox/closure/assign_to_closure.lox
Normal file
27
interpreter/tests/lox/closure/assign_to_closure.lox
Normal file
|
|
@ -0,0 +1,27 @@
|
|||
var f;
|
||||
var g;
|
||||
|
||||
{
|
||||
var local = "local";
|
||||
fun f_() {
|
||||
print local;
|
||||
local = "after f";
|
||||
print local;
|
||||
}
|
||||
f = f_;
|
||||
|
||||
fun g_() {
|
||||
print local;
|
||||
local = "after g";
|
||||
print local;
|
||||
}
|
||||
g = g_;
|
||||
}
|
||||
|
||||
f();
|
||||
// expect: local
|
||||
// expect: after f
|
||||
|
||||
g();
|
||||
// expect: after f
|
||||
// expect: after g
|
||||
13
interpreter/tests/lox/closure/assign_to_shadowed_later.lox
Normal file
13
interpreter/tests/lox/closure/assign_to_shadowed_later.lox
Normal file
|
|
@ -0,0 +1,13 @@
|
|||
var a = "global";
|
||||
|
||||
{
|
||||
fun assign() {
|
||||
a = "assigned";
|
||||
}
|
||||
|
||||
var a = "inner";
|
||||
assign();
|
||||
print a; // expect: inner
|
||||
}
|
||||
|
||||
print a; // expect: assigned
|
||||
|
|
@ -0,0 +1,11 @@
|
|||
var f;
|
||||
|
||||
fun foo(param) {
|
||||
fun f_() {
|
||||
print param;
|
||||
}
|
||||
f = f_;
|
||||
}
|
||||
foo("param");
|
||||
|
||||
f(); // expect: param
|
||||
15
interpreter/tests/lox/closure/close_over_later_variable.lox
Normal file
15
interpreter/tests/lox/closure/close_over_later_variable.lox
Normal file
|
|
@ -0,0 +1,15 @@
|
|||
// This is a regression test. There was a bug where if an upvalue for an
|
||||
// earlier local (here "a") was captured *after* a later one ("b"), then it
|
||||
// would crash because it walked to the end of the upvalue list (correct), but
|
||||
// then didn't handle not finding the variable.
|
||||
|
||||
fun f() {
|
||||
var a = "a";
|
||||
var b = "b";
|
||||
fun g() {
|
||||
print b; // expect: b
|
||||
print a; // expect: a
|
||||
}
|
||||
g();
|
||||
}
|
||||
f();
|
||||
|
|
@ -0,0 +1,13 @@
|
|||
var f;
|
||||
|
||||
class Foo {
|
||||
method(param) {
|
||||
fun f_() {
|
||||
print param;
|
||||
}
|
||||
f = f_;
|
||||
}
|
||||
}
|
||||
|
||||
Foo().method("param");
|
||||
f(); // expect: param
|
||||
11
interpreter/tests/lox/closure/closed_closure_in_function.lox
Normal file
11
interpreter/tests/lox/closure/closed_closure_in_function.lox
Normal file
|
|
@ -0,0 +1,11 @@
|
|||
var f;
|
||||
|
||||
{
|
||||
var local = "local";
|
||||
fun f_() {
|
||||
print local;
|
||||
}
|
||||
f = f_;
|
||||
}
|
||||
|
||||
f(); // expect: local
|
||||
25
interpreter/tests/lox/closure/nested_closure.lox
Normal file
25
interpreter/tests/lox/closure/nested_closure.lox
Normal file
|
|
@ -0,0 +1,25 @@
|
|||
var f;
|
||||
|
||||
fun f1() {
|
||||
var a = "a";
|
||||
fun f2() {
|
||||
var b = "b";
|
||||
fun f3() {
|
||||
var c = "c";
|
||||
fun f4() {
|
||||
print a;
|
||||
print b;
|
||||
print c;
|
||||
}
|
||||
f = f4;
|
||||
}
|
||||
f3();
|
||||
}
|
||||
f2();
|
||||
}
|
||||
f1();
|
||||
|
||||
f();
|
||||
// expect: a
|
||||
// expect: b
|
||||
// expect: c
|
||||
|
|
@ -0,0 +1,7 @@
|
|||
{
|
||||
var local = "local";
|
||||
fun f() {
|
||||
print local; // expect: local
|
||||
}
|
||||
f();
|
||||
}
|
||||
|
|
@ -0,0 +1,14 @@
|
|||
var f;
|
||||
|
||||
{
|
||||
var a = "a";
|
||||
fun f_() {
|
||||
print a;
|
||||
print a;
|
||||
}
|
||||
f = f_;
|
||||
}
|
||||
|
||||
f();
|
||||
// expect: a
|
||||
// expect: a
|
||||
16
interpreter/tests/lox/closure/reuse_closure_slot.lox
Normal file
16
interpreter/tests/lox/closure/reuse_closure_slot.lox
Normal file
|
|
@ -0,0 +1,16 @@
|
|||
{
|
||||
var f;
|
||||
|
||||
{
|
||||
var a = "a";
|
||||
fun f_() { print a; }
|
||||
f = f_;
|
||||
}
|
||||
|
||||
{
|
||||
// Since a is out of scope, the local slot will be reused by b. Make sure
|
||||
// that f still closes over a.
|
||||
var b = "b";
|
||||
f(); // expect: a
|
||||
}
|
||||
}
|
||||
12
interpreter/tests/lox/closure/shadow_closure_with_local.lox
Normal file
12
interpreter/tests/lox/closure/shadow_closure_with_local.lox
Normal file
|
|
@ -0,0 +1,12 @@
|
|||
{
|
||||
var foo = "closure";
|
||||
fun f() {
|
||||
{
|
||||
print foo; // expect: closure
|
||||
var foo = "shadow";
|
||||
print foo; // expect: shadow
|
||||
}
|
||||
print foo; // expect: closure
|
||||
}
|
||||
f();
|
||||
}
|
||||
13
interpreter/tests/lox/closure/unused_closure.lox
Normal file
13
interpreter/tests/lox/closure/unused_closure.lox
Normal file
|
|
@ -0,0 +1,13 @@
|
|||
// This is a regression test. There was a bug where the VM would try to close
|
||||
// an upvalue even if the upvalue was never created because the codepath for
|
||||
// the closure was not executed.
|
||||
|
||||
{
|
||||
var a = "a";
|
||||
if (false) {
|
||||
fun foo() { a; }
|
||||
}
|
||||
}
|
||||
|
||||
// If we get here, we didn't segfault when a went out of scope.
|
||||
print "ok"; // expect: ok
|
||||
28
interpreter/tests/lox/closure/unused_later_closure.lox
Normal file
28
interpreter/tests/lox/closure/unused_later_closure.lox
Normal file
|
|
@ -0,0 +1,28 @@
|
|||
// This is a regression test. When closing upvalues for discarded locals, it
|
||||
// wouldn't make sure it discarded the upvalue for the correct stack slot.
|
||||
//
|
||||
// Here we create two locals that can be closed over, but only the first one
|
||||
// actually is. When "b" goes out of scope, we need to make sure we don't
|
||||
// prematurely close "a".
|
||||
var closure;
|
||||
|
||||
{
|
||||
var a = "a";
|
||||
|
||||
{
|
||||
var b = "b";
|
||||
fun returnA() {
|
||||
return a;
|
||||
}
|
||||
|
||||
closure = returnA;
|
||||
|
||||
if (false) {
|
||||
fun returnB() {
|
||||
return b;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
print closure(); // expect: a
|
||||
}
|
||||
2
interpreter/tests/lox/comments/line_at_eof.lox
Normal file
2
interpreter/tests/lox/comments/line_at_eof.lox
Normal file
|
|
@ -0,0 +1,2 @@
|
|||
print "ok"; // expect: ok
|
||||
// comment
|
||||
1
interpreter/tests/lox/comments/only_line_comment.lox
Normal file
1
interpreter/tests/lox/comments/only_line_comment.lox
Normal file
|
|
@ -0,0 +1 @@
|
|||
// comment
|
||||
|
|
@ -0,0 +1 @@
|
|||
// comment
|
||||
9
interpreter/tests/lox/comments/unicode.lox
Normal file
9
interpreter/tests/lox/comments/unicode.lox
Normal file
|
|
@ -0,0 +1,9 @@
|
|||
// Unicode characters are allowed in comments.
|
||||
//
|
||||
// Latin 1 Supplement: £§¶ÜÞ
|
||||
// Latin Extended-A: ĐĦŋœ
|
||||
// Latin Extended-B: ƂƢƩǁ
|
||||
// Other stuff: ឃᢆ᯽₪ℜ↩⊗┺░
|
||||
// Emoji: ☃☺♣
|
||||
|
||||
print "ok"; // expect: ok
|
||||
11
interpreter/tests/lox/constructor/arguments.lox
Normal file
11
interpreter/tests/lox/constructor/arguments.lox
Normal file
|
|
@ -0,0 +1,11 @@
|
|||
class Foo {
|
||||
init(a, b) {
|
||||
print "init"; // expect: init
|
||||
this.a = a;
|
||||
this.b = b;
|
||||
}
|
||||
}
|
||||
|
||||
var foo = Foo(1, 2);
|
||||
print foo.a; // expect: 1
|
||||
print foo.b; // expect: 2
|
||||
11
interpreter/tests/lox/constructor/call_init_early_return.lox
Normal file
11
interpreter/tests/lox/constructor/call_init_early_return.lox
Normal file
|
|
@ -0,0 +1,11 @@
|
|||
class Foo {
|
||||
init() {
|
||||
print "init";
|
||||
return;
|
||||
print "nope";
|
||||
}
|
||||
}
|
||||
|
||||
var foo = Foo(); // expect: init
|
||||
print foo.init(); // expect: init
|
||||
// expect: Foo instance
|
||||
15
interpreter/tests/lox/constructor/call_init_explicitly.lox
Normal file
15
interpreter/tests/lox/constructor/call_init_explicitly.lox
Normal file
|
|
@ -0,0 +1,15 @@
|
|||
class Foo {
|
||||
init(arg) {
|
||||
print "Foo.init(" + arg + ")";
|
||||
this.field = "init";
|
||||
}
|
||||
}
|
||||
|
||||
var foo = Foo("one"); // expect: Foo.init(one)
|
||||
foo.field = "field";
|
||||
|
||||
var foo2 = foo.init("two"); // expect: Foo.init(two)
|
||||
print foo2; // expect: Foo instance
|
||||
|
||||
// Make sure init() doesn't create a fresh instance.
|
||||
print foo.field; // expect: init
|
||||
4
interpreter/tests/lox/constructor/default.lox
Normal file
4
interpreter/tests/lox/constructor/default.lox
Normal file
|
|
@ -0,0 +1,4 @@
|
|||
class Foo {}
|
||||
|
||||
var foo = Foo();
|
||||
print foo; // expect: Foo instance
|
||||
3
interpreter/tests/lox/constructor/default_arguments.lox
Normal file
3
interpreter/tests/lox/constructor/default_arguments.lox
Normal file
|
|
@ -0,0 +1,3 @@
|
|||
class Foo {}
|
||||
|
||||
var foo = Foo(1, 2, 3); // expect runtime error: Expected 0 arguments but got 3.
|
||||
10
interpreter/tests/lox/constructor/early_return.lox
Normal file
10
interpreter/tests/lox/constructor/early_return.lox
Normal file
|
|
@ -0,0 +1,10 @@
|
|||
class Foo {
|
||||
init() {
|
||||
print "init";
|
||||
return;
|
||||
print "nope";
|
||||
}
|
||||
}
|
||||
|
||||
var foo = Foo(); // expect: init
|
||||
print foo; // expect: Foo instance
|
||||
8
interpreter/tests/lox/constructor/extra_arguments.lox
Normal file
8
interpreter/tests/lox/constructor/extra_arguments.lox
Normal file
|
|
@ -0,0 +1,8 @@
|
|||
class Foo {
|
||||
init(a, b) {
|
||||
this.a = a;
|
||||
this.b = b;
|
||||
}
|
||||
}
|
||||
|
||||
var foo = Foo(1, 2, 3, 4); // expect runtime error: Expected 2 arguments but got 4.
|
||||
12
interpreter/tests/lox/constructor/init_not_method.lox
Normal file
12
interpreter/tests/lox/constructor/init_not_method.lox
Normal file
|
|
@ -0,0 +1,12 @@
|
|||
class Foo {
|
||||
init(arg) {
|
||||
print "Foo.init(" + arg + ")";
|
||||
this.field = "init";
|
||||
}
|
||||
}
|
||||
|
||||
fun init() {
|
||||
print "not initializer";
|
||||
}
|
||||
|
||||
init(); // expect: not initializer
|
||||
5
interpreter/tests/lox/constructor/missing_arguments.lox
Normal file
5
interpreter/tests/lox/constructor/missing_arguments.lox
Normal file
|
|
@ -0,0 +1,5 @@
|
|||
class Foo {
|
||||
init(a, b) {}
|
||||
}
|
||||
|
||||
var foo = Foo(1); // expect runtime error: Expected 2 arguments but got 1.
|
||||
|
|
@ -0,0 +1,10 @@
|
|||
class Foo {
|
||||
init() {
|
||||
fun init() {
|
||||
return "bar";
|
||||
}
|
||||
print init(); // expect: bar
|
||||
}
|
||||
}
|
||||
|
||||
print Foo(); // expect: Foo instance
|
||||
5
interpreter/tests/lox/constructor/return_value.lox
Normal file
5
interpreter/tests/lox/constructor/return_value.lox
Normal file
|
|
@ -0,0 +1,5 @@
|
|||
class Foo {
|
||||
init() {
|
||||
return "result"; // Error at 'return': Can't return a value from an initializer.
|
||||
}
|
||||
}
|
||||
16
interpreter/tests/lox/continue/for.lox
Normal file
16
interpreter/tests/lox/continue/for.lox
Normal file
|
|
@ -0,0 +1,16 @@
|
|||
for (var i = 0; i < 10; i = i + 1) {
|
||||
if (i == 5)
|
||||
continue;
|
||||
|
||||
print i;
|
||||
}
|
||||
// expect: 0
|
||||
// expect: 1
|
||||
// expect: 2
|
||||
// expect: 3
|
||||
// expect: 4
|
||||
// expect: 6
|
||||
// expect: 7
|
||||
// expect: 8
|
||||
// expect: 9
|
||||
|
||||
2
interpreter/tests/lox/continue/outside_loop.lox
Normal file
2
interpreter/tests/lox/continue/outside_loop.lox
Normal file
|
|
@ -0,0 +1,2 @@
|
|||
continue;
|
||||
// expect: error
|
||||
21
interpreter/tests/lox/continue/while.lox
Normal file
21
interpreter/tests/lox/continue/while.lox
Normal file
|
|
@ -0,0 +1,21 @@
|
|||
var i = 0;
|
||||
|
||||
while (i < 10) {
|
||||
if (i == 5) {
|
||||
i = i + 1;
|
||||
continue;
|
||||
}
|
||||
|
||||
print i;
|
||||
|
||||
i = i + 1;
|
||||
}
|
||||
// expect: 0
|
||||
// expect: 1
|
||||
// expect: 2
|
||||
// expect: 3
|
||||
// expect: 4
|
||||
// expect: 6
|
||||
// expect: 7
|
||||
// expect: 8
|
||||
// expect: 9
|
||||
0
interpreter/tests/lox/empty_file.lox
Normal file
0
interpreter/tests/lox/empty_file.lox
Normal file
15
interpreter/tests/lox/field/call_function_field.lox
Normal file
15
interpreter/tests/lox/field/call_function_field.lox
Normal file
|
|
@ -0,0 +1,15 @@
|
|||
class Foo {}
|
||||
|
||||
fun bar(a, b) {
|
||||
print "bar";
|
||||
print a;
|
||||
print b;
|
||||
}
|
||||
|
||||
var foo = Foo();
|
||||
foo.bar = bar;
|
||||
|
||||
foo.bar(1, 2);
|
||||
// expect: bar
|
||||
// expect: 1
|
||||
// expect: 2
|
||||
6
interpreter/tests/lox/field/call_nonfunction_field.lox
Normal file
6
interpreter/tests/lox/field/call_nonfunction_field.lox
Normal file
|
|
@ -0,0 +1,6 @@
|
|||
class Foo {}
|
||||
|
||||
var foo = Foo();
|
||||
foo.bar = "not fn";
|
||||
|
||||
foo.bar(); // expect runtime error: Can only call functions and classes.
|
||||
25
interpreter/tests/lox/field/get_and_set_method.lox
Normal file
25
interpreter/tests/lox/field/get_and_set_method.lox
Normal file
|
|
@ -0,0 +1,25 @@
|
|||
// Bound methods have identity equality.
|
||||
class Foo {
|
||||
method(a) {
|
||||
print "method";
|
||||
print a;
|
||||
}
|
||||
other(a) {
|
||||
print "other";
|
||||
print a;
|
||||
}
|
||||
}
|
||||
|
||||
var foo = Foo();
|
||||
var method = foo.method;
|
||||
|
||||
// Setting a property shadows the instance method.
|
||||
foo.method = foo.other;
|
||||
foo.method(1);
|
||||
// expect: other
|
||||
// expect: 1
|
||||
|
||||
// The old method handle still points to the original method.
|
||||
method(2);
|
||||
// expect: method
|
||||
// expect: 2
|
||||
1
interpreter/tests/lox/field/get_on_bool.lox
Normal file
1
interpreter/tests/lox/field/get_on_bool.lox
Normal file
|
|
@ -0,0 +1 @@
|
|||
true.foo; // expect runtime error: Only instances have properties.
|
||||
2
interpreter/tests/lox/field/get_on_class.lox
Normal file
2
interpreter/tests/lox/field/get_on_class.lox
Normal file
|
|
@ -0,0 +1,2 @@
|
|||
class Foo {}
|
||||
Foo.bar; // expect runtime error: Only instances have properties.
|
||||
3
interpreter/tests/lox/field/get_on_function.lox
Normal file
3
interpreter/tests/lox/field/get_on_function.lox
Normal file
|
|
@ -0,0 +1,3 @@
|
|||
fun foo() {}
|
||||
|
||||
foo.bar; // expect runtime error: Only instances have properties.
|
||||
1
interpreter/tests/lox/field/get_on_nil.lox
Normal file
1
interpreter/tests/lox/field/get_on_nil.lox
Normal file
|
|
@ -0,0 +1 @@
|
|||
nil.foo; // expect runtime error: Only instances have properties.
|
||||
1
interpreter/tests/lox/field/get_on_num.lox
Normal file
1
interpreter/tests/lox/field/get_on_num.lox
Normal file
|
|
@ -0,0 +1 @@
|
|||
123.foo; // expect runtime error: Only instances have properties.
|
||||
1
interpreter/tests/lox/field/get_on_string.lox
Normal file
1
interpreter/tests/lox/field/get_on_string.lox
Normal file
|
|
@ -0,0 +1 @@
|
|||
"str".foo; // expect runtime error: Only instances have properties.
|
||||
170
interpreter/tests/lox/field/many.lox
Normal file
170
interpreter/tests/lox/field/many.lox
Normal file
|
|
@ -0,0 +1,170 @@
|
|||
class Foo {}
|
||||
|
||||
var foo = Foo();
|
||||
fun setFields() {
|
||||
foo.bilberry = "bilberry";
|
||||
foo.lime = "lime";
|
||||
foo.elderberry = "elderberry";
|
||||
foo.raspberry = "raspberry";
|
||||
foo.gooseberry = "gooseberry";
|
||||
foo.longan = "longan";
|
||||
foo.mandarine = "mandarine";
|
||||
foo.kiwifruit = "kiwifruit";
|
||||
foo.orange = "orange";
|
||||
foo.pomegranate = "pomegranate";
|
||||
foo.tomato = "tomato";
|
||||
foo.banana = "banana";
|
||||
foo.juniper = "juniper";
|
||||
foo.damson = "damson";
|
||||
foo.blackcurrant = "blackcurrant";
|
||||
foo.peach = "peach";
|
||||
foo.grape = "grape";
|
||||
foo.mango = "mango";
|
||||
foo.redcurrant = "redcurrant";
|
||||
foo.watermelon = "watermelon";
|
||||
foo.plumcot = "plumcot";
|
||||
foo.papaya = "papaya";
|
||||
foo.cloudberry = "cloudberry";
|
||||
foo.rambutan = "rambutan";
|
||||
foo.salak = "salak";
|
||||
foo.physalis = "physalis";
|
||||
foo.huckleberry = "huckleberry";
|
||||
foo.coconut = "coconut";
|
||||
foo.date = "date";
|
||||
foo.tamarind = "tamarind";
|
||||
foo.lychee = "lychee";
|
||||
foo.raisin = "raisin";
|
||||
foo.apple = "apple";
|
||||
foo.avocado = "avocado";
|
||||
foo.nectarine = "nectarine";
|
||||
foo.pomelo = "pomelo";
|
||||
foo.melon = "melon";
|
||||
foo.currant = "currant";
|
||||
foo.plum = "plum";
|
||||
foo.persimmon = "persimmon";
|
||||
foo.olive = "olive";
|
||||
foo.cranberry = "cranberry";
|
||||
foo.boysenberry = "boysenberry";
|
||||
foo.blackberry = "blackberry";
|
||||
foo.passionfruit = "passionfruit";
|
||||
foo.mulberry = "mulberry";
|
||||
foo.marionberry = "marionberry";
|
||||
foo.plantain = "plantain";
|
||||
foo.lemon = "lemon";
|
||||
foo.yuzu = "yuzu";
|
||||
foo.loquat = "loquat";
|
||||
foo.kumquat = "kumquat";
|
||||
foo.salmonberry = "salmonberry";
|
||||
foo.tangerine = "tangerine";
|
||||
foo.durian = "durian";
|
||||
foo.pear = "pear";
|
||||
foo.cantaloupe = "cantaloupe";
|
||||
foo.quince = "quince";
|
||||
foo.guava = "guava";
|
||||
foo.strawberry = "strawberry";
|
||||
foo.nance = "nance";
|
||||
foo.apricot = "apricot";
|
||||
foo.jambul = "jambul";
|
||||
foo.grapefruit = "grapefruit";
|
||||
foo.clementine = "clementine";
|
||||
foo.jujube = "jujube";
|
||||
foo.cherry = "cherry";
|
||||
foo.feijoa = "feijoa";
|
||||
foo.jackfruit = "jackfruit";
|
||||
foo.fig = "fig";
|
||||
foo.cherimoya = "cherimoya";
|
||||
foo.pineapple = "pineapple";
|
||||
foo.blueberry = "blueberry";
|
||||
foo.jabuticaba = "jabuticaba";
|
||||
foo.miracle = "miracle";
|
||||
foo.dragonfruit = "dragonfruit";
|
||||
foo.satsuma = "satsuma";
|
||||
foo.tamarillo = "tamarillo";
|
||||
foo.honeydew = "honeydew";
|
||||
}
|
||||
|
||||
setFields();
|
||||
|
||||
fun printFields() {
|
||||
print foo.apple; // expect: apple
|
||||
print foo.apricot; // expect: apricot
|
||||
print foo.avocado; // expect: avocado
|
||||
print foo.banana; // expect: banana
|
||||
print foo.bilberry; // expect: bilberry
|
||||
print foo.blackberry; // expect: blackberry
|
||||
print foo.blackcurrant; // expect: blackcurrant
|
||||
print foo.blueberry; // expect: blueberry
|
||||
print foo.boysenberry; // expect: boysenberry
|
||||
print foo.cantaloupe; // expect: cantaloupe
|
||||
print foo.cherimoya; // expect: cherimoya
|
||||
print foo.cherry; // expect: cherry
|
||||
print foo.clementine; // expect: clementine
|
||||
print foo.cloudberry; // expect: cloudberry
|
||||
print foo.coconut; // expect: coconut
|
||||
print foo.cranberry; // expect: cranberry
|
||||
print foo.currant; // expect: currant
|
||||
print foo.damson; // expect: damson
|
||||
print foo.date; // expect: date
|
||||
print foo.dragonfruit; // expect: dragonfruit
|
||||
print foo.durian; // expect: durian
|
||||
print foo.elderberry; // expect: elderberry
|
||||
print foo.feijoa; // expect: feijoa
|
||||
print foo.fig; // expect: fig
|
||||
print foo.gooseberry; // expect: gooseberry
|
||||
print foo.grape; // expect: grape
|
||||
print foo.grapefruit; // expect: grapefruit
|
||||
print foo.guava; // expect: guava
|
||||
print foo.honeydew; // expect: honeydew
|
||||
print foo.huckleberry; // expect: huckleberry
|
||||
print foo.jabuticaba; // expect: jabuticaba
|
||||
print foo.jackfruit; // expect: jackfruit
|
||||
print foo.jambul; // expect: jambul
|
||||
print foo.jujube; // expect: jujube
|
||||
print foo.juniper; // expect: juniper
|
||||
print foo.kiwifruit; // expect: kiwifruit
|
||||
print foo.kumquat; // expect: kumquat
|
||||
print foo.lemon; // expect: lemon
|
||||
print foo.lime; // expect: lime
|
||||
print foo.longan; // expect: longan
|
||||
print foo.loquat; // expect: loquat
|
||||
print foo.lychee; // expect: lychee
|
||||
print foo.mandarine; // expect: mandarine
|
||||
print foo.mango; // expect: mango
|
||||
print foo.marionberry; // expect: marionberry
|
||||
print foo.melon; // expect: melon
|
||||
print foo.miracle; // expect: miracle
|
||||
print foo.mulberry; // expect: mulberry
|
||||
print foo.nance; // expect: nance
|
||||
print foo.nectarine; // expect: nectarine
|
||||
print foo.olive; // expect: olive
|
||||
print foo.orange; // expect: orange
|
||||
print foo.papaya; // expect: papaya
|
||||
print foo.passionfruit; // expect: passionfruit
|
||||
print foo.peach; // expect: peach
|
||||
print foo.pear; // expect: pear
|
||||
print foo.persimmon; // expect: persimmon
|
||||
print foo.physalis; // expect: physalis
|
||||
print foo.pineapple; // expect: pineapple
|
||||
print foo.plantain; // expect: plantain
|
||||
print foo.plum; // expect: plum
|
||||
print foo.plumcot; // expect: plumcot
|
||||
print foo.pomegranate; // expect: pomegranate
|
||||
print foo.pomelo; // expect: pomelo
|
||||
print foo.quince; // expect: quince
|
||||
print foo.raisin; // expect: raisin
|
||||
print foo.rambutan; // expect: rambutan
|
||||
print foo.raspberry; // expect: raspberry
|
||||
print foo.redcurrant; // expect: redcurrant
|
||||
print foo.salak; // expect: salak
|
||||
print foo.salmonberry; // expect: salmonberry
|
||||
print foo.satsuma; // expect: satsuma
|
||||
print foo.strawberry; // expect: strawberry
|
||||
print foo.tamarillo; // expect: tamarillo
|
||||
print foo.tamarind; // expect: tamarind
|
||||
print foo.tangerine; // expect: tangerine
|
||||
print foo.tomato; // expect: tomato
|
||||
print foo.watermelon; // expect: watermelon
|
||||
print foo.yuzu; // expect: yuzu
|
||||
}
|
||||
|
||||
printFields();
|
||||
9
interpreter/tests/lox/field/method.lox
Normal file
9
interpreter/tests/lox/field/method.lox
Normal file
|
|
@ -0,0 +1,9 @@
|
|||
class Foo {
|
||||
bar(arg) {
|
||||
print arg;
|
||||
}
|
||||
}
|
||||
|
||||
var bar = Foo().bar;
|
||||
print "got method"; // expect: got method
|
||||
bar("arg"); // expect: arg
|
||||
19
interpreter/tests/lox/field/method_binds_this.lox
Normal file
19
interpreter/tests/lox/field/method_binds_this.lox
Normal file
|
|
@ -0,0 +1,19 @@
|
|||
class Foo {
|
||||
sayName(a) {
|
||||
print this.name;
|
||||
print a;
|
||||
}
|
||||
}
|
||||
|
||||
var foo1 = Foo();
|
||||
foo1.name = "foo1";
|
||||
|
||||
var foo2 = Foo();
|
||||
foo2.name = "foo2";
|
||||
|
||||
// Store the method reference on another object.
|
||||
foo2.fn = foo1.sayName;
|
||||
// Still retains original receiver.
|
||||
foo2.fn(1);
|
||||
// expect: foo1
|
||||
// expect: 1
|
||||
9
interpreter/tests/lox/field/on_instance.lox
Normal file
9
interpreter/tests/lox/field/on_instance.lox
Normal file
|
|
@ -0,0 +1,9 @@
|
|||
class Foo {}
|
||||
|
||||
var foo = Foo();
|
||||
|
||||
print foo.bar = "bar value"; // expect: bar value
|
||||
print foo.baz = "baz value"; // expect: baz value
|
||||
|
||||
print foo.bar; // expect: bar value
|
||||
print foo.baz; // expect: baz value
|
||||
2
interpreter/tests/lox/field/set_evaluation_order.lox
Normal file
2
interpreter/tests/lox/field/set_evaluation_order.lox
Normal file
|
|
@ -0,0 +1,2 @@
|
|||
undefined1.bar // expect runtime error: Undefined variable 'undefined1'.
|
||||
= undefined2;
|
||||
1
interpreter/tests/lox/field/set_on_bool.lox
Normal file
1
interpreter/tests/lox/field/set_on_bool.lox
Normal file
|
|
@ -0,0 +1 @@
|
|||
true.foo = "value"; // expect runtime error: Only instances have fields.
|
||||
2
interpreter/tests/lox/field/set_on_class.lox
Normal file
2
interpreter/tests/lox/field/set_on_class.lox
Normal file
|
|
@ -0,0 +1,2 @@
|
|||
class Foo {}
|
||||
Foo.bar = "value"; // expect runtime error: Only instances have fields.
|
||||
3
interpreter/tests/lox/field/set_on_function.lox
Normal file
3
interpreter/tests/lox/field/set_on_function.lox
Normal file
|
|
@ -0,0 +1,3 @@
|
|||
fun foo() {}
|
||||
|
||||
foo.bar = "value"; // expect runtime error: Only instances have fields.
|
||||
1
interpreter/tests/lox/field/set_on_nil.lox
Normal file
1
interpreter/tests/lox/field/set_on_nil.lox
Normal file
|
|
@ -0,0 +1 @@
|
|||
nil.foo = "value"; // expect runtime error: Only instances have fields.
|
||||
1
interpreter/tests/lox/field/set_on_num.lox
Normal file
1
interpreter/tests/lox/field/set_on_num.lox
Normal file
|
|
@ -0,0 +1 @@
|
|||
123.foo = "value"; // expect runtime error: Only instances have fields.
|
||||
1
interpreter/tests/lox/field/set_on_string.lox
Normal file
1
interpreter/tests/lox/field/set_on_string.lox
Normal file
|
|
@ -0,0 +1 @@
|
|||
"str".foo = "value"; // expect runtime error: Only instances have fields.
|
||||
4
interpreter/tests/lox/field/undefined.lox
Normal file
4
interpreter/tests/lox/field/undefined.lox
Normal file
|
|
@ -0,0 +1,4 @@
|
|||
class Foo {}
|
||||
var foo = Foo();
|
||||
|
||||
foo.bar; // expect runtime error: Undefined property 'bar'.
|
||||
2
interpreter/tests/lox/for/class_in_body.lox
Normal file
2
interpreter/tests/lox/for/class_in_body.lox
Normal file
|
|
@ -0,0 +1,2 @@
|
|||
// [line 2] Error at 'class': Expect expression.
|
||||
for (;;) class Foo {}
|
||||
22
interpreter/tests/lox/for/closure_in_body.lox
Normal file
22
interpreter/tests/lox/for/closure_in_body.lox
Normal file
|
|
@ -0,0 +1,22 @@
|
|||
var f1;
|
||||
var f2;
|
||||
var f3;
|
||||
|
||||
for (var i = 1; i < 4; i = i + 1) {
|
||||
var j = i;
|
||||
fun f() {
|
||||
print i;
|
||||
print j;
|
||||
}
|
||||
|
||||
if (j == 1) f1 = f;
|
||||
else if (j == 2) f2 = f;
|
||||
else f3 = f;
|
||||
}
|
||||
|
||||
f1(); // expect: 4
|
||||
// expect: 1
|
||||
f2(); // expect: 4
|
||||
// expect: 2
|
||||
f3(); // expect: 4
|
||||
// expect: 3
|
||||
2
interpreter/tests/lox/for/fun_in_body.lox
Normal file
2
interpreter/tests/lox/for/fun_in_body.lox
Normal file
|
|
@ -0,0 +1,2 @@
|
|||
// [line 2] Error at 'fun': Expect expression.
|
||||
for (;;) fun foo() {}
|
||||
10
interpreter/tests/lox/for/return_closure.lox
Normal file
10
interpreter/tests/lox/for/return_closure.lox
Normal file
|
|
@ -0,0 +1,10 @@
|
|||
fun f() {
|
||||
for (;;) {
|
||||
var i = "i";
|
||||
fun g() { print i; }
|
||||
return g;
|
||||
}
|
||||
}
|
||||
|
||||
var h = f();
|
||||
h(); // expect: i
|
||||
9
interpreter/tests/lox/for/return_inside.lox
Normal file
9
interpreter/tests/lox/for/return_inside.lox
Normal file
|
|
@ -0,0 +1,9 @@
|
|||
fun f() {
|
||||
for (;;) {
|
||||
var i = "i";
|
||||
return i;
|
||||
}
|
||||
}
|
||||
|
||||
print f();
|
||||
// expect: i
|
||||
26
interpreter/tests/lox/for/scope.lox
Normal file
26
interpreter/tests/lox/for/scope.lox
Normal file
|
|
@ -0,0 +1,26 @@
|
|||
{
|
||||
var i = "before";
|
||||
|
||||
// New variable is in inner scope.
|
||||
for (var i = 0; i < 1; i = i + 1) {
|
||||
print i; // expect: 0
|
||||
|
||||
// Loop body is in second inner scope.
|
||||
var i = -1;
|
||||
print i; // expect: -1
|
||||
}
|
||||
}
|
||||
|
||||
{
|
||||
// New variable shadows outer variable.
|
||||
for (var i = 0; i > 0; i = i + 1) {}
|
||||
|
||||
// Goes out of scope after loop.
|
||||
var i = "after";
|
||||
print i; // expect: after
|
||||
|
||||
// Can reuse an existing variable.
|
||||
for (i = 0; i < 1; i = i + 1) {
|
||||
print i; // expect: 0
|
||||
}
|
||||
}
|
||||
3
interpreter/tests/lox/for/statement_condition.lox
Normal file
3
interpreter/tests/lox/for/statement_condition.lox
Normal file
|
|
@ -0,0 +1,3 @@
|
|||
// [line 3] Error at '{': Expect expression.
|
||||
// [line 3] Error at ')': Expect ';' after expression.
|
||||
for (var a = 1; {}; a = a + 1) {}
|
||||
2
interpreter/tests/lox/for/statement_increment.lox
Normal file
2
interpreter/tests/lox/for/statement_increment.lox
Normal file
|
|
@ -0,0 +1,2 @@
|
|||
// [line 2] Error at '{': Expect expression.
|
||||
for (var a = 1; a < 2; {}) {}
|
||||
3
interpreter/tests/lox/for/statement_initializer.lox
Normal file
3
interpreter/tests/lox/for/statement_initializer.lox
Normal file
|
|
@ -0,0 +1,3 @@
|
|||
// [line 3] Error at '{': Expect expression.
|
||||
// [line 3] Error at ')': Expect ';' after expression.
|
||||
for ({}; a < 2; a = a + 1) {}
|
||||
50
interpreter/tests/lox/for/syntax.lox
Normal file
50
interpreter/tests/lox/for/syntax.lox
Normal file
|
|
@ -0,0 +1,50 @@
|
|||
// Single-expression body.
|
||||
for (var c = 0; c < 3;) print c = c + 1;
|
||||
// expect: 1
|
||||
// expect: 2
|
||||
// expect: 3
|
||||
|
||||
// Block body.
|
||||
for (var a = 0; a < 3; a = a + 1) {
|
||||
print a;
|
||||
}
|
||||
// expect: 0
|
||||
// expect: 1
|
||||
// expect: 2
|
||||
|
||||
// No clauses.
|
||||
fun foo() {
|
||||
for (;;) return "done";
|
||||
}
|
||||
print foo(); // expect: done
|
||||
|
||||
// No variable.
|
||||
var i = 0;
|
||||
for (; i < 2; i = i + 1) print i;
|
||||
// expect: 0
|
||||
// expect: 1
|
||||
|
||||
// No condition.
|
||||
fun bar() {
|
||||
for (var i = 0;; i = i + 1) {
|
||||
print i;
|
||||
if (i >= 2) return;
|
||||
}
|
||||
}
|
||||
bar();
|
||||
// expect: 0
|
||||
// expect: 1
|
||||
// expect: 2
|
||||
|
||||
// No increment.
|
||||
for (var i = 0; i < 2;) {
|
||||
print i;
|
||||
i = i + 1;
|
||||
}
|
||||
// expect: 0
|
||||
// expect: 1
|
||||
|
||||
// Statement bodies.
|
||||
for (; false;) if (true) 1; else 2;
|
||||
for (; false;) while (true) 1;
|
||||
for (; false;) for (;;) 1;
|
||||
2
interpreter/tests/lox/for/var_in_body.lox
Normal file
2
interpreter/tests/lox/for/var_in_body.lox
Normal file
|
|
@ -0,0 +1,2 @@
|
|||
// [line 2] Error at 'var': Expect expression.
|
||||
for (;;) var foo;
|
||||
3
interpreter/tests/lox/function/body_must_be_block.lox
Normal file
3
interpreter/tests/lox/function/body_must_be_block.lox
Normal file
|
|
@ -0,0 +1,3 @@
|
|||
// [line 3] Error at '123': Expect '{' before function body.
|
||||
// [c line 4] Error at end: Expect '}' after block.
|
||||
fun f() 123;
|
||||
2
interpreter/tests/lox/function/empty_body.lox
Normal file
2
interpreter/tests/lox/function/empty_body.lox
Normal file
|
|
@ -0,0 +1,2 @@
|
|||
fun f() {}
|
||||
print f(); // expect: nil
|
||||
6
interpreter/tests/lox/function/extra_arguments.lox
Normal file
6
interpreter/tests/lox/function/extra_arguments.lox
Normal file
|
|
@ -0,0 +1,6 @@
|
|||
fun f(a, b) {
|
||||
print a;
|
||||
print b;
|
||||
}
|
||||
|
||||
f(1, 2, 3, 4); // expect runtime error: Expected 2 arguments but got 4.
|
||||
13
interpreter/tests/lox/function/local_mutual_recursion.lox
Normal file
13
interpreter/tests/lox/function/local_mutual_recursion.lox
Normal file
|
|
@ -0,0 +1,13 @@
|
|||
{
|
||||
fun isEven(n) {
|
||||
if (n == 0) return true;
|
||||
return isOdd(n - 1); // expect runtime error: Undefined variable 'isOdd'.
|
||||
}
|
||||
|
||||
fun isOdd(n) {
|
||||
if (n == 0) return false;
|
||||
return isEven(n - 1);
|
||||
}
|
||||
|
||||
isEven(4);
|
||||
}
|
||||
8
interpreter/tests/lox/function/local_recursion.lox
Normal file
8
interpreter/tests/lox/function/local_recursion.lox
Normal file
|
|
@ -0,0 +1,8 @@
|
|||
{
|
||||
fun fib(n) {
|
||||
if (n < 2) return n;
|
||||
return fib(n - 1) + fib(n - 2);
|
||||
}
|
||||
|
||||
print fib(8); // expect: 21
|
||||
}
|
||||
3
interpreter/tests/lox/function/missing_arguments.lox
Normal file
3
interpreter/tests/lox/function/missing_arguments.lox
Normal file
|
|
@ -0,0 +1,3 @@
|
|||
fun f(a, b) {}
|
||||
|
||||
f(1); // expect runtime error: Expected 2 arguments but got 1.
|
||||
|
|
@ -0,0 +1,3 @@
|
|||
// [line 3] Error at 'c': Expect ')' after parameters.
|
||||
// [c line 4] Error at end: Expect '}' after block.
|
||||
fun foo(a, b c, d, e, f) {}
|
||||
Some files were not shown because too many files have changed in this diff Show more
Loading…
Add table
Add a link
Reference in a new issue