## Copyright (c) Eduardo Julian. All rights reserved. ## This Source Code Form is subject to the terms of the Mozilla Public License, v. 2.0. ## If a copy of the MPL was not distributed with this file, ## You can obtain one at http://mozilla.org/MPL/2.0/. (;module: lux (lux (control eq) (data bool number [char] [text #+ Eq "Text/" Monoid] ident (struct [list #* "" Functor Fold]) ))) ## [Types] ## (type: (AST' w) ## (#;BoolS Bool) ## (#;NatS Nat) ## (#;IntS Int) ## (#;RealS Real) ## (#;CharS Char) ## (#;TextS Text) ## (#;SymbolS Text Text) ## (#;TagS Text Text) ## (#;FormS (List (w (AST' w)))) ## (#;TupleS (List (w (AST' w)))) ## (#;RecordS (List [(w (AST' w)) (w (AST' w))]))) ## (type: AST ## (Meta Cursor (AST' (Meta Cursor)))) ## [Utils] (def: _cursor Cursor ["" -1 -1]) ## [Functions] (do-template [ ] [(def: #export ( x) (-> AST) [_cursor ( x)])] [bool Bool #;BoolS] [nat Nat #;NatS] [int Int #;IntS] [frac Frac #;FracS] [real Real #;RealS] [char Char #;CharS] [text Text #;TextS] [symbol Ident #;SymbolS] [tag Ident #;TagS] [form (List AST) #;FormS] [tuple (List AST) #;TupleS] [record (List [AST AST]) #;RecordS] ) (do-template [ ] [(def: #export ( name) (-> Text AST) [_cursor ( ["" name])])] [local-symbol #;SymbolS] [local-tag #;TagS]) ## [Structures] (struct: #export _ (Eq AST) (def: (= x y) (case [x y] (^template [ ] [[_ ( x')] [_ ( y')]] (:: = x' y')) ([#;BoolS Eq] [#;NatS Eq] [#;IntS Eq] [#;FracS Eq] [#;RealS Eq] [#;CharS char;Eq] [#;TextS Eq] [#;SymbolS Eq] [#;TagS Eq]) (^template [] [[_ ( xs')] [_ ( ys')]] (and (:: Eq = (size xs') (size ys')) (fold (lambda [[x' y'] old] (and old (= x' y'))) true (zip2 xs' ys')))) ([#;FormS] [#;TupleS]) [[_ (#;RecordS xs')] [_ (#;RecordS ys')]] (and (:: Eq = (size xs') (size ys')) (fold (lambda [[[xl' xr'] [yl' yr']] old] (and old (= xl' yl') (= xr' yr'))) true (zip2 xs' ys'))) _ false))) ## [Values] (def: #export (ast-to-text ast) (-> AST Text) (case ast (^template [ ] [_ ( value)] (:: encode value)) ([#;BoolS Codec] [#;NatS Codec] [#;IntS Codec] [#;FracS Codec] [#;RealS Codec] [#;CharS char;Codec] [#;TextS text;Codec] [#;SymbolS Codec]) [_ (#;TagS ident)] (Text/append "#" (:: Codec encode ident)) (^template [ ] [_ ( members)] ($_ Text/append (|> members (map ast-to-text) (interpose " ") (text;join-with "")) )) ([#;FormS "(" ")"] [#;TupleS "[" "]"]) [_ (#;RecordS pairs)] ($_ Text/append "{" (|> pairs (map (lambda [[left right]] ($_ Text/append (ast-to-text left) " " (ast-to-text right)))) (interpose " ") (text;join-with "")) "}") )) (def: #export (replace source target ast) (-> AST AST AST AST) (if (:: Eq = source ast) target (case ast (^template [] [cursor ( parts)] [cursor ( (map (replace source target) parts))]) ([#;FormS] [#;TupleS]) [cursor (#;RecordS parts)] [cursor (#;RecordS (map (lambda [[left right]] [(replace source target left) (replace source target right)]) parts))] _ ast)))