diff options
Diffstat (limited to 'stdlib/source/library/lux/meta/macro/syntax/definition.lux')
-rw-r--r-- | stdlib/source/library/lux/meta/macro/syntax/definition.lux | 97 |
1 files changed, 97 insertions, 0 deletions
diff --git a/stdlib/source/library/lux/meta/macro/syntax/definition.lux b/stdlib/source/library/lux/meta/macro/syntax/definition.lux new file mode 100644 index 000000000..750c94d60 --- /dev/null +++ b/stdlib/source/library/lux/meta/macro/syntax/definition.lux @@ -0,0 +1,97 @@ +(.require + [library + [lux (.except Definition) + [abstract + [equivalence (.only Equivalence)] + [monad (.only do)]] + [control + ["<>" parser] + ["[0]" exception (.only exception)]] + [data + ["[0]" sum] + ["[0]" product] + ["[0]" bit] + ["[0]" text (.only) + ["%" \\format]] + [collection + ["[0]" list]]] + ["[0]" meta (.only) + ["[0]" location] + ["[0]" macro] + ["[0]" code (.only) + ["<[1]>" \\parser (.only Parser)]]]]] + ["[0]" // (.only) + ["[1][0]" check (.only Check)]]) + +(type .public Definition + (Record + [#name Text + #value (Either Check + Code) + #export? Bit])) + +(def .public equivalence + (Equivalence Definition) + (all product.equivalence + text.equivalence + (all sum.equivalence + //check.equivalence + code.equivalence + ) + bit.equivalence + )) + +(def extension + "lux def") + +(def dummy + Code + (` [.#module (, (code.text (the .#module location.dummy))) + .#line (, (code.nat (the .#line location.dummy))) + .#column (, (code.nat (the .#column location.dummy)))])) + +(def .public (format (open "_[0]")) + (-> Definition Code) + (` ((, (code.text ..extension)) + (, (code.local _#name)) + (, (case _#value + {.#Left check} + (//check.format check) + + {.#Right value} + value)) + (, (code.bit _#export?))))) + +(def .public (parser compiler) + (-> Lux (Parser Definition)) + (do [! <>.monad] + [raw <code>.any + me_raw (|> raw + macro.full_expansion + (meta.result compiler) + <>.lifted)] + (<| (<code>.locally me_raw) + <code>.form + (<>.after (<code>.this_text ..extension)) + (all <>.and + <code>.local + (<>.or //check.parser + <code>.any) + <code>.bit + )))) + +(exception .public (lacks_type [definition Definition]) + (exception.report + "Definition" (%.code (..format definition)))) + +(def .public (typed compiler) + (-> Lux (Parser Definition)) + (do <>.monad + [definition (..parser compiler) + _ (case (the #value definition) + {.#Left _} + (in []) + + {.#Right _} + (<>.lifted (exception.except ..lacks_type [definition])))] + (in definition))) |