diff options
author | Eduardo Julian | 2017-11-29 04:51:04 -0400 |
---|---|---|
committer | Eduardo Julian | 2017-11-29 04:51:04 -0400 |
commit | 8c5cca122817bc63f4f84cc8351ced3cb67e5eea (patch) | |
tree | 8803dd3ed59ddcc6b964354fd312ab9e62e12cd8 /stdlib/source/lux/lang | |
parent | 1ef969c8ce0f1a83ffa8d26d779806190ac3eced (diff) |
- Changed the identifier separator, from the semi-colon (;) to the period/dot (.).
Diffstat (limited to '')
-rw-r--r-- | stdlib/source/lux/lang/syntax.lux | 426 | ||||
-rw-r--r-- | stdlib/source/lux/lang/type.lux | 188 | ||||
-rw-r--r-- | stdlib/source/lux/lang/type/check.lux | 398 |
3 files changed, 506 insertions, 506 deletions
diff --git a/stdlib/source/lux/lang/syntax.lux b/stdlib/source/lux/lang/syntax.lux index 49e27aecd..46558014e 100644 --- a/stdlib/source/lux/lang/syntax.lux +++ b/stdlib/source/lux/lang/syntax.lux @@ -24,7 +24,7 @@ ## Lux Code nodes/tokens are annotated with cursor meta-data ## (file-name, line, column) to keep track of their provenance and ## location, which is helpful for documentation and debugging. -(;module: +(.module: lux (lux (control monad ["p" parser "p/" Monad<Parser>] @@ -51,42 +51,42 @@ ## It operates recursively in order to produce the longest continuous ## chunk of white-space. (def: (space^ where) - (-> Cursor (l;Lexer [Cursor Text])) - (p;either (do p;Monad<Parser> - [content (l;many (l;one-of white-space))] - (wrap [(update@ #;column (n/+ (text;size content)) where) + (-> Cursor (l.Lexer [Cursor Text])) + (p.either (do p.Monad<Parser> + [content (l.many (l.one-of white-space))] + (wrap [(update@ #.column (n/+ (text.size content)) where) content])) ## New-lines must be handled as a separate case to ensure line ## information is handled properly. - (do p;Monad<Parser> - [content (l;many (l;one-of new-line))] + (do p.Monad<Parser> + [content (l.many (l.one-of new-line))] (wrap [(|> where - (update@ #;line (n/+ (text;size content))) - (set@ #;column +0)) + (update@ #.line (n/+ (text.size content))) + (set@ #.column +0)) content])) )) ## Single-line comments can start anywhere, but only go up to the ## next new-line. (def: (single-line-comment^ where) - (-> Cursor (l;Lexer [Cursor Text])) - (do p;Monad<Parser> - [_ (l;this "##") - comment (l;some (l;none-of new-line)) - _ (l;this new-line)] + (-> Cursor (l.Lexer [Cursor Text])) + (do p.Monad<Parser> + [_ (l.this "##") + comment (l.some (l.none-of new-line)) + _ (l.this new-line)] (wrap [(|> where - (update@ #;line n/inc) - (set@ #;column +0)) + (update@ #.line n/inc) + (set@ #.column +0)) comment]))) ## This is just a helper parser to find text which doesn't run into ## any special character sequences for multi-line comments. (def: comment-bound^ - (l;Lexer Unit) - ($_ p;either - (l;this new-line) - (l;this ")#") - (l;this "#("))) + (l.Lexer Unit) + ($_ p.either + (l.this new-line) + (l.this ")#") + (l.this "#("))) ## Multi-line comments are bounded by #( these delimiters, #(and, they may ## also be nested)# )#. @@ -94,26 +94,26 @@ ## That is, any nested comment must have matched delimiters. ## Unbalanced comments ought to be rejected as invalid code. (def: (multi-line-comment^ where) - (-> Cursor (l;Lexer [Cursor Text])) - (do p;Monad<Parser> - [_ (l;this "#(")] + (-> Cursor (l.Lexer [Cursor Text])) + (do p.Monad<Parser> + [_ (l.this "#(")] (loop [comment "" - where (update@ #;column (n/+ +2) where)] - ($_ p;either + where (update@ #.column (n/+ +2) where)] + ($_ p.either ## These are normal chunks of commented text. (do @ - [chunk (l;many (l;not comment-bound^))] + [chunk (l.many (l.not comment-bound^))] (recur (format comment chunk) (|> where - (update@ #;column (n/+ (text;size chunk)))))) + (update@ #.column (n/+ (text.size chunk)))))) ## This is a special rule to handle new-lines within ## comments properly. (do @ - [_ (l;this new-line)] + [_ (l.this new-line)] (recur (format comment new-line) (|> where - (update@ #;line n/inc) - (set@ #;column +0)))) + (update@ #.line n/inc) + (set@ #.column +0)))) ## This is the rule for handling nested sub-comments. ## Ultimately, the whole comment is just treated as text ## (the comment must respect the syntax structure, but the @@ -126,8 +126,8 @@ sub-where)) ## Finally, this is the rule for closing the comment. (do @ - [_ (l;this ")#")] - (wrap [(update@ #;column (n/+ +2) where) + [_ (l.this ")#")] + (wrap [(update@ #.column (n/+ +2) where) comment])) )))) @@ -138,8 +138,8 @@ ## from being used in any situation (alternatively, forcing one type ## of comment to be the only usable one). (def: (comment^ where) - (-> Cursor (l;Lexer [Cursor Text])) - (p;either (single-line-comment^ where) + (-> Cursor (l.Lexer [Cursor Text])) + (p.either (single-line-comment^ where) (multi-line-comment^ where))) ## To simplify parsing, I remove any left-padding that an Code token @@ -147,15 +147,15 @@ ## Left-padding is assumed to be either white-space or a comment. ## The cursor gets updated, but the padding gets ignored. (def: (left-padding^ where) - (-> Cursor (l;Lexer Cursor)) - ($_ p;either - (do p;Monad<Parser> + (-> Cursor (l.Lexer Cursor)) + ($_ p.either + (do p.Monad<Parser> [[where comment] (comment^ where)] (left-padding^ where)) - (do p;Monad<Parser> + (do p.Monad<Parser> [[where white-space] (space^ where)] (left-padding^ where)) - (:: p;Monad<Parser> wrap where))) + (:: p.Monad<Parser> wrap where))) ## Escaped character sequences follow the usual syntax of ## back-slash followed by a letter (e.g. \n). @@ -163,10 +163,10 @@ ## and 4 characters long (e.g. \u12aB). ## Escaped characters may show up in Char and Text literals. (def: escaped-char^ - (l;Lexer [Nat Text]) - (p;after (l;this "\\") - (do p;Monad<Parser> - [code l;any] + (l.Lexer [Nat Text]) + (p.after (l.this "\\") + (do p.Monad<Parser> + [code l.any] (case code ## Handle special cases. "t" (wrap [+2 "\t"]) @@ -180,169 +180,169 @@ ## Handle unicode escapes. "u" - (do p;Monad<Parser> - [code (l;between +1 +4 l;hexadecimal)] - (wrap (case (|> code (format "+") (:: number;Hex@Codec<Text,Nat> decode)) - (#;Right value) - [(n/+ +2 (text;size code)) (text;from-code value)] + (do p.Monad<Parser> + [code (l.between +1 +4 l.hexadecimal)] + (wrap (case (|> code (format "+") (:: number.Hex@Codec<Text,Nat> decode)) + (#.Right value) + [(n/+ +2 (text.size code)) (text.from-code value)] _ (undefined)))) _ - (p;fail (format "Invalid escaping syntax: " (%t code))))))) + (p.fail (format "Invalid escaping syntax: " (%t code))))))) ## These are very simple parsers that just cut chunks of text in ## specific shapes and then use decoders already present in the ## standard library to actually produce the values from the literals. (def: rich-digit - (l;Lexer Text) - (p;either l;decimal - (p;after (l;this "_") (p/wrap "")))) + (l.Lexer Text) + (p.either l.decimal + (p.after (l.this "_") (p/wrap "")))) (def: rich-digits^ - (l;Lexer Text) - (l;seq l;decimal - (l;some rich-digit))) + (l.Lexer Text) + (l.seq l.decimal + (l.some rich-digit))) (def: (marker^ token) - (-> Text (l;Lexer Text)) - (p;after (l;this token) (p/wrap token))) + (-> Text (l.Lexer Text)) + (p.after (l.this token) (p/wrap token))) (do-template [<name> <tag> <lexer> <codec>] [(def: #export (<name> where) - (-> Cursor (l;Lexer [Cursor Code])) - (do p;Monad<Parser> + (-> Cursor (l.Lexer [Cursor Code])) + (do p.Monad<Parser> [chunk <lexer>] (case (:: <codec> decode chunk) - (#;Left error) - (p;fail error) + (#.Left error) + (p.fail error) - (#;Right value) - (wrap [(update@ #;column (n/+ (text;size chunk)) where) + (#.Right value) + (wrap [(update@ #.column (n/+ (text.size chunk)) where) [where (<tag> value)]]))))] - [bool #;Bool - (p;either (marker^ "true") (marker^ "false")) - bool;Codec<Text,Bool>] + [bool #.Bool + (p.either (marker^ "true") (marker^ "false")) + bool.Codec<Text,Bool>] - [int #;Int - (l;seq (p;default "" (l;one-of "-")) + [int #.Int + (l.seq (p.default "" (l.one-of "-")) rich-digits^) - number;Codec<Text,Int>] + number.Codec<Text,Int>] - [deg #;Deg - (l;seq (l;one-of ".") + [deg #.Deg + (l.seq (l.one-of ".") rich-digits^) - number;Codec<Text,Deg>] + number.Codec<Text,Deg>] ) (def: (nat-char where) - (-> Cursor (l;Lexer [Cursor Code])) - (do p;Monad<Parser> - [_ (l;this "#\"") - [where' char] (: (l;Lexer [Cursor Text]) - ($_ p;either + (-> Cursor (l.Lexer [Cursor Code])) + (do p.Monad<Parser> + [_ (l.this "#\"") + [where' char] (: (l.Lexer [Cursor Text]) + ($_ p.either ## Normal text characters. (do @ - [normal (l;none-of "\\\"\n")] + [normal (l.none-of "\\\"\n")] (wrap [(|> where - (update@ #;column n/inc)) + (update@ #.column n/inc)) normal])) ## Must handle escaped ## chars separately. (do @ [[chars-consumed char] escaped-char^] (wrap [(|> where - (update@ #;column (n/+ chars-consumed))) + (update@ #.column (n/+ chars-consumed))) char])))) - _ (l;this "\"") - #let [char (maybe;assume (text;nth +0 char))]] + _ (l.this "\"") + #let [char (maybe.assume (text.nth +0 char))]] (wrap [(|> where' - (update@ #;column n/inc)) - [where (#;Nat char)]]))) + (update@ #.column n/inc)) + [where (#.Nat char)]]))) (def: (normal-nat where) - (-> Cursor (l;Lexer [Cursor Code])) - (do p;Monad<Parser> - [chunk (l;seq (l;one-of "+") + (-> Cursor (l.Lexer [Cursor Code])) + (do p.Monad<Parser> + [chunk (l.seq (l.one-of "+") rich-digits^)] - (case (:: number;Codec<Text,Nat> decode chunk) - (#;Left error) - (p;fail error) + (case (:: number.Codec<Text,Nat> decode chunk) + (#.Left error) + (p.fail error) - (#;Right value) - (wrap [(update@ #;column (n/+ (text;size chunk)) where) - [where (#;Nat value)]])))) + (#.Right value) + (wrap [(update@ #.column (n/+ (text.size chunk)) where) + [where (#.Nat value)]])))) (def: #export (nat where) - (-> Cursor (l;Lexer [Cursor Code])) - (p;either (normal-nat where) + (-> Cursor (l.Lexer [Cursor Code])) + (p.either (normal-nat where) (nat-char where))) (def: (normal-frac where) - (-> Cursor (l;Lexer [Cursor Code])) - (do p;Monad<Parser> - [chunk ($_ l;seq - (p;default "" (l;one-of "-")) + (-> Cursor (l.Lexer [Cursor Code])) + (do p.Monad<Parser> + [chunk ($_ l.seq + (p.default "" (l.one-of "-")) rich-digits^ - (l;one-of ".") + (l.one-of ".") rich-digits^ - (p;default "" - ($_ l;seq - (l;one-of "eE") - (p;default "" (l;one-of "+-")) + (p.default "" + ($_ l.seq + (l.one-of "eE") + (p.default "" (l.one-of "+-")) rich-digits^)))] - (case (:: number;Codec<Text,Frac> decode chunk) - (#;Left error) - (p;fail error) + (case (:: number.Codec<Text,Frac> decode chunk) + (#.Left error) + (p.fail error) - (#;Right value) - (wrap [(update@ #;column (n/+ (text;size chunk)) where) - [where (#;Frac value)]])))) + (#.Right value) + (wrap [(update@ #.column (n/+ (text.size chunk)) where) + [where (#.Frac value)]])))) (def: frac-ratio-fragment - (l;Lexer Frac) - (<| (p;codec number;Codec<Text,Frac>) - (:: p;Monad<Parser> map (function [digits] + (l.Lexer Frac) + (<| (p.codec number.Codec<Text,Frac>) + (:: p.Monad<Parser> map (function [digits] (format digits ".0"))) rich-digits^)) (def: (ratio-frac where) - (-> Cursor (l;Lexer [Cursor Code])) - (do p;Monad<Parser> - [chunk ($_ l;seq - (p;default "" (l;one-of "-")) + (-> Cursor (l.Lexer [Cursor Code])) + (do p.Monad<Parser> + [chunk ($_ l.seq + (p.default "" (l.one-of "-")) rich-digits^ - (l;one-of "/") + (l.one-of "/") rich-digits^) - value (l;local chunk + value (l.local chunk (do @ - [signed? (l;this? "-") + [signed? (l.this? "-") numerator frac-ratio-fragment - _ (l;this? "/") + _ (l.this? "/") denominator frac-ratio-fragment - _ (p;assert "Denominator cannot be 0." + _ (p.assert "Denominator cannot be 0." (not (f/= 0.0 denominator)))] (wrap (|> numerator (f/* (if signed? -1.0 1.0)) (f// denominator)))))] - (wrap [(update@ #;column (n/+ (text;size chunk)) where) - [where (#;Frac value)]]))) + (wrap [(update@ #.column (n/+ (text.size chunk)) where) + [where (#.Frac value)]]))) (def: #export (frac where) - (-> Cursor (l;Lexer [Cursor Code])) - (p;either (normal-frac where) + (-> Cursor (l.Lexer [Cursor Code])) + (p.either (normal-frac where) (ratio-frac where))) ## This parser looks so complex because text in Lux can be multi-line ## and there are rules regarding how this is handled. (def: #export (text where) - (-> Cursor (l;Lexer [Cursor Code])) - (do p;Monad<Parser> + (-> Cursor (l.Lexer [Cursor Code])) + (do p.Monad<Parser> [## Lux text "is delimited by double-quotes", as usual in most ## programming languages. - _ (l;this "\"") + _ (l.this "\"") ## I must know what column the text body starts at (which is ## always 1 column after the left-delimiting quote). ## This is important because, when procesing subsequent lines, @@ -350,8 +350,8 @@ ## as many spaces as necessary to be column-aligned. ## This helps ensure that the formatting on the text in the ## source-code matches the formatting of the Text value. - #let [offset-column (n/inc (get@ #;column where))] - [where' text-read] (: (l;Lexer [Cursor Text]) + #let [offset-column (n/inc (get@ #.column where))] + [where' text-read] (: (l.Lexer [Cursor Text]) ## I must keep track of how much of the ## text body has been read, how far the ## cursor has progressed, and whether I'm @@ -359,9 +359,9 @@ ## processing normal text body. (loop [text-read "" where (|> where - (update@ #;column n/inc)) + (update@ #.column n/inc)) must-have-offset? false] - (p;either (if must-have-offset? + (p.either (if must-have-offset? ## If I'm at the start of a ## new line, I must ensure the ## space-offset is at least @@ -369,30 +369,30 @@ ## the text's body's column, ## to ensure they are aligned. (do @ - [offset (l;many (l;one-of " ")) - #let [offset-size (text;size offset)]] + [offset (l.many (l.one-of " ")) + #let [offset-size (text.size offset)]] (if (n/>= offset-column offset-size) ## Any extra offset ## becomes part of the ## text's body. (recur (|> offset - (text;split offset-column) - (maybe;default (undefined)) - product;right + (text.split offset-column) + (maybe.default (undefined)) + product.right (format text-read)) (|> where - (update@ #;column (n/+ offset-size))) + (update@ #.column (n/+ offset-size))) false) - (p;fail (format "Each line of a multi-line text must have an appropriate offset!\n" + (p.fail (format "Each line of a multi-line text must have an appropriate offset!\n" "Expected: " (%i (nat-to-int offset-column)) " columns.\n" " Actual: " (%i (nat-to-int offset-size)) " columns.\n")))) - ($_ p;either + ($_ p.either ## Normal text characters. (do @ - [normal (l;many (l;none-of "\\\"\n"))] + [normal (l.many (l.none-of "\\\"\n"))] (recur (format text-read normal) (|> where - (update@ #;column (n/+ (text;size normal)))) + (update@ #.column (n/+ (text.size normal)))) false)) ## Must handle escaped ## chars separately. @@ -400,13 +400,13 @@ [[chars-consumed char] escaped-char^] (recur (format text-read char) (|> where - (update@ #;column (n/+ chars-consumed))) + (update@ #.column (n/+ chars-consumed))) false)) ## The text ends when it ## reaches the right-delimiter. (do @ - [_ (l;this "\"")] - (wrap [(update@ #;column n/inc where) + [_ (l.this "\"")] + (wrap [(update@ #.column n/inc where) text-read])))) ## If a new-line is ## encountered, it gets @@ -414,14 +414,14 @@ ## the loop is alerted that the ## next line must have an offset. (do @ - [_ (l;this new-line)] + [_ (l.this new-line)] (recur (format text-read new-line) (|> where - (update@ #;line n/inc) - (set@ #;column +0)) + (update@ #.line n/inc) + (set@ #.column +0)) true)))))] (wrap [where' - [where (#;Text text-read)]]))) + [where (#.Text text-read)]]))) ## Form and tuple syntax is mostly the same, differing only in the ## delimiters involved. @@ -429,32 +429,32 @@ (do-template [<name> <tag> <open> <close>] [(def: (<name> where ast) (-> Cursor - (-> Cursor (l;Lexer [Cursor Code])) - (l;Lexer [Cursor Code])) - (do p;Monad<Parser> - [_ (l;this <open>) + (-> Cursor (l.Lexer [Cursor Code])) + (l.Lexer [Cursor Code])) + (do p.Monad<Parser> + [_ (l.this <open>) [where' elems] (loop [elems (: (Sequence Code) - sequence;empty) + sequence.empty) where where] - (p;either (do @ + (p.either (do @ [## Must update the cursor as I ## go along, to keep things accurate. [where' elem] (ast where)] - (recur (sequence;add elem elems) + (recur (sequence.add elem elems) where')) (do @ [## Must take into account any ## padding present before the ## end-delimiter. where' (left-padding^ where) - _ (l;this <close>)] - (wrap [(update@ #;column n/inc where') - (sequence;to-list elems)]))))] + _ (l.this <close>)] + (wrap [(update@ #.column n/inc where') + (sequence.to-list elems)]))))] (wrap [where' [where (<tag> elems)]])))] - [form #;Form "(" ")"] - [tuple #;Tuple "[" "]"] + [form #.Form "(" ")"] + [tuple #.Tuple "[" "]"] ) ## Records are almost (syntactically) the same as forms and tuples, @@ -468,34 +468,34 @@ ## macros. (def: (record where ast) (-> Cursor - (-> Cursor (l;Lexer [Cursor Code])) - (l;Lexer [Cursor Code])) - (do p;Monad<Parser> - [_ (l;this "{") + (-> Cursor (l.Lexer [Cursor Code])) + (l.Lexer [Cursor Code])) + (do p.Monad<Parser> + [_ (l.this "{") [where' elems] (loop [elems (: (Sequence [Code Code]) - sequence;empty) + sequence.empty) where where] - (p;either (do @ + (p.either (do @ [[where' key] (ast where) [where' val] (ast where')] - (recur (sequence;add [key val] elems) + (recur (sequence.add [key val] elems) where')) (do @ [where' (left-padding^ where) - _ (l;this "}")] - (wrap [(update@ #;column n/inc where') - (sequence;to-list elems)]))))] + _ (l.this "}")] + (wrap [(update@ #.column n/inc where') + (sequence.to-list elems)]))))] (wrap [where' - [where (#;Record elems)]]))) + [where (#.Record elems)]]))) ## The parts of an identifier are separated by a single mark. -## E.g. module;name. +## E.g. module.name. ## Only one such mark may be used in an identifier, since there ## can only be 2 parts to an identifier (the module [before the ## mark], and the name [after the mark]). ## There are also some extra rules regarding identifier syntax, ## encoded on the parser. -(def: identifier-separator Text ";") +(def: identifier-separator Text ".") ## A Lux identifier is a pair of chunks of text, where the first-part ## refers to the module that gives context to the identifier, and the @@ -511,13 +511,13 @@ ## Additionally, the first character in an identifier's part cannot be ## a digit, to avoid confusion with regards to numbers. (def: ident-part^ - (l;Lexer Text) - (do p;Monad<Parser> + (l.Lexer Text) + (do p.Monad<Parser> [#let [digits "0123456789" delimiters (format "()[]{}#\"" identifier-separator) space (format white-space new-line) - head-lexer (l;none-of (format digits delimiters space)) - tail-lexer (l;some (l;none-of (format delimiters space)))] + head-lexer (l.none-of (format digits delimiters space)) + tail-lexer (l.some (l.none-of (format delimiters space)))] head head-lexer tail tail-lexer] (wrap (format head tail)))) @@ -525,28 +525,28 @@ (def: current-module-mark Text (format identifier-separator identifier-separator)) (def: (ident^ current-module aliases) - (-> Text Aliases (l;Lexer [Ident Nat])) - ($_ p;either + (-> Text Aliases (l.Lexer [Ident Nat])) + ($_ p.either ## When an identifier starts with 2 marks, its module is ## taken to be the current-module being compiled at the moment. ## This can be useful when mentioning identifiers and tags ## inside quoted/templated code in macros. - (do p;Monad<Parser> - [_ (l;this current-module-mark) + (do p.Monad<Parser> + [_ (l.this current-module-mark) def-name ident-part^] (wrap [[current-module def-name] - (n/+ +2 (text;size def-name))])) + (n/+ +2 (text.size def-name))])) ## If the identifier is prefixed by the mark, but no module ## part, the module is assumed to be "lux" (otherwise known as ## the 'prelude'). ## This makes it easy to refer to definitions in that module, ## since it is the most fundamental module in the entire ## standard library. - (do p;Monad<Parser> - [_ (l;this identifier-separator) + (do p.Monad<Parser> + [_ (l.this identifier-separator) def-name ident-part^] (wrap [["lux" def-name] - (n/inc (text;size def-name))])) + (n/inc (text.size def-name))])) ## Not all identifiers must be specified with a module part. ## If that part is not provided, the identifier will be created ## with the empty "" text as the module. @@ -556,19 +556,19 @@ ## Function arguments and local-variables may not be referred-to ## using identifiers with module parts, so being able to specify ## identifiers with empty modules helps with those use-cases. - (do p;Monad<Parser> + (do p.Monad<Parser> [first-part ident-part^] - (p;either (do @ - [_ (l;this identifier-separator) + (p.either (do @ + [_ (l.this identifier-separator) second-part ident-part^] - (wrap [[(|> aliases (dict;get first-part) (maybe;default first-part)) + (wrap [[(|> aliases (dict.get first-part) (maybe.default first-part)) second-part] ($_ n/+ - (text;size first-part) + (text.size first-part) +1 - (text;size second-part))])) + (text.size second-part))])) (wrap [["" first-part] - (text;size first-part)]))))) + (text.size first-part)]))))) ## The only (syntactic) difference between a symbol and a tag (both ## being identifiers), is that tags must be prefixed with a hash-sign @@ -579,26 +579,26 @@ ## construction and de-structuring (during pattern-matching). (do-template [<name> <tag> <lexer> <extra>] [(def: #export (<name> current-module aliases where) - (-> Text Aliases Cursor (l;Lexer [Cursor Code])) - (do p;Monad<Parser> + (-> Text Aliases Cursor (l.Lexer [Cursor Code])) + (do p.Monad<Parser> [[value length] <lexer>] - (wrap [(update@ #;column (|>> ($_ n/+ <extra> length)) where) + (wrap [(update@ #.column (|>> ($_ n/+ <extra> length)) where) [where (<tag> value)]])))] - [symbol #;Symbol (ident^ current-module aliases) +0] - [tag #;Tag (p;after (l;this "#") (ident^ current-module aliases)) +1] + [symbol #.Symbol (ident^ current-module aliases) +0] + [tag #.Tag (p.after (l.this "#") (ident^ current-module aliases)) +1] ) (exception: #export End-Of-File) (exception: #export Unrecognized-Input) (def: (ast current-module aliases) - (-> Text Aliases Cursor (l;Lexer [Cursor Code])) - (: (-> Cursor (l;Lexer [Cursor Code])) + (-> Text Aliases Cursor (l.Lexer [Cursor Code])) + (: (-> Cursor (l.Lexer [Cursor Code])) (function ast' [where] - (do p;Monad<Parser> + (do p.Monad<Parser> [where (left-padding^ where)] - ($_ p;either + ($_ p.either (form where ast') (tuple where ast') (record where ast') @@ -611,17 +611,17 @@ (tag current-module aliases where) (text where) (do @ - [end? l;end?] + [end? l.end?] (if end? - (p;fail (End-Of-File current-module)) - (p;fail (Unrecognized-Input current-module)))) + (p.fail (End-Of-File current-module)) + (p.fail (Unrecognized-Input current-module)))) ))))) (def: #export (read current-module aliases [where offset source]) - (-> Text Aliases Source (e;Error [Source Code])) - (case (p;run [offset source] (ast current-module aliases where)) - (#e;Error error) - (#e;Error error) + (-> Text Aliases Source (e.Error [Source Code])) + (case (p.run [offset source] (ast current-module aliases where)) + (#e.Error error) + (#e.Error error) - (#e;Success [[offset' remaining] [where' output]]) - (#e;Success [[where' offset' remaining] output]))) + (#e.Success [[offset' remaining] [where' output]]) + (#e.Success [[where' offset' remaining] output]))) diff --git a/stdlib/source/lux/lang/type.lux b/stdlib/source/lux/lang/type.lux index 217320ab2..ab680cb6c 100644 --- a/stdlib/source/lux/lang/type.lux +++ b/stdlib/source/lux/lang/type.lux @@ -1,4 +1,4 @@ -(;module: {#;doc "Basic functionality for working with types."} +(.module: {#.doc "Basic functionality for working with types."} [lux #- function] (lux (control [eq #+ Eq] [monad #+ do Monad]) @@ -14,29 +14,29 @@ (def: (beta-reduce env type) (-> (List Type) Type Type) (case type - (#;Primitive name params) - (#;Primitive name (list/map (beta-reduce env) params)) + (#.Primitive name params) + (#.Primitive name (list/map (beta-reduce env) params)) (^template [<tag>] (<tag> left right) (<tag> (beta-reduce env left) (beta-reduce env right))) - ([#;Sum] [#;Product] - [#;Function] [#;Apply]) + ([#.Sum] [#.Product] + [#.Function] [#.Apply]) (^template [<tag>] (<tag> old-env def) (case old-env - #;Nil + #.Nil (<tag> env def) _ (<tag> (list/map (beta-reduce env) old-env) def))) - ([#;UnivQ] - [#;ExQ]) + ([#.UnivQ] + [#.ExQ]) - (#;Bound idx) - (maybe;default (error! (text/compose "Unknown type var: " (nat/encode idx))) - (list;nth idx env)) + (#.Bound idx) + (maybe.default (error! (text/compose "Unknown type var: " (nat/encode idx))) + (list.nth idx env)) _ type @@ -46,44 +46,44 @@ (struct: #export _ (Eq Type) (def: (= x y) (case [x y] - [(#;Primitive xname xparams) (#;Primitive yname yparams)] + [(#.Primitive xname xparams) (#.Primitive yname yparams)] (and (text/= xname yname) - (n/= (list;size yparams) (list;size xparams)) - (list/fold (;function [[x y] prev] (and prev (= x y))) + (n/= (list.size yparams) (list.size xparams)) + (list/fold (.function [[x y] prev] (and prev (= x y))) true - (list;zip2 xparams yparams))) + (list.zip2 xparams yparams))) (^template [<tag>] [<tag> <tag>] true) - ([#;Void] [#;Unit]) + ([#.Void] [#.Unit]) (^template [<tag>] [(<tag> xid) (<tag> yid)] (n/= yid xid)) - ([#;Var] [#;Ex] [#;Bound]) + ([#.Var] [#.Ex] [#.Bound]) - (^or [(#;Function xleft xright) (#;Function yleft yright)] - [(#;Apply xleft xright) (#;Apply yleft yright)]) + (^or [(#.Function xleft xright) (#.Function yleft yright)] + [(#.Apply xleft xright) (#.Apply yleft yright)]) (and (= xleft yleft) (= xright yright)) - [(#;Named xname xtype) (#;Named yname ytype)] + [(#.Named xname xtype) (#.Named yname ytype)] (and (ident/= xname yname) (= xtype ytype)) (^template [<tag>] [(<tag> xL xR) (<tag> yL yR)] (and (= xL yL) (= xR yR))) - ([#;Sum] [#;Product]) + ([#.Sum] [#.Product]) - (^or [(#;UnivQ xenv xbody) (#;UnivQ yenv ybody)] - [(#;ExQ xenv xbody) (#;ExQ yenv ybody)]) - (and (n/= (list;size yenv) (list;size xenv)) + (^or [(#.UnivQ xenv xbody) (#.UnivQ yenv ybody)] + [(#.ExQ xenv xbody) (#.ExQ yenv ybody)]) + (and (n/= (list.size yenv) (list.size xenv)) (= xbody ybody) - (list/fold (;function [[x y] prev] (and prev (= x y))) + (list/fold (.function [[x y] prev] (and prev (= x y))) true - (list;zip2 xenv yenv))) + (list.zip2 xenv yenv))) _ false @@ -102,14 +102,14 @@ _ [num-args type])))] - [flatten-univ-q #;UnivQ] - [flatten-ex-q #;ExQ] + [flatten-univ-q #.UnivQ] + [flatten-ex-q #.ExQ] ) (def: #export (flatten-function type) (-> Type [(List Type) Type]) (case type - (#;Function in out') + (#.Function in out') (let [[ins out] (flatten-function out')] [(list& in ins) out]) @@ -119,7 +119,7 @@ (def: #export (flatten-application type) (-> Type [Type (List Type)]) (case type - (#;Apply arg func') + (#.Apply arg func') (let [[func args] (flatten-application func')] [func (list/compose args (list arg))]) @@ -136,88 +136,88 @@ _ (list type)))] - [flatten-variant #;Sum] - [flatten-tuple #;Product] + [flatten-variant #.Sum] + [flatten-tuple #.Product] ) (def: #export (apply params func) (-> (List Type) Type (Maybe Type)) (case params - #;Nil - (#;Some func) + #.Nil + (#.Some func) - (#;Cons param params') + (#.Cons param params') (case func (^template [<tag>] (<tag> env body) (|> body (beta-reduce (list& func param env)) (apply params'))) - ([#;UnivQ] [#;ExQ]) + ([#.UnivQ] [#.ExQ]) - (#;Apply A F) + (#.Apply A F) (apply (list& A params) F) - (#;Named name unnamed) + (#.Named name unnamed) (apply params unnamed) _ - #;None))) + #.None))) (def: #export (to-ast type) (-> Type Code) (case type - (#;Primitive name params) - (` (#;Primitive (~ (code;text name)) + (#.Primitive name params) + (` (#.Primitive (~ (code.text name)) (list (~@ (list/map to-ast params))))) (^template [<tag>] <tag> (` <tag>)) - ([#;Void] [#;Unit]) + ([#.Void] [#.Unit]) (^template [<tag>] (<tag> idx) - (` (<tag> (~ (code;nat idx))))) - ([#;Var] [#;Ex] [#;Bound]) + (` (<tag> (~ (code.nat idx))))) + ([#.Var] [#.Ex] [#.Bound]) (^template [<tag>] (<tag> left right) (` (<tag> (~ (to-ast left)) (~ (to-ast right))))) - ([#;Function] [#;Apply]) + ([#.Function] [#.Apply]) (^template [<tag> <macro> <flattener>] (<tag> left right) (` (<macro> (~@ (list/map to-ast (<flattener> type)))))) - ([#;Sum | flatten-variant] - [#;Product & flatten-tuple]) + ([#.Sum | flatten-variant] + [#.Product & flatten-tuple]) - (#;Named name sub-type) - (code;symbol name) + (#.Named name sub-type) + (code.symbol name) (^template [<tag>] (<tag> env body) (` (<tag> (list (~@ (list/map to-ast env))) (~ (to-ast body))))) - ([#;UnivQ] [#;ExQ]) + ([#.UnivQ] [#.ExQ]) )) (def: #export (to-text type) (-> Type Text) (case type - (#;Primitive name params) + (#.Primitive name params) (case params - #;Nil + #.Nil ($_ text/compose "(primitive " name ")") _ - ($_ text/compose "(primitive " name " " (|> params (list/map to-text) list;reverse (list;interpose " ") (list/fold text/compose "")) ")")) + ($_ text/compose "(primitive " name " " (|> params (list/map to-text) list.reverse (list.interpose " ") (list/fold text/compose "")) ")")) - #;Void + #.Void "Void" - #;Unit + #.Unit "Unit" (^template [<tag> <open> <close> <flatten>] @@ -225,51 +225,51 @@ ($_ text/compose <open> (|> (<flatten> type) (list/map to-text) - list;reverse - (list;interpose " ") + list.reverse + (list.interpose " ") (list/fold text/compose "")) <close>)) - ([#;Sum "(| " ")" flatten-variant] - [#;Product "[" "]" flatten-tuple]) + ([#.Sum "(| " ")" flatten-variant] + [#.Product "[" "]" flatten-tuple]) - (#;Function input output) + (#.Function input output) (let [[ins out] (flatten-function type)] ($_ text/compose "(-> " (|> ins (list/map to-text) - list;reverse - (list;interpose " ") + list.reverse + (list.interpose " ") (list/fold text/compose "")) " " (to-text out) ")")) - (#;Bound idx) + (#.Bound idx) (nat/encode idx) - (#;Var id) + (#.Var id) ($_ text/compose "⌈v:" (nat/encode id) "⌋") - (#;Ex id) + (#.Ex id) ($_ text/compose "⟨e:" (nat/encode id) "⟩") - (#;Apply param fun) + (#.Apply param fun) (let [[type-func type-args] (flatten-application type)] - ($_ text/compose "(" (to-text type-func) " " (|> type-args (list/map to-text) list;reverse (list;interpose " ") (list/fold text/compose "")) ")")) + ($_ text/compose "(" (to-text type-func) " " (|> type-args (list/map to-text) list.reverse (list.interpose " ") (list/fold text/compose "")) ")")) (^template [<tag> <desc>] (<tag> env body) - ($_ text/compose "(" <desc> " {" (|> env (list/map to-text) (text;join-with " ")) "} " (to-text body) ")")) - ([#;UnivQ "All"] - [#;ExQ "Ex"]) + ($_ text/compose "(" <desc> " {" (|> env (list/map to-text) (text.join-with " ")) "} " (to-text body) ")")) + ([#.UnivQ "All"] + [#.ExQ "Ex"]) - (#;Named [module name] type) - ($_ text/compose module ";" name) + (#.Named [module name] type) + ($_ text/compose module "." name) )) (def: #export (un-alias type) (-> Type Type) (case type - (#;Named _ (#;Named ident type')) - (un-alias (#;Named ident type')) + (#.Named _ (#.Named ident type')) + (un-alias (#.Named ident type')) _ type)) @@ -277,7 +277,7 @@ (def: #export (un-name type) (-> Type Type) (case type - (#;Named ident type') + (#.Named ident type') (un-name type') _ @@ -287,36 +287,36 @@ [(def: #export (<name> types) (-> (List Type) Type) (case types - #;Nil + #.Nil <base> - (#;Cons type #;Nil) + (#.Cons type #.Nil) type - (#;Cons type types') + (#.Cons type types') (<ctor> type (<name> types'))))] - [variant Void #;Sum] - [tuple Unit #;Product] + [variant Void #.Sum] + [tuple Unit #.Product] ) (def: #export (function inputs output) (-> (List Type) Type Type) (case inputs - #;Nil + #.Nil output - (#;Cons input inputs') - (#;Function input (function inputs' output)))) + (#.Cons input inputs') + (#.Function input (function inputs' output)))) (def: #export (application params quant) (-> (List Type) Type Type) (case params - #;Nil + #.Nil quant - (#;Cons param params') - (application params' (#;Apply param quant)))) + (#.Cons param params') + (application params' (#.Apply param quant)))) (do-template [<name> <tag>] [(def: #export (<name> size body) @@ -325,23 +325,23 @@ +0 body _ (<tag> (list) (<name> (n/dec size) body))))] - [univ-q #;UnivQ] - [ex-q #;ExQ] + [univ-q #.UnivQ] + [ex-q #.ExQ] ) (def: #export (quantified? type) (-> Type Bool) (case type - (#;Named [module name] _type) + (#.Named [module name] _type) (quantified? _type) - (#;Apply A F) - (maybe;default false - (do maybe;Monad<Maybe> + (#.Apply A F) + (maybe.default false + (do maybe.Monad<Maybe> [applied (apply (list A) F)] (wrap (quantified? applied)))) - (^or (#;UnivQ _) (#;ExQ _)) + (^or (#.UnivQ _) (#.ExQ _)) true _ @@ -351,4 +351,4 @@ (-> Nat Type Type) (case level +0 elem-type - _ (#;Primitive "#Array" (list (array (n/dec level) elem-type))))) + _ (#.Primitive "#Array" (list (array (n/dec level) elem-type))))) diff --git a/stdlib/source/lux/lang/type/check.lux b/stdlib/source/lux/lang/type/check.lux index 9dc1a6565..9dc7e81b0 100644 --- a/stdlib/source/lux/lang/type/check.lux +++ b/stdlib/source/lux/lang/type/check.lux @@ -1,4 +1,4 @@ -(;module: {#;doc "Type-checking functionality."} +(.module: {#.doc "Type-checking functionality."} lux (lux (control [functor #+ Functor] [applicative #+ Applicative] @@ -28,7 +28,7 @@ #verdict Bool}) (type: #export (Check a) - (-> Type-Context (e;Error [Type-Context a]))) + (-> Type-Context (e.Error [Type-Context a]))) (type: #export Type-Vars (List [Var (Maybe Type)])) @@ -37,11 +37,11 @@ (def: (map f fa) (function [context] (case (fa context) - (#e;Error error) - (#e;Error error) + (#e.Error error) + (#e.Error error) - (#e;Success [context' output]) - (#e;Success [context' (f output)]) + (#e.Success [context' output]) + (#e.Success [context' (f output)]) )))) (struct: #export _ (Applicative Check) @@ -49,21 +49,21 @@ (def: (wrap x) (function [context] - (#e;Success [context x]))) + (#e.Success [context x]))) (def: (apply ff fa) (function [context] (case (ff context) - (#e;Success [context' f]) + (#e.Success [context' f]) (case (fa context') - (#e;Success [context'' a]) - (#e;Success [context'' (f a)]) + (#e.Success [context'' a]) + (#e.Success [context'' (f a)]) - (#e;Error error) - (#e;Error error)) + (#e.Error error) + (#e.Error error)) - (#e;Error error) - (#e;Error error) + (#e.Error error) + (#e.Error error) ))) ) @@ -73,16 +73,16 @@ (def: (join ffa) (function [context] (case (ffa context) - (#e;Success [context' fa]) + (#e.Success [context' fa]) (case (fa context') - (#e;Success [context'' a]) - (#e;Success [context'' a]) + (#e.Success [context'' a]) + (#e.Success [context'' a]) - (#e;Error error) - (#e;Error error)) + (#e.Error error) + (#e.Error error)) - (#e;Error error) - (#e;Error error) + (#e.Error error) + (#e.Error error) ))) ) @@ -91,248 +91,248 @@ (def: (var::get id plist) (-> Var Type-Vars (Maybe (Maybe Type))) (case plist - #;Nil - #;None + #.Nil + #.None - (#;Cons [var-id var-type] + (#.Cons [var-id var-type] plist') (if (n/= id var-id) - (#;Some var-type) + (#.Some var-type) (var::get id plist')) )) (def: (var::put id value plist) (-> Var (Maybe Type) Type-Vars Type-Vars) (case plist - #;Nil + #.Nil (list [id value]) - (#;Cons [var-id var-type] + (#.Cons [var-id var-type] plist') (if (n/= id var-id) - (#;Cons [var-id value] + (#.Cons [var-id value] plist') - (#;Cons [var-id var-type] + (#.Cons [var-id var-type] (var::put id value plist'))) )) (def: (var::remove id plist) (-> Var Type-Vars Type-Vars) (case plist - #;Nil - #;Nil + #.Nil + #.Nil - (#;Cons [var-id var-type] + (#.Cons [var-id var-type] plist') (if (n/= id var-id) plist' - (#;Cons [var-id var-type] + (#.Cons [var-id var-type] (var::remove id plist'))) )) ## [[Logic]] (def: #export (run context proc) - (All [a] (-> Type-Context (Check a) (e;Error a))) + (All [a] (-> Type-Context (Check a) (e.Error a))) (case (proc context) - (#e;Error error) - (#e;Error error) + (#e.Error error) + (#e.Error error) - (#e;Success [context' output]) - (#e;Success output))) + (#e.Success [context' output]) + (#e.Success output))) (def: #export (throw exception message) - (All [a] (-> ex;Exception Text (Check a))) + (All [a] (-> ex.Exception Text (Check a))) (function [context] - (ex;throw exception message))) + (ex.throw exception message))) (def: #export existential - {#;doc "A producer of existential types."} + {#.doc "A producer of existential types."} (Check [Nat Type]) (function [context] - (let [id (get@ #;ex-counter context)] - (#e;Success [(update@ #;ex-counter n/inc context) - [id (#;Ex id)]])))) + (let [id (get@ #.ex-counter context)] + (#e.Success [(update@ #.ex-counter n/inc context) + [id (#.Ex id)]])))) (do-template [<name> <outputT> <fail> <succeed>] [(def: #export (<name> id) (-> Var (Check <outputT>)) (function [context] - (case (|> context (get@ #;var-bindings) (var::get id)) - (^or (#;Some (#;Some (#;Var _))) - (#;Some #;None)) - (#e;Success [context <fail>]) + (case (|> context (get@ #.var-bindings) (var::get id)) + (^or (#.Some (#.Some (#.Var _))) + (#.Some #.None)) + (#e.Success [context <fail>]) - (#;Some (#;Some bound)) - (#e;Success [context <succeed>]) + (#.Some (#.Some bound)) + (#e.Success [context <succeed>]) - #;None - (ex;throw Unknown-Type-Var (nat/encode id)))))] + #.None + (ex.throw Unknown-Type-Var (nat/encode id)))))] [bound? Bool false true] - [read (Maybe Type) #;None (#;Some bound)] + [read (Maybe Type) #.None (#.Some bound)] ) (def: (peek id) (-> Var (Check Type)) (function [context] - (case (|> context (get@ #;var-bindings) (var::get id)) - (#;Some (#;Some bound)) - (#e;Success [context bound]) + (case (|> context (get@ #.var-bindings) (var::get id)) + (#.Some (#.Some bound)) + (#e.Success [context bound]) - (#;Some #;None) - (ex;throw Unbound-Type-Var (nat/encode id)) + (#.Some #.None) + (ex.throw Unbound-Type-Var (nat/encode id)) - #;None - (ex;throw Unknown-Type-Var (nat/encode id))))) + #.None + (ex.throw Unknown-Type-Var (nat/encode id))))) (def: #export (write type id) (-> Type Var (Check Unit)) (function [context] - (case (|> context (get@ #;var-bindings) (var::get id)) - (#;Some (#;Some bound)) - (ex;throw Cannot-Rebind-Var + (case (|> context (get@ #.var-bindings) (var::get id)) + (#.Some (#.Some bound)) + (ex.throw Cannot-Rebind-Var ($_ text/compose " Var: " (nat/encode id) "\n" - " Wanted Type: " (type;to-text type) "\n" - "Current Type: " (type;to-text bound))) + " Wanted Type: " (type.to-text type) "\n" + "Current Type: " (type.to-text bound))) - (#;Some #;None) - (#e;Success [(update@ #;var-bindings (var::put id (#;Some type)) context) + (#.Some #.None) + (#e.Success [(update@ #.var-bindings (var::put id (#.Some type)) context) []]) - #;None - (ex;throw Unknown-Type-Var (nat/encode id))))) + #.None + (ex.throw Unknown-Type-Var (nat/encode id))))) (def: (update type id) (-> Type Var (Check Unit)) (function [context] - (case (|> context (get@ #;var-bindings) (var::get id)) - (#;Some _) - (#e;Success [(update@ #;var-bindings (var::put id (#;Some type)) context) + (case (|> context (get@ #.var-bindings) (var::get id)) + (#.Some _) + (#e.Success [(update@ #.var-bindings (var::put id (#.Some type)) context) []]) - #;None - (ex;throw Unknown-Type-Var (nat/encode id))))) + #.None + (ex.throw Unknown-Type-Var (nat/encode id))))) (def: #export var (Check [Var Type]) (function [context] - (let [id (get@ #;var-counter context)] - (#e;Success [(|> context - (update@ #;var-counter n/inc) - (update@ #;var-bindings (var::put id #;None))) - [id (#;Var id)]])))) + (let [id (get@ #.var-counter context)] + (#e.Success [(|> context + (update@ #.var-counter n/inc) + (update@ #.var-bindings (var::put id #.None))) + [id (#.Var id)]])))) (def: get-bindings (Check (List [Var (Maybe Type)])) (function [context] - (#e;Success [context - (get@ #;var-bindings context)]))) + (#e.Success [context + (get@ #.var-bindings context)]))) (def: (set-bindings value) (-> (List [Var (Maybe Type)]) (Check Unit)) (function [context] - (#e;Success [(set@ #;var-bindings value context) + (#e.Success [(set@ #.var-bindings value context) []]))) (def: (apply-type! funcT argT) (-> Type Type (Check Type)) (case funcT - (#;Var func-id) + (#.Var func-id) (do Monad<Check> [?funcT' (read func-id)] (case ?funcT' - #;None - (throw Invalid-Type-Application (type;to-text (#;Apply argT funcT))) + #.None + (throw Invalid-Type-Application (type.to-text (#.Apply argT funcT))) - (#;Some funcT') + (#.Some funcT') (apply-type! funcT' argT))) _ (function [context] - (case (type;apply (list argT) funcT) - #;None - (ex;throw Invalid-Type-Application (type;to-text (#;Apply argT funcT))) + (case (type.apply (list argT) funcT) + #.None + (ex.throw Invalid-Type-Application (type.to-text (#.Apply argT funcT))) - (#;Some output) - (#e;Success [context output]))))) + (#.Some output) + (#e.Success [context output]))))) (type: #export Ring (Set Var)) -(def: empty-ring Ring (set;new number;Hash<Nat>)) +(def: empty-ring Ring (set.new number.Hash<Nat>)) (def: #export (ring id) (-> Var (Check Ring)) (function [context] (loop [current id - output (set;add id empty-ring)] - (case (|> context (get@ #;var-bindings) (var::get current)) - (#;Some (#;Some type)) + output (set.add id empty-ring)] + (case (|> context (get@ #.var-bindings) (var::get current)) + (#.Some (#.Some type)) (case type - (#;Var post) + (#.Var post) (if (n/= id post) - (#e;Success [context output]) - (recur post (set;add post output))) + (#e.Success [context output]) + (recur post (set.add post output))) _ - (#e;Success [context empty-ring])) + (#e.Success [context empty-ring])) - (#;Some #;None) - (#e;Success [context output]) + (#.Some #.None) + (#e.Success [context output]) - #;None - (ex;throw Unknown-Type-Var (nat/encode current)))))) + #.None + (ex.throw Unknown-Type-Var (nat/encode current)))))) (def: #export fresh-context Type-Context - {#;var-counter +0 - #;ex-counter +0 - #;var-bindings (list) + {#.var-counter +0 + #.ex-counter +0 + #.var-bindings (list) }) (def: (attempt op) (All [a] (-> (Check a) (Check (Maybe a)))) (function [context] (case (op context) - (#e;Success [context' output]) - (#e;Success [context' (#;Some output)]) + (#e.Success [context' output]) + (#e.Success [context' (#.Some output)]) - (#e;Error _) - (#e;Success [context #;None])))) + (#e.Error _) + (#e.Success [context #.None])))) (def: #export (fail message) (All [a] (-> Text (Check a))) (function [context] - (#e;Error message))) + (#e.Error message))) (def: #export (assert message test) (-> Text Bool (Check Unit)) (function [context] (if test - (#e;Success [context []]) - (#e;Error message)))) + (#e.Success [context []]) + (#e.Error message)))) (def: (either left right) (All [a] (-> (Check a) (Check a) (Check a))) (function [context] (case (left context) - (#e;Success [context' output]) - (#e;Success [context' output]) + (#e.Success [context' output]) + (#e.Success [context' output]) - (#e;Error _) + (#e.Error _) (right context)))) (def: (assumed? [e a] assumptions) (-> [Type Type] (List Assumption) (Maybe Bool)) - (:: maybe;Monad<Maybe> map product;right - (list;find (function [[[fe fa] status]] + (:: maybe.Monad<Maybe> map product.right + (list.find (function [[[fe fa] status]] (and (type/= e fe) (type/= a fa))) assumptions))) (def: (assume! ea status assumptions) (-> [Type Type] Bool (List Assumption) (List Assumption)) - (#;Cons [ea status] assumptions)) + (#.Cons [ea status] assumptions)) (def: (on id type then else) (All [a] @@ -344,24 +344,24 @@ then) (do Monad<Check> [ring (ring id) - _ (assert "" (n/> +1 (set;size ring))) - _ (monad;map @ (update type) (set;to-list ring))] + _ (assert "" (n/> +1 (set.size ring))) + _ (monad.map @ (update type) (set.to-list ring))] then) (do Monad<Check> [?bound (read id)] - (else (maybe;default (#;Var id) ?bound))))) + (else (maybe.default (#.Var id) ?bound))))) (def: (link-2 left right) (-> Var Var (Check Unit)) (do Monad<Check> - [_ (write (#;Var right) left)] - (write (#;Var left) right))) + [_ (write (#.Var right) left)] + (write (#.Var left) right))) (def: (link-3 interpose to from) (-> Var Var Var (Check Unit)) (do Monad<Check> - [_ (update (#;Var interpose) from)] - (update (#;Var to) interpose))) + [_ (update (#.Var interpose) from)] + (update (#.Var to) interpose))) (def: (check-vars check' assumptions idE idA) (-> (-> Type Type (List Assumption) (Check (List Assumption))) @@ -375,61 +375,61 @@ abound (attempt (peek idA))] (case [ebound abound] ## Link the 2 variables circularily - [#;None #;None] + [#.None #.None] (do @ [_ (link-2 idE idA)] (wrap assumptions)) ## Interpose new variable between 2 existing links - [(#;Some etype) #;None] + [(#.Some etype) #.None] (case etype - (#;Var targetE) + (#.Var targetE) (do @ [_ (link-3 idA targetE idE)] (wrap assumptions)) _ - (check' etype (#;Var idA) assumptions)) + (check' etype (#.Var idA) assumptions)) ## Interpose new variable between 2 existing links - [#;None (#;Some atype)] + [#.None (#.Some atype)] (case atype - (#;Var targetA) + (#.Var targetA) (do @ [_ (link-3 idE targetA idA)] (wrap assumptions)) _ - (check' (#;Var idE) atype assumptions)) + (check' (#.Var idE) atype assumptions)) - [(#;Some etype) (#;Some atype)] + [(#.Some etype) (#.Some atype)] (case [etype atype] - [(#;Var targetE) (#;Var targetA)] + [(#.Var targetE) (#.Var targetA)] (do @ [ringE (ring idE) ringA (ring idA)] - (if (:: set;Eq<Set> = ringE ringA) + (if (:: set.Eq<Set> = ringE ringA) (wrap assumptions) ## Fuse 2 rings (do @ - [_ (monad;fold @ (function [interpose to] + [_ (monad.fold @ (function [interpose to] (do @ [_ (link-3 interpose to idE)] (wrap interpose))) targetE - (set;to-list ringA))] + (set.to-list ringA))] (wrap assumptions)))) - [(#;Var targetE) _] + [(#.Var targetE) _] (do @ [ring (ring idE) - _ (monad;map @ (update atype) (set;to-list ring))] + _ (monad.map @ (update atype) (set.to-list ring))] (wrap assumptions)) - [_ (#;Var targetA)] + [_ (#.Var targetA)] (do @ [ring (ring idA) - _ (monad;map @ (update etype) (set;to-list ring))] + _ (monad.map @ (update etype) (set.to-list ring))] (wrap assumptions)) _ @@ -439,8 +439,8 @@ (All [a] (-> (-> Unit Text) (Check a) (Check a))) (function [context] (case (check context) - (#e;Error error) - (#e;Error (case error + (#e.Error error) + (#e.Error (case error "" (on-error []) @@ -458,27 +458,27 @@ [Type Type] [Type Type] (Check (List Assumption))) (case [eFT aFT] - (^or [(#;UnivQ _ _) (#;Ex _)] [(#;UnivQ _ _) (#;Var _)]) + (^or [(#.UnivQ _ _) (#.Ex _)] [(#.UnivQ _ _) (#.Var _)]) (do Monad<Check> [eFT' (apply-type! eFT eAT)] - (check' eFT' (#;Apply aAT aFT) assumptions)) + (check' eFT' (#.Apply aAT aFT) assumptions)) - (^or [(#;Ex _) (#;UnivQ _ _)] [(#;Var _) (#;UnivQ _ _)]) + (^or [(#.Ex _) (#.UnivQ _ _)] [(#.Var _) (#.UnivQ _ _)]) (do Monad<Check> [aFT' (apply-type! aFT aAT)] - (check' (#;Apply eAT eFT) aFT' assumptions)) + (check' (#.Apply eAT eFT) aFT' assumptions)) - (^or [(#;Ex _) _] [_ (#;Ex _)]) + (^or [(#.Ex _) _] [_ (#.Ex _)]) (do Monad<Check> [assumptions (check' eFT aFT assumptions)] (check' eAT aAT assumptions)) - [(#;Var id) _] + [(#.Var id) _] (do Monad<Check> [?rFT (read id)] (case ?rFT - (#;Some rFT) - (check' (#;Apply eAT rFT) (#;Apply aAT aFT) assumptions) + (#.Some rFT) + (check' (#.Apply eAT rFT) (#.Apply aAT aFT) assumptions) _ (do Monad<Check> @@ -487,12 +487,12 @@ a' (apply-type! aFT aAT)] (check' e' a' assumptions)))) - [_ (#;Var id)] + [_ (#.Var id)] (do Monad<Check> [?rFT (read id)] (case ?rFT - (#;Some rFT) - (check' (#;Apply eAT eFT) (#;Apply aAT rFT) assumptions) + (#.Some rFT) + (check' (#.Apply eAT eFT) (#.Apply aAT rFT) assumptions) _ (do Monad<Check> @@ -505,53 +505,53 @@ (fail ""))) (def: #export (check' expected actual assumptions) - {#;doc "Type-check to ensure that the 'expected' type subsumes the 'actual' type."} + {#.doc "Type-check to ensure that the 'expected' type subsumes the 'actual' type."} (-> Type Type (List Assumption) (Check (List Assumption))) (if (is expected actual) (check/wrap assumptions) (with-error-stack (function [_] (Type-Check-Failed ($_ text/compose - "Expected: " (type;to-text expected) "\n\n" - " Actual: " (type;to-text actual)))) + "Expected: " (type.to-text expected) "\n\n" + " Actual: " (type.to-text actual)))) (case [expected actual] - [(#;Var idE) (#;Var idA)] + [(#.Var idE) (#.Var idA)] (check-vars check' assumptions idE idA) - [(#;Var id) _] + [(#.Var id) _] (on id actual (check/wrap assumptions) (function [bound] (check' bound actual assumptions))) - [_ (#;Var id)] + [_ (#.Var id)] (on id expected (check/wrap assumptions) (function [bound] (check' expected bound assumptions))) (^template [<fe> <fa>] - [(#;Apply A1 <fe>) (#;Apply A2 <fa>)] + [(#.Apply A1 <fe>) (#.Apply A2 <fa>)] (check-apply check' assumptions [A1 <fe>] [A2 <fa>])) - ([F1 (#;Ex ex)] - [(#;Ex ex) F2] - [F1 (#;Var id)] - [(#;Var id) F2]) + ([F1 (#.Ex ex)] + [(#.Ex ex) F2] + [F1 (#.Var id)] + [(#.Var id) F2]) - [(#;Apply A F) _] + [(#.Apply A F) _] (let [fx-pair [expected actual]] (case (assumed? fx-pair assumptions) - (#;Some ?) + (#.Some ?) (if ? (check/wrap assumptions) (fail "")) - #;None + #.None (do Monad<Check> [expected' (apply-type! F A)] (check' expected' actual (assume! fx-pair true assumptions))))) - [_ (#;Apply A F)] + [_ (#.Apply A F)] (do Monad<Check> [actual' (apply-type! F A)] (check' expected actual' assumptions)) @@ -562,8 +562,8 @@ [[_ paramT] <instancer> expected' (apply-type! expected paramT)] (check' expected' actual assumptions))) - ([#;UnivQ ;;existential] - [#;ExQ ;;var]) + ([#.UnivQ ..existential] + [#.ExQ ..var]) (^template [<tag> <instancer>] [_ (<tag> _)] @@ -571,18 +571,18 @@ [[_ paramT] <instancer> actual' (apply-type! actual paramT)] (check' expected actual' assumptions))) - ([#;UnivQ ;;var] - [#;ExQ ;;existential]) + ([#.UnivQ ..var] + [#.ExQ ..existential]) - [(#;Primitive e-name e-params) (#;Primitive a-name a-params)] + [(#.Primitive e-name e-params) (#.Primitive a-name a-params)] (if (and (text/= e-name a-name) - (n/= (list;size e-params) - (list;size a-params))) + (n/= (list.size e-params) + (list.size a-params))) (do Monad<Check> - [assumptions (monad;fold Monad<Check> + [assumptions (monad.fold Monad<Check> (function [[e a] assumptions] (check' e a assumptions)) assumptions - (list;zip2 e-params a-params))] + (list.zip2 e-params a-params))] (check/wrap assumptions)) (fail "")) @@ -594,59 +594,59 @@ (do Monad<Check> [assumptions (check' eL aL assumptions)] (check' eR aR assumptions))) - ([#;Void #;Sum] - [#;Unit #;Product]) + ([#.Void #.Sum] + [#.Unit #.Product]) - [(#;Function eI eO) (#;Function aI aO)] + [(#.Function eI eO) (#.Function aI aO)] (do Monad<Check> [assumptions (check' aI eI assumptions)] (check' eO aO assumptions)) - [(#;Ex e!id) (#;Ex a!id)] + [(#.Ex e!id) (#.Ex a!id)] (if (n/= e!id a!id) (check/wrap assumptions) (fail "")) - [(#;Named _ ?etype) _] + [(#.Named _ ?etype) _] (check' ?etype actual assumptions) - [_ (#;Named _ ?atype)] + [_ (#.Named _ ?atype)] (check' expected ?atype assumptions) _ (fail ""))))) (def: #export (check expected actual) - {#;doc "Type-check to ensure that the 'expected' type subsumes the 'actual' type."} + {#.doc "Type-check to ensure that the 'expected' type subsumes the 'actual' type."} (-> Type Type (Check Unit)) (do Monad<Check> [assumptions (check' expected actual (list))] (wrap []))) (def: #export (checks? expected actual) - {#;doc "A simple type-checking function that just returns a yes/no answer."} + {#.doc "A simple type-checking function that just returns a yes/no answer."} (-> Type Type Bool) (case (run fresh-context (check expected actual)) - (#e;Error error) + (#e.Error error) false - (#e;Success _) + (#e.Success _) true)) (def: #export get-context (Check Type-Context) (function [context] - (#e;Success [context context]))) + (#e.Success [context context]))) (def: #export (clean inputT) (-> Type (Check Type)) (case inputT - (#;Primitive name paramsT+) + (#.Primitive name paramsT+) (do Monad<Check> - [paramsT+' (monad;map @ clean paramsT+)] - (wrap (#;Primitive name paramsT+'))) + [paramsT+' (monad.map @ clean paramsT+)] + (wrap (#.Primitive name paramsT+'))) - (^or #;Void #;Unit (#;Bound _) (#;Ex _) (#;Named _)) + (^or #.Void #.Unit (#.Bound _) (#.Ex _) (#.Named _)) (:: Monad<Check> wrap inputT) (^template [<tag>] @@ -655,13 +655,13 @@ [leftT' (clean leftT) rightT' (clean rightT)] (wrap (<tag> leftT' rightT')))) - ([#;Sum] [#;Product] [#;Function] [#;Apply]) + ([#.Sum] [#.Product] [#.Function] [#.Apply]) - (#;Var id) + (#.Var id) (do Monad<Check> [?actualT (read id)] (case ?actualT - (#;Some actualT) + (#.Some actualT) (clean actualT) _ @@ -670,7 +670,7 @@ (^template [<tag>] (<tag> envT+ unquantifiedT) (do Monad<Check> - [envT+' (monad;map @ clean envT+)] + [envT+' (monad.map @ clean envT+)] (wrap (<tag> envT+' unquantifiedT)))) - ([#;UnivQ] [#;ExQ]) + ([#.UnivQ] [#.ExQ]) )) |