From 414c0a1a1f53322d8f4c11230ded98c5b83b6310 Mon Sep 17 00:00:00 2001 From: Eduardo Julian Date: Fri, 1 Dec 2017 23:40:15 -0400 Subject: - Changed some of the syntax for macro templating. - "gensym" now produces Ident instead of Code. --- stdlib/source/lux.lux | 585 +++++++++++++++++++++++++------------------------- 1 file changed, 297 insertions(+), 288 deletions(-) (limited to 'stdlib/source/lux.lux') diff --git a/stdlib/source/lux.lux b/stdlib/source/lux.lux index 4ec6e1ea1..e7326f34b 100644 --- a/stdlib/source/lux.lux +++ b/stdlib/source/lux.lux @@ -1064,7 +1064,7 @@ _ (fail "Wrong syntax for $'")})) -(def:'' (map f xs) +(def:'' (list/map f xs) #Nil (#UnivQ #Nil (#UnivQ #Nil @@ -1076,7 +1076,7 @@ #Nil (#Cons x xs') - (#Cons (f x) (map f xs'))})) + (#Cons (f x) (list/map f xs'))})) (def:'' RepEnv #Nil @@ -1126,18 +1126,18 @@ syntax}) [meta (#Form parts)] - [meta (#Form (map (replace-syntax reps) parts))] + [meta (#Form (list/map (replace-syntax reps) parts))] [meta (#Tuple members)] - [meta (#Tuple (map (replace-syntax reps) members))] + [meta (#Tuple (list/map (replace-syntax reps) members))] [meta (#Record slots)] - [meta (#Record (map ("lux check" (#Function (#Product Code Code) (#Product Code Code)) - (function'' [slot] - ("lux case" slot - {[k v] - [(replace-syntax reps k) (replace-syntax reps v)]}))) - slots))] + [meta (#Record (list/map ("lux check" (#Function (#Product Code Code) (#Product Code Code)) + (function'' [slot] + ("lux case" slot + {[k v] + [(replace-syntax reps k) (replace-syntax reps v)]}))) + slots))] _ syntax}) @@ -1148,20 +1148,20 @@ (#Function Code Code) ("lux case" code {[_ (#Tuple members)] - (tuple$ (map update-bounds members)) + (tuple$ (list/map update-bounds members)) [_ (#Record pairs)] - (record$ (map ("lux check" (#Function (#Product Code Code) (#Product Code Code)) - (function'' [pair] - (let'' [name val] pair - [name (update-bounds val)]))) - pairs)) + (record$ (list/map ("lux check" (#Function (#Product Code Code) (#Product Code Code)) + (function'' [pair] + (let'' [name val] pair + [name (update-bounds val)]))) + pairs)) [_ (#Form (#Cons [_ (#Tag "lux" "Bound")] (#Cons [_ (#Nat idx)] #Nil)))] (form$ (#Cons (tag$ ["lux" "Bound"]) (#Cons (nat$ ("lux nat +" +2 idx)) #Nil))) [_ (#Form members)] - (form$ (map update-bounds members)) + (form$ (list/map update-bounds members)) _ code})) @@ -1854,7 +1854,7 @@ (#Cons lastI inits) (do Monad [lastO ("lux case" lastI - {[_ (#Form (#Cons [[_ (#Symbol ["" "~@"])] (#Cons [spliced #Nil])]))] + {[_ (#Form (#Cons [[_ (#Symbol ["" "~+"])] (#Cons [spliced #Nil])]))] (wrap spliced) _ @@ -1864,7 +1864,7 @@ (monad/fold Monad (function' [leftI rightO] ("lux case" leftI - {[_ (#Form (#Cons [[_ (#Symbol ["" "~@"])] (#Cons [spliced #Nil])]))] + {[_ (#Form (#Cons [[_ (#Symbol ["" "~+"])] (#Cons [spliced #Nil])]))] (wrap (form$ (list (symbol$ ["lux" "splice-helper"]) spliced rightO))) @@ -1933,6 +1933,9 @@ [true [_ (#Form (#Cons [[_ (#Symbol ["" "~"])] (#Cons [unquoted #Nil])]))]] (return unquoted) + [true [_ (#Form (#Cons [[_ (#Symbol ["" "~@"])] (#Cons [ident #Nil])]))]] + (return (wrap-meta (form$ (list (tag$ ["lux" "Symbol"]) ident)))) + [true [_ (#Form (#Cons [[_ (#Symbol ["" "~'"])] (#Cons [keep-quoted #Nil])]))]] (untemplate false subst keep-quoted) @@ -1996,10 +1999,10 @@ (macro:' #export (` tokens) (list [(tag$ ["lux" "doc"]) - (text$ "## Hygienic quasi-quotation as a macro. Unquote (~) and unquote-splice (~@) must also be used as forms. + (text$ "## Hygienic quasi-quotation as a macro. Unquote (~) and unquote-splice (~+) must also be used as forms. ## All unprefixed macros will receive their parent module's prefix if imported; otherwise will receive the prefix of the module on which the quasi-quote is being used. (` (def: (~ name) - (function [(~@ args)] + (function [(~+ args)] (~ body))))")]) ("lux case" tokens {(#Cons template #Nil) @@ -2013,9 +2016,9 @@ (macro:' #export (`' tokens) (list [(tag$ ["lux" "doc"]) - (text$ "## Unhygienic quasi-quotation as a macro. Unquote (~) and unquote-splice (~@) must also be used as forms. + (text$ "## Unhygienic quasi-quotation as a macro. Unquote (~) and unquote-splice (~+) must also be used as forms. (`' (def: (~ name) - (function [(~@ args)] + (function [(~+ args)] (~ body))))")]) ("lux case" tokens {(#Cons template #Nil) @@ -2042,12 +2045,12 @@ (macro:' #export (|> tokens) (list [(tag$ ["lux" "doc"]) (text$ "## Piping macro. - (|> elems (map int/encode) (interpose \" \") (fold text/compose \"\")) + (|> elems (list/map int/encode) (interpose \" \") (fold text/compose \"\")) ## => (fold text/compose \"\" (interpose \" \" - (map int/encode elems)))")]) + (list/map int/encode elems)))")]) ("lux case" tokens {(#Cons [init apps]) (return (list (list/fold ("lux check" (-> Code Code Code) @@ -2070,12 +2073,12 @@ (macro:' #export (<| tokens) (list [(tag$ ["lux" "doc"]) (text$ "## Reverse piping macro. - (<| (fold text/compose \"\") (interpose \" \") (map int/encode) elems) + (<| (fold text/compose \"\") (interpose \" \") (list/map int/encode) elems) ## => (fold text/compose \"\" (interpose \" \" - (map int/encode elems)))")]) + (list/map int/encode elems)))")]) ("lux case" (list/reverse tokens) {(#Cons [init apps]) (return (list (list/fold ("lux check" (-> Code Code Code) @@ -2155,17 +2158,17 @@ template}) [meta (#Tuple elems)] - [meta (#Tuple (map (apply-template env) elems))] + [meta (#Tuple (list/map (apply-template env) elems))] [meta (#Form elems)] - [meta (#Form (map (apply-template env) elems))] + [meta (#Form (list/map (apply-template env) elems))] [meta (#Record members)] - [meta (#Record (map ("lux check" (-> (& Code Code) (& Code Code)) - (function' [kv] - (let' [[slot value] kv] - [(apply-template env slot) (apply-template env value)]))) - members))] + [meta (#Record (list/map ("lux check" (-> (& Code Code) (& Code Code)) + (function' [kv] + (let' [[slot value] kv] + [(apply-template env slot) (apply-template env value)]))) + members))] _ template})) @@ -2203,10 +2206,10 @@ (monad/map Monad tuple->list data)] {[(#Some bindings') (#Some data')] (let' [apply ("lux check" (-> RepEnv ($' List Code)) - (function' [env] (map (apply-template env) templates))) + (function' [env] (list/map (apply-template env) templates))) num-bindings (list/size bindings')] (if (every? (function' [sample] ("lux nat =" num-bindings sample)) - (map list/size data')) + (list/map list/size data')) (|> data' (join-map (compose apply (make-env bindings'))) return) @@ -2591,16 +2594,16 @@ (-> Code Code) ("lux case" type {[_ (#Form (#Cons [_ (#Tag tag)] parts))] - (form$ (#Cons [(tag$ tag) (map walk-type parts)])) + (form$ (#Cons [(tag$ tag) (list/map walk-type parts)])) [_ (#Tuple members)] - (` (& (~@ (map walk-type members)))) + (` (& (~+ (list/map walk-type members)))) [_ (#Form (#Cons type-fn args))] (list/fold ("lux check" (-> Code Code Code) (function' [arg type-fn] (` (#.Apply (~ arg) (~ type-fn))))) (walk-type type-fn) - (map walk-type args)) + (list/map walk-type args)) _ type})) @@ -2677,8 +2680,8 @@ _ (fail "Wrong syntax for variant case.")}))) pairs)] - (return [(` (& (~@ (map second members)))) - (#Some (map first members))])) + (return [(` (& (~+ (list/map second members)))) + (#Some (list/map first members))])) (#Cons type #Nil) ("lux case" type @@ -2686,7 +2689,7 @@ (return [(` #.Unit) (#Some (list member-name))]) [_ (#Form (#Cons [_ (#Tag "" member-name)] member-types))] - (return [(` (& (~@ member-types))) (#Some (list member-name))]) + (return [(` (& (~+ member-types))) (#Some (list member-name))]) _ (return [type #None])}) @@ -2704,20 +2707,20 @@ (return [member-name member-type]) [_ (#Form (#Cons [_ (#Tag "" member-name)] member-types))] - (return [member-name (` (& (~@ member-types)))]) + (return [member-name (` (& (~+ member-types)))]) _ (fail "Wrong syntax for variant case.")}))) (list& case cases))] - (return [(` (| (~@ (map second members)))) - (#Some (map first members))])) + (return [(` (| (~+ (list/map second members)))) + (#Some (list/map first members))])) _ (fail "Improper type-definition syntax")})) (def:''' (gensym prefix state) #Nil - (-> Text ($' Meta Code)) + (-> Text ($' Meta Ident)) ("lux case" state {{#info info #source source #current-module _ #modules modules #scopes scopes #type-context types #host host @@ -2729,7 +2732,7 @@ #seed (n/+ +1 seed) #expected expected #cursor cursor #scope-type-vars scope-type-vars} - (symbol$ ["" ($_ text/compose "__gensym__" prefix (nat/encode seed))]))})) + ["" ($_ text/compose "__gensym__" prefix (nat/encode seed))])})) (macro:' #export (Rec tokens) (list [(tag$ ["lux" "doc"]) @@ -2795,7 +2798,7 @@ body _ - (` (function' (~ name) [(~@ args)] (~ body)))}) + (` (function' (~ name) [(~+ args)] (~ body)))}) body'' ("lux case" ?type {(#Some type) (` (: (~ type) (~ body'))) @@ -2849,21 +2852,21 @@ [_ (#Form xs)] ($_ text/compose "(" (|> xs - (map code-to-text) + (list/map code-to-text) (interpose " ") list/reverse (list/fold text/compose "")) ")") [_ (#Tuple xs)] ($_ text/compose "[" (|> xs - (map code-to-text) + (list/map code-to-text) (interpose " ") list/reverse (list/fold text/compose "")) "]") [_ (#Record kvs)] ($_ text/compose "{" (|> kvs - (map (function' [kv] ("lux case" kv {[k v] ($_ text/compose (code-to-text k) " " (code-to-text v))}))) + (list/map (function' [kv] ("lux case" kv {[k v] ($_ text/compose (code-to-text k) " " (code-to-text v))}))) (interpose " ") list/reverse (list/fold text/compose "")) "}")} @@ -2897,7 +2900,7 @@ _ (fail ($_ text/compose "\"lux.case\" expects an even number of tokens: " (|> branches - (map code-to-text) + (list/map code-to-text) (interpose " ") list/reverse (list/fold text/compose ""))))})) @@ -2974,7 +2977,7 @@ _ (let' [pairs (|> patterns - (map (function' [pattern] (list pattern body))) + (list/map (function' [pattern] (list pattern body))) (list/join))] (return (list/compose pairs branches)))) _ @@ -3033,20 +3036,19 @@ _ #None)) - (#Some ident head tail body) - (let [g!blank (symbol$ ["" ""]) - g!name (symbol$ ident) + (#Some g!name head tail body) + (let [g!blank ["" ""] body+ (list/fold (: (-> Code Code Code) (function' [arg body'] (if (symbol? arg) - (` ("lux function" (~ g!blank) (~ arg) (~ body'))) - (` ("lux function" (~ g!blank) (~ g!blank) - (case (~ g!blank) (~ arg) (~ body'))))))) + (` ("lux function" (~@ g!blank) (~ arg) (~ body'))) + (` ("lux function" (~@ g!blank) (~@ g!blank) + (case (~@ g!blank) (~ arg) (~ body'))))))) body (list/reverse tail))] (return (list (if (symbol? head) - (` ("lux function" (~ g!name) (~ head) (~ body+))) - (` ("lux function" (~ g!name) (~ g!blank) (case (~ g!blank) (~ head) (~ body+)))))))) + (` ("lux function" (~@ g!name) (~ head) (~ body+))) + (` ("lux function" (~@ g!name) (~@ g!blank) (case (~@ g!blank) (~ head) (~ body+)))))))) #None (fail "Wrong syntax for function"))) @@ -3080,27 +3082,27 @@ [_ (#Tuple xs)] (|> xs - (map process-def-meta-value) + (list/map process-def-meta-value) untemplate-list (meta-code ["lux" "Tuple"])) [_ (#Record kvs)] (|> kvs - (map (: (-> [Code Code] Code) - (function [[k v]] - (` [(~ (process-def-meta-value k)) - (~ (process-def-meta-value v))])))) + (list/map (: (-> [Code Code] Code) + (function [[k v]] + (` [(~ (process-def-meta-value k)) + (~ (process-def-meta-value v))])))) untemplate-list (meta-code ["lux" "Record"])) )) (def:' (process-def-meta kvs) (-> (List [Code Code]) Code) - (untemplate-list (map (: (-> [Code Code] Code) - (function [[k v]] - (` [(~ (process-def-meta-value k)) - (~ (process-def-meta-value v))]))) - kvs))) + (untemplate-list (list/map (: (-> [Code Code] Code) + (function [[k v]] + (` [(~ (process-def-meta-value k)) + (~ (process-def-meta-value v))]))) + kvs))) (def:' (with-func-args args meta) (-> (List Code) Code Code) @@ -3110,15 +3112,15 @@ _ (` (#.Cons [[(~ cursor-code) (#.Tag ["lux" "func-args"])] - [(~ cursor-code) (#.Tuple (.list (~@ (map (function [arg] - (` [(~ cursor-code) (#.Text (~ (text$ (code-to-text arg))))])) - args))))]] + [(~ cursor-code) (#.Tuple (.list (~+ (list/map (function [arg] + (` [(~ cursor-code) (#.Text (~ (text$ (code-to-text arg))))])) + args))))]] (~ meta))))) (def:' (with-type-args args) (-> (List Code) Code) - (` {#.type-args [(~@ (map (function [arg] (text$ (code-to-text arg))) - args))]})) + (` {#.type-args [(~+ (list/map (function [arg] (text$ (code-to-text arg))) + args))]})) (def:' Export-Level Type @@ -3198,7 +3200,7 @@ body _ - (` (function (~ name) [(~@ args)] (~ body)))) + (` (function (~ name) [(~+ args)] (~ body)))) body (case ?type (#Some type) (` (: (~ type) (~ body))) @@ -3279,8 +3281,8 @@ (let [name (symbol$ name) def-sig (case args #Nil name - _ (` ((~ name) (~@ args))))] - (return (list (` (..def: (~@ (export-level exported?)) + _ (` ((~ name) (~+ args))))] + (return (list (` (..def: (~+ (export-level exported?)) (~ def-sig) (~ (meta-code-merge (` {#.macro? true}) meta)) @@ -3340,10 +3342,10 @@ (list/join sigs'))) #let [[_module _name] name+ def-name (symbol$ name) - sig-type (record$ (map (: (-> [Text Code] [Code Code]) - (function [[m-name m-type]] - [(tag$ ["" m-name]) m-type])) - members)) + sig-type (record$ (list/map (: (-> [Text Code] [Code Code]) + (function [[m-name m-type]] + [(tag$ ["" m-name]) m-type])) + members)) sig-meta (meta-code-merge (` {#.sig? true}) meta) usage (case args @@ -3351,8 +3353,8 @@ def-name _ - (` ((~ def-name) (~@ args))))]] - (return (list (` (..type: (~@ (export-level exported?)) (~ usage) (~ sig-meta) (~ sig-type)))))) + (` ((~ def-name) (~+ args))))]] + (return (list (` (..type: (~+ (export-level exported?)) (~ usage) (~ sig-meta) (~ sig-type)))))) #None (fail "Wrong syntax for sig:")))) @@ -3678,8 +3680,8 @@ _ (fail "No tags available for type."))) #let [tag-mappings (: (List [Text Code]) - (map (function [tag] [(second tag) (tag$ tag)]) - tags))] + (list/map (function [tag] [(second tag) (tag$ tag)]) + tags))] members (monad/map Monad (: (-> Code (Meta [Code Code])) (function [token] @@ -3766,12 +3768,12 @@ name _ - (` ((~ name) (~@ args))))] - (return (list (` (..def: (~@ (export-level exported?)) (~ usage) + (` ((~ name) (~+ args))))] + (return (list (` (..def: (~+ (export-level exported?)) (~ usage) (~ (meta-code-merge (` {#.struct? true}) meta)) (~ type) - (struct (~@ defs))))))) + (struct (~+ defs))))))) #None (fail "Cannot infer name, so struct must have a name other than \"_\"!")) @@ -3830,7 +3832,7 @@ type-meta (: Code (case tags?? (#Some tags) - (` {#.tags [(~@ (map text$ tags))] + (` {#.tags [(~+ (list/map text$ tags))] #.type? true}) _ @@ -3849,10 +3851,10 @@ (#Some type) _ - (#Some (` (All (~ type-name) [(~@ args)] (~ type)))))))] + (#Some (` (All (~ type-name) [(~+ args)] (~ type)))))))] (case type' (#Some type'') - (return (list (` (..def: (~@ (export-level exported?)) (~ type-name) + (return (list (` (..def: (~+ (export-level exported?)) (~ type-name) (~ ($_ meta-code-merge (with-type-args args) (if rec? (' {#.type-rec? true}) (' {})) type-meta @@ -3986,14 +3988,14 @@ (case tokens (^ (list& [_ (#Tag "" "open")] [_ (#Form parts)] tokens')) (if (|> parts - (map (: (-> Code Bool) - (function [part] - (case part - (^or [_ (#Text _)] [_ (#Symbol _)]) - true + (list/map (: (-> Code Bool) + (function [part] + (case part + (^or [_ (#Text _)] [_ (#Symbol _)]) + true - _ - false)))) + _ + false)))) (list/fold (function [r l] (and l r)) true)) (let [openings (list/fold (: (-> Code (List Openings) (List Openings)) (function [part openings] @@ -4022,14 +4024,14 @@ (def: (parse-short-openings parts) (-> (List Code) (Meta [(List Openings) (List Code)])) (if (|> parts - (map (: (-> Code Bool) - (function [part] - (case part - (^or [_ (#Text _)] [_ (#Symbol _)]) - true + (list/map (: (-> Code Bool) + (function [part] + (case part + (^or [_ (#Text _)] [_ (#Symbol _)]) + true - _ - false)))) + _ + false)))) (list/fold (function [r l] (and l r)) true)) (let [openings (list/fold (: (-> Code (List Openings) (List Openings)) (function [part openings] @@ -4054,16 +4056,16 @@ (def: (decorate-sub-importations super-name) (-> Text (List Importation) (List Importation)) - (map (: (-> Importation Importation) - (function [importation] - (let [{#import-name _name - #import-alias _alias - #import-refer {#refer-defs _referrals - #refer-open _openings}} importation] - {#import-name ($_ text/compose super-name "/" _name) - #import-alias _alias - #import-refer {#refer-defs _referrals - #refer-open _openings}}))))) + (list/map (: (-> Importation Importation) + (function [importation] + (let [{#import-name _name + #import-alias _alias + #import-refer {#refer-defs _referrals + #refer-open _openings}} importation] + {#import-name ($_ text/compose super-name "/" _name) + #import-alias _alias + #import-refer {#refer-defs _referrals + #refer-open _openings}}))))) (def: (replace-all pattern value template) (-> Text Text Text Text) @@ -4187,18 +4189,18 @@ modules)] (case (get module modules) (#Some =module) - (let [to-alias (map (: (-> [Text Def] - (List Text)) - (function [[name [def-type def-meta def-value]]] - (case [(get-meta ["lux" "export?"] def-meta) - (get-meta ["lux" "hidden?"] def-meta)] - [(#Some [_ (#Bool true)]) #None] - (list name) + (let [to-alias (list/map (: (-> [Text Def] + (List Text)) + (function [[name [def-type def-meta def-value]]] + (case [(get-meta ["lux" "export?"] def-meta) + (get-meta ["lux" "hidden?"] def-meta)] + [(#Some [_ (#Bool true)]) #None] + (list name) - _ - (list)))) - (let [{#module-hash _ #module-aliases _ #defs defs #imports _ #tags tags #types types #module-annotations _ #module-state _} =module] - defs))] + _ + (list)))) + (let [{#module-hash _ #module-aliases _ #defs defs #imports _ #tags tags #types types #module-annotations _ #module-state _} =module] + defs))] (#Right state (list/join to-alias))) #None @@ -4369,7 +4371,7 @@ name _ - ($_ text/compose "(" name " " (|> params (map type/show) (interpose " ") list/reverse (list/fold text/compose "")) ")")) + ($_ text/compose "(" name " " (|> params (list/map type/show) (interpose " ") list/reverse (list/fold text/compose "")) ")")) #Void "Void" @@ -4378,13 +4380,13 @@ "Unit" (#Sum _) - ($_ text/compose "(| " (|> (flatten-variant type) (map type/show) (interpose " ") list/reverse (list/fold text/compose "")) ")") + ($_ text/compose "(| " (|> (flatten-variant type) (list/map type/show) (interpose " ") list/reverse (list/fold text/compose "")) ")") (#Product _) - ($_ text/compose "[" (|> (flatten-tuple type) (map type/show) (interpose " ") list/reverse (list/fold text/compose "")) "]") + ($_ text/compose "[" (|> (flatten-tuple type) (list/map type/show) (interpose " ") list/reverse (list/fold text/compose "")) "]") (#Function _) - ($_ text/compose "(-> " (|> (flatten-lambda type) (map type/show) (interpose " ") list/reverse (list/fold text/compose "")) ")") + ($_ text/compose "(-> " (|> (flatten-lambda type) (list/map type/show) (interpose " ") list/reverse (list/fold text/compose "")) ")") (#Bound id) (nat/encode id) @@ -4405,7 +4407,7 @@ (let [[func args] (flatten-app type)] ($_ text/compose "(" (type/show func) " " - (|> args (map type/show) (interpose " ") list/reverse (list/fold text/compose "")) + (|> args (list/map type/show) (interpose " ") list/reverse (list/fold text/compose "")) ")")) (#Named [prefix name] _) @@ -4426,10 +4428,10 @@ (do Monad [full-body ((: (-> Ident [(List Ident) (List Type)] Code (Meta Code)) (function recur [source [tags members] target] - (let [pattern (record$ (map (function [[t-module t-name]] - [(tag$ [t-module t-name]) - (symbol$ ["" (text/compose prefix t-name)])]) - tags))] + (let [pattern (record$ (list/map (function [[t-module t-name]] + [(tag$ [t-module t-name]) + (symbol$ ["" (text/compose prefix t-name)])]) + tags))] (do Monad [enhanced-target (monad/fold Monad (function [[[_ m-name] m-type] enhanced-target] @@ -4462,7 +4464,7 @@ (^ (list& [_ (#Form (list [_ (#Text prefix)]))] body branches)) (do Monad [g!temp (gensym "temp")] - (return (list& g!temp (` (^open' (~ g!temp) (~ (text$ prefix)) (~ body))) branches))) + (return (list& (symbol$ g!temp) (` (^open' (~@ g!temp) (~ (text$ prefix)) (~ body))) branches))) (^ (list& [_ (#Form (list))] body branches)) (return (list& (` (..^open "")) body branches)) @@ -4524,13 +4526,14 @@ g!output (gensym "")] (case (resolve-struct-type type) (#Some members) - (let [pattern (record$ (map (: (-> [Ident [Nat Type]] [Code Code]) - (function [[[r-prefix r-name] [r-idx r-type]]] - [(tag$ [r-prefix r-name]) (if (n/= idx r-idx) - g!output - g!_)])) - (zip2 tags (enumerate members))))] - (return (list (` ("lux case" (~ record) {(~ pattern) (~ g!output)}))))) + (let [pattern (record$ (list/map (: (-> [Ident [Nat Type]] [Code Code]) + (function [[[r-prefix r-name] [r-idx r-type]]] + [(tag$ [r-prefix r-name]) + (symbol$ (if (n/= idx r-idx) + g!output + g!_))])) + (zip2 tags (enumerate members))))] + (return (list (` ("lux case" (~ record) {(~ pattern) (~@ g!output)}))))) _ (fail "get@ can only use records."))) @@ -4545,7 +4548,7 @@ (^ (list selector)) (do Monad [g!record (gensym "record")] - (wrap (list (` (function [(~ g!record)] (..get@ (~ selector) (~ g!record))))))) + (wrap (list (` (function [(~@ g!record)] (..get@ (~ selector) (~@ g!record))))))) _ (fail "Wrong syntax for get@"))) @@ -4606,27 +4609,27 @@ (macro: #export (|>> tokens) {#.doc "## Similar to the piping macro, but rather than taking an initial object to work on, creates a function for taking it. - (|>> (map int/encode) (interpose \" \") (fold text/compose \"\")) + (|>> (list/map int/encode) (interpose \" \") (fold text/compose \"\")) ## => (function [] (fold text/compose \"\" (interpose \" \" - (map int/encode ))))"} + (list/map int/encode ))))"} (do Monad [g!arg (gensym "arg")] - (return (list (` (function [(~ g!arg)] (|> (~ g!arg) (~@ tokens)))))))) + (return (list (` (function [(~@ g!arg)] (|> (~@ g!arg) (~+ tokens)))))))) (macro: #export (<<| tokens) {#.doc "## Similar to the piping macro, but rather than taking an initial object to work on, creates a function for taking it. - (<<| (fold text/compose \"\") (interpose \" \") (map int/encode)) + (<<| (fold text/compose \"\") (interpose \" \") (list/map int/encode)) ## => (function [] (fold text/compose \"\" (interpose \" \" - (map int/encode ))))"} + (list/map int/encode ))))"} (do Monad [g!arg (gensym "arg")] - (return (list (` (function [(~ g!arg)] (<| (~@ tokens) (~ g!arg)))))))) + (return (list (` (function [(~@ g!arg)] (<| (~+ tokens) (~@ g!arg)))))))) (def: (imported-by? import-name module-name) (-> Text Text (Meta Bool)) @@ -4660,7 +4663,7 @@ _ (fail ($_ text/compose "Wrong syntax for refer @ " current-module "\n" (|> options - (map code-to-text) + (list/map code-to-text) (interpose " ") (list/fold text/compose ""))))))) @@ -4695,19 +4698,19 @@ #Nothing (wrap (list))) - #let [defs (map (: (-> Text Code) - (function [def] - (` ("lux def" (~ (symbol$ ["" def])) - (~ (symbol$ [module-name def])) - [(~ cursor-code) - (#.Record (#Cons [[(~ cursor-code) (#.Tag ["lux" "alias"])] - [(~ cursor-code) (#.Symbol [(~ (text$ module-name)) (~ (text$ def))])]] - #Nil))])))) - defs') + #let [defs (list/map (: (-> Text Code) + (function [def] + (` ("lux def" (~ (symbol$ ["" def])) + (~ (symbol$ [module-name def])) + [(~ cursor-code) + (#.Record (#Cons [[(~ cursor-code) (#.Tag ["lux" "alias"])] + [(~ cursor-code) (#.Symbol [(~ (text$ module-name)) (~ (text$ def))])]] + #Nil))])))) + defs') openings (join-map (: (-> Openings (List Code)) (function [[prefix structs]] - (map (function [[_ name]] (` (open (~ (symbol$ [module-name name])) (~ (text$ prefix))))) - structs))) + (list/map (function [[_ name]] (` (open (~ (symbol$ [module-name name])) (~ (text$ prefix))))) + structs))) r-opens)]] (wrap (list/compose defs openings)) )) @@ -4730,21 +4733,21 @@ (list (' #refer) (' #all)) (#Only defs) - (list (' #refer) (`' (#only (~@ (map (|>> [""] symbol$) - defs))))) + (list (' #refer) (`' (#only (~+ (list/map (|>> [""] symbol$) + defs))))) (#Exclude defs) - (list (' #refer) (`' (#exclude (~@ (map (|>> [""] symbol$) - defs))))) + (list (' #refer) (`' (#exclude (~+ (list/map (|>> [""] symbol$) + defs))))) #Nothing (list))) =opens (join-map (function [[prefix structs]] - (list& (text$ prefix) (map symbol$ structs))) + (list& (text$ prefix) (list/map symbol$ structs))) r-opens)] (` (..refer (~ (text$ module-name)) - (~@ =defs) - (~' #open) ((~@ =opens)))))) + (~+ =defs) + (~' #open) ((~+ =opens)))))) (macro: #export (module: tokens) {#.doc "Module-definition macro. @@ -4783,15 +4786,15 @@ [(list) tokens]))] current-module current-module-name imports (parse-imports current-module _imports) - #let [=imports (map (: (-> Importation Code) - (function [[m-name m-alias =refer]] - (` [(~ (text$ m-name)) (~ (text$ (default "" m-alias)))]))) - imports) - =refers (map (: (-> Importation Code) - (function [[m-name m-alias =refer]] - (refer-to-code m-name =refer))) - imports) - =meta (process-def-meta (list& [(` #.imports) (` [(~@ =imports)])] + #let [=imports (list/map (: (-> Importation Code) + (function [[m-name m-alias =refer]] + (` [(~ (text$ m-name)) (~ (text$ (default "" m-alias)))]))) + imports) + =refers (list/map (: (-> Importation Code) + (function [[m-name m-alias =refer]] + (refer-to-code m-name =refer))) + imports) + =meta (process-def-meta (list& [(` #.imports) (` [(~+ =imports)])] _meta)) =module (` ("lux module" [(~ cursor-code) (#.Record (~ =meta))]))]] @@ -4808,7 +4811,7 @@ (return (list (` (let [(^open) (~ struct)] (~ (symbol$ member)))))) (^ (list& struct [_ (#Symbol member)] args)) - (return (list (` ((let [(^open) (~ struct)] (~ (symbol$ member))) (~@ args))))) + (return (list (` ((let [(^open) (~ struct)] (~ (symbol$ member))) (~+ args))))) _ (fail "Wrong syntax for ::"))) @@ -4841,18 +4844,20 @@ (function [[r-slot-name [r-idx r-type]]] (do Monad [g!slot (gensym "")] - (return [r-slot-name r-idx g!slot])))) + (return [r-slot-name r-idx (symbol$ g!slot)])))) (zip2 tags (enumerate members)))] - (let [pattern (record$ (map (: (-> [Ident Nat Code] [Code Code]) - (function [[r-slot-name r-idx r-var]] - [(tag$ r-slot-name) r-var])) - pattern')) - output (record$ (map (: (-> [Ident Nat Code] [Code Code]) - (function [[r-slot-name r-idx r-var]] - [(tag$ r-slot-name) (if (n/= idx r-idx) - value - r-var)])) - pattern'))] + (let [pattern (record$ (list/map (: (-> [Ident Nat Code] [Code Code]) + (function [[r-slot-name r-idx r-var]] + [(tag$ r-slot-name) + r-var])) + pattern')) + output (record$ (list/map (: (-> [Ident Nat Code] [Code Code]) + (function [[r-slot-name r-idx r-var]] + [(tag$ r-slot-name) + (if (n/= idx r-idx) + value + r-var)])) + pattern'))] (return (list (` ("lux case" (~ record) {(~ pattern) (~ output)})))))) _ @@ -4866,35 +4871,36 @@ _ (do Monad [bindings (monad/map Monad - (: (-> Code (Meta Code)) + (: (-> Code (Meta Ident)) (function [_] (gensym "temp"))) slots) #let [pairs (zip2 slots bindings) - update-expr (list/fold (: (-> [Code Code] Code Code) + update-expr (list/fold (: (-> [Code Ident] Code Code) (function [[s b] v] - (` (..set@ (~ s) (~ v) (~ b))))) + (` (..set@ (~ s) (~ v) (~@ b))))) value (list/reverse pairs)) - [_ accesses'] (list/fold (: (-> [Code Code] [Code (List (List Code))] [Code (List (List Code))]) + [_ accesses'] (list/fold (: (-> [Code Ident] [Code (List (List Code))] [Code (List (List Code))]) (function [[new-slot new-binding] [old-record accesses']] - [(` (get@ (~ new-slot) (~ new-binding))) - (#Cons (list new-binding old-record) accesses')])) + (let [new-binding (symbol$ new-binding)] + [(` (get@ (~ new-slot) (~ new-binding))) + (#Cons (list new-binding old-record) accesses')]))) [record (: (List (List Code)) #Nil)] pairs) accesses (list/join (list/reverse accesses'))]] - (wrap (list (` (let [(~@ accesses)] + (wrap (list (` (let [(~+ accesses)] (~ update-expr))))))) (^ (list selector value)) (do Monad [g!record (gensym "record")] - (wrap (list (` (function [(~ g!record)] (..set@ (~ selector) (~ value) (~ g!record))))))) + (wrap (list (` (function [(~@ g!record)] (..set@ (~ selector) (~ value) (~@ g!record))))))) (^ (list selector)) (do Monad [g!value (gensym "value") g!record (gensym "record")] - (wrap (list (` (function [(~ g!value) (~ g!record)] (..set@ (~ selector) (~ g!value) (~ g!record))))))) + (wrap (list (` (function [(~@ g!value) (~@ g!record)] (..set@ (~ selector) (~@ g!value) (~@ g!record))))))) _ (fail "Wrong syntax for set@"))) @@ -4927,18 +4933,20 @@ (function [[r-slot-name [r-idx r-type]]] (do Monad [g!slot (gensym "")] - (return [r-slot-name r-idx g!slot])))) + (return [r-slot-name r-idx (symbol$ g!slot)])))) (zip2 tags (enumerate members)))] - (let [pattern (record$ (map (: (-> [Ident Nat Code] [Code Code]) - (function [[r-slot-name r-idx r-var]] - [(tag$ r-slot-name) r-var])) - pattern')) - output (record$ (map (: (-> [Ident Nat Code] [Code Code]) - (function [[r-slot-name r-idx r-var]] - [(tag$ r-slot-name) (if (n/= idx r-idx) - (` ((~ fun) (~ r-var))) - r-var)])) - pattern'))] + (let [pattern (record$ (list/map (: (-> [Ident Nat Code] [Code Code]) + (function [[r-slot-name r-idx r-var]] + [(tag$ r-slot-name) + r-var])) + pattern')) + output (record$ (list/map (: (-> [Ident Nat Code] [Code Code]) + (function [[r-slot-name r-idx r-var]] + [(tag$ r-slot-name) + (if (n/= idx r-idx) + (` ((~ fun) (~ r-var))) + r-var)])) + pattern'))] (return (list (` ("lux case" (~ record) {(~ pattern) (~ output)})))))) _ @@ -4953,20 +4961,20 @@ (do Monad [g!record (gensym "record") g!temp (gensym "temp")] - (wrap (list (` (let [(~ g!record) (~ record) - (~ g!temp) (get@ [(~@ slots)] (~ g!record))] - (set@ [(~@ slots)] ((~ fun) (~ g!temp)) (~ g!record)))))))) + (wrap (list (` (let [(~@ g!record) (~ record) + (~@ g!temp) (get@ [(~+ slots)] (~@ g!record))] + (set@ [(~+ slots)] ((~ fun) (~@ g!temp)) (~@ g!record)))))))) (^ (list selector fun)) (do Monad [g!record (gensym "record")] - (wrap (list (` (function [(~ g!record)] (..update@ (~ selector) (~ fun) (~ g!record))))))) + (wrap (list (` (function [(~@ g!record)] (..update@ (~ selector) (~ fun) (~@ g!record))))))) (^ (list selector)) (do Monad [g!fun (gensym "fun") g!record (gensym "record")] - (wrap (list (` (function [(~ g!fun) (~ g!record)] (..update@ (~ selector) (~ g!fun) (~ g!record))))))) + (wrap (list (` (function [(~@ g!fun) (~@ g!record)] (..update@ (~ selector) (~@ g!fun) (~@ g!record))))))) _ (fail "Wrong syntax for update@"))) @@ -5015,9 +5023,9 @@ (do Monad [bindings' (monad/map Monad get-name bindings) data' (monad/map Monad tuple->list data)] - (if (every? (n/= (list/size bindings')) (map list/size data')) + (if (every? (n/= (list/size bindings')) (list/map list/size data')) (let [apply (: (-> RepEnv (List Code)) - (function [env] (map (apply-template env) templates)))] + (function [env] (list/map (apply-template env) templates)))] (|> data' (join-map (compose apply (make-env bindings'))) wrap)) @@ -5057,14 +5065,14 @@ (^template [] [[_ _ column] ( parts)] - (list/fold n/min column (map find-baseline-column parts))) + (list/fold n/min column (list/map find-baseline-column parts))) ([#Form] [#Tuple]) [[_ _ column] (#Record pairs)] (list/fold n/min column - (list/compose (map (|>> first find-baseline-column) pairs) - (map (|>> second find-baseline-column) pairs))) + (list/compose (list/map (|>> first find-baseline-column) pairs) + (list/map (|>> second find-baseline-column) pairs))) )) (type: Doc-Fragment @@ -5149,7 +5157,7 @@ (def: rejoin-all-pairs (-> (List [Code Code]) (List Code)) - (|>> (map rejoin-pair) list/join)) + (|>> (list/map rejoin-pair) list/join)) (def: (doc-example->Text prev-cursor baseline example) (-> Cursor Nat Code [Cursor Text]) @@ -5198,7 +5206,7 @@ (#Doc-Comment comment) (|> comment (text/split "\n") - (map (function [line] ($_ text/compose "## " line "\n"))) + (list/map (function [line] ($_ text/compose "## " line "\n"))) text/join) (#Doc-Example example) @@ -5220,7 +5228,7 @@ x)))"} (return (list (` [(~ cursor-code) (#.Text (~ (|> tokens - (map (|>> identify-doc-fragment doc-fragment->Text)) + (list/map (|>> identify-doc-fragment doc-fragment->Text)) text/join text$)))])))) @@ -5242,7 +5250,7 @@ (-> Type Code) (case type (#Primitive name params) - (` (#Primitive (~ (text$ name)) (~ (untemplate-list (map type-to-code params))))) + (` (#Primitive (~ (text$ name)) (~ (untemplate-list (list/map type-to-code params))))) #Void (` #Void) @@ -5268,11 +5276,11 @@ (` (#Ex (~ (nat$ id)))) (#UnivQ env type) - (let [env' (untemplate-list (map type-to-code env))] + (let [env' (untemplate-list (list/map type-to-code env))] (` (#UnivQ (~ env') (~ (type-to-code type))))) (#ExQ env type) - (let [env' (untemplate-list (map type-to-code env))] + (let [env' (untemplate-list (list/map type-to-code env))] (` (#ExQ (~ env') (~ (type-to-code type))))) (#Apply arg fun) @@ -5293,8 +5301,8 @@ (case tokens (^ (list [_ (#Tuple bindings)] body)) (let [pairs (as-pairs bindings) - vars (map first pairs) - inits (map second pairs)] + vars (list/map first pairs) + inits (list/map second pairs)] (if (every? symbol? inits) (do Monad [inits' (: (Meta (List Ident)) @@ -5303,18 +5311,19 @@ #None (fail "Wrong syntax for loop"))) init-types (monad/map Monad find-type inits') expected get-expected-type] - (return (list (` (("lux check" (-> (~@ (map type-to-code init-types)) + (return (list (` (("lux check" (-> (~+ (list/map type-to-code init-types)) (~ (type-to-code expected))) - (function (~ (symbol$ ["" "recur"])) [(~@ vars)] + (function (~ (symbol$ ["" "recur"])) [(~+ vars)] (~ body))) - (~@ inits)))))) + (~+ inits)))))) (do Monad [aliases (monad/map Monad - (: (-> Code (Meta Code)) + (: (-> Code (Meta Ident)) (function [_] (gensym ""))) - inits)] - (return (list (` (let [(~@ (interleave aliases inits))] - (.loop [(~@ (interleave vars aliases))] + inits) + #let [aliases (list/map symbol$ aliases)]] + (return (list (` (let [(~+ (interleave aliases inits))] + (.loop [(~+ (interleave vars aliases))] (~ body))))))))) _ @@ -5345,16 +5354,16 @@ output (resolve-tag hslot) g!_ (gensym "_") #let [[idx tags exported? type] output - slot-pairings (map (: (-> Ident [Text Code]) - (function [[module name]] [name (symbol$ ["" name])])) - (list& hslot tslots)) - pattern (record$ (map (: (-> Ident [Code Code]) - (function [[module name]] - (let [tag (tag$ [module name])] - (case (get name slot-pairings) - (#Some binding) [tag binding] - #None [tag g!_])))) - tags))]] + slot-pairings (list/map (: (-> Ident [Text Code]) + (function [[module name]] [name (symbol$ ["" name])])) + (list& hslot tslots)) + pattern (record$ (list/map (: (-> Ident [Code Code]) + (function [[module name]] + (let [tag (tag$ [module name])] + (case (get name slot-pairings) + (#Some binding) [tag binding] + #None [tag (symbol$ g!_)])))) + tags))]] (return (list& pattern body branches))) _ @@ -5430,8 +5439,8 @@ (do Monad [expansion (macro-expand-once macro-expr)] (case (place-tokens var-name expansion (` (.with-expansions - [(~@ bindings')] - (~@ bodies)))) + [(~+ bindings')] + (~+ bodies)))) (#Some output) (wrap output) @@ -5569,13 +5578,13 @@ (wrap [init extras'])))) (def: (multi-level-case$ g!_ [[init-pattern levels] body]) - (-> Code [Multi-Level-Case Code] (List Code)) + (-> Ident [Multi-Level-Case Code] (List Code)) (let [inner-pattern-body (list/fold (function [[calculation pattern] success] (` (case (~ calculation) (~ pattern) (~ success) - (~ g!_) + (~@ g!_) #.None))) (` (#.Some (~ body))) (: (List [Code Code]) (list/reverse levels)))] @@ -5606,19 +5615,19 @@ [mlc (multi-level-case^ levels) expected get-expected-type g!temp (gensym "temp")] - (let [output (list g!temp + (let [output (list (symbol$ g!temp) (` ("lux case" ("lux check" (#.Apply (~ (type-to-code expected)) Maybe) - (case (~ g!temp) - (~@ (multi-level-case$ g!temp [mlc body])) + (case (~@ g!temp) + (~+ (multi-level-case$ g!temp [mlc body])) - (~ g!temp) + (~@ g!temp) #.None)) - {(#Some (~ g!temp)) - (~ g!temp) + {(#Some (~@ g!temp)) + (~@ g!temp) #None - (case (~ g!temp) - (~@ next-branches))})))] + (case (~@ g!temp) + (~+ next-branches))})))] (wrap output))) _ @@ -5713,9 +5722,9 @@ (to-list set))))} (case tokens (^ (list& [_meta (#Form (list [_ (#Symbol ["" name])] pattern))] body branches)) - (let [g!whole (symbol$ ["" name])] - (return (list& g!whole - (` (case (~ g!whole) (~ pattern) (~ body))) + (let [g!whole ["" name]] + (return (list& (symbol$ g!whole) + (` (case (~@ g!whole) (~ pattern) (~ body))) branches))) _ @@ -5728,9 +5737,9 @@ (foo value)))} (case tokens (^ (list& [_meta (#Form (list [_ (#Symbol ["" name])] [_ (#Tuple steps)]))] body branches)) - (let [g!name (symbol$ ["" name])] - (return (list& g!name - (` (let [(~ g!name) (|> (~ g!name) (~@ steps))] + (let [g!name ["" name]] + (return (list& (symbol$ g!name) + (` (let [(~@ g!name) (|> (~@ g!name) (~+ steps))] (~ body))) branches))) @@ -5876,18 +5885,18 @@ g!tokens (gensym "tokens") g!compiler (gensym "compiler") g!_ (gensym "_") - #let [rep-env (map (function [arg] - [arg (` ((~' ~) (~ (symbol$ ["" arg]))))]) - args)]] - (wrap (list (` (macro: (~@ (gen-export-level ?export-level)) - ((~ (symbol$ ["" name])) (~ g!tokens) (~ g!compiler)) + #let [rep-env (list/map (function [arg] + [arg (` ((~' ~) (~ (symbol$ ["" arg]))))]) + args)]] + (wrap (list (` (macro: (~+ (gen-export-level ?export-level)) + ((~ (symbol$ ["" name])) (~@ g!tokens) (~@ g!compiler)) (~ anns) - (case (~ g!tokens) - (^ (list (~@ (map (|>> [""] symbol$) args)))) - (#.Right [(~ g!compiler) + (case (~@ g!tokens) + (^ (list (~+ (list/map (|>> [""] symbol$) args)))) + (#.Right [(~@ g!compiler) (list (` (~ (replace-syntax rep-env input-template))))]) - (~ g!_) + (~@ g!_) (#.Left (~ (text$ (text/compose "Wrong syntax for " name)))) ))))) )) @@ -5972,14 +5981,14 @@ (^ [ann (#Form (list [_ (#Symbol ["" "~~"])] expansion))]) (do Monad [g!expansion (gensym "g!expansion")] - (wrap [(list [g!expansion expansion]) g!expansion])) + (wrap [(list [(symbol$ g!expansion) expansion]) (symbol$ g!expansion)])) (^template [] [ann ( parts)] (do Monad [=parts (monad/map Monad label-code parts)] - (wrap [(list/fold list/compose (list) (map left =parts)) - [ann ( (map right =parts))]]))) + (wrap [(list/fold list/compose (list) (list/map left =parts)) + [ann ( (list/map right =parts))]]))) ([#Form] [#Tuple]) [ann (#Record kvs)] @@ -5993,8 +6002,8 @@ [val-labels val-labelled] =val]] (wrap [(list/compose key-labels val-labels) [key-labelled val-labelled]]))) kvs)] - (wrap [(list/fold list/compose (list) (map left =kvs)) - [ann (#Record (map right =kvs))]])) + (wrap [(list/fold list/compose (list) (list/map left =kvs)) + [ann (#Record (list/map right =kvs))]])) _ (return [(list) code]))) @@ -6005,8 +6014,8 @@ (do Monad [=raw (label-code raw) #let [[labels labelled] =raw]] - (wrap (list (` (with-expansions [(~@ (|> labels - (map (function [[label expansion]] (list label expansion))) + (wrap (list (` (with-expansions [(~+ (|> labels + (list/map (function [[label expansion]] (list label expansion))) list/join))] (~ labelled)))))) @@ -6034,7 +6043,7 @@ [_ ( value)] (do Monad [g!meta (gensym "g!meta")] - (wrap (` [(~ g!meta) ( (~ ( value)))])))) + (wrap (` [(~@ g!meta) ( (~ ( value)))])))) ([#Bool "Bool" bool$] [#Nat "Nat" nat$] [#Int "Int" int$] @@ -6054,29 +6063,29 @@ (wrap (` [(~ =key) (~ =value)])))) fields) g!meta (gensym "g!meta")] - (wrap (` [(~ g!meta) (#.Record (~ (untemplate-list =fields)))]))) + (wrap (` [(~@ g!meta) (#.Record (~ (untemplate-list =fields)))]))) [_ (#Form (#Cons [[_ (#Symbol ["" "~"])] (#Cons [unquoted #Nil])]))] (return unquoted) - [_ (#Form (#Cons [[_ (#Symbol ["" "~@"])] (#Cons [spliced #Nil])]))] - (fail "Cannot use (~@) inside of ^code unless it is the last element in a form or a tuple.") + [_ (#Form (#Cons [[_ (#Symbol ["" "~+"])] (#Cons [spliced #Nil])]))] + (fail "Cannot use (~+) inside of ^code unless it is the last element in a form or a tuple.") (^template [] [_ ( elems)] (case (list/reverse elems) - (#Cons [_ (#Form (#Cons [[_ (#Symbol ["" "~@"])] (#Cons [spliced #Nil])]))] + (#Cons [_ (#Form (#Cons [[_ (#Symbol ["" "~+"])] (#Cons [spliced #Nil])]))] inits) (do Monad [=inits (monad/map Monad untemplate-pattern (list/reverse inits)) g!meta (gensym "g!meta")] - (wrap (` [(~ g!meta) ( (~ (untemplate-list& spliced =inits)))]))) + (wrap (` [(~@ g!meta) ( (~ (untemplate-list& spliced =inits)))]))) _ (do Monad [=elems (monad/map Monad untemplate-pattern elems) g!meta (gensym "g!meta")] - (wrap (` [(~ g!meta) ( (~ (untemplate-list =elems)))]))))) + (wrap (` [(~@ g!meta) ( (~ (untemplate-list =elems)))]))))) ([#Tuple] [#Form]) )) -- cgit v1.2.3