diff options
Diffstat (limited to 'stdlib/source/parser/lux/tool/compiler/language/lux/analysis.lux')
-rw-r--r-- | stdlib/source/parser/lux/tool/compiler/language/lux/analysis.lux | 133 |
1 files changed, 133 insertions, 0 deletions
diff --git a/stdlib/source/parser/lux/tool/compiler/language/lux/analysis.lux b/stdlib/source/parser/lux/tool/compiler/language/lux/analysis.lux new file mode 100644 index 000000000..159c1c62e --- /dev/null +++ b/stdlib/source/parser/lux/tool/compiler/language/lux/analysis.lux @@ -0,0 +1,133 @@ +(.using + [library + [lux (.except nat int rev local) + [abstract + [monad (.only do)]] + [control + ["//" parser] + ["[0]" try (.only Try)] + ["[0]" exception (.only exception:)]] + [data + ["[0]" bit] + ["[0]" text (.only) + ["%" format (.only format)]] + [collection + ["[0]" list (.open: "[1]#[0]" functor)]]] + [macro + ["[0]" template]] + [math + [number + ["[0]" i64] + ["[0]" nat] + ["[0]" int] + ["[0]" rev] + ["[0]" frac]]] + [meta + ["[0]" symbol]] + [tool + [compiler + [arity (.only Arity)] + [reference (.only) + [variable (.only)]]]]]] + ["/" \\library (.only Environment Analysis)]) + +(def: (remaining_inputs asts) + (-> (List Analysis) Text) + (format text.new_line "Remaining input: " + (|> asts + (list#each /.format) + (text.interposed " ")))) + +(exception: .public (cannot_parse [input (List Analysis)]) + (exception.report + "Input" (exception.listing /.format input))) + +(exception: .public (unconsumed_input [input (List Analysis)]) + (exception.report + "Input" (exception.listing /.format input))) + +(type: .public Parser + (//.Parser (List Analysis))) + +(def: .public (result parser input) + (All (_ a) (-> (Parser a) (List Analysis) (Try a))) + (case (parser input) + {try.#Failure error} + {try.#Failure error} + + {try.#Success [{.#End} value]} + {try.#Success value} + + {try.#Success [unconsumed _]} + (exception.except ..unconsumed_input unconsumed))) + +(def: .public any + (Parser Analysis) + (function (_ input) + (case input + {.#End} + (exception.except ..cannot_parse input) + + {.#Item [head tail]} + {try.#Success [tail head]}))) + +(def: .public end + (Parser Any) + (function (_ tokens) + (case tokens + {.#End} {try.#Success [tokens []]} + _ {try.#Failure (format "Expected list of tokens to be empty!" + (remaining_inputs tokens))}))) + +(def: .public end? + (Parser Bit) + (function (_ tokens) + {try.#Success [tokens (case tokens + {.#End} true + _ false)]})) + +(with_template [<query> <assertion> <tag> <type> <eq>] + [(`` (these (def: .public <query> + (Parser <type>) + (function (_ input) + (case input + (pattern (partial_list (<tag> x) input')) + {try.#Success [input' x]} + + _ + (exception.except ..cannot_parse input)))) + + (def: .public (<assertion> expected) + (-> <type> (Parser Any)) + (function (_ input) + (case input + (pattern (partial_list (<tag> actual) input')) + (if (at <eq> = expected actual) + {try.#Success [input' []]} + (exception.except ..cannot_parse input)) + + _ + (exception.except ..cannot_parse input))))))] + + [bit this_bit /.bit Bit bit.equivalence] + [nat this_nat /.nat Nat nat.equivalence] + [int this_int /.int Int int.equivalence] + [rev this_rev /.rev Rev rev.equivalence] + [frac this_frac /.frac Frac frac.equivalence] + [text this_text /.text Text text.equivalence] + [local this_local /.local Nat nat.equivalence] + [foreign this_foreign /.foreign Nat nat.equivalence] + [constant this_constant /.constant Symbol symbol.equivalence] + ) + +(def: .public (tuple parser) + (All (_ a) (-> (Parser a) (Parser a))) + (function (_ input) + (case input + (pattern (partial_list (/.tuple head) tail)) + (do try.monad + [output (..result parser head)] + {try.#Success [tail output]}) + + _ + (exception.except ..cannot_parse input)))) |