(.require [library [lux (.except Alias) [abstract [monad (.only do)]] [control ["<>" parser (.use "[1]#[0]" monad)] ["[0]" io] ["[0]" maybe]] [data ["[0]" product] ["[0]" text ["%" \\format (.only format)]] [collection ["[0]" list (.use "[1]#[0]" functor)]]] ["[0]" meta (.only) ["@" target] [type ["[0]" nominal (.except def)]] ["[0]" code (.only) ["<[1]>" \\parser (.only Parser)]] [macro (.only with_symbols) [syntax (.only syntax)] ["[0]" template]]]]]) (nominal.def .public (Object brand) Any) (with_template [] [(with_expansions [ (template.symbol [ "'"])] (nominal.def .public Any) (type .public (..Object )))] [Nil] [Function] ) (with_template [ ] [(type .public )] [Boolean Bit] [Integer Int] [Float Frac] [String Text] ) (type Nilable [Bit Code]) (def nilable (Parser Nilable) (let [token (' "?")] (<| (<>.and (<>.parses? (.this token))) (<>.after (<>.not (.this token))) .any))) (type Alias Text) (def alias (Parser Alias) (<>.after (.this (' "as")) .local)) (type Field [Bit Text (Maybe Alias) Nilable]) (def static! (Parser Any) (.this (' "static"))) (def field (Parser Field) (.form (all <>.and (<>.parses? ..static!) .local (<>.maybe ..alias) ..nilable))) (def constant (Parser Field) (.form (all <>.and (<>#in true) .local (<>.maybe ..alias) ..nilable))) (type Common_Method (Record [#name Text #alias (Maybe Alias) #inputs (List Nilable) #io? Bit #try? Bit #output Nilable])) (def common_method (Parser Common_Method) (all <>.and .local (<>.maybe ..alias) (.tuple (<>.some ..nilable)) (<>.parses? (.this (' "io"))) (<>.parses? (.this (' "try"))) ..nilable)) (def input_variables (-> (List Nilable) (List [Bit Code])) (|>> list.enumeration (list#each (function (_ [idx [nilable? type]]) [nilable? (|> idx %.nat code.local)])))) (def (nilable_type [nilable? type]) (-> Nilable Code) (if nilable? (` (.Maybe (, type))) type)) (def (with_nil g!temp [nilable? input]) (-> Code [Bit Code] Code) (if nilable? (` (when (, input) {.#Some (, g!temp)} (, g!temp) {.#None} ("scheme object nil"))) input)) (def (without_nil g!temp [nilable? outputT] output) (-> Code Nilable Code Code) (if nilable? (` (let [(, g!temp) (, output)] (if ("scheme object nil?" (, g!temp)) {.#None} {.#Some (, g!temp)}))) (` (let [(, g!temp) (, output)] (if (not ("scheme object nil?" (, g!temp))) (, g!temp) (.panic! "Nil is an invalid value!")))))) (type Import (Variant {#Function Common_Method} {#Constant Field})) (def import (Parser Import) (all <>.or (.form ..common_method) ..constant )) (def (with_io with? without) (-> Bit Code Code) (if with? (` (io.io (, without))) without)) (def (io_type io? rawT) (-> Bit Code Code) (if io? (` (io.IO (, rawT))) rawT)) (def (with_try with? without_try) (-> Bit Code Code) (if with? (` (..try (, without_try))) without_try)) (def (try_type try? rawT) (-> Bit Code Code) (if try? (` (.Either .Text (, rawT))) rawT)) (def (make_function g!method g!temp source inputsT io? try? outputT) (-> Code Code Code (List Nilable) Bit Bit Nilable Code) (let [g!inputs (input_variables inputsT)] (` (def ((, g!method) [(,* (list#each product.right g!inputs))]) (-> [(,* (list#each nilable_type inputsT))] (, (|> (nilable_type outputT) (try_type try?) (io_type io?)))) (as_expected (, (<| (with_io io?) (with_try try?) (without_nil g!temp outputT) (` ("scheme apply" (as ..Function (, source)) (,* (list#each (with_nil g!temp) g!inputs))))))))))) (def .public import (syntax (_ [import ..import]) (with_symbols [g!temp] (when import {#Function [name alias inputsT io? try? outputT]} (let [imported (` ("scheme constant" (, (code.text name))))] (in (list (..make_function (code.local (maybe.else name alias)) g!temp imported inputsT io? try? outputT)))) {#Constant [_ name alias fieldT]} (let [imported (` ("scheme constant" (, (code.text name)))) g!name (code.local (maybe.else name alias))] (in (list (` (def (, g!name) (syntax ((, g!name) []) (at meta.monad (,' in) (list (` (.as (, (nilable_type fieldT)) (, imported))))))))))) ))))