lang: Add a bunch of new language tests
These test both graph shape consistency and single value outputs. Eventually we want to make the graph shape tests more precise, and also verify specific outputs how it used to be. For now, this is okay. Co-authored-by: Samuel Gélineau <gelisam@gmail.com>
This commit is contained in:
10
lang/interpret_test/TestAstFunc2/chained-vars.txtar
Normal file
10
lang/interpret_test/TestAstFunc2/chained-vars.txtar
Normal file
@@ -0,0 +1,10 @@
|
||||
-- main.mcl --
|
||||
import "fmt"
|
||||
|
||||
$zero = 0
|
||||
$one = $zero + 1
|
||||
$two = $one + 1 # needs a chain to panic
|
||||
|
||||
test fmt.printf("%d%d%d", $zero, $one, $two) {}
|
||||
-- OUTPUT --
|
||||
Vertex: test[012]
|
||||
@@ -1,5 +1,6 @@
|
||||
-- main.mcl --
|
||||
$x1 = "bad1"
|
||||
$x2 = "also bad"
|
||||
include defs.foo
|
||||
|
||||
import "defs.mcl" # out of order for fun
|
||||
|
||||
25
lang/interpret_test/TestAstFunc2/complex-example.txtar
Normal file
25
lang/interpret_test/TestAstFunc2/complex-example.txtar
Normal file
@@ -0,0 +1,25 @@
|
||||
-- main.mcl --
|
||||
import "fmt"
|
||||
import "iter"
|
||||
|
||||
# function expression
|
||||
$id1 = func($x str) { # definition site
|
||||
$x
|
||||
}
|
||||
$id2 = func($x str) {
|
||||
$x + $x
|
||||
}
|
||||
|
||||
$generate = func($idn) {
|
||||
$idn("foo") # 1 call site, 2 calls
|
||||
}
|
||||
|
||||
$foo = iter.map([$id1, $id2,], $generate)
|
||||
|
||||
#test $foo[0] {}
|
||||
#test $foo[1] {}
|
||||
test listlookup($foo, 0, "fail") {} # TODO: add syntactic sugar for listlookup
|
||||
test listlookup($foo, 1, "fail") {} # TODO: add syntactic sugar for listlookup
|
||||
-- OUTPUT --
|
||||
Vertex: test[foo]
|
||||
Vertex: test[foofoo]
|
||||
19
lang/interpret_test/TestAstFunc2/definition-site-scope.txtar
Normal file
19
lang/interpret_test/TestAstFunc2/definition-site-scope.txtar
Normal file
@@ -0,0 +1,19 @@
|
||||
-- main.mcl --
|
||||
$x = "top-level"
|
||||
func f1() {
|
||||
$x + "1"
|
||||
}
|
||||
$f2 = func() {
|
||||
$x + "2"
|
||||
}
|
||||
$call_f1 = func($x) {
|
||||
f1() + $x
|
||||
}
|
||||
$call_f2 = func($x) {
|
||||
$f2() + $x
|
||||
}
|
||||
test $call_f1("!") {}
|
||||
test $call_f2("?") {}
|
||||
-- OUTPUT --
|
||||
Vertex: test[top-level1!]
|
||||
Vertex: test[top-level2?]
|
||||
11
lang/interpret_test/TestAstFunc2/func-duplicate-arg.txtar
Normal file
11
lang/interpret_test/TestAstFunc2/func-duplicate-arg.txtar
Normal file
@@ -0,0 +1,11 @@
|
||||
-- main.mcl --
|
||||
# function statement
|
||||
func stradd($x) {
|
||||
$x + $x
|
||||
}
|
||||
|
||||
$x1 = stradd("hey")
|
||||
|
||||
test $x1 {}
|
||||
-- OUTPUT --
|
||||
Vertex: test[heyhey]
|
||||
@@ -2,20 +2,14 @@
|
||||
import "fmt"
|
||||
|
||||
# function statement
|
||||
func sq1($x, $y) {
|
||||
$y + $x * $x
|
||||
func sq1($x) {
|
||||
$x + $x
|
||||
#$x + 3
|
||||
#6
|
||||
}
|
||||
|
||||
# function expression
|
||||
$sq2 = func($x, $y) {
|
||||
$y + $x * $x
|
||||
}
|
||||
|
||||
$x1 = sq1(3, 4) # 3^2 + 4 = 13
|
||||
$x2 = $sq2(7, -7) # 7^2 + 2 = 42
|
||||
$x1 = sq1(3) # 3^2 + 4 = 13
|
||||
|
||||
test fmt.printf("sq1: %d", $x1) {}
|
||||
test fmt.printf("sq2: %d", $x2) {}
|
||||
-- OUTPUT --
|
||||
Vertex: test[sq1: 13]
|
||||
Vertex: test[sq2: 42]
|
||||
Vertex: test[sq1: 6]
|
||||
|
||||
17
lang/interpret_test/TestAstFunc2/func-math2.txtar
Normal file
17
lang/interpret_test/TestAstFunc2/func-math2.txtar
Normal file
@@ -0,0 +1,17 @@
|
||||
-- main.mcl --
|
||||
import "fmt"
|
||||
import "math"
|
||||
|
||||
# XXX: do the input nodes to _operator look weird here? in my testing I saw
|
||||
# fortytwo appear, and then disappear before we finished running...
|
||||
# function statement
|
||||
func sq1($x) {
|
||||
$x + 3
|
||||
}
|
||||
|
||||
$x1 = sq1(math.fortytwo())
|
||||
|
||||
test fmt.printf("sq1: %d", $x1) {}
|
||||
|
||||
-- OUTPUT --
|
||||
Vertex: test[sq1: 45]
|
||||
13
lang/interpret_test/TestAstFunc2/func-one-arg.txtar
Normal file
13
lang/interpret_test/TestAstFunc2/func-one-arg.txtar
Normal file
@@ -0,0 +1,13 @@
|
||||
-- main.mcl --
|
||||
import "fmt"
|
||||
|
||||
# function statement
|
||||
func stradd($x) {
|
||||
$x + "there"
|
||||
}
|
||||
|
||||
$x1 = stradd("hey")
|
||||
|
||||
test $x1 {}
|
||||
-- OUTPUT --
|
||||
Vertex: test[heythere]
|
||||
13
lang/interpret_test/TestAstFunc2/func-unused-arg.txtar
Normal file
13
lang/interpret_test/TestAstFunc2/func-unused-arg.txtar
Normal file
@@ -0,0 +1,13 @@
|
||||
-- main.mcl --
|
||||
import "fmt"
|
||||
|
||||
# function statement
|
||||
func stradd($x) {
|
||||
"nothing"
|
||||
}
|
||||
|
||||
$x1 = stradd("hey")
|
||||
|
||||
test $x1 {}
|
||||
-- OUTPUT --
|
||||
Vertex: test[nothing]
|
||||
@@ -0,0 +1,9 @@
|
||||
-- main.mcl --
|
||||
# function statement
|
||||
func identity($x) {
|
||||
$x
|
||||
}
|
||||
|
||||
test identity("hey") {}
|
||||
-- OUTPUT --
|
||||
Vertex: test[hey]
|
||||
10
lang/interpret_test/TestAstFunc2/if-0.txtar
Normal file
10
lang/interpret_test/TestAstFunc2/if-0.txtar
Normal file
@@ -0,0 +1,10 @@
|
||||
-- main.mcl --
|
||||
$out1 = if true {
|
||||
"hello"
|
||||
} else {
|
||||
"world"
|
||||
}
|
||||
|
||||
test $out1 {}
|
||||
-- OUTPUT --
|
||||
Vertex: test[hello]
|
||||
15
lang/interpret_test/TestAstFunc2/if-in-func-0.txtar
Normal file
15
lang/interpret_test/TestAstFunc2/if-in-func-0.txtar
Normal file
@@ -0,0 +1,15 @@
|
||||
-- main.mcl --
|
||||
# this can return changing functions, and could be optimized, too
|
||||
$fn = func($b) {
|
||||
if true {
|
||||
"hello"
|
||||
} else {
|
||||
"world"
|
||||
}
|
||||
}
|
||||
|
||||
$out1 = $fn(true)
|
||||
|
||||
test $out1 {}
|
||||
-- OUTPUT --
|
||||
Vertex: test[hello]
|
||||
@@ -10,4 +10,4 @@ print "msg" {
|
||||
msg => fmt.printf("notfn: %d", $x),
|
||||
}
|
||||
-- OUTPUT --
|
||||
# err: errUnify: expected: Func, got: Int
|
||||
# err: errUnify: func arg count differs
|
||||
|
||||
13
lang/interpret_test/TestAstFunc2/lambda-duplicate-arg.txtar
Normal file
13
lang/interpret_test/TestAstFunc2/lambda-duplicate-arg.txtar
Normal file
@@ -0,0 +1,13 @@
|
||||
-- main.mcl --
|
||||
import "fmt"
|
||||
|
||||
# function statement
|
||||
$stradd = func($x) {
|
||||
$x + $x
|
||||
}
|
||||
|
||||
$x1 = $stradd("hey")
|
||||
|
||||
test $x1 {}
|
||||
-- OUTPUT --
|
||||
Vertex: test[heyhey]
|
||||
8
lang/interpret_test/TestAstFunc2/lambda-no-args1.txtar
Normal file
8
lang/interpret_test/TestAstFunc2/lambda-no-args1.txtar
Normal file
@@ -0,0 +1,8 @@
|
||||
-- main.mcl --
|
||||
$hey = func() {
|
||||
"hello"
|
||||
}
|
||||
|
||||
test $hey() {}
|
||||
-- OUTPUT --
|
||||
Vertex: test[hello]
|
||||
13
lang/interpret_test/TestAstFunc2/lambda-one-arg.txtar
Normal file
13
lang/interpret_test/TestAstFunc2/lambda-one-arg.txtar
Normal file
@@ -0,0 +1,13 @@
|
||||
-- main.mcl --
|
||||
import "fmt"
|
||||
|
||||
# function statement
|
||||
$stradd = func($x) {
|
||||
$x + "there"
|
||||
}
|
||||
|
||||
$x1 = $stradd("hey")
|
||||
|
||||
test $x1 {}
|
||||
-- OUTPUT --
|
||||
Vertex: test[heythere]
|
||||
6
lang/interpret_test/TestAstFunc2/lambda-one-func.txtar
Normal file
6
lang/interpret_test/TestAstFunc2/lambda-one-func.txtar
Normal file
@@ -0,0 +1,6 @@
|
||||
-- main.mcl --
|
||||
import "fmt"
|
||||
|
||||
test fmt.printf("hello: %d", 42) {}
|
||||
-- OUTPUT --
|
||||
Vertex: test[hello: 42]
|
||||
13
lang/interpret_test/TestAstFunc2/lambda-unused-arg.txtar
Normal file
13
lang/interpret_test/TestAstFunc2/lambda-unused-arg.txtar
Normal file
@@ -0,0 +1,13 @@
|
||||
-- main.mcl --
|
||||
import "fmt"
|
||||
|
||||
# function statement
|
||||
$stradd = func($x) {
|
||||
"nothing"
|
||||
}
|
||||
|
||||
$x1 = $stradd("hey")
|
||||
|
||||
test $x1 {}
|
||||
-- OUTPUT --
|
||||
Vertex: test[nothing]
|
||||
10
lang/interpret_test/TestAstFunc2/map-ignore-arg.txtar
Normal file
10
lang/interpret_test/TestAstFunc2/map-ignore-arg.txtar
Normal file
@@ -0,0 +1,10 @@
|
||||
-- main.mcl --
|
||||
import "iter"
|
||||
|
||||
$fn = func($x) { # ignore arg
|
||||
"hey"
|
||||
}
|
||||
|
||||
test iter.map([1, 2, 3,], $fn) {}
|
||||
-- OUTPUT --
|
||||
Vertex: test[hey]
|
||||
13
lang/interpret_test/TestAstFunc2/map-numbered.txtar
Normal file
13
lang/interpret_test/TestAstFunc2/map-numbered.txtar
Normal file
@@ -0,0 +1,13 @@
|
||||
-- main.mcl --
|
||||
import "fmt"
|
||||
import "iter"
|
||||
|
||||
$fn = func($x) {
|
||||
fmt.printf("hey%d", $x)
|
||||
}
|
||||
|
||||
test iter.map([1, 2, 3,], $fn) {}
|
||||
-- OUTPUT --
|
||||
Vertex: test[hey1]
|
||||
Vertex: test[hey2]
|
||||
Vertex: test[hey3]
|
||||
2
lang/interpret_test/TestAstFunc2/res0.txtar
Normal file
2
lang/interpret_test/TestAstFunc2/res0.txtar
Normal file
@@ -0,0 +1,2 @@
|
||||
-- main.mcl --
|
||||
-- OUTPUT --
|
||||
6
lang/interpret_test/TestAstFunc2/res1.txtar
Normal file
6
lang/interpret_test/TestAstFunc2/res1.txtar
Normal file
@@ -0,0 +1,6 @@
|
||||
-- main.mcl --
|
||||
test "t1" {
|
||||
stringptr => 42, # int, not str
|
||||
}
|
||||
-- OUTPUT --
|
||||
# err: errUnify: can't unify, invariant illogicality with equals: base kind does not match (Int != Str)
|
||||
8
lang/interpret_test/TestAstFunc2/res2.txtar
Normal file
8
lang/interpret_test/TestAstFunc2/res2.txtar
Normal file
@@ -0,0 +1,8 @@
|
||||
-- main.mcl --
|
||||
test "t1" {
|
||||
int64ptr => 42,
|
||||
stringptr => "okay cool",
|
||||
int8ptrptrptr => 127, # super nested
|
||||
}
|
||||
-- OUTPUT --
|
||||
Vertex: test[t1]
|
||||
13
lang/interpret_test/TestAstFunc2/res3.txtar
Normal file
13
lang/interpret_test/TestAstFunc2/res3.txtar
Normal file
@@ -0,0 +1,13 @@
|
||||
-- main.mcl --
|
||||
test "t1" {
|
||||
int64ptr => 42,
|
||||
}
|
||||
test "t2" {
|
||||
int64ptr => 13,
|
||||
}
|
||||
|
||||
Test["t1"].hello -> Test["t2"].stringptr # send/recv
|
||||
-- OUTPUT --
|
||||
Edge: test[t1] -> test[t2] # test[t1] -> test[t2]
|
||||
Vertex: test[t1]
|
||||
Vertex: test[t2]
|
||||
37
lang/interpret_test/TestAstFunc2/res4.txtar
Normal file
37
lang/interpret_test/TestAstFunc2/res4.txtar
Normal file
@@ -0,0 +1,37 @@
|
||||
-- main.mcl --
|
||||
test "t1" {
|
||||
stringptr => "this is meta",
|
||||
|
||||
#Meta => struct{
|
||||
# noop => false,
|
||||
# retry => -1,
|
||||
# retryreset => false,
|
||||
# delay => 0,
|
||||
# poll => 5,
|
||||
# limit => 4.2,
|
||||
# burst => 3,
|
||||
# reset => false,
|
||||
# sema => ["foo:1", "bar:3",],
|
||||
# rewatch => false,
|
||||
# realize => true,
|
||||
# reverse => true,
|
||||
# autoedge => true,
|
||||
# autogroup => true,
|
||||
#},
|
||||
Meta:noop => false,
|
||||
Meta:retry => -1,
|
||||
Meta:retryreset => false,
|
||||
Meta:delay => 0,
|
||||
Meta:poll => 5,
|
||||
Meta:limit => 4.2,
|
||||
Meta:burst => 3,
|
||||
Meta:reset => false,
|
||||
Meta:sema => ["foo:1", "bar:3",],
|
||||
Meta:rewatch => false,
|
||||
Meta:realize => true,
|
||||
Meta:reverse => true,
|
||||
Meta:autoedge => true,
|
||||
Meta:autogroup => true,
|
||||
}
|
||||
-- OUTPUT --
|
||||
Vertex: test[t1]
|
||||
8
lang/interpret_test/TestAstFunc2/template-1.txtar
Normal file
8
lang/interpret_test/TestAstFunc2/template-1.txtar
Normal file
@@ -0,0 +1,8 @@
|
||||
-- main.mcl --
|
||||
$v = 42
|
||||
$x = template("hello", $v) # redirect var for harder unification
|
||||
test $x {
|
||||
#anotherstr => $x,
|
||||
}
|
||||
-- OUTPUT --
|
||||
Vertex: test[hello]
|
||||
78
lang/interpret_test/TestAstFunc2/very-complex-example.txtar
Normal file
78
lang/interpret_test/TestAstFunc2/very-complex-example.txtar
Normal file
@@ -0,0 +1,78 @@
|
||||
-- main.mcl --
|
||||
# This code should fail during type-checking.
|
||||
#
|
||||
# $id1 and $id2 are both polymorphic functions, which can be specialized to a
|
||||
# different monomorphic type at every use site. In simple code, this
|
||||
# specialization happens when the polymorphic function is called, but in more
|
||||
# complex code, the specialization happens earlier, when the polymorphic
|
||||
# function is passed as an argument to higher-order functions such as $generate
|
||||
# and iter.map.
|
||||
#
|
||||
# In:
|
||||
#
|
||||
# $id1 = func($x str) { # definition site
|
||||
# $x
|
||||
# }
|
||||
# $id2 = func($x str) {
|
||||
# $x + $x
|
||||
# }
|
||||
#
|
||||
# $generate = func($idn) {
|
||||
# $idn("foo") # 1 call site, 2 calls
|
||||
# }
|
||||
#
|
||||
# $foo = iter.map([$id1, $id2,], $generate)
|
||||
#
|
||||
# $generate is specialized to `func(func(str) str) str`, and $id1 and $id2 are
|
||||
# specialized to `func(str) str`.
|
||||
#
|
||||
# In:
|
||||
#
|
||||
# $id1 = func($x) { # definition site
|
||||
# $x
|
||||
# }
|
||||
# $id2 = func($x) {
|
||||
# $x + $x
|
||||
# }
|
||||
#
|
||||
# $generate = func($idn) {
|
||||
# fmt.printf("%s %d",
|
||||
# $idn("foo"), # 1 call site, 2 calls
|
||||
# $idn(42)
|
||||
# )
|
||||
# }
|
||||
#
|
||||
# $foo = iter.map([$id1, $id2,], $generate)
|
||||
#
|
||||
# $idn cannot be given a monomorphic type, since it is used both as a
|
||||
# `func(str) str` and as a `func(int) int`. Therefore, $generate cannot be
|
||||
# given a monomorphic type either, and neither can the call to iter.map.
|
||||
|
||||
import "fmt"
|
||||
import "iter"
|
||||
|
||||
# function expression
|
||||
$id1 = func($x) { # definition site
|
||||
$x
|
||||
}
|
||||
$id2 = func($x) {
|
||||
$x + $x
|
||||
}
|
||||
|
||||
#$str = $id1("foo")
|
||||
#$int = $id1(42)
|
||||
|
||||
$generate = func($idn) {
|
||||
fmt.printf("%s %d",
|
||||
$idn("foo"), # 1 call site, 2 calls
|
||||
$idn(42)
|
||||
)
|
||||
}
|
||||
|
||||
# this code should be rejected during type unification
|
||||
$foo = iter.map([$id1, $id2,], $generate)
|
||||
|
||||
#test $foo[0] {}
|
||||
test listlookup($foo, 0, "fail") {} # TODO: add syntactic sugar for listlookup
|
||||
-- OUTPUT --
|
||||
# err: errUnify: can't unify, invariant illogicality with equals: base kind does not match (Str != Int)
|
||||
Reference in New Issue
Block a user