lang: Improve graph shape with speculative execution

Most of the time, we don't need to have a dynamic call sub graph, since
the actual function call could be represented statically as it
originally was before lambda functions were implemented. Simplifying the
graph shape has important performance benefits in terms of both keep the
graph smaller (memory, etc) and in avoiding the need to run transactions
at runtime (speed) to reshape the graph.

Co-authored-by: Samuel Gélineau <gelisam@gmail.com>
This commit is contained in:
James Shubin
2025-03-17 02:31:01 -04:00
parent 9c9f2f558a
commit 37bb67dffd
139 changed files with 1871 additions and 262 deletions

View File

@@ -21,15 +21,21 @@ $out2 = $fn2()
test "${out1}" {}
test "${out2}" {}
-- OUTPUT --
Edge: FuncValue -> call # fn
Edge: FuncValue -> call # fn
Edge: call -> call # fn
Edge: call -> call # fn
Edge: FuncValue -> if # a
Edge: FuncValue -> if # a
Edge: FuncValue -> if # b
Edge: FuncValue -> if # b
Edge: const: bool(false) -> if # c
Edge: const: bool(true) -> if # c
Edge: if -> call # fn
Edge: if -> call # fn
Vertex: FuncValue
Vertex: FuncValue
Vertex: FuncValue
Vertex: FuncValue
Vertex: call
Vertex: call
Vertex: call
Vertex: call
Vertex: const: bool(false)
Vertex: const: bool(true)
Vertex: if
Vertex: if

View File

@@ -6,17 +6,14 @@ class c1($b) {
test [fmt.printf("len is: %d", len($b)),] {} # len is 4
}
-- OUTPUT --
Edge: FuncValue -> call # fn
Edge: FuncValue -> call # fn
Edge: call -> composite: []str # 0
Edge: composite: []int -> len # 0
Edge: const: int(-37) -> composite: []int # 3
Edge: const: int(0) -> composite: []int # 2
Edge: const: int(13) -> composite: []int # 0
Edge: const: int(42) -> composite: []int # 1
Vertex: FuncValue
Vertex: FuncValue
Vertex: call
Vertex: call
Edge: const: str("len is: %d") -> printf: func(format str, a int) str # format
Edge: len -> printf: func(format str, a int) str # a
Edge: printf: func(format str, a int) str -> composite: []str # 0
Vertex: composite: []int
Vertex: composite: []str
Vertex: const: int(-37)
@@ -24,3 +21,5 @@ Vertex: const: int(0)
Vertex: const: int(13)
Vertex: const: int(42)
Vertex: const: str("len is: %d")
Vertex: len
Vertex: printf: func(format str, a int) str

View File

@@ -15,36 +15,42 @@ include foo(1)
include foo(2)
include foo(3)
-- OUTPUT --
Edge: FuncValue -> call # fn
Edge: FuncValue -> call # fn
Edge: FuncValue -> call # fn
Edge: FuncValue -> call # fn
Edge: FuncValue -> call # fn
Edge: FuncValue -> call # fn
Edge: FuncValue -> call # fn
Edge: FuncValue -> call # fn
Edge: FuncValue -> call # fn
Edge: call -> composite: []str # 0
Edge: call -> composite: []str # 0
Edge: call -> composite: []str # 0
Vertex: FuncValue
Vertex: FuncValue
Vertex: FuncValue
Vertex: FuncValue
Vertex: FuncValue
Vertex: FuncValue
Vertex: FuncValue
Vertex: FuncValue
Vertex: FuncValue
Vertex: call
Vertex: call
Vertex: call
Vertex: call
Vertex: call
Vertex: call
Vertex: call
Vertex: call
Vertex: call
Edge: _operator -> _operator # a
Edge: _operator -> _operator # a
Edge: _operator -> _operator # a
Edge: _operator -> printf: func(format str, a int, b int) str # b
Edge: _operator -> printf: func(format str, a int, b int) str # b
Edge: _operator -> printf: func(format str, a int, b int) str # b
Edge: const: int(1) -> printf: func(format str, a int, b int) str # a
Edge: const: int(13) -> _operator # b
Edge: const: int(13) -> _operator # b
Edge: const: int(13) -> _operator # b
Edge: const: int(2) -> printf: func(format str, a int, b int) str # a
Edge: const: int(3) -> printf: func(format str, a int, b int) str # a
Edge: const: int(4) -> _operator # b
Edge: const: int(4) -> _operator # b
Edge: const: int(4) -> _operator # b
Edge: const: int(42) -> _operator # a
Edge: const: int(42) -> _operator # a
Edge: const: int(42) -> _operator # a
Edge: const: str("+") -> _operator # op
Edge: const: str("+") -> _operator # op
Edge: const: str("+") -> _operator # op
Edge: const: str("+") -> _operator # op
Edge: const: str("+") -> _operator # op
Edge: const: str("+") -> _operator # op
Edge: const: str("test-%d-%d") -> printf: func(format str, a int, b int) str # format
Edge: const: str("test-%d-%d") -> printf: func(format str, a int, b int) str # format
Edge: const: str("test-%d-%d") -> printf: func(format str, a int, b int) str # format
Edge: printf: func(format str, a int, b int) str -> composite: []str # 0
Edge: printf: func(format str, a int, b int) str -> composite: []str # 0
Edge: printf: func(format str, a int, b int) str -> composite: []str # 0
Vertex: _operator
Vertex: _operator
Vertex: _operator
Vertex: _operator
Vertex: _operator
Vertex: _operator
Vertex: composite: []str
Vertex: composite: []str
Vertex: composite: []str
@@ -65,3 +71,6 @@ Vertex: const: str("+")
Vertex: const: str("test-%d-%d")
Vertex: const: str("test-%d-%d")
Vertex: const: str("test-%d-%d")
Vertex: printf: func(format str, a int, b int) str
Vertex: printf: func(format str, a int, b int) str
Vertex: printf: func(format str, a int, b int) str

View File

@@ -17,9 +17,7 @@ pkg "cowsay" {
state => "newest",
}
-- OUTPUT --
Edge: FuncValue -> call # fn
Vertex: FuncValue
Vertex: call
Edge: const: str("hello world") -> printf: func(format str) str # format
Vertex: const: str("/tmp/foo")
Vertex: const: str("/tmp/foo")
Vertex: const: str("cowsay")
@@ -28,3 +26,4 @@ Vertex: const: str("hello world")
Vertex: const: str("hello world")
Vertex: const: str("installed")
Vertex: const: str("newest")
Vertex: printf: func(format str) str

View File

@@ -10,10 +10,17 @@ $out2 = $prefixer("b")
test "${out1}" {} # helloa
test "${out2}" {} # hellob
-- OUTPUT --
Edge: FuncValue -> call # fn
Edge: FuncValue -> call # fn
Vertex: FuncValue
Vertex: call
Vertex: call
Edge: const: str("+") -> _operator # op
Edge: const: str("+") -> _operator # op
Edge: const: str("a") -> _operator # b
Edge: const: str("b") -> _operator # b
Edge: const: str("hello") -> _operator # a
Edge: const: str("hello") -> _operator # a
Vertex: _operator
Vertex: _operator
Vertex: const: str("+")
Vertex: const: str("+")
Vertex: const: str("a")
Vertex: const: str("b")
Vertex: const: str("hello")
Vertex: const: str("hello")

View File

@@ -4,9 +4,10 @@ test "t" {
int64ptr => 42 + 13,
}
-- OUTPUT --
Edge: FuncValue -> call # fn
Vertex: FuncValue
Vertex: call
Edge: const: int(13) -> _operator # b
Edge: const: int(42) -> _operator # a
Edge: const: str("+") -> _operator # op
Vertex: _operator
Vertex: const: int(13)
Vertex: const: int(42)
Vertex: const: str("+")

View File

@@ -4,12 +4,14 @@ test "t" {
int64ptr => 42 + 13 - 99,
}
-- OUTPUT --
Edge: FuncValue -> call # fn
Edge: FuncValue -> call # fn
Vertex: FuncValue
Vertex: FuncValue
Vertex: call
Vertex: call
Edge: _operator -> _operator # a
Edge: const: int(13) -> _operator # b
Edge: const: int(42) -> _operator # a
Edge: const: int(99) -> _operator # b
Edge: const: str("+") -> _operator # op
Edge: const: str("-") -> _operator # op
Vertex: _operator
Vertex: _operator
Vertex: const: int(13)
Vertex: const: int(42)
Vertex: const: int(99)

View File

@@ -8,9 +8,10 @@ if true {
}
$i = 13
-- OUTPUT --
Edge: FuncValue -> call # fn
Vertex: FuncValue
Vertex: call
Edge: const: int(13) -> _operator # b
Edge: const: int(42) -> _operator # a
Edge: const: str("+") -> _operator # op
Vertex: _operator
Vertex: const: bool(true)
Vertex: const: int(13)
Vertex: const: int(42)

View File

@@ -7,9 +7,9 @@ test "greeting" {
anotherstr => fmt.printf("hello: %s", $s),
}
-- OUTPUT --
Edge: FuncValue -> call # fn
Vertex: FuncValue
Vertex: call
Edge: const: str("hello: %s") -> printf: func(format str, a str) str # format
Edge: const: str("world") -> printf: func(format str, a str) str # a
Vertex: const: str("greeting")
Vertex: const: str("hello: %s")
Vertex: const: str("world")
Vertex: printf: func(format str, a str) str

View File

@@ -16,13 +16,11 @@ class xclass {
}
}
-- OUTPUT --
Edge: FuncValue -> call # fn
Edge: call -> if # c
Edge: const: str("bbb") -> if # a
Edge: const: str("ccc") -> if # b
Vertex: FuncValue
Vertex: call
Edge: os.is_family_debian -> if # c
Vertex: const: str("bbb")
Vertex: const: str("ccc")
Vertex: const: str("hello")
Vertex: if
Vertex: os.is_family_debian

View File

@@ -15,13 +15,11 @@ class xclass {
}
}
-- OUTPUT --
Edge: FuncValue -> call # fn
Edge: call -> if # c
Edge: const: str("bbb") -> if # a
Edge: const: str("ccc") -> if # b
Vertex: FuncValue
Vertex: call
Edge: os.is_family_debian -> if # c
Vertex: const: str("bbb")
Vertex: const: str("ccc")
Vertex: const: str("hello")
Vertex: if
Vertex: os.is_family_debian

View File

@@ -12,9 +12,27 @@ $out2 = $prefixer($out1)
test "${out1}" {}
test "${out2}" {}
-- OUTPUT --
Edge: FuncValue -> call # fn
Edge: FuncValue -> call # fn
Vertex: FuncValue
Vertex: call
Vertex: call
Edge: _operator -> _operator # a
Edge: _operator -> _operator # a
Edge: _operator -> _operator # b
Edge: const: str("+") -> _operator # op
Edge: const: str("+") -> _operator # op
Edge: const: str("+") -> _operator # op
Edge: const: str("+") -> _operator # op
Edge: const: str(":") -> _operator # b
Edge: const: str(":") -> _operator # b
Edge: const: str("hello") -> _operator # a
Edge: const: str("hello") -> _operator # a
Edge: const: str("world") -> _operator # b
Vertex: _operator
Vertex: _operator
Vertex: _operator
Vertex: _operator
Vertex: const: str("+")
Vertex: const: str("+")
Vertex: const: str("+")
Vertex: const: str("+")
Vertex: const: str(":")
Vertex: const: str(":")
Vertex: const: str("hello")
Vertex: const: str("world")

View File

@@ -62,27 +62,29 @@ $ex1 = $example1.name
$name = "i am github.com/purpleidea/mgmt-example2/ and i contain: " + $ex1
-- OUTPUT --
Edge: FuncValue -> call # fn
Edge: FuncValue -> call # fn
Edge: FuncValue -> call # fn
Edge: FuncValue -> call # fn
Edge: FuncValue -> call # fn
Edge: FuncValue -> call # fn
Edge: FuncValue -> call # fn
Vertex: FuncValue
Vertex: FuncValue
Vertex: FuncValue
Vertex: FuncValue
Vertex: FuncValue
Vertex: FuncValue
Vertex: FuncValue
Vertex: call
Vertex: call
Vertex: call
Vertex: call
Vertex: call
Vertex: call
Vertex: call
Edge: _operator -> printf: func(format str, a int) str # a
Edge: _operator -> printf: func(format str, a str) str # a
Edge: _operator -> printf: func(format str, a str, b str) str # a
Edge: _operator -> printf: func(format str, a str, b str) str # b
Edge: const: int(3) -> _operator # b
Edge: const: int(42) -> _operator # a
Edge: const: str("+") -> _operator # op
Edge: const: str("+") -> _operator # op
Edge: const: str("+") -> _operator # op
Edge: const: str("+") -> _operator # op
Edge: const: str("i am github.com/purpleidea/mgmt-example1/ and i contain: ") -> _operator # a
Edge: const: str("i am github.com/purpleidea/mgmt-example1/ and i contain: ") -> _operator # a
Edge: const: str("i imported local: %s") -> printf: func(format str, a str) str # format
Edge: const: str("i imported remote: %s and %s") -> printf: func(format str, a str, b str) str # format
Edge: const: str("the answer is: %d") -> printf: func(format str, a int) str # format
Edge: const: str("this is module mod1 which contains: ") -> _operator # a
Edge: const: str("this is the nested git module mod1") -> _operator # b
Edge: const: str("this is the nested git module mod1") -> _operator # b
Edge: const: str("this is the nested local module mod1") -> _operator # b
Vertex: _operator
Vertex: _operator
Vertex: _operator
Vertex: _operator
Vertex: const: int(3)
Vertex: const: int(42)
Vertex: const: str("+")
@@ -101,3 +103,6 @@ Vertex: const: str("this is module mod1 which contains: ")
Vertex: const: str("this is the nested git module mod1")
Vertex: const: str("this is the nested git module mod1")
Vertex: const: str("this is the nested local module mod1")
Vertex: printf: func(format str, a int) str
Vertex: printf: func(format str, a str) str
Vertex: printf: func(format str, a str, b str) str

View File

@@ -10,22 +10,16 @@ class c1($a, $b) {
}
}
-- OUTPUT --
Edge: FuncValue -> call # fn
Edge: FuncValue -> call # fn
Edge: FuncValue -> call # fn
Edge: FuncValue -> call # fn
Edge: composite: []int -> len # 0
Edge: const: int(-37) -> composite: []int # 3
Edge: const: int(0) -> composite: []int # 2
Edge: const: int(13) -> composite: []int # 0
Edge: const: int(42) -> composite: []int # 1
Vertex: FuncValue
Vertex: FuncValue
Vertex: FuncValue
Vertex: FuncValue
Vertex: call
Vertex: call
Vertex: call
Vertex: call
Edge: const: str("hello") -> len # 0
Edge: const: str("len is: %d") -> printf: func(format str, a int) str # format
Edge: const: str("len is: %d") -> printf: func(format str, a int) str # format
Edge: len -> printf: func(format str, a int) str # a
Edge: len -> printf: func(format str, a int) str # a
Vertex: composite: []int
Vertex: const: int(-37)
Vertex: const: int(0)
@@ -36,3 +30,7 @@ Vertex: const: str("len is: %d")
Vertex: const: str("len is: %d")
Vertex: const: str("t1")
Vertex: const: str("t2")
Vertex: len
Vertex: len
Vertex: printf: func(format str, a int) str
Vertex: printf: func(format str, a int) str

View File

@@ -60,27 +60,29 @@ $ex1 = $example1.name
$name = "i am github.com/purpleidea/mgmt-example2/ and i contain: " + $ex1
-- OUTPUT --
Edge: FuncValue -> call # fn
Edge: FuncValue -> call # fn
Edge: FuncValue -> call # fn
Edge: FuncValue -> call # fn
Edge: FuncValue -> call # fn
Edge: FuncValue -> call # fn
Edge: FuncValue -> call # fn
Vertex: FuncValue
Vertex: FuncValue
Vertex: FuncValue
Vertex: FuncValue
Vertex: FuncValue
Vertex: FuncValue
Vertex: FuncValue
Vertex: call
Vertex: call
Vertex: call
Vertex: call
Vertex: call
Vertex: call
Vertex: call
Edge: _operator -> printf: func(format str, a int) str # a
Edge: _operator -> printf: func(format str, a str) str # a
Edge: _operator -> printf: func(format str, a str, b str) str # a
Edge: _operator -> printf: func(format str, a str, b str) str # b
Edge: const: int(3) -> _operator # b
Edge: const: int(42) -> _operator # a
Edge: const: str("+") -> _operator # op
Edge: const: str("+") -> _operator # op
Edge: const: str("+") -> _operator # op
Edge: const: str("+") -> _operator # op
Edge: const: str("i am github.com/purpleidea/mgmt-example1/ and i contain: ") -> _operator # a
Edge: const: str("i am github.com/purpleidea/mgmt-example1/ and i contain: ") -> _operator # a
Edge: const: str("i imported local: %s") -> printf: func(format str, a str) str # format
Edge: const: str("i imported remote: %s and %s") -> printf: func(format str, a str, b str) str # format
Edge: const: str("the answer is: %d") -> printf: func(format str, a int) str # format
Edge: const: str("this is module mod1 which contains: ") -> _operator # a
Edge: const: str("this is the nested git module mod1") -> _operator # b
Edge: const: str("this is the nested git module mod1") -> _operator # b
Edge: const: str("this is the nested local module mod1") -> _operator # b
Vertex: _operator
Vertex: _operator
Vertex: _operator
Vertex: _operator
Vertex: const: int(3)
Vertex: const: int(42)
Vertex: const: str("+")
@@ -99,3 +101,6 @@ Vertex: const: str("this is module mod1 which contains: ")
Vertex: const: str("this is the nested git module mod1")
Vertex: const: str("this is the nested git module mod1")
Vertex: const: str("this is the nested local module mod1")
Vertex: printf: func(format str, a int) str
Vertex: printf: func(format str, a str) str
Vertex: printf: func(format str, a str, b str) str

View File

@@ -12,7 +12,5 @@ $out = $fn()
test "${out}" {}
-- OUTPUT --
Edge: FuncValue -> call # fn
Edge: call -> call # fn
Vertex: FuncValue
Vertex: call
Vertex: call

View File

@@ -11,7 +11,5 @@ $out = $fn()
test "${out}" {}
-- OUTPUT --
Edge: FuncValue -> call # fn
Edge: call -> call # fn
Vertex: FuncValue
Vertex: call
Vertex: call

View File

@@ -0,0 +1,24 @@
-- main.mcl --
# this was originally: optimized-higher-order-function.txtar
import "fmt"
func apply($f, $x) {
$f($x)
}
$add1 = func($x) {
$x + 1
}
$z = apply($add1, 1)
test [fmt.printf("%d", $z),] {}
-- OUTPUT --
Edge: FuncValue -> call # fn
Edge: call -> printf: func(format str, a int) str # a
Edge: const: str("%d") -> printf: func(format str, a int) str # format
Edge: printf: func(format str, a int) str -> composite: []str # 0
Vertex: FuncValue
Vertex: call
Vertex: composite: []str
Vertex: const: int(1)
Vertex: const: str("%d")
Vertex: printf: func(format str, a int) str

View File

@@ -0,0 +1,12 @@
-- main.mcl --
print ["a" + "b",] {}
-- OUTPUT --
Edge: _operator -> composite: []str # 0
Edge: const: str("+") -> _operator # op
Edge: const: str("a") -> _operator # a
Edge: const: str("b") -> _operator # b
Vertex: _operator
Vertex: composite: []str
Vertex: const: str("+")
Vertex: const: str("a")
Vertex: const: str("b")

View File

@@ -0,0 +1,16 @@
-- main.mcl --
$lambda = func($x) {
$x + "!"
}
test [$lambda("hello"),] {}
-- OUTPUT --
Edge: _operator -> composite: []str # 0
Edge: const: str("!") -> _operator # b
Edge: const: str("+") -> _operator # op
Edge: const: str("hello") -> _operator # a
Vertex: _operator
Vertex: composite: []str
Vertex: const: str("!")
Vertex: const: str("+")
Vertex: const: str("hello")

View File

@@ -0,0 +1,25 @@
-- main.mcl --
$lambda1 = func($x) {
$x + "!"
}
$lambda2 = func($x) {
$x + "?"
}
$lambda = if true { # must be a const, otherwise this is a dynamic graph
$lambda1
} else {
$lambda2
}
test [$lambda("hello"),] {}
-- OUTPUT --
Edge: _operator -> composite: []str # 0
Edge: const: str("!") -> _operator # b
Edge: const: str("+") -> _operator # op
Edge: const: str("hello") -> _operator # a
Vertex: _operator
Vertex: composite: []str
Vertex: const: str("!")
Vertex: const: str("+")
Vertex: const: str("hello")

View File

@@ -0,0 +1,25 @@
-- main.mcl --
$lambda1 = func($x) {
$x + "!"
}
$lambda2 = func($x) {
$x + "?"
}
$lambda = if 10 > 0 { # must be a const, otherwise this is a dynamic graph
$lambda1
} else {
$lambda2
}
test [$lambda("hello"),] {}
-- OUTPUT --
Edge: _operator -> composite: []str # 0
Edge: const: str("!") -> _operator # b
Edge: const: str("+") -> _operator # op
Edge: const: str("hello") -> _operator # a
Vertex: _operator
Vertex: composite: []str
Vertex: const: str("!")
Vertex: const: str("+")
Vertex: const: str("hello")

View File

@@ -0,0 +1,34 @@
-- main.mcl --
import "datetime"
import "fmt"
$lambda1 = func($x) {
$x + "!"
}
$lambda2 = func($x) {
$x + "?"
}
$lambda = if 10 > 0 { # must be a const, otherwise this is a dynamic graph
$lambda1
} else {
$lambda2
}
$s = fmt.printf("%d", datetime.now())
test [$lambda($s),] {}
-- OUTPUT --
Edge: _operator -> composite: []str # 0
Edge: const: str("!") -> _operator # b
Edge: const: str("%d") -> printf: func(format str, a int) str # format
Edge: const: str("+") -> _operator # op
Edge: now -> printf: func(format str, a int) str # a
Edge: printf: func(format str, a int) str -> _operator # a
Vertex: _operator
Vertex: composite: []str
Vertex: const: str("!")
Vertex: const: str("%d")
Vertex: const: str("+")
Vertex: now
Vertex: printf: func(format str, a int) str

View File

@@ -0,0 +1,33 @@
-- main.mcl --
import "iter"
import "golang"
$fn = func($x) { # notable because concrete type is fn(t1) t2, where t1 != t2
len($x)
}
$in1 = ["a", "bb", "ccc",]
$out1 = iter.map($in1, $fn)
$s = golang.template("out1: {{ . }}", $out1)
test [$s,] {}
-- OUTPUT --
Edge: FuncValue -> map # function
Edge: composite: []str -> map # inputs
Edge: const: str("a") -> composite: []str # 0
Edge: const: str("bb") -> composite: []str # 1
Edge: const: str("ccc") -> composite: []str # 2
Edge: const: str("out1: {{ . }}") -> template # template
Edge: map -> template # vars
Edge: template -> composite: []str # 0
Vertex: FuncValue
Vertex: composite: []str
Vertex: composite: []str
Vertex: const: str("a")
Vertex: const: str("bb")
Vertex: const: str("ccc")
Vertex: const: str("out1: {{ . }}")
Vertex: map
Vertex: template

View File

@@ -0,0 +1,57 @@
-- main.mcl --
import "datetime"
import "iter"
import "golang"
$lambda1 = func($x) {
$x + "!"
}
$lambda2 = func($x) {
$x + "?"
}
$lambda = if 10 > 0 { # must be a const, otherwise this is a dynamic graph
$lambda1
} else {
$lambda2
}
$fn = func($x) { # notable because concrete type is fn(t1) t2, where t1 != t2
len($x)
}
$in1 = ["a", "bb", "ccc", "dddd", "eeeee",]
$out1 = iter.map($in1, $fn)
$s = golang.template("out1: {{ . }}", $out1)
test [$lambda($s),] {}
-- OUTPUT --
Edge: FuncValue -> map # function
Edge: _operator -> composite: []str # 0
Edge: composite: []str -> map # inputs
Edge: const: str("!") -> _operator # b
Edge: const: str("+") -> _operator # op
Edge: const: str("a") -> composite: []str # 0
Edge: const: str("bb") -> composite: []str # 1
Edge: const: str("ccc") -> composite: []str # 2
Edge: const: str("dddd") -> composite: []str # 3
Edge: const: str("eeeee") -> composite: []str # 4
Edge: const: str("out1: {{ . }}") -> template # template
Edge: map -> template # vars
Edge: template -> _operator # a
Vertex: FuncValue
Vertex: _operator
Vertex: composite: []str
Vertex: composite: []str
Vertex: const: str("!")
Vertex: const: str("+")
Vertex: const: str("a")
Vertex: const: str("bb")
Vertex: const: str("ccc")
Vertex: const: str("dddd")
Vertex: const: str("eeeee")
Vertex: const: str("out1: {{ . }}")
Vertex: map
Vertex: template

View File

@@ -0,0 +1,38 @@
-- main.mcl --
$gt = func($one, $two) {
$one > $two
}
$lambda1 = func($x) {
$x + "!"
}
$lambda2 = func($x) {
$x + "?"
}
$lambda = if $gt(10, 0) { # must be a const, otherwise this is a dynamic graph
$lambda1
} else {
$lambda2
}
test [$lambda("hello"),] {}
-- OUTPUT --
Edge: FuncValue -> if # a
Edge: FuncValue -> if # b
Edge: _operator -> if # c
Edge: call -> composite: []str # 0
Edge: const: int(0) -> _operator # b
Edge: const: int(10) -> _operator # a
Edge: const: str(">") -> _operator # op
Edge: if -> call # fn
Vertex: FuncValue
Vertex: FuncValue
Vertex: _operator
Vertex: call
Vertex: composite: []str
Vertex: const: int(0)
Vertex: const: int(10)
Vertex: const: str(">")
Vertex: const: str("hello")
Vertex: if

View File

@@ -7,6 +7,4 @@ $out1 = answer()
test "${out1}" {}
-- OUTPUT --
Edge: FuncValue -> call # fn
Vertex: FuncValue
Vertex: call
Vertex: const: str("the answer is 42")

View File

@@ -8,15 +8,12 @@ $out2 = answer()
test [$out1 + $out2,] {}
-- OUTPUT --
Edge: FuncValue -> call # fn
Edge: FuncValue -> call # fn
Edge: FuncValue -> call # fn
Edge: call -> composite: []str # 0
Vertex: FuncValue
Vertex: FuncValue
Vertex: FuncValue
Vertex: call
Vertex: call
Vertex: call
Edge: _operator -> composite: []str # 0
Edge: const: str("+") -> _operator # op
Edge: const: str("the answer is 42") -> _operator # a
Edge: const: str("the answer is 42") -> _operator # b
Vertex: _operator
Vertex: composite: []str
Vertex: const: str("+")
Vertex: const: str("the answer is 42")
Vertex: const: str("the answer is 42")

View File

@@ -10,6 +10,4 @@ $out = $answer()
test "${out}" {}
-- OUTPUT --
Edge: FuncValue -> call # fn
Vertex: FuncValue
Vertex: call
Vertex: const: str("the answer is 42")

View File

@@ -11,14 +11,12 @@ $out2 = $answer()
test [$out1 + $out2,] {}
-- OUTPUT --
Edge: FuncValue -> call # fn
Edge: FuncValue -> call # fn
Edge: FuncValue -> call # fn
Edge: call -> composite: []str # 0
Vertex: FuncValue
Vertex: FuncValue
Vertex: call
Vertex: call
Vertex: call
Edge: _operator -> composite: []str # 0
Edge: const: str("+") -> _operator # op
Edge: const: str("the answer is 42") -> _operator # a
Edge: const: str("the answer is 42") -> _operator # b
Vertex: _operator
Vertex: composite: []str
Vertex: const: str("+")
Vertex: const: str("the answer is 42")
Vertex: const: str("the answer is 42")

View File

@@ -52,27 +52,31 @@ if $state == "three" {
Exec["timer"] -> Kv["${ns}"]
}
-- OUTPUT --
Edge: FuncValue -> call # fn
Edge: FuncValue -> call # fn
Edge: FuncValue -> call # fn
Edge: FuncValue -> call # fn
Edge: FuncValue -> call # fn
Edge: FuncValue -> call # fn
Edge: FuncValue -> call # fn
Vertex: FuncValue
Vertex: FuncValue
Vertex: FuncValue
Vertex: FuncValue
Vertex: FuncValue
Vertex: FuncValue
Vertex: FuncValue
Vertex: call
Vertex: call
Vertex: call
Vertex: call
Vertex: call
Vertex: call
Vertex: call
Edge: _lookup_default -> _operator # a
Edge: _lookup_default -> _operator # a
Edge: _lookup_default -> _operator # a
Edge: _lookup_default -> _operator # a
Edge: _operator -> _operator # a
Edge: _operator -> _operator # b
Edge: const: str("") -> _lookup_default # indexorkey
Edge: const: str("==") -> _operator # op
Edge: const: str("==") -> _operator # op
Edge: const: str("==") -> _operator # op
Edge: const: str("==") -> _operator # op
Edge: const: str("default") -> _lookup_default # default
Edge: const: str("default") -> _operator # b
Edge: const: str("estate") -> kvlookup # namespace
Edge: const: str("one") -> _operator # b
Edge: const: str("or") -> _operator # op
Edge: const: str("three") -> _operator # b
Edge: const: str("two") -> _operator # b
Edge: kvlookup -> _lookup_default # listormap
Vertex: _lookup_default
Vertex: _operator
Vertex: _operator
Vertex: _operator
Vertex: _operator
Vertex: _operator
Vertex: const: str("")
Vertex: const: str("/tmp/mgmt/state")
Vertex: const: str("/tmp/mgmt/state")
@@ -103,3 +107,4 @@ Vertex: const: str("timer")
Vertex: const: str("timer")
Vertex: const: str("two")
Vertex: const: str("two")
Vertex: kvlookup

View File

@@ -16,13 +16,9 @@ test "greeting3" {
anotherstr => $fn(),
}
-- OUTPUT --
Edge: FuncValue -> call # fn
Edge: FuncValue -> call # fn
Edge: FuncValue -> call # fn
Vertex: FuncValue
Vertex: call
Vertex: call
Vertex: call
Vertex: const: str("greeting1")
Vertex: const: str("greeting2")
Vertex: const: str("greeting3")
Vertex: const: str("hello world")
Vertex: const: str("hello world")
Vertex: const: str("hello world")

View File

@@ -18,13 +18,41 @@ test "greeting3" {
anotherstr => $fn(),
}
-- OUTPUT --
Edge: FuncValue -> call # fn
Edge: FuncValue -> call # fn
Edge: FuncValue -> call # fn
Vertex: FuncValue
Vertex: call
Vertex: call
Vertex: call
Edge: _operator -> _operator # a
Edge: _operator -> _operator # a
Edge: _operator -> _operator # a
Edge: const: str(" ") -> _operator # b
Edge: const: str(" ") -> _operator # b
Edge: const: str(" ") -> _operator # b
Edge: const: str("+") -> _operator # op
Edge: const: str("+") -> _operator # op
Edge: const: str("+") -> _operator # op
Edge: const: str("+") -> _operator # op
Edge: const: str("+") -> _operator # op
Edge: const: str("+") -> _operator # op
Edge: const: str("hello") -> _operator # a
Edge: const: str("hello") -> _operator # a
Edge: const: str("hello") -> _operator # a
Edge: const: str("world") -> _operator # b
Edge: const: str("world") -> _operator # b
Edge: const: str("world") -> _operator # b
Vertex: _operator
Vertex: _operator
Vertex: _operator
Vertex: _operator
Vertex: _operator
Vertex: _operator
Vertex: const: str(" ")
Vertex: const: str(" ")
Vertex: const: str(" ")
Vertex: const: str("+")
Vertex: const: str("+")
Vertex: const: str("+")
Vertex: const: str("+")
Vertex: const: str("+")
Vertex: const: str("+")
Vertex: const: str("greeting1")
Vertex: const: str("greeting2")
Vertex: const: str("greeting3")
Vertex: const: str("hello")
Vertex: const: str("world")