aboutsummaryrefslogtreecommitdiff
path: root/stdlib/source/parser/lux/tool/compiler/language/lux/analysis.lux
diff options
context:
space:
mode:
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.lux133
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))))