-
-
Notifications
You must be signed in to change notification settings - Fork 320
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
lang: unification: Improve type unification algorithm
The simple type unification algorithm suffered from some serious performance and memory problems when used with certain code bases. This adds some crucial optimizations that improve performance drastically.
- Loading branch information
1 parent
97d60ac
commit d70bbfb
Showing
17 changed files
with
770 additions
and
27 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,11 @@ | ||
Edge: str("hey") -> var(foo) # foo | ||
Edge: str("hey") -> var(foo) # foo | ||
Edge: str("t1") -> var(a) # a | ||
Edge: str("t2") -> var(a) # a | ||
Vertex: str("hey") | ||
Vertex: str("t1") | ||
Vertex: str("t2") | ||
Vertex: var(a) | ||
Vertex: var(a) | ||
Vertex: var(foo) | ||
Vertex: var(foo) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,8 @@ | ||
include c1("t1") | ||
include c1("t2") | ||
class c1($a) { | ||
test $a { | ||
stringptr => $foo, | ||
} | ||
} | ||
$foo = "hey" |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,32 @@ | ||
Edge: call:len(var(b)) -> call:fmt.printf(str("len is: %d"), call:len(var(b))) # b | ||
Edge: call:len(var(b)) -> call:fmt.printf(str("len is: %d"), call:len(var(b))) # b | ||
Edge: int(-37) -> list(int(13), int(42), int(0), int(-37)) # 3 | ||
Edge: int(0) -> list(int(13), int(42), int(0), int(-37)) # 2 | ||
Edge: int(13) -> list(int(13), int(42), int(0), int(-37)) # 0 | ||
Edge: int(42) -> list(int(13), int(42), int(0), int(-37)) # 1 | ||
Edge: list(int(13), int(42), int(0), int(-37)) -> var(b) # b | ||
Edge: str("hello") -> var(b) # b | ||
Edge: str("len is: %d") -> call:fmt.printf(str("len is: %d"), call:len(var(b))) # a | ||
Edge: str("len is: %d") -> call:fmt.printf(str("len is: %d"), call:len(var(b))) # a | ||
Edge: str("t1") -> var(a) # a | ||
Edge: str("t2") -> var(a) # a | ||
Edge: var(b) -> call:len(var(b)) # 0 | ||
Edge: var(b) -> call:len(var(b)) # 0 | ||
Vertex: call:fmt.printf(str("len is: %d"), call:len(var(b))) | ||
Vertex: call:fmt.printf(str("len is: %d"), call:len(var(b))) | ||
Vertex: call:len(var(b)) | ||
Vertex: call:len(var(b)) | ||
Vertex: int(-37) | ||
Vertex: int(0) | ||
Vertex: int(13) | ||
Vertex: int(42) | ||
Vertex: list(int(13), int(42), int(0), int(-37)) | ||
Vertex: str("hello") | ||
Vertex: str("len is: %d") | ||
Vertex: str("len is: %d") | ||
Vertex: str("t1") | ||
Vertex: str("t2") | ||
Vertex: var(a) | ||
Vertex: var(a) | ||
Vertex: var(b) | ||
Vertex: var(b) |
10 changes: 10 additions & 0 deletions
10
lang/interpret_test/TestAstFunc1/polydoubleinclude/main.mcl
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,10 @@ | ||
import "fmt" | ||
|
||
# note that the class can have two separate types for $b | ||
include c1("t1", "hello") # len is 5 | ||
include c1("t2", [13, 42, 0, -37,]) # len is 4 | ||
class c1($a, $b) { | ||
test $a { | ||
anotherstr => fmt.printf("len is: %d", len($b)), | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,88 @@ | ||
Edge: call:_operator(str("=="), var(state), str("default")) -> call:_operator(str("||"), call:_operator(str("=="), var(state), str("one")), call:_operator(str("=="), var(state), str("default"))) # b | ||
Edge: call:_operator(str("=="), var(state), str("one")) -> call:_operator(str("||"), call:_operator(str("=="), var(state), str("one")), call:_operator(str("=="), var(state), str("default"))) # a | ||
Edge: call:maplookup(var(exchanged), var(hostname), str("default")) -> var(state) # state | ||
Edge: call:maplookup(var(exchanged), var(hostname), str("default")) -> var(state) # state | ||
Edge: call:maplookup(var(exchanged), var(hostname), str("default")) -> var(state) # state | ||
Edge: call:maplookup(var(exchanged), var(hostname), str("default")) -> var(state) # state | ||
Edge: call:world.kvlookup(var(ns)) -> var(exchanged) # exchanged | ||
Edge: str("") -> var(hostname) # hostname | ||
Edge: str("==") -> call:_operator(str("=="), var(state), str("default")) # x | ||
Edge: str("==") -> call:_operator(str("=="), var(state), str("one")) # x | ||
Edge: str("==") -> call:_operator(str("=="), var(state), str("three")) # x | ||
Edge: str("==") -> call:_operator(str("=="), var(state), str("two")) # x | ||
Edge: str("default") -> call:_operator(str("=="), var(state), str("default")) # b | ||
Edge: str("default") -> call:maplookup(var(exchanged), var(hostname), str("default")) # default | ||
Edge: str("estate") -> var(ns) # ns | ||
Edge: str("estate") -> var(ns) # ns | ||
Edge: str("estate") -> var(ns) # ns | ||
Edge: str("estate") -> var(ns) # ns | ||
Edge: str("estate") -> var(ns) # ns | ||
Edge: str("estate") -> var(ns) # ns | ||
Edge: str("estate") -> var(ns) # ns | ||
Edge: str("estate") -> var(ns) # ns | ||
Edge: str("estate") -> var(ns) # ns | ||
Edge: str("estate") -> var(ns) # ns | ||
Edge: str("one") -> call:_operator(str("=="), var(state), str("one")) # b | ||
Edge: str("three") -> call:_operator(str("=="), var(state), str("three")) # b | ||
Edge: str("two") -> call:_operator(str("=="), var(state), str("two")) # b | ||
Edge: str("||") -> call:_operator(str("||"), call:_operator(str("=="), var(state), str("one")), call:_operator(str("=="), var(state), str("default"))) # x | ||
Edge: var(exchanged) -> call:maplookup(var(exchanged), var(hostname), str("default")) # map | ||
Edge: var(hostname) -> call:maplookup(var(exchanged), var(hostname), str("default")) # key | ||
Edge: var(ns) -> call:world.kvlookup(var(ns)) # namespace | ||
Edge: var(state) -> call:_operator(str("=="), var(state), str("default")) # a | ||
Edge: var(state) -> call:_operator(str("=="), var(state), str("one")) # a | ||
Edge: var(state) -> call:_operator(str("=="), var(state), str("three")) # a | ||
Edge: var(state) -> call:_operator(str("=="), var(state), str("two")) # a | ||
Vertex: call:_operator(str("=="), var(state), str("default")) | ||
Vertex: call:_operator(str("=="), var(state), str("one")) | ||
Vertex: call:_operator(str("=="), var(state), str("three")) | ||
Vertex: call:_operator(str("=="), var(state), str("two")) | ||
Vertex: call:_operator(str("||"), call:_operator(str("=="), var(state), str("one")), call:_operator(str("=="), var(state), str("default"))) | ||
Vertex: call:maplookup(var(exchanged), var(hostname), str("default")) | ||
Vertex: call:world.kvlookup(var(ns)) | ||
Vertex: str("") | ||
Vertex: str("/tmp/mgmt/state") | ||
Vertex: str("/tmp/mgmt/state") | ||
Vertex: str("/tmp/mgmt/state") | ||
Vertex: str("/usr/bin/sleep 1s") | ||
Vertex: str("/usr/bin/sleep 1s") | ||
Vertex: str("/usr/bin/sleep 1s") | ||
Vertex: str("==") | ||
Vertex: str("==") | ||
Vertex: str("==") | ||
Vertex: str("==") | ||
Vertex: str("default") | ||
Vertex: str("default") | ||
Vertex: str("estate") | ||
Vertex: str("one") | ||
Vertex: str("one") | ||
Vertex: str("state: one\n") | ||
Vertex: str("state: three\n") | ||
Vertex: str("state: two\n") | ||
Vertex: str("three") | ||
Vertex: str("three") | ||
Vertex: str("timer") | ||
Vertex: str("timer") | ||
Vertex: str("timer") | ||
Vertex: str("timer") | ||
Vertex: str("timer") | ||
Vertex: str("timer") | ||
Vertex: str("two") | ||
Vertex: str("two") | ||
Vertex: str("||") | ||
Vertex: var(exchanged) | ||
Vertex: var(hostname) | ||
Vertex: var(ns) | ||
Vertex: var(ns) | ||
Vertex: var(ns) | ||
Vertex: var(ns) | ||
Vertex: var(ns) | ||
Vertex: var(ns) | ||
Vertex: var(ns) | ||
Vertex: var(ns) | ||
Vertex: var(ns) | ||
Vertex: var(ns) | ||
Vertex: var(state) | ||
Vertex: var(state) | ||
Vertex: var(state) | ||
Vertex: var(state) |
52 changes: 52 additions & 0 deletions
52
lang/interpret_test/TestAstFunc1/slow_unification0/main.mcl
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,52 @@ | ||
# state machine that previously experienced unusable slow type unification | ||
import "world" | ||
|
||
$ns = "estate" | ||
$exchanged = world.kvlookup($ns) | ||
$state = maplookup($exchanged, $hostname, "default") | ||
|
||
if $state == "one" || $state == "default" { | ||
|
||
file "/tmp/mgmt/state" { | ||
content => "state: one\n", | ||
} | ||
|
||
exec "timer" { | ||
cmd => "/usr/bin/sleep 1s", | ||
} | ||
kv "${ns}" { | ||
key => $ns, | ||
value => "two", | ||
} | ||
Exec["timer"] -> Kv["${ns}"] | ||
} | ||
if $state == "two" { | ||
|
||
file "/tmp/mgmt/state" { | ||
content => "state: two\n", | ||
} | ||
|
||
exec "timer" { | ||
cmd => "/usr/bin/sleep 1s", | ||
} | ||
kv "${ns}" { | ||
key => $ns, | ||
value => "three", | ||
} | ||
Exec["timer"] -> Kv["${ns}"] | ||
} | ||
if $state == "three" { | ||
|
||
file "/tmp/mgmt/state" { | ||
content => "state: three\n", | ||
} | ||
|
||
exec "timer" { | ||
cmd => "/usr/bin/sleep 1s", | ||
} | ||
kv "${ns}" { | ||
key => $ns, | ||
value => "one", | ||
} | ||
Exec["timer"] -> Kv["${ns}"] | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.