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:
James Shubin
2023-09-25 16:16:33 -04:00
parent d4b1e8f1be
commit 8d63b98212
74 changed files with 1001 additions and 686 deletions

View 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]

View File

@@ -1,5 +1,6 @@
-- main.mcl --
$x1 = "bad1"
$x2 = "also bad"
include defs.foo
import "defs.mcl" # out of order for fun

View 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]

View 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?]

View File

@@ -0,0 +1,11 @@
-- main.mcl --
# function statement
func stradd($x) {
$x + $x
}
$x1 = stradd("hey")
test $x1 {}
-- OUTPUT --
Vertex: test[heyhey]

View File

@@ -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]

View 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]

View 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]

View File

@@ -0,0 +1,13 @@
-- main.mcl --
import "fmt"
# function statement
func stradd($x) {
"nothing"
}
$x1 = stradd("hey")
test $x1 {}
-- OUTPUT --
Vertex: test[nothing]

View File

@@ -0,0 +1,9 @@
-- main.mcl --
# function statement
func identity($x) {
$x
}
test identity("hey") {}
-- OUTPUT --
Vertex: test[hey]

View File

@@ -0,0 +1,10 @@
-- main.mcl --
$out1 = if true {
"hello"
} else {
"world"
}
test $out1 {}
-- OUTPUT --
Vertex: test[hello]

View 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]

View File

@@ -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

View 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]

View File

@@ -0,0 +1,8 @@
-- main.mcl --
$hey = func() {
"hello"
}
test $hey() {}
-- OUTPUT --
Vertex: test[hello]

View 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]

View File

@@ -0,0 +1,6 @@
-- main.mcl --
import "fmt"
test fmt.printf("hello: %d", 42) {}
-- OUTPUT --
Vertex: test[hello: 42]

View File

@@ -0,0 +1,13 @@
-- main.mcl --
import "fmt"
# function statement
$stradd = func($x) {
"nothing"
}
$x1 = $stradd("hey")
test $x1 {}
-- OUTPUT --
Vertex: test[nothing]

View 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]

View 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]

View File

@@ -0,0 +1,2 @@
-- main.mcl --
-- OUTPUT --

View 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)

View File

@@ -0,0 +1,8 @@
-- main.mcl --
test "t1" {
int64ptr => 42,
stringptr => "okay cool",
int8ptrptrptr => 127, # super nested
}
-- OUTPUT --
Vertex: test[t1]

View 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]

View 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]

View 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]

View 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)