(;module: lux (lux (control [eq #+ Eq]) (data bool number [text #+ Eq "Text/" Monoid] ident (coll [list #* "" Functor Fold]) ))) ## [Types] ## (type: (Code' w) ## (#;Bool Bool) ## (#;Nat Nat) ## (#;Int Int) ## (#;Frac Frac) ## (#;Text Text) ## (#;Symbol Text Text) ## (#;Tag Text Text) ## (#;Form (List (w (Code' w)))) ## (#;Tuple (List (w (Code' w)))) ## (#;Record (List [(w (Code' w)) (w (Code' w))]))) ## (type: Code ## (Ann Cursor (Code' (Ann Cursor)))) ## [Utils] (def: _cursor Cursor ["" +0 +0]) ## [Functions] (do-template [ ] [(def: #export ( x) (-> Code) [_cursor ( x)])] [bool Bool #;Bool] [nat Nat #;Nat] [int Int #;Int] [deg Deg #;Deg] [frac Frac #;Frac] [text Text #;Text] [symbol Ident #;Symbol] [tag Ident #;Tag] [form (List Code) #;Form] [tuple (List Code) #;Tuple] [record (List [Code Code]) #;Record] ) (do-template [ ] [(def: #export ( name) {#;doc } (-> Text Code) [_cursor ( ["" name])])] [local-symbol #;Symbol "Produces a local symbol (a symbol with no module prefix)."] [local-tag #;Tag "Produces a local tag (a tag with no module prefix)."]) ## [Structures] (struct: #export _ (Eq Code) (def: (= x y) (case [x y] (^template [ ] [[_ ( x')] [_ ( y')]] (:: = x' y')) ([#;Bool Eq] [#;Nat Eq] [#;Int Eq] [#;Deg Eq] [#;Frac Eq] [#;Text Eq] [#;Symbol Eq] [#;Tag Eq]) (^template [] [[_ ( xs')] [_ ( ys')]] (and (:: Eq = (size xs') (size ys')) (fold (function [[x' y'] old] (and old (= x' y'))) true (zip2 xs' ys')))) ([#;Form] [#;Tuple]) [[_ (#;Record xs')] [_ (#;Record ys')]] (and (:: Eq = (size xs') (size ys')) (fold (function [[[xl' xr'] [yl' yr']] old] (and old (= xl' yl') (= xr' yr'))) true (zip2 xs' ys'))) _ false))) ## [Values] (def: #export (to-text ast) (-> Code Text) (case ast (^template [ ] [_ ( value)] (:: encode value)) ([#;Bool Codec] [#;Nat Codec] [#;Int Codec] [#;Deg Codec] [#;Frac Codec] [#;Symbol Codec]) [_ (#;Text value)] (text;encode value) [_ (#;Tag ident)] (Text/compose "#" (:: Codec encode ident)) (^template [ ] [_ ( members)] ($_ Text/compose (|> members (map to-text) (interpose " ") (text;join-with "")) )) ([#;Form "(" ")"] [#;Tuple "[" "]"]) [_ (#;Record pairs)] ($_ Text/compose "{" (|> pairs (map (function [[left right]] ($_ Text/compose (to-text left) " " (to-text right)))) (interpose " ") (text;join-with "")) "}") )) (def: #export (replace original substitute ast) {#;doc "Replaces all code that looks like the 'original' with the 'substitute'."} (-> Code Code Code Code) (if (:: Eq = original ast) substitute (case ast (^template [] [cursor ( parts)] [cursor ( (map (replace original substitute) parts))]) ([#;Form] [#;Tuple]) [cursor (#;Record parts)] [cursor (#;Record (map (function [[left right]] [(replace original substitute left) (replace original substitute right)]) parts))] _ ast)))