(;module: lux (lux (control monad) (data ["E" error] [text "T/" Eq] text/format [number] [product]) [macro #+ Monad] [type] (type ["TC" check])) (luxc ["&" base] (lang ["la" analysis]) ["&;" module] ["&;" env]) (. ["&&;" common] ["&&;" function] ["&&;" primitive] ["&&;" reference] ["&&;" type] ["&&;" struct] ["&&;" proc])) (def: #export (analyser eval) (-> &;Eval &;Analyser) (: (-> Code (Lux la;Analysis)) (function analyse [ast] (case ast (^template [ ] [cursor ( value)] ( value)) ([#;Bool &&primitive;analyse-bool] [#;Nat &&primitive;analyse-nat] [#;Int &&primitive;analyse-int] [#;Deg &&primitive;analyse-deg] [#;Real &&primitive;analyse-real] [#;Char &&primitive;analyse-char] [#;Text &&primitive;analyse-text]) (^ [cursor (#;Tuple (list))]) &&primitive;analyse-unit (^ [cursor (#;Tuple (list singleton))]) (analyse singleton) (^ [cursor (#;Tuple elems)]) (&&struct;analyse-tuple analyse elems) [cursor (#;Symbol reference)] (&&reference;analyse-reference reference) (^ [cursor (#;Form (list [_ (#;Symbol ["" "_lux_check"])] type value))]) (&&type;analyse-check analyse eval type value) (^ [cursor (#;Form (list [_ (#;Symbol ["" "_lux_coerce"])] type value))]) (&&type;analyse-coerce analyse eval type value) (^ [cursor (#;Form (list [_ (#;Symbol ["" "_lux_proc"])] [_ (#;Symbol proc)] [_ (#;Tuple args)]))]) (&&proc;analyse-proc analyse proc args) (^ [cursor (#;Form (list [_ (#;Nat tag)] value))]) (&&struct;analyse-variant analyse tag value) (^ [cursor (#;Form (list& func args))]) (do Monad [[funcT =func] (&&common;with-unknown-type (analyse func))] (case =func (#la;Absolute def-name) (do @ [[def-type def-anns def-value] (macro;find-def def-name)] (if (macro;macro? def-anns) (do @ [## macro-expansion (function [compiler] ## (case (macro-caller def-value args compiler) ## (#E;Success [compiler' output]) ## (#E;Success [compiler' output]) ## (#E;Error error) ## ((&;fail error) compiler))) macro-expansion (: (Lux (List Code)) (undefined))] (case macro-expansion (^ (list single-expansion)) (analyse single-expansion) _ (&;fail (format "Macro expressions must expand to a single expression: " (%code ast))))) (&&function;analyse-apply analyse funcT =func args))) _ (&&function;analyse-apply analyse funcT =func args))) _ (&;fail (format "Unrecognized syntax: " (%code ast))) ))))