123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413 |
- (import test ())
- (import tests/compiler/codegen/codegen-helpers ())
- (describe "The codegen"
- (will "simplify elseif branches"
- (affirm-codegen
- '((cond
- [foo 0]
- [bar 1]))
- "if foo then
- return 0
- elseif bar then
- return 1
- else
- _error(\"unmatched item\")
- end")
- (affirm-codegen
- '((cond
- [foo 0]
- [bar 1]
- [true true]))
- "if foo then
- return 0
- elseif bar then
- return 1
- else
- return true
- end")
- (affirm-codegen
- '((cond
- [foo 0]
- [true true]
- [bar 1]))
- "if foo then
- return 0
- else
- return true
- end")
- (affirm-codegen
- '((cond
- [true true]
- [foo 0]
- [foo 1]))
- "do
- return true
- end"))
- (will "handle nested conds"
- (affirm-codegen
- '((cond
- [(cond
- [foo 0]
- [bar false]) 1]
- [true 2]))
- "local temp
- if foo then
- temp = 0
- elseif bar then
- temp = false
- else
- _error(\"unmatched item\")
- end
- if temp then
- return 1
- else
- return 2
- end")
- (affirm-codegen
- '((cond
- [(cond
- [foo 0]
- [bar 10]) 1]
- [(cond
- [foo 0]
- [bar 10]) 2]
- [(cond
- [foo 0]
- [bar 10]) 3]
- [true 1]))
- "local temp
- if foo then
- temp = 0
- elseif bar then
- temp = 10
- else
- _error(\"unmatched item\")
- end
- if temp then
- return 1
- else
- local temp
- if foo then
- temp = 0
- elseif bar then
- temp = 10
- else
- _error(\"unmatched item\")
- end
- if temp then
- return 2
- else
- local temp
- if foo then
- temp = 0
- elseif bar then
- temp = 10
- else
- _error(\"unmatched item\")
- end
- if temp then
- return 3
- else
- return 1
- end
- end
- end"))
- (will "handle deeply nested conds"
- (affirm-codegen
- '((cond
- [(cond
- [(cond
- [(cond [foo 0]) 1]) 2]) 3]))
- "local temp
- local temp1
- local temp2
- if foo then
- temp2 = 0
- else
- _error(\"unmatched item\")
- end
- if temp2 then
- temp1 = 1
- else
- _error(\"unmatched item\")
- end
- if temp1 then
- temp = 2
- else
- _error(\"unmatched item\")
- end
- if temp then
- return 3
- else
- _error(\"unmatched item\")
- end"))
- (section "will emit and expressions"
- (it "which are simple"
- (affirm-codegen
- '((cond
- [foo bar]
- [true foo]))
- "return foo and bar")
- (affirm-codegen
- '((cond
- [foo bar]
- [true false]))
- "if foo then
- return bar
- else
- return false
- end")
- (affirm-codegen
- '((cond
- [(cond
- [foo bar]
- [true false]) 1]
- [true 2]))
- "if foo and bar then
- return 1
- else
- return 2
- end"))
- (it "which are nested"
- (affirm-codegen
- '((cond
- [foo (cond
- [bar 2]
- [true bar])]
- [true foo]))
- "return foo and (bar and 2)"))
- (it "with a directly called lambda"
- (affirm-codegen
- '(((lambda (x)
- (cond
- [x bar]
- [true x]))
- foo))
- "return foo and bar")
- (affirm-codegen
- '(((lambda (x)
- (cond
- [x (bar x)]
- [true x]))
- foo))
- "local x = foo
- return x and bar(x)"))
- (pending "with nested directly called lambdas"
- (affirm-codegen
- '((cond
- [(cond
- [foo
- (cond
- [bar ((lambda (x)
- (cond
- [x (baz x)]
- [true x])) bar)]
- [true false])]
- [true false])
- 1]
- [true 2]))
- "local temp
- if foo and bar then
- local x = bar
- temp = x and baz(x)
- else
- temp = false
- end
- if temp then
- return 1
- else
- return 2
- end")))
- (section "will emit or expressions"
- (it "which are simple"
- (affirm-codegen
- '((cond
- [foo foo]
- [true bar]))
- "return foo or bar")
- (affirm-codegen
- '((cond
- [foo true]
- [true bar]))
- "if foo then
- return true
- else
- return bar
- end")
- (affirm-codegen
- '((cond
- [(cond
- [foo true]
- [true bar]) 1]
- [true 2]))
- "if foo or bar then
- return 1
- else
- return 2
- end"))
- (it "which are nested"
- (affirm-codegen
- '((cond
- [foo foo]
- [true (cond
- [bar bar]
- [true 2])]))
- "return foo or (bar or 2)"))
- (it "which are sequential"
- (affirm-codegen
- '((cond
- [foo foo]
- [bar bar]
- [true 2]))
- "return foo or bar or 2"))
- (it "with a directly called lambda"
- (affirm-codegen
- '(((lambda (x)
- (cond
- [x x]
- [true bar]))
- foo))
- "return foo or bar")
- (affirm-codegen
- '(((lambda (x)
- (cond
- [x x]
- [true (bar x)]))
- foo))
- "local x = foo
- return x or bar(x)"))
- (section "will handle a trailing `and`"
- (it "in the simple case"
- (affirm-codegen
- '((cond
- [foo foo]
- [bar bar]
- [baz qux]
- [true baz]))
- "return foo or bar or baz and qux"))
- (it "with a directly called lambda"
- (affirm-codegen
- '(((lambda (x)
- (cond
- [x x]
- [bar (foo 3)]
- [true bar])) (foo 2)))
- "return foo(2) or bar and foo(3)"))
- (it "inside a condition"
- (affirm-codegen
- '((cond
- [(cond
- [foo foo]
- [bar baz]
- [true bar]) 1]
- [true 2]))
- "if foo or bar and baz then
- return 1
- else
- return 2
- end")))
- (section "will handle a trailing `or not`"
- (it "in the simple case"
- '((cond
- [foo foo]
- [bar bar]
- [baz false]
- [true true]))
- "return foo or bar or not baz")
- (it "with a directly called lambda"
- '(((lambda (x)
- (cond
- [x x]
- [bar false]
- [true true])) (foo 2)))
- "return foo(2) or not bar")
- (it "inside a condition"
- (affirm-codegen
- '((cond
- [(cond
- [foo foo]
- [bar false]
- [true true]) 1]
- [true 2]))
- "if foo or not bar then
- return 1
- else
- return 2
- end"))))
- (will "emit not expressions"
- (affirm-codegen
- '((cond
- [foo false]
- [true true]))
- "return not foo"))
- (will "invert if statements"
- (affirm-codegen
- '((cond
- [foo]
- [true (bar)])
- nil)
- "if not foo then
- bar()
- end
- return nil")
- (affirm-codegen
- '((cond
- [foo]
- [true (bar)]))
- "if foo then
- return nil
- else
- return bar()
- end"))
- (will "emit if statements in bindings"
- (affirm-codegen
- '(((lambda (x) (+ x 1))
- (cond
- [foo 1]
- [true 2])))
- "local x
- if foo then
- x = 1
- else
- x = 2
- end
- return x + 1")
- (affirm-codegen
- '(((lambda (x) (+ x 1))
- ((lambda (y)
- (cond
- [y 1]
- [true 2]))
- 3)))
- "local x
- local y = 3
- if y then
- x = 1
- else
- x = 2
- end
- return x + 1")))
|