aboutsummaryrefslogtreecommitdiff
path: root/new-luxc/test
diff options
context:
space:
mode:
authorEduardo Julian2017-06-06 20:23:15 -0400
committerEduardo Julian2017-06-06 20:23:15 -0400
commit4480e41e949ba3ba0c9bceeed43e3f144f82103b (patch)
treee31476d83b24a55746738c0b0b5100931ce289c3 /new-luxc/test
parentaa3dcb411db1bfbf41ca59c334c6c792b9e40d0c (diff)
- Now optimizing functions.
Diffstat (limited to 'new-luxc/test')
-rw-r--r--new-luxc/test/test/luxc/synthesizer/function.lux127
1 files changed, 125 insertions, 2 deletions
diff --git a/new-luxc/test/test/luxc/synthesizer/function.lux b/new-luxc/test/test/luxc/synthesizer/function.lux
index 9243294a2..7c4776727 100644
--- a/new-luxc/test/test/luxc/synthesizer/function.lux
+++ b/new-luxc/test/test/luxc/synthesizer/function.lux
@@ -4,15 +4,138 @@
(control monad
pipe)
(data [product]
- (coll [list]))
+ [number]
+ text/format
+ (coll [list "L/" Functor<List> Fold<List>]
+ ["D" dict]
+ ["s" set]))
["r" math/random "r/" Monad<Random>]
test)
(luxc (lang ["la" analysis]
["ls" synthesis])
(analyser [";A" structure])
- [synthesizer])
+ [synthesizer]
+ (synthesizer ["&&;" function]))
(.. common))
+(def: (reference var)
+ (-> ls;Variable Ref)
+ (if (&&function;captured-var? var)
+ (#;Captured (|> var (i.* -1) int-to-nat n.dec))
+ (#;Local (int-to-nat var))))
+
+(def: (make-scope env)
+ (-> (List ls;Variable) Scope)
+ {#;name (list)
+ #;inner +0
+ #;locals {#;counter +0 #;mappings (list)}
+ #;captured {#;counter +0
+ #;mappings (L/map (|>. reference [Void] [""])
+ env)}})
+
+(def: gen-function//constant
+ (r;Random [Nat la;Analysis la;Analysis])
+ (r;rec
+ (function [gen-function//constant]
+ (do r;Monad<Random>
+ [function? r;bool]
+ (if function?
+ (do @
+ [[num-args outputA subA] gen-function//constant]
+ (wrap [(n.inc num-args)
+ outputA
+ (#la;Function (make-scope (list)) subA)]))
+ (do @
+ [outputA gen-primitive]
+ (wrap [+0 outputA outputA])))))))
+
+(def: (pick scope-size)
+ (-> Nat (r;Random Nat))
+ (|> r;nat (:: r;Monad<Random> map (n.% scope-size))))
+
+(def: gen-function//captured
+ (r;Random [Nat Int la;Analysis])
+ (do r;Monad<Random>
+ [num-locals (|> r;nat (:: @ map (|>. (n.% +100) (n.max +10))))
+ #let [indices (list;n.range +0 (n.dec num-locals))
+ absolute-env (L/map &&function;to-local indices)
+ relative-env (L/map &&function;to-captured indices)]
+ [total-args prediction bodyA] (: (r;Random [Nat Int la;Analysis])
+ (loop [num-args +1
+ global-env relative-env]
+ (let [env-size (list;size global-env)
+ resolver (L/fold (function [[idx var] resolver]
+ (D;put idx var resolver))
+ (: (D;Dict Nat Int)
+ (D;new number;Hash<Nat>))
+ (list;zip2 (list;n.range +0 (n.dec env-size))
+ global-env))]
+ (do @
+ [nest? r;bool]
+ (if nest?
+ (do @
+ [num-picks (:: @ map (n.max +1) (pick (n.inc env-size)))
+ picks (|> (r;set number;Hash<Nat> num-picks (pick env-size))
+ (:: @ map s;to-list))
+ [total-args prediction bodyA] (recur (n.inc num-args)
+ (L/map (function [pick] (assume (list;nth pick global-env)))
+ picks))]
+ (wrap [total-args prediction (#la;Function (make-scope (L/map &&function;to-captured picks))
+ bodyA)]))
+ (do @
+ [chosen (pick (list;size global-env))]
+ (wrap [num-args
+ (assume (D;get chosen resolver))
+ (#la;Relative (#;Captured chosen))])))))))]
+ (wrap [total-args prediction (#la;Function (make-scope absolute-env) bodyA)])
+ ))
+
+(def: gen-function//local
+ (r;Random [Nat Int la;Analysis])
+ (loop [num-args +0
+ nest? true]
+ (if nest?
+ (do r;Monad<Random>
+ [nest?' r;bool
+ [total-args prediction bodyA] (recur (n.inc num-args) nest?')]
+ (wrap [total-args prediction (#la;Function (make-scope (list)) bodyA)]))
+ (do r;Monad<Random>
+ [chosen (|> r;nat (:: @ map (|>. (n.% +100) (n.max +2))))]
+ (wrap [num-args
+ (|> chosen (n.+ (n.dec num-args)) nat-to-int)
+ (#la;Relative (#;Local chosen))])))))
+
+(test: "Function definition."
+ [[args1 prediction1 function1] gen-function//constant
+ [args2 prediction2 function2] gen-function//captured
+ [args3 prediction3 function3] gen-function//local]
+ ($_ seq
+ (assert "Nested functions will get folded together."
+ (|> (synthesizer;synthesize function1)
+ (case> (#ls;Function args captured output)
+ (and (n.= args1 args)
+ (corresponds? prediction1 output))
+
+ _
+ (n.= +0 args1))))
+ (assert "Folded functions provide direct access to captured variables."
+ (|> (synthesizer;synthesize function2)
+ (case> (#ls;Function args captured (#ls;Variable output))
+ (and (n.= args2 args)
+ (i.= prediction2 output))
+
+ _
+ false)))
+ (assert "Folded functions properly offset local variables."
+ (|> (synthesizer;synthesize function3)
+ (case> (#ls;Function args captured (#ls;Variable output))
+ (and (n.= args3 args)
+ (i.= prediction3 output))
+
+ _
+ false)))
+ ))
+
(test: "Function application."
[num-args (|> r;nat (:: @ map (|>. (n.% +10) (n.max +1))))
funcA gen-primitive