blob: aecabc914475c5844f4f2437737b54a04c80cf14 (
plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
|
(.module:
lux
(lux (control [monad #+ do])
(data [product]
[text]
text/format
(coll [list "list/" Functor<List>]))
[macro])
(luxc ["&" lang]
(lang ["ls" synthesis]
[".L" variable #+ Variable Register]
(host [ruby #+ Ruby Expression Statement])))
[//]
(// [".T" reference]
[".T" runtime]))
(def: #export (translate-apply translate functionS argsS+)
(-> (-> ls.Synthesis (Meta Expression)) ls.Synthesis (List ls.Synthesis) (Meta Expression))
(do macro.Monad<Meta>
[functionO (translate functionS)
argsO+ (monad.map @ translate argsS+)]
(wrap (ruby.call argsO+ functionO))))
(def: (input-declaration registers)
(-> (List Register) Statement)
(ruby.set! (list.concat (list (list/map (|>> inc referenceT.variable) registers)
(list "_")))
"curried"))
(def: (with-closure inits function-definition)
(-> (List Expression) Statement Expression)
(case inits
#.Nil
function-definition
_
(ruby.call inits
(ruby.lambda #.None
(|> (list.enumerate inits)
(list/map (|>> product.left referenceT.closure)))
(ruby.return! function-definition)))))
(def: #export (translate-function translate env arity bodyS)
(-> (-> ls.Synthesis (Meta Expression))
(List Variable) ls.Arity ls.Synthesis
(Meta Expression))
(do macro.Monad<Meta>
[[function-name bodyO] (//.with-sub-context
(do @
[function-name //.context]
(//.with-anchor [function-name +1]
(translate bodyS))))
closureO+ (monad.map @ referenceT.translate-variable env)
#let [args-initsO+ (input-declaration (list.n/range +0 (dec arity)))
selfO (ruby.set! (list (referenceT.variable +0)) function-name)
arityO (|> arity .int %i)
limitO (|> arity dec .int %i)]]
(wrap (with-closure closureO+
(ruby.lambda (#.Some function-name)
(list (ruby.splat "curried"))
(ruby.block! (list (ruby.set! (list "num_args") (ruby.length "curried"))
(ruby.if! (ruby.= arityO "num_args")
(ruby.block! (list selfO
args-initsO+
(ruby.while! (ruby.bool true)
(ruby.return! bodyO))))
(ruby.return! (let [recur (function (_ args) (ruby.call (list args) function-name))]
(ruby.? (ruby.> arityO "num_args")
(let [slice (function (_ from to)
(ruby.array-range from to "curried"))
arity-args (ruby.splat (slice (ruby.int 0) limitO))
output-func-args (ruby.splat (slice arityO "num_args"))]
(ruby.call (list output-func-args)
(recur arity-args)))
(ruby.lambda #.None
(list (ruby.splat "extra"))
(recur (ruby.splat (|> (ruby.array (list))
(ruby.send "concat" (list "curried"))
(ruby.send "concat" (list "extra")))))))))))))))))
|