(.module: lux (lux (control [monad #+ do] ["ex" exception #+ exception:] ["p" parser]) (data ["e" error] [text] text/format [number #+ hex] (coll [list "list/" Functor] (dictionary ["dict" unordered #+ Dict]))) [macro #+ with-gensyms] (macro [code] ["s" syntax #+ syntax:]) [host]) (luxc ["&" lang] (lang ["la" analysis] ["ls" synthesis] (host ["_" common-lisp #+ Expression]))) [///] (/// [".T" runtime] [".T" case] [".T" function] [".T" loop])) ## [Types] (type: #export Translator (-> ls.Synthesis (Meta Expression))) (type: #export Proc (-> Translator (List ls.Synthesis) (Meta Expression))) (type: #export Bundle (Dict Text Proc)) (syntax: (Vector {size s.nat} elemT) (wrap (list (` [(~+ (list.repeat size elemT))])))) (type: #export Nullary (-> (Vector +0 Expression) Expression)) (type: #export Unary (-> (Vector +1 Expression) Expression)) (type: #export Binary (-> (Vector +2 Expression) Expression)) (type: #export Trinary (-> (Vector +3 Expression) Expression)) (type: #export Variadic (-> (List Expression) Expression)) ## [Utils] (def: #export (install name unnamed) (-> Text (-> Text Proc) (-> Bundle Bundle)) (dict.put name (unnamed name))) (def: #export (prefix prefix bundle) (-> Text Bundle Bundle) (|> bundle dict.entries (list/map (function (_ [key val]) [(format prefix " " key) val])) (dict.from-list text.Hash))) (def: (wrong-arity proc expected actual) (-> Text Nat Nat Text) (format "Wrong number of arguments for " (%t proc) "\n" "Expected: " (|> expected .int %i) "\n" " Actual: " (|> actual .int %i))) (syntax: (arity: {name s.local-identifier} {arity s.nat}) (with-gensyms [g!_ g!proc g!name g!translate g!inputs] (do @ [g!input+ (monad.seq @ (list.repeat arity (macro.gensym "input")))] (wrap (list (` (def: #export ((~ (code.local-identifier name)) (~ g!proc)) (-> (-> (..Vector (~ (code.nat arity)) Expression) Expression) (-> Text ..Proc)) (function ((~ g!_) (~ g!name)) (function ((~ g!_) (~ g!translate) (~ g!inputs)) (case (~ g!inputs) (^ (list (~+ g!input+))) (do macro.Monad [(~+ (|> g!input+ (list/map (function (_ g!input) (list g!input (` ((~ g!translate) (~ g!input)))))) list.concat))] ((~' wrap) ((~ g!proc) [(~+ g!input+)]))) (~' _) (macro.fail (wrong-arity (~ g!name) +1 (list.size (~ g!inputs)))))))))))))) (arity: nullary +0) (arity: unary +1) (arity: binary +2) (arity: trinary +3) (def: #export (variadic proc) (-> Variadic (-> Text Proc)) (function (_ proc-name) (function (_ translate inputsS) (do macro.Monad [inputsI (monad.map @ translate inputsS)] (wrap (proc inputsI)))))) ## [Procedures] ## [[Lux]] (def: (lux//is [leftO rightO]) Binary (_.eq leftO rightO)) (def: (lux//if [testO thenO elseO]) Trinary (caseT.translate-if testO thenO elseO)) (exception: #export (Wrong-Syntax {message Text}) message) (def: #export (wrong-syntax procedure args) (-> Text (List ls.Synthesis) Text) (format "Procedure: " procedure "\n" "Arguments: " (%code (code.tuple args)))) (def: lux//loop (-> Text Proc) (function (_ proc-name) (function (_ translate inputsS) (case (s.run inputsS ($_ p.seq s.nat (s.tuple (p.many s.any)) s.any)) (#e.Success [offset initsS+ bodyS]) (loopT.translate-loop translate offset initsS+ bodyS) (#e.Error error) (&.throw Wrong-Syntax (wrong-syntax proc-name inputsS))) ))) (def: lux//recur (-> Text Proc) (function (_ proc-name) (function (_ translate inputsS) (loopT.translate-recur translate inputsS)))) (def: lux-procs Bundle (|> (dict.new text.Hash) (install "is" (binary lux//is)) (install "try" (unary runtimeT.lux//try)) (install "if" (trinary lux//if)) (install "loop" lux//loop) (install "recur" lux//recur) )) ## [[Bits]] (template [ ] [(def: ( [subjectO paramO]) Binary ( paramO subjectO))] [bit//and _.logand] [bit//or _.logior] [bit//xor _.logxor] ) (def: (bit//left-shift [subjectO paramO]) Binary (_.ash (_.rem (_.int 64) paramO) subjectO)) (def: (bit//arithmetic-right-shift [subjectO paramO]) Binary (_.ash (|> paramO (_.rem (_.int 64)) (_.* (_.int -1))) subjectO)) (def: (bit//logical-right-shift [subjectO paramO]) Binary (runtimeT.bit//logical-right-shift (_.rem (_.int 64) paramO) subjectO)) (def: bit-procs Bundle (<| (prefix "bit") (|> (dict.new text.Hash) (install "and" (binary bit//and)) (install "or" (binary bit//or)) (install "xor" (binary bit//xor)) (install "left-shift" (binary bit//left-shift)) (install "logical-right-shift" (binary bit//logical-right-shift)) (install "arithmetic-right-shift" (binary bit//arithmetic-right-shift)) ))) ## [[Numbers]] (host.import: java/lang/Double (#static MIN_VALUE Double) (#static MAX_VALUE Double)) (template [ ] [(def: ( _) Nullary ( ))] [frac//smallest Double::MIN_VALUE _.double] [frac//min (f/* -1.0 Double::MAX_VALUE) _.double] [frac//max Double::MAX_VALUE _.double] ) (template [ ] [(def: ( [subjectO paramO]) Binary (|> subjectO ( paramO)))] [int//+ _.+] [int//- _.-] [int//* _.*] [int/// _.floor] [int//% _.rem] [int//= _.=] [int//< _.<] ) (template [ ] [(def: ( [subjectO paramO]) Binary ( paramO subjectO))] [frac//+ _.+] [frac//- _.-] [frac//* _.*] [frac/// _./] [frac//% _.mod] [frac//= _.=] [frac//< _.<] [text//= _.string=] ) (def: (text//< [subjectO paramO]) Binary (|> (_.string< paramO subjectO) _.null _.not)) (def: int-procs Bundle (<| (prefix "int") (|> (dict.new text.Hash) (install "+" (binary int//+)) (install "-" (binary int//-)) (install "*" (binary int//*)) (install "/" (binary int///)) (install "%" (binary int//%)) (install "=" (binary int//=)) (install "<" (binary int//<)) (install "to-frac" (unary (|>> (_./ (_.double 1.0)))))))) (def: frac-procs Bundle (<| (prefix "frac") (|> (dict.new text.Hash) (install "+" (binary frac//+)) (install "-" (binary frac//-)) (install "*" (binary frac//*)) (install "/" (binary frac///)) (install "%" (binary frac//%)) (install "=" (binary frac//=)) (install "<" (binary frac//<)) (install "smallest" (nullary frac//smallest)) (install "min" (nullary frac//min)) (install "max" (nullary frac//max)) (install "to-int" (unary _.floor/1))))) ## ## [[Text]] (def: (text//concat [subjectO paramO]) Binary (_.concatenate/string subjectO paramO)) (def: (text//char [text idx]) Binary (runtimeT.text//char idx text)) (def: (text//clip [text from to]) Trinary (runtimeT.text//clip from to text)) (def: (text//index [space reference start]) Trinary (runtimeT.text//index reference start space)) (def: text-procs Bundle (<| (prefix "text") (|> (dict.new text.Hash) (install "=" (binary text//=)) (install "<" (binary text//<)) (install "concat" (binary text//concat)) (install "index" (trinary text//index)) (install "size" (unary _.length)) (install "char" (binary text//char)) (install "clip" (trinary text//clip)) ))) ## [[IO]] (def: (void code) (-> Expression Expression) (_.progn (list code runtimeT.unit))) (def: io-procs Bundle (<| (prefix "io") (|> (dict.new text.Hash) (install "log" (unary (|>> _.print ..void))) (install "error" (unary _.error)) (install "exit" (unary runtimeT.io//exit)) (install "current-time" (nullary (function (_ _) (runtimeT.io//current-time runtimeT.unit))))))) ## [Bundles] (def: #export procedures Bundle (<| (prefix "lux") (|> lux-procs (dict.merge bit-procs) (dict.merge int-procs) (dict.merge frac-procs) (dict.merge text-procs) (dict.merge io-procs) )))