(.module: [library [lux (#- Alias) ["@" target] ["." meta] [abstract [monad (#+ do)]] [control ["." io] ["." maybe] ["<>" parser ("#\." monad) ["<.>" code (#+ Parser)]]] [data ["." product] ["." text ["%" format (#+ format)]] [collection ["." list ("#\." functor)]]] [type abstract] [macro (#+ with_identifiers) [syntax (#+ syntax:)] ["." code] ["." template]]]]) (abstract: .public (Object brand) {} Any) (template [] [(with_expansions [ (template.identifier [ "'"])] (abstract: .public {} Any) (type: .public (..Object )))] [Nil] [Function] ) (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_identifier)) (type: Field [Bit Text (Maybe Alias) Nilable]) (def: static! (Parser Any) (.this! (' #static))) (def: field (Parser Field) (.form ($_ <>.and (<>.parses? ..static!) .local_identifier (<>.maybe ..alias) ..nilable))) (def: constant (Parser Field) (.form ($_ <>.and (<>\in true) .local_identifier (<>.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) ($_ <>.and .local_identifier (<>.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_identifier)])))) (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? (` (case (~ 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) ($_ <>.or (.form ..common_method) ..constant )) (syntax: .public (try [expression .any]) {#.doc (example (case (try (risky_computation input)) (#.Right success) (do_something success) (#.Left error) (recover_from_failure error)))} (in (list (` ("lux try" ((~! io.io) (~ expression))))))) (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?)))) (: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))))))))))) (syntax: .public (import: [import ..import]) (with_identifiers [g!temp] (case import (#Function [name alias inputsT io? try? outputT]) (let [imported (` ("scheme constant" (~ (code.text name))))] (in (list (..make_function (code.local_identifier (maybe.else name alias)) g!temp imported inputsT io? try? outputT)))) (#Constant [_ name alias fieldT]) (let [imported (` ("scheme constant" (~ (code.text name))))] (in (list (` ((~! syntax:) ((~ (code.local_identifier (maybe.else name alias)))) (\ (~! meta.monad) (~' in) (list (` (.:as (~ (nilable_type fieldT)) (~ imported)))))))))) )))