(.module: [lux #- nat int deg] (lux (control [equality #+ 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)))