diff options
author | Eduardo Julian | 2018-04-04 00:56:16 -0400 |
---|---|---|
committer | Eduardo Julian | 2018-04-04 00:56:16 -0400 |
commit | 787fc34a8f7c66746046a8ce0c16403cf6c2bf6c (patch) | |
tree | 31c054f4a61e784875b7d66642558e9357d91493 /new-luxc/source | |
parent | b14f95ca68887d9e6cea211b47e04e5ec00c05fa (diff) |
- Initial Python back-end implementation.
Diffstat (limited to 'new-luxc/source')
18 files changed, 2601 insertions, 5 deletions
diff --git a/new-luxc/source/luxc/lang/host.jvm.lux b/new-luxc/source/luxc/lang/host.jvm.lux index f22bf3302..58b79cfa4 100644 --- a/new-luxc/source/luxc/lang/host.jvm.lux +++ b/new-luxc/source/luxc/lang/host.jvm.lux @@ -183,4 +183,4 @@ (def: #export runtime-class Text "LuxRuntime") (def: #export function-class Text "LuxFunction") (def: #export runnable-class Text "LuxRunnable") -(def: #export unit Text "\u0000") +(def: #export unit Text "") diff --git a/new-luxc/source/luxc/lang/host/python.lux b/new-luxc/source/luxc/lang/host/python.lux new file mode 100644 index 000000000..335d418a3 --- /dev/null +++ b/new-luxc/source/luxc/lang/host/python.lux @@ -0,0 +1,340 @@ +(.module: + [lux #- not or and list if is] + (lux (control pipe) + (data [text] + text/format + [number] + (coll [list "list/" Functor<List> Fold<List>])) + (type abstract))) + +(abstract: #export Single {} Unit) +(abstract: #export Poly {} Unit) +(abstract: #export Keyword {} Unit) + +(abstract: #export (Var kind) + {} + + Text + + (def: name (All [k] (-> (Var k) Text)) (|>> @representation)) + + (def: #export var (-> Text (Var Single)) (|>> @abstraction)) + + (do-template [<name> <kind> <prefix>] + [(def: #export <name> + (-> (Var Single) (Var <kind>)) + (|>> @representation (format <prefix>) @abstraction))] + + [poly Poly "*"] + [keyword Keyword "**"] + ) + ) + +(type: #export SVar (Var Single)) +(type: #export PVar (Var Poly)) +(type: #export KVar (Var Keyword)) + +(abstract: #export Expression + {} + + Text + + (def: #export expression (-> Expression Text) (|>> @representation)) + + (def: #export code (-> Text Expression) (|>> @abstraction)) + + (def: #export none + Expression + (@abstraction "None")) + + (def: #export bool + (-> Bool Expression) + (|>> (case> true "True" + false "False") + @abstraction)) + + (def: #export int + (-> Int Expression) + (|>> %i @abstraction)) + + (def: #export float + (-> Frac Expression) + (|>> (cond> [(f/= number.positive-infinity)] + [(new> "float(\"inf\")")] + + [(f/= number.negative-infinity)] + [(new> "float(\"-inf\")")] + + [(f/= number.not-a-number)] + [(new> "float(\"nan\")")] + + ## else + [%f]) + @abstraction)) + + (def: #export string + (-> Text Expression) + (|>> %t @abstraction)) + + (def: (composite-literal left-delimiter right-delimiter entry-serializer) + (All [a] (-> Text Text (-> a Text) + (-> (List a) Expression))) + (function [entries] + (@abstraction (format "(" left-delimiter + (|> entries (list/map entry-serializer) (text.join-with ",")) + right-delimiter ")")))) + + (do-template [<name> <pre> <post>] + [(def: #export <name> + (-> (List Expression) Expression) + (composite-literal <pre> <post> expression))] + + [tuple "(" ")"] + [list "[" "]"] + ) + + (def: #export (slice from to list) + (-> Expression Expression Expression Expression) + (@abstraction (format "(" (@representation list) + "[" (@representation from) ":" (@representation to) "]" + ")"))) + + (def: #export (slice-from from list) + (-> Expression Expression Expression) + (@abstraction (format "(" (@representation list) + "[" (@representation from) ":]" + ")"))) + + (def: #export dict + (-> (List [Expression Expression]) Expression) + (composite-literal "{" "}" (.function [[k v]] (format (@representation k) " : " (@representation v))))) + + (def: #export (apply args func) + (-> (List Expression) Expression Expression) + (@abstraction (format "(" (@representation func) + "(" (text.join-with "," (list/map expression args)) ")" + ")"))) + + (do-template [<name> <kind> <prefix>] + [(def: (<name> var) + (-> Expression Text) + (format <prefix> (@representation var)))] + + [splat-poly Poly "*"] + [splat-keyword Keyword "**"] + ) + + (do-template [<name> <splat>] + [(def: #export (<name> args extra func) + (-> (List Expression) Expression Expression Expression) + (@abstraction (format "(" (@representation func) + (format "(" (|> args + (list/map (function [arg] (format (@representation arg) ", "))) + (text.join-with "")) + (<splat> extra) ")") + ")")))] + + [apply-poly splat-poly] + [apply-keyword splat-keyword] + ) + + (def: #export (field name object) + (-> Text Expression Expression) + (@abstraction (format "(" (@representation object) "." name ")"))) + + (def: #export (send args method object) + (-> (List Expression) Text Expression Expression) + (|> object (field method) (apply args))) + + (do-template [<name> <apply>] + [(def: #export (<name> args extra method) + (-> (List Expression) Expression Text + (-> Expression Expression)) + (|>> (field method) (<apply> args extra)))] + + [send-poly apply-poly] + [send-keyword apply-keyword] + ) + + (def: #export (nth idx array) + (-> Expression Expression Expression) + (@abstraction (format "(" (@representation array) "[" (@representation idx) "])"))) + + (def: #export (if test then else) + (-> Expression Expression Expression Expression) + (@abstraction (format "(" (@representation then) + " if " (@representation test) + " else " (@representation else) + ")"))) + + (do-template [<name> <op>] + [(def: #export (<name> param subject) + (-> Expression Expression Expression) + (@abstraction (format "(" (@representation subject) + " " <op> " " + (@representation param) ")")))] + + [is "is"] + [= "=="] + [< "<"] + [<= "<="] + [> ">"] + [>= ">="] + [+ "+"] + [- "-"] + [* "*"] + [/ "/"] + [% "%"] + [** "**"] + [bit-or "|"] + [bit-and "&"] + [bit-xor "^"] + [bit-shl "<<"] + [bit-shr ">>"] + ) + + (do-template [<name> <op>] + [(def: #export (<name> param subject) + (-> Expression Expression Expression) + (@abstraction (format "(" (@representation param) + " " <op> " " + (@representation subject) ")")))] + + [or "or"] + [and "and"] + ) + + (def: #export (not subject) + (-> Expression Expression) + (@abstraction (format "(not " (@representation subject) ")"))) + + (def: #export (@@ var) + (All [k] (-> (Var k) Expression)) + (@abstraction (format "(" (..name var) ")"))) + + (def: #export (lambda arguments body) + (-> (List (Ex [k] (Var k))) Expression Expression) + (@abstraction (format "(" "lambda " (|> arguments (list/map ..name) (text.join-with ", ")) ": " + (@representation body) ")"))) + + (def: #export global + (-> Text Expression) + (|>> var @@)) + + (def: #export (length sequence) + (-> Expression Expression) + (apply (.list sequence) (global "len"))) + ) + +(abstract: #export Statement + {} + + Text + + (def: #export statement (-> Statement Text) (|>> @representation)) + + (def: nest + (-> Statement Text) + (|>> @representation + (format "\n") + (text.replace-all "\n" "\n "))) + + (def: #export (set-nth! idx value array) + (-> Expression Expression Expression Statement) + (@abstraction (format (expression array) "[" (expression idx) "] = " (expression value)))) + + (def: #export (set! vars value) + (-> (List (Var Single)) Expression Statement) + (@abstraction + (format (|> vars (list/map ..name) (text.join-with ", ")) + " = " + (expression value)))) + + (def: #export (if! test then! else!) + (-> Expression Statement Statement Statement) + (@abstraction + (format "if " (expression test) ":" + (nest then!) + "\n" "else:" + (nest else!)))) + + (def: #export (when! test then!) + (-> Expression Statement Statement) + (@abstraction + (format "if " (expression test) ":" + (nest then!)))) + + (def: #export (cond! clauses else!) + (-> (List [Expression Statement]) Statement Statement) + (list/fold (.function [[test then!] next!] + (if! test then! next!)) + else! + (list.reverse clauses))) + + (def: #export (then! pre! post!) + (-> Statement Statement Statement) + (@abstraction + (format (@representation pre!) + "\n" + (@representation post!)))) + + (def: #export (while! test body!) + (-> Expression Statement Statement) + (@abstraction + (format "while " (expression test) ":" + (nest body!)))) + + (def: #export (for-in! var inputs body!) + (-> SVar Expression Statement Statement) + (@abstraction + (format "for " (..name var) " in " (expression inputs) ":" + (nest body!)))) + + (def: #export (do! expression) + (-> Expression Statement) + (@abstraction + (format (..expression expression) ";"))) + + (def: #export no-op! + Statement + (@abstraction "\n")) + + (type: #export Except + {#classes (List Text) + #exception SVar + #handler Statement}) + + (def: #export (try! body! excepts) + (-> Statement (List Except) Statement) + (@abstraction + (format "try:" + (nest body!) + (|> excepts + (list/map (function [[classes exception catch!]] + (format "\n" "except (" (text.join-with "," classes) + ") as " (..name exception) ":" + (nest catch!)))) + (text.join-with ""))))) + + (do-template [<name> <keyword>] + [(def: #export (<name> message) + (-> Expression Statement) + (@abstraction + (format <keyword> " " (expression message))))] + + [raise! "raise"] + [return! "return"] + [print! "print"] + ) + + (def: #export (def! name args body) + (-> (Var Single) (List (Ex [k] (Var k))) Statement Statement) + (@abstraction + (format "def " (..name name) + "(" (|> args (list/map ..name) (text.join-with ",")) "):" + (nest body)))) + + (def: #export (import! module-name) + (-> Text Statement) + (@abstraction (format "import " module-name))) + ) diff --git a/new-luxc/source/luxc/lang/translation/jvm/procedure/common.jvm.lux b/new-luxc/source/luxc/lang/translation/jvm/procedure/common.jvm.lux index 422d9da1d..abd2d49c8 100644 --- a/new-luxc/source/luxc/lang/translation/jvm/procedure/common.jvm.lux +++ b/new-luxc/source/luxc/lang/translation/jvm/procedure/common.jvm.lux @@ -381,7 +381,6 @@ [text//size "java.lang.String" "length" lux-intI $t.int] [text//hash "java.lang.Object" "hashCode" lux-intI $t.int] - [text//trim "java.lang.String" "trim" id $String] [text//upper "java.lang.String" "toUpperCase" id $String] [text//lower "java.lang.String" "toLowerCase" id $String] ) diff --git a/new-luxc/source/luxc/lang/translation/python.lux b/new-luxc/source/luxc/lang/translation/python.lux new file mode 100644 index 000000000..7304ea560 --- /dev/null +++ b/new-luxc/source/luxc/lang/translation/python.lux @@ -0,0 +1,208 @@ +(.module: + lux + (lux (control ["ex" exception #+ exception:] + pipe + [monad #+ do]) + (data [bit] + [maybe] + ["e" error #+ Error] + [text "text/" Eq<Text>] + text/format + (coll [array])) + [macro] + [io #+ IO Process io] + [host #+ class: interface: object] + (world [file #+ File])) + (luxc [lang] + (lang [".L" variable #+ Register] + (host [python #+ Expression Statement])) + [".C" io])) + +(host.import java/lang/Object) + +(host.import java/lang/String + (getBytes [String] #try (Array byte))) + +(host.import java/lang/CharSequence) + +(host.import java/lang/Appendable + (append [CharSequence] Appendable)) + +(host.import java/lang/StringBuilder + (new []) + (toString [] String)) + +(host.import org/python/core/PyObject) + +(host.import org/python/util/PythonInterpreter + (new []) + (exec [String] void) + (eval [String] PyObject)) + +(type: #export Anchor [Text Register]) + +(type: #export Host + {#context [Text Nat] + #anchor (Maybe Anchor) + #loader (-> Statement (Error Unit)) + #interpreter (-> Expression (Error PyObject)) + #module-buffer (Maybe StringBuilder) + #program-buffer StringBuilder}) + +(def: #export init + (IO Host) + (io (let [interpreter (PythonInterpreter::new [])] + {#context ["" +0] + #anchor #.None + #loader (function [code] + ("lux try" (io (PythonInterpreter::exec [(python.statement code)] interpreter)))) + #interpreter (function [code] + ("lux try" (io (PythonInterpreter::eval [(python.expression code)] interpreter)))) + #module-buffer #.None + #program-buffer (StringBuilder::new [])}))) + +(def: #export python-module-name Text "module.py") + +(def: #export init-module-buffer + (Meta Unit) + (function [compiler] + (#e.Success [(update@ #.host + (|>> (:! Host) + (set@ #module-buffer (#.Some (StringBuilder::new []))) + (:! Void)) + compiler) + []]))) + +(exception: #export No-Active-Module-Buffer) +(exception: #export Cannot-Execute) + +(def: #export (with-sub-context expr) + (All [a] (-> (Meta a) (Meta [Text a]))) + (function [compiler] + (let [old (:! Host (get@ #.host compiler)) + [old-name old-sub] (get@ #context old) + new-name (format old-name "___" (%i (nat-to-int old-sub)))] + (case (expr (set@ #.host + (:! Void (set@ #context [new-name +0] old)) + compiler)) + (#e.Success [compiler' output]) + (#e.Success [(update@ #.host + (|>> (:! Host) + (set@ #context [old-name (n/inc old-sub)]) + (:! Void)) + compiler') + [new-name output]]) + + (#e.Error error) + (#e.Error error))))) + +(def: #export context + (Meta Text) + (function [compiler] + (#e.Success [compiler + (|> (get@ #.host compiler) + (:! Host) + (get@ #context) + (let> [name sub] + name))]))) + +(def: #export (with-anchor anchor expr) + (All [a] (-> Anchor (Meta a) (Meta a))) + (function [compiler] + (let [old (:! Host (get@ #.host compiler))] + (case (expr (set@ #.host + (:! Void (set@ #anchor (#.Some anchor) old)) + compiler)) + (#e.Success [compiler' output]) + (#e.Success [(update@ #.host + (|>> (:! Host) + (set@ #anchor (get@ #anchor old)) + (:! Void)) + compiler') + output]) + + (#e.Error error) + (#e.Error error))))) + +(exception: #export No-Anchor) + +(def: #export anchor + (Meta Anchor) + (function [compiler] + (case (|> compiler (get@ #.host) (:! Host) (get@ #anchor)) + (#.Some anchor) + (#e.Success [compiler anchor]) + + #.None + ((lang.throw No-Anchor "") compiler)))) + +(def: #export module-buffer + (Meta StringBuilder) + (function [compiler] + (case (|> compiler (get@ #.host) (:! Host) (get@ #module-buffer)) + #.None + ((lang.fail (No-Active-Module-Buffer "")) compiler) + + (#.Some module-buffer) + (#e.Success [compiler module-buffer])))) + +(def: #export program-buffer + (Meta StringBuilder) + (function [compiler] + (#e.Success [compiler (|> compiler (get@ #.host) (:! Host) (get@ #program-buffer))]))) + +(do-template [<name> <field> <inputT> <outputT>] + [(def: (<name> code) + (-> <inputT> (Meta <outputT>)) + (function [compiler] + (let [runner (|> compiler (get@ #.host) (:! Host) (get@ <field>))] + (case (runner code) + (#e.Error error) + ((lang.fail (Cannot-Execute error)) compiler) + + (#e.Success output) + (#e.Success [compiler output])))))] + + [load! #loader Statement Unit] + [interpret #interpreter Expression PyObject] + ) + +(exception: #export Unknown-Member) + +(def: #export variant-tag-field "_lux_tag") +(def: #export variant-flag-field "_lux_flag") +(def: #export variant-value-field "_lux_value") + +(def: #export unit Text "") + +(def: #export (definition-name [module name]) + (-> Ident Text) + (lang.normalize-name (format module "$" name))) + +(do-template [<name> <eval> <un-wrap> <inputT> <outputT>] + [(def: #export (<name> code) + (-> <inputT> (Meta <outputT>)) + (do macro.Monad<Meta> + [module-buffer module-buffer + #let [_ (Appendable::append [(:! CharSequence (<un-wrap> code))] + module-buffer)]] + (<eval> code)))] + + [save load! python.statement Statement Unit] + [run interpret python.expression Expression PyObject] + ) + +(def: #export (save-module! target) + (-> File (Meta (Process Unit))) + (do macro.Monad<Meta> + [module macro.current-module-name + module-buffer module-buffer + program-buffer program-buffer + #let [module-code (StringBuilder::toString [] module-buffer) + _ (Appendable::append [(:! CharSequence (format module-code "\n"))] + program-buffer)]] + (wrap (ioC.write target + (format (lang.normalize-name module) "/" python-module-name) + (|> module-code + (String::getBytes ["UTF-8"]) + e.assume))))) diff --git a/new-luxc/source/luxc/lang/translation/python/case.jvm.lux b/new-luxc/source/luxc/lang/translation/python/case.jvm.lux new file mode 100644 index 000000000..2218c1994 --- /dev/null +++ b/new-luxc/source/luxc/lang/translation/python/case.jvm.lux @@ -0,0 +1,265 @@ +(.module: + lux + (lux (control [monad #+ do] + ["ex" exception #+ exception:]) + (data [number] + [text] + text/format + (coll [list "list/" Functor<List> Fold<List>] + [set #+ Set])) + [macro #+ "meta/" Monad<Meta>] + (macro [code])) + (luxc [lang] + (lang [".L" variable #+ Register Variable] + ["ls" synthesis #+ Synthesis Path] + (host [python #+ Expression Statement Except SVar @@]))) + [//] + (// [".T" runtime] + [".T" primitive] + [".T" reference])) + +(def: #export (translate-let translate register valueS bodyS) + (-> (-> Synthesis (Meta Expression)) Register Synthesis Synthesis + (Meta Expression)) + (do macro.Monad<Meta> + [valueO (translate valueS) + bodyO (translate bodyS) + #let [$register (referenceT.variable register)]] + (wrap (|> bodyO + (python.lambda (list $register)) + (python.apply (list valueO)))))) + +(def: #export (translate-record-get translate valueS pathP) + (-> (-> Synthesis (Meta Expression)) Synthesis (List [Nat Bool]) + (Meta Expression)) + (do macro.Monad<Meta> + [valueO (translate valueS)] + (wrap (list/fold (function [[idx tail?] source] + (let [method (if tail? + runtimeT.product//right + runtimeT.product//left)] + (method source (python.int (:! Int idx))))) + valueO + pathP)))) + +(def: #export (translate-if testO thenO elseO) + (-> Expression Expression Expression Expression) + (python.if testO thenO elseO)) + +(def: $savepoint (python.var "pm_cursor_savepoint")) +(def: $cursor (python.var "pm_cursor")) + +(def: (push-cursor! value) + (-> Expression Statement) + (python.do! + (python.send (list value) + "append" (@@ $cursor)))) + +(def: save-cursor! + Statement + (python.do! + (python.send (list (python.slice-from (python.int 0) (@@ $cursor))) + "append" (@@ $savepoint)))) + +(def: restore-cursor! + Statement + (python.set! (list $cursor) + (python.send (list) "pop" (@@ $savepoint)))) + +(def: cursor-top + Expression + (python.nth (python.int -1) (@@ $cursor))) + +(def: pop-cursor! + Statement + (python.do! + (python.send (list) "pop" (@@ $cursor)))) + +(def: pm-error (python.string "PM-ERROR")) + +(def: (new-Exception error) + (-> Expression Expression) + (python.apply (list pm-error) (python.global "Exception"))) + +(def: fail-pm! (python.raise! (new-Exception pm-error))) + +(def: $temp (python.var "temp")) + +(exception: #export Unrecognized-Path) + +(def: $alt_error (python.var "alt_error")) + +(def: (pm-catch! handler!) + (-> Statement Except) + [(list "Exception") $alt_error + (python.if! (python.= pm-error (python.apply (list (@@ $alt_error)) (python.global "str"))) + handler! + (python.raise! (@@ $alt_error)))]) + +(def: (translate-pattern-matching' translate pathP) + (-> (-> Synthesis (Meta Expression)) Path (Meta Statement)) + (case pathP + (^code ("lux case exec" (~ bodyS))) + (do macro.Monad<Meta> + [bodyO (translate bodyS)] + (wrap (python.return! bodyO))) + + (^code ("lux case pop")) + (meta/wrap pop-cursor!) + + (^code ("lux case bind" (~ [_ (#.Nat register)]))) + (meta/wrap (python.set! (list (referenceT.variable register)) cursor-top)) + + (^template [<tag> <format>] + [_ (<tag> value)] + (meta/wrap (python.when! (python.not (python.= (|> value <format>) cursor-top)) + fail-pm!))) + ([#.Nat (<| python.int (:! Int))] + [#.Int python.int] + [#.Deg (<| python.int (:! Int))] + [#.Bool python.bool] + [#.Frac python.float] + [#.Text python.string]) + + (^template [<pm> <getter>] + (^code (<pm> (~ [_ (#.Nat idx)]))) + (meta/wrap (push-cursor! (<getter> cursor-top (python.int (:! Int idx)))))) + (["lux case tuple left" runtimeT.product//left] + ["lux case tuple right" runtimeT.product//right]) + + (^template [<pm> <flag>] + (^code (<pm> (~ [_ (#.Nat idx)]))) + (meta/wrap ($_ python.then! + (python.set! (list $temp) (runtimeT.sum//get cursor-top (python.int (:! Int idx)) <flag>)) + (python.if! (python.not (python.= python.none (@@ $temp))) + (push-cursor! (@@ $temp)) + fail-pm!)))) + (["lux case variant left" python.none] + ["lux case variant right" (python.string "")]) + + (^code ("lux case seq" (~ leftP) (~ rightP))) + (do macro.Monad<Meta> + [leftO (translate-pattern-matching' translate leftP) + rightO (translate-pattern-matching' translate rightP)] + (wrap ($_ python.then! + leftO + rightO))) + + (^code ("lux case alt" (~ leftP) (~ rightP))) + (do macro.Monad<Meta> + [leftO (translate-pattern-matching' translate leftP) + rightO (translate-pattern-matching' translate rightP)] + (wrap (python.try! ($_ python.then! + save-cursor! + leftO) + (list (pm-catch! + ($_ python.then! + restore-cursor! + rightO)))))) + + _ + (lang.throw Unrecognized-Path (%code pathP)) + )) + +(def: (translate-pattern-matching translate pathP) + (-> (-> Synthesis (Meta Expression)) Path (Meta Statement)) + (do macro.Monad<Meta> + [pattern-matching (translate-pattern-matching' translate pathP)] + (wrap (python.try! pattern-matching + (list (pm-catch! + (python.raise! (new-Exception (python.string "Invalid expression for pattern-matching."))))))))) + +(def: (initialize-pattern-matching! stack-init) + (-> Expression Statement) + ($_ python.then! + (python.set! (list $cursor) (python.list (list stack-init))) + (python.set! (list $savepoint) (python.list (list))))) + +(def: empty (Set Variable) (set.new number.Hash<Int>)) + +(type: Storage + {#bindings (Set Variable) + #dependencies (Set Variable)}) + +(def: (path-variables pathP) + (-> Path Storage) + (loop [pathP pathP + outer-variables {#bindings empty + #dependencies empty}] + ## TODO: Remove (let [outer recur]) once loops can have names. + (let [outer recur] + (case pathP + (^code ("lux case bind" (~ [_ (#.Nat register)]))) + (update@ #bindings (set.add (nat-to-int register)) + outer-variables) + + (^or (^code ("lux case seq" (~ leftP) (~ rightP))) + (^code ("lux case alt" (~ leftP) (~ rightP)))) + (list/fold outer outer-variables (list leftP rightP)) + + (^code ("lux case exec" (~ bodyS))) + (loop [bodyS bodyS + inner-variables outer-variables] + ## TODO: Remove (let [inner recur]) once loops can have names. + (let [inner recur] + (case bodyS + (^code ((~ [_ (#.Nat tag)]) (~ [_ (#.Bool last?)]) (~ valueS))) + (inner valueS inner-variables) + + (^code [(~+ members)]) + (list/fold inner inner-variables members) + + (^ [_ (#.Form (list [_ (#.Int var)]))]) + (if (set.member? (get@ #bindings inner-variables) var) + inner-variables + (update@ #dependencies (set.add var) inner-variables)) + + (^code ("lux call" (~ functionS) (~+ argsS))) + (list/fold inner inner-variables (#.Cons functionS argsS)) + + (^code ("lux function" (~ [_ (#.Nat arity)]) [(~+ environment)] (~ bodyS))) + (|> environment + (list/map (|>> (list) code.form)) + (list/fold inner inner-variables)) + + (^code ("lux let" (~ [_ (#.Nat register)]) (~ inputS) (~ exprS))) + (list/fold inner (update@ #bindings (set.add (nat-to-int register)) + inner-variables) + (list inputS exprS)) + + (^code ("lux case" (~ inputS) (~ pathPS))) + (|> inner-variables (inner inputS) (outer pathPS)) + + (^code ((~ [_ (#.Text procedure)]) (~+ argsS))) + (list/fold inner inner-variables argsS) + + _ + inner-variables))) + + _ + outer-variables)))) + +(def: generated-name + (-> Text (Meta SVar)) + (|>> macro.gensym + (:: macro.Monad<Meta> map (|>> %code + lang.normalize-name + python.var)))) + +(def: #export (translate-case translate valueS pathP) + (-> (-> Synthesis (Meta Expression)) Synthesis Path (Meta Expression)) + (do macro.Monad<Meta> + [valueO (translate valueS) + $case (generated-name "case") + $value (generated-name "value") + #let [$dependencies+ (|> (path-variables pathP) + (get@ #dependencies) + set.to-list + (list/map referenceT.local)) + @dependencies+ (list/map @@ $dependencies+)] + pattern-matching! (translate-pattern-matching translate pathP) + _ (//.save (python.def! $case (list& $value $dependencies+) + ($_ python.then! + (initialize-pattern-matching! (@@ $value)) + pattern-matching!)))] + (wrap (python.apply (list& valueO @dependencies+) (@@ $case))))) diff --git a/new-luxc/source/luxc/lang/translation/python/eval.jvm.lux b/new-luxc/source/luxc/lang/translation/python/eval.jvm.lux new file mode 100644 index 000000000..bc6e1a342 --- /dev/null +++ b/new-luxc/source/luxc/lang/translation/python/eval.jvm.lux @@ -0,0 +1,146 @@ +(.module: + lux + (lux (control ["ex" exception #+ exception:]) + (data [bit] + [maybe] + ["e" error #+ Error] + text/format + (coll [array])) + [host]) + (luxc [lang] + (lang (host [python #+ Expression Statement]))) + [//]) + +(host.import java/lang/Object + (toString [] String) + (getClass [] (Class Object))) + +(host.import java/lang/Long + (intValue [] Integer)) + +(host.import org/python/core/PyType + (getName [] String)) + +(host.import org/python/core/PyString + (new [String])) + +(host.import org/python/core/PyObject + (asLong [] long) + (asDouble [] double) + (asString [] String) + (__nonzero__ [] boolean) + (__getitem__ [int] #try PyObject) + (__getitem__ #as __getitem__dict [PyObject] #try PyObject) + (__len__ [] int) + (getType [] PyType)) + +(def: (tuple lux-object host-object) + (-> (-> PyObject (Error Top)) PyObject (Error Top)) + (let [size (:! Nat (PyObject::__len__ [] host-object))] + (loop [idx +0 + output (:! (Array Top) (array.new size))] + (if (n/< size idx) + (case (PyObject::__getitem__ [(:! Int idx)] host-object) + (#e.Error error) + (#e.Error error) + + (#e.Success value) + (case (lux-object value) + (#e.Error error) + (#e.Error error) + + (#e.Success lux-value) + (recur (n/inc idx) (array.write idx lux-value output)))) + (#e.Success output))))) + +(def: python-type + (-> PyObject Text) + (|>> (PyObject::getType []) (PyType::getName []) (:! Text))) + +(exception: #export Not-A-Variant) + +(def: tag-field (PyString::new [//.variant-tag-field])) +(def: flag-field (PyString::new [//.variant-flag-field])) +(def: value-field (PyString::new [//.variant-value-field])) + +(def: (variant lux-object host-object) + (-> (-> PyObject (Error Top)) PyObject (Error Top)) + (case [(PyObject::__getitem__dict [tag-field] host-object) + (PyObject::__getitem__dict [flag-field] host-object) + (PyObject::__getitem__dict [value-field] host-object)] + (^or [(#e.Error error) _ _] [_ (#e.Error error) _] [_ _ (#e.Error error)]) + (#e.Error error) + + (^multi [(#e.Success tag) (#e.Success flag) (#e.Success value)] + [(lux-object tag) + (#e.Success tag)] + [(lux-object value) + (#e.Success value)]) + (#e.Success [(Long::intValue [] (:! Long tag)) + (: Top + (case (python-type (:! PyObject flag)) + "NoneType" + (host.null) + + _ + "")) + value]) + + _ + (ex.throw Not-A-Variant (Object::toString [] host-object)))) + +(exception: #export Unknown-Kind-Of-Host-Object) +(exception: #export Null-Has-No-Lux-Representation) + +(def: (lux-object host-object) + (-> PyObject (Error Top)) + (case (python-type host-object) + "str" + (#e.Success (PyObject::asString [] host-object)) + + "bool" + (#e.Success (PyObject::__nonzero__ [] host-object)) + + "float" + (#e.Success (PyObject::asDouble [] host-object)) + + (^or "int" "long") + (#e.Success (PyObject::asLong [] host-object)) + + "tuple" + (tuple lux-object host-object) + + "dict" + (variant lux-object host-object) + + "NoneType" + (#e.Success []) + + type + (ex.throw Unknown-Kind-Of-Host-Object (format type " " (Object::toString [] host-object))))) + +(exception: #export Cannot-Evaluate) + +(def: #export (eval code) + (-> Expression (Meta Top)) + (function [compiler] + (let [interpreter (|> compiler (get@ #.host) (:! //.Host) (get@ #//.interpreter))] + (case (interpreter code) + (#e.Error error) + (exec (log! (format "eval #e.Error\n" + "<< " (python.expression code) "\n" + error)) + ((lang.throw Cannot-Evaluate error) compiler)) + + (#e.Success output) + (case (lux-object output) + (#e.Success parsed-output) + (exec ## (log! (format "eval #e.Success\n" + ## "<< " (python.expression code))) + (#e.Success [compiler parsed-output])) + + (#e.Error error) + (exec (log! (format "eval #e.Error\n" + "<< " (python.expression code) "\n" + error)) + ((lang.throw Cannot-Evaluate error) compiler))))))) diff --git a/new-luxc/source/luxc/lang/translation/python/expression.jvm.lux b/new-luxc/source/luxc/lang/translation/python/expression.jvm.lux new file mode 100644 index 000000000..6a7497c22 --- /dev/null +++ b/new-luxc/source/luxc/lang/translation/python/expression.jvm.lux @@ -0,0 +1,82 @@ +(.module: + lux + (lux (control [monad #+ do] + ["ex" exception #+ exception:] + ["p" parser]) + (data ["e" error] + text/format) + [macro] + (macro ["s" syntax])) + (luxc ["&" lang] + (lang [".L" variable #+ Variable Register] + [".L" extension] + ["ls" synthesis] + (host [python #+ Expression Statement]))) + [//] + (// [".T" runtime] + [".T" primitive] + [".T" structure] + [".T" function] + [".T" reference] + [".T" case] + [".T" procedure])) + +(exception: #export Invalid-Function-Syntax) +(exception: #export Unrecognized-Synthesis) + +(def: #export (translate synthesis) + (-> ls.Synthesis (Meta Expression)) + (case synthesis + (^code []) + (:: macro.Monad<Meta> wrap runtimeT.unit) + + (^code [(~ singleton)]) + (translate singleton) + + (^template [<tag> <generator>] + [_ (<tag> value)] + (<generator> value)) + ([#.Bool primitiveT.translate-bool] + [#.Nat primitiveT.translate-nat] + [#.Int primitiveT.translate-int] + [#.Deg primitiveT.translate-deg] + [#.Frac primitiveT.translate-frac] + [#.Text primitiveT.translate-text]) + + (^code ((~ [_ (#.Nat tag)]) (~ [_ (#.Bool last?)]) (~ valueS))) + (structureT.translate-variant translate tag last? valueS) + + (^code [(~+ members)]) + (structureT.translate-tuple translate members) + + (^ [_ (#.Form (list [_ (#.Int var)]))]) + (referenceT.translate-variable var) + + [_ (#.Symbol definition)] + (referenceT.translate-definition definition) + + (^code ("lux let" (~ [_ (#.Nat register)]) (~ inputS) (~ exprS))) + (caseT.translate-let translate register inputS exprS) + + (^code ("lux case" (~ inputS) (~ pathPS))) + (caseT.translate-case translate inputS pathPS) + + (^code ("lux function" (~ [_ (#.Nat arity)]) [(~+ environment)] (~ bodyS))) + (case (s.run environment (p.some s.int)) + (#e.Success environment) + (functionT.translate-function translate environment arity bodyS) + + _ + (&.throw Invalid-Function-Syntax (%code synthesis))) + + (^code ("lux call" (~ functionS) (~+ argsS))) + (functionT.translate-apply translate functionS argsS) + + (^code ((~ [_ (#.Text procedure)]) (~+ argsS))) + (procedureT.translate-procedure translate procedure argsS) + ## (do macro.Monad<Meta> + ## [translation (extensionL.find-translation procedure)] + ## (translation argsS)) + + _ + (&.throw Unrecognized-Synthesis (%code synthesis)))) diff --git a/new-luxc/source/luxc/lang/translation/python/function.jvm.lux b/new-luxc/source/luxc/lang/translation/python/function.jvm.lux new file mode 100644 index 000000000..97b936fc4 --- /dev/null +++ b/new-luxc/source/luxc/lang/translation/python/function.jvm.lux @@ -0,0 +1,99 @@ +(.module: + lux + (lux (control [monad #+ do] + pipe) + (data [product] + [text] + text/format + (coll [list "list/" Functor<List> Fold<List>])) + [macro]) + (luxc ["&" lang] + (lang ["ls" synthesis] + [".L" variable #+ Variable] + (host [python #+ Expression Statement @@]))) + [//] + (// [".T" reference])) + +(def: #export (translate-apply translate functionS argsS+) + (-> (-> ls.Synthesis (Meta Expression)) ls.Synthesis (List ls.Synthesis) (Meta Expression)) + (do macro.Monad<Meta> + [functionO (translate functionS) + argsO+ (monad.map @ translate argsS+)] + (wrap (python.apply argsO+ functionO)))) + +(def: $curried (python.var "curried")) + +(def: (input-declaration register) + (python.set! (list (referenceT.variable (n/inc register))) + (python.nth (|> register nat-to-int python.int) + (@@ $curried)))) + +(def: (with-closure function-name inits function-definition) + (-> Text (List Expression) Statement (Meta Expression)) + (let [$closure (python.var (format function-name "___CLOSURE"))] + (case inits + #.Nil + (do macro.Monad<Meta> + [_ (//.save function-definition)] + (wrap (python.global function-name))) + + _ + (do macro.Monad<Meta> + [_ (//.save (python.def! $closure + (|> (list.enumerate inits) + (list/map (|>> product.left referenceT.closure))) + ($_ python.then! + function-definition + (python.return! (python.global function-name)))))] + (wrap (python.apply inits (@@ $closure))))))) + +(def: #export (translate-function translate env arity bodyS) + (-> (-> ls.Synthesis (Meta Expression)) + (List Variable) ls.Arity ls.Synthesis + (Meta Expression)) + (do macro.Monad<Meta> + [[function-name bodyO] (//.with-sub-context + (do @ + [function-name //.context] + (//.with-anchor [function-name +1] + (translate bodyS)))) + closureO+ (monad.map @ referenceT.translate-variable env) + #let [args-initsO+ (|> (list.n/range +0 (n/dec arity)) + (list/map input-declaration) + (case> #.Nil + python.no-op! + + (#.Cons head tail) + (list/fold python.then! head tail))) + arityO (|> arity nat-to-int python.int) + @curried (@@ $curried) + $num_args (python.var "num_args") + @num_args (@@ $num_args) + $function (python.var function-name) + @function (@@ $function)]] + (with-closure function-name closureO+ + (python.def! $function (list (python.poly $curried)) + ($_ python.then! + (let [@len (python.global "len")] + (python.set! (list $num_args) (python.apply (list @curried) @len))) + (python.if! (python.= arityO @num_args) + ($_ python.then! + (python.set! (list (referenceT.variable +0)) @function) + args-initsO+ + (python.while! (python.bool true) + (python.return! bodyO))) + (python.if! (python.> arityO @num_args) + (let [arity-args (python.slice (python.int 0) arityO @curried) + output-func-args (python.slice arityO @num_args @curried)] + (python.return! (|> @function + (python.apply-poly (list) arity-args) + (python.apply-poly (list) output-func-args)))) + (let [$next (python.var "next") + $missing (python.var "missing")] + ($_ python.then! + (python.def! $next (list (python.poly $missing)) + (python.return! (|> @function + (python.apply-poly (list) (|> @curried + (python.+ (@@ $missing))))))) + (python.return! (@@ $next))))))))) + )) diff --git a/new-luxc/source/luxc/lang/translation/python/loop.jvm.lux b/new-luxc/source/luxc/lang/translation/python/loop.jvm.lux new file mode 100644 index 000000000..e490033bf --- /dev/null +++ b/new-luxc/source/luxc/lang/translation/python/loop.jvm.lux @@ -0,0 +1,36 @@ +(.module: + lux + (lux (control [monad #+ do]) + (data [text] + text/format + (coll [list "list/" Functor<List>])) + [macro]) + (luxc [lang] + (lang ["ls" synthesis] + (host [python #+ Expression Statement @@]))) + [//] + (// [".T" reference])) + +(def: #export (translate-loop translate offset initsS+ bodyS) + (-> (-> ls.Synthesis (Meta Expression)) Nat (List ls.Synthesis) ls.Synthesis + (Meta Expression)) + (do macro.Monad<Meta> + [loop-name (|> (macro.gensym "loop") + (:: @ map (|>> %code lang.normalize-name))) + initsO+ (monad.map @ translate initsS+) + bodyO (//.with-anchor [loop-name offset] + (translate bodyS)) + #let [$loop-name (python.var loop-name) + @loop-name (@@ $loop-name)] + _ (//.save (python.def! $loop-name (|> (list.n/range +0 (n/dec (list.size initsS+))) + (list/map (|>> (n/+ offset) referenceT.variable))) + (python.return! bodyO)))] + (wrap (python.apply initsO+ @loop-name)))) + +(def: #export (translate-recur translate argsS+) + (-> (-> ls.Synthesis (Meta Expression)) (List ls.Synthesis) + (Meta Expression)) + (do macro.Monad<Meta> + [[loop-name offset] //.anchor + argsO+ (monad.map @ translate argsS+)] + (wrap (python.apply argsO+ (python.global loop-name))))) diff --git a/new-luxc/source/luxc/lang/translation/python/primitive.jvm.lux b/new-luxc/source/luxc/lang/translation/python/primitive.jvm.lux new file mode 100644 index 000000000..7b2ba1786 --- /dev/null +++ b/new-luxc/source/luxc/lang/translation/python/primitive.jvm.lux @@ -0,0 +1,28 @@ +(.module: + lux + (lux [macro "meta/" Monad<Meta>]) + (luxc (lang (host [python #+ Expression Statement])))) + +(def: #export translate-bool + (-> Bool (Meta Expression)) + (|>> python.bool meta/wrap)) + +(def: #export translate-int + (-> Int (Meta Expression)) + (|>> python.int meta/wrap)) + +(def: #export translate-nat + (-> Nat (Meta Expression)) + (|>> (:! Int) python.int meta/wrap)) + +(def: #export translate-deg + (-> Deg (Meta Expression)) + (|>> (:! Int) python.int meta/wrap)) + +(def: #export translate-frac + (-> Frac (Meta Expression)) + (|>> python.float meta/wrap)) + +(def: #export translate-text + (-> Text (Meta Expression)) + (|>> python.string meta/wrap)) diff --git a/new-luxc/source/luxc/lang/translation/python/procedure.jvm.lux b/new-luxc/source/luxc/lang/translation/python/procedure.jvm.lux new file mode 100644 index 000000000..a46778503 --- /dev/null +++ b/new-luxc/source/luxc/lang/translation/python/procedure.jvm.lux @@ -0,0 +1,28 @@ +(.module: + lux + (lux (control [monad #+ do] + ["ex" exception #+ exception:]) + (data [maybe] + text/format + (coll [dict]))) + (luxc ["&" lang] + (lang ["ls" synthesis] + (host [python #+ Expression Statement]))) + [//] + (/ ["/." common] + ["/." host])) + +(exception: #export Unknown-Procedure) + +(def: procedures + /common.Bundle + (|> /common.procedures + (dict.merge /host.procedures))) + +(def: #export (translate-procedure translate name args) + (-> (-> ls.Synthesis (Meta Expression)) Text (List ls.Synthesis) + (Meta Expression)) + (<| (maybe.default (&.throw Unknown-Procedure (%t name))) + (do maybe.Monad<Maybe> + [proc (dict.get name procedures)] + (wrap (proc translate args))))) diff --git a/new-luxc/source/luxc/lang/translation/python/procedure/common.jvm.lux b/new-luxc/source/luxc/lang/translation/python/procedure/common.jvm.lux new file mode 100644 index 000000000..6205d22a7 --- /dev/null +++ b/new-luxc/source/luxc/lang/translation/python/procedure/common.jvm.lux @@ -0,0 +1,572 @@ +(.module: + lux + (lux (control [monad #+ do] + ["ex" exception #+ exception:] + ["p" parser]) + (data ["e" error] + [text] + text/format + [number] + (coll [list "list/" Functor<List>] + [dict #+ Dict])) + [macro #+ with-gensyms] + (macro [code] + ["s" syntax #+ syntax:]) + [host]) + (luxc ["&" lang] + (lang ["la" analysis] + ["ls" synthesis] + (host [python #+ Expression Statement]))) + [///] + (/// [".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<Text>))) + +(def: (wrong-arity proc expected actual) + (-> Text Nat Nat Text) + (format "Wrong number of arguments for " (%t proc) "\n" + "Expected: " (|> expected nat-to-int %i) "\n" + " Actual: " (|> actual nat-to-int %i))) + +(syntax: (arity: [name s.local-symbol] [arity s.nat]) + (with-gensyms [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-symbol name)) (~ g!proc)) + (-> (-> (..Vector (~ (code.nat arity)) Expression) Expression) + (-> Text ..Proc)) + (function [(~ g!name)] + (function [(~ g!translate) (~ g!inputs)] + (case (~ g!inputs) + (^ (list (~+ g!input+))) + (do macro.Monad<Meta> + [(~+ (|> 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<Meta> + [inputsI (monad.map @ translate inputsS)] + (wrap (proc inputsI)))))) + +## [Procedures] +## [[Lux]] +(def: (lux//is [leftO rightO]) + Binary + (python.is leftO rightO)) + +(def: (lux//if [testO thenO elseO]) + Trinary + (caseT.translate-if testO thenO elseO)) + +(def: (lux//try riskyO) + Unary + (runtimeT.lux//try riskyO)) + +(def: (lux//noop valueO) + Unary + valueO) + +(exception: #export Wrong-Syntax) +(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<Text>) + (install "noop" (unary lux//noop)) + (install "is" (binary lux//is)) + (install "try" (unary lux//try)) + (install "if" (trinary lux//if)) + (install "loop" lux//loop) + (install "recur" lux//recur) + )) + +## [[Bits]] +(do-template [<name> <op>] + [(def: (<name> [subjectO paramO]) + Binary + (<op> paramO subjectO))] + + [bit//and python.bit-and] + [bit//or python.bit-or] + [bit//xor python.bit-xor] + ) + +(def: (bit//shift-left [subjectO paramO]) + Binary + (|> (python.bit-shl paramO subjectO) + runtimeT.bit//64)) + +(do-template [<name> <op>] + [(def: (<name> [subjectO paramO]) + Binary + (<op> paramO subjectO))] + + [bit//shift-right python.bit-shr] + [bit//unsigned-shift-right runtimeT.bit//shift-right] + ) + +(def: bit-procs + Bundle + (<| (prefix "bit") + (|> (dict.new text.Hash<Text>) + (install "count" (unary runtimeT.bit//count)) + (install "and" (binary bit//and)) + (install "or" (binary bit//or)) + (install "xor" (binary bit//xor)) + (install "shift-left" (binary bit//shift-left)) + (install "unsigned-shift-right" (binary bit//unsigned-shift-right)) + (install "shift-right" (binary bit//shift-right)) + ))) + +## [[Arrays]] +(def: (array//new sizeO) + Unary + (|> python.none + list python.list + (python.* sizeO))) + +(def: (array//get [arrayO idxO]) + Binary + (runtimeT.array//get arrayO idxO)) + +(def: (array//put [arrayO idxO elemO]) + Trinary + (runtimeT.array//put arrayO idxO elemO)) + +(def: (array//remove [arrayO idxO]) + Binary + (runtimeT.array//put arrayO idxO python.none)) + +(def: array-procs + Bundle + (<| (prefix "array") + (|> (dict.new text.Hash<Text>) + (install "new" (unary array//new)) + (install "get" (binary array//get)) + (install "put" (trinary array//put)) + (install "remove" (binary array//remove)) + (install "size" (unary python.length)) + ))) + +## [[Numbers]] +(host.import java/lang/Double + (#static MIN_VALUE Double) + (#static MAX_VALUE Double)) + +(do-template [<name> <const> <encode>] + [(def: (<name> _) + Nullary + (<encode> <const>))] + + [nat//min 0 python.int] + [nat//max -1 python.int] + + [frac//smallest Double::MIN_VALUE python.float] + [frac//min (f/* -1.0 Double::MAX_VALUE) python.float] + [frac//max Double::MAX_VALUE python.float] + + [deg//min 0 python.int] + [deg//max -1 python.int] + ) + +(do-template [<name> <expression>] + [(def: (<name> _) + Nullary + <expression>)] + + [int//min (|> (python.int -2) (python.** (python.int 63)))] + [int//max (|> (python.int 2) (python.** (python.int 63)) (python.- (python.int 1)))] + ) + +(do-template [<name> <label>] + [(def: (<name> _) + Nullary + (python.apply (list (python.string <label>)) (python.global "float")))] + + [frac//not-a-number "nan"] + [frac//positive-infinity "inf"] + [frac//negative-infinity "-inf"] + ) + +(do-template [<name> <op>] + [(def: (<name> [subjectO paramO]) + Binary + (|> subjectO + (<op> paramO) + runtimeT.bit//64))] + + [int//add python.+] + [int//sub python.-] + [int//mul python.*] + + [nat//add python.+] + [nat//sub python.-] + [nat//mul python.*] + + [deg//add python.+] + [deg//sub python.-] + [deg//rem python.-] + [deg//scale python.*] + ) + +(do-template [<name> <op>] + [(def: (<name> [subjectO paramO]) + Binary + (|> subjectO + (<op> paramO)))] + + [int//div python./] + [int//rem python.%] + + [nat//div runtimeT.nat///] + [nat//rem runtimeT.nat//%] + + [deg//mul runtimeT.deg//*] + [deg//div runtimeT.deg///] + [deg//reciprocal python./] + ) + +(do-template [<name> <op>] + [(def: (<name> [subjectO paramO]) + Binary + (<op> paramO subjectO))] + + [frac//add python.+] + [frac//sub python.-] + [frac//mul python.*] + [frac//div python./] + [frac//rem python.%] + [frac//= python.=] + [frac//< python.<] + + [text//= python.=] + [text//< python.<] + ) + +(do-template [<name> <cmp>] + [(def: (<name> [subjectO paramO]) + Binary + (<cmp> paramO subjectO))] + + [nat//= python.=] + [nat//< runtimeT.nat//<] + + [int//= python.=] + [int//< python.<] + + [deg//= python.=] + [deg//< runtimeT.nat//<] + ) + +(def: (apply1 func) + (-> Expression (-> Expression Expression)) + (function [value] + (python.apply (list value) func))) + +(def: (send0 method) + (-> Text (-> Expression Expression)) + (function [object] + (python.send (list) method object))) + +(do-template [<name> <divisor>] + [(def: (<name> inputO) + Unary + (|> inputO (python./ <divisor>)))] + + [deg//to-frac (python.apply (list (|> (python.int 1) (python.bit-shl (python.int 32)))) + (python.global "float"))] + ) + +(def: nat-procs + Bundle + (<| (prefix "nat") + (|> (dict.new text.Hash<Text>) + (install "+" (binary nat//add)) + (install "-" (binary nat//sub)) + (install "*" (binary nat//mul)) + (install "/" (binary nat//div)) + (install "%" (binary nat//rem)) + (install "=" (binary nat//=)) + (install "<" (binary nat//<)) + (install "min" (nullary nat//min)) + (install "max" (nullary nat//max)) + (install "to-int" (unary id)) + (install "char" (unary (apply1 (python.global "chr"))))))) + +(def: int-procs + Bundle + (<| (prefix "int") + (|> (dict.new text.Hash<Text>) + (install "+" (binary int//add)) + (install "-" (binary int//sub)) + (install "*" (binary int//mul)) + (install "/" (binary int//div)) + (install "%" (binary int//rem)) + (install "=" (binary int//=)) + (install "<" (binary int//<)) + (install "min" (nullary int//min)) + (install "max" (nullary int//max)) + (install "to-nat" (unary id)) + (install "to-frac" (unary (apply1 (python.global "float"))))))) + +(def: deg-procs + Bundle + (<| (prefix "deg") + (|> (dict.new text.Hash<Text>) + (install "+" (binary deg//add)) + (install "-" (binary deg//sub)) + (install "*" (binary deg//mul)) + (install "/" (binary deg//div)) + (install "%" (binary deg//rem)) + (install "=" (binary deg//=)) + (install "<" (binary deg//<)) + (install "scale" (binary deg//scale)) + (install "reciprocal" (binary deg//reciprocal)) + (install "min" (nullary deg//min)) + (install "max" (nullary deg//max)) + (install "to-frac" (unary deg//to-frac))))) + +(def: frac-procs + Bundle + (<| (prefix "frac") + (|> (dict.new text.Hash<Text>) + (install "+" (binary frac//add)) + (install "-" (binary frac//sub)) + (install "*" (binary frac//mul)) + (install "/" (binary frac//div)) + (install "%" (binary frac//rem)) + (install "=" (binary frac//=)) + (install "<" (binary frac//<)) + (install "smallest" (nullary frac//smallest)) + (install "min" (nullary frac//min)) + (install "max" (nullary frac//max)) + (install "not-a-number" (nullary frac//not-a-number)) + (install "positive-infinity" (nullary frac//positive-infinity)) + (install "negative-infinity" (nullary frac//negative-infinity)) + (install "to-deg" (unary runtimeT.deg//from-frac)) + (install "to-int" (unary (apply1 (python.global "int")))) + (install "encode" (unary (apply1 (python.global "repr")))) + (install "decode" (unary runtimeT.frac//decode))))) + +## [[Text]] +(def: (text//concat [subjectO paramO]) + Binary + (|> subjectO (python.+ paramO))) + +(def: (text//char [subjectO paramO]) + Binary + (runtimeT.text//char subjectO paramO)) + +(def: (text//replace-all [subjectO paramO extraO]) + Trinary + (python.send (list paramO extraO) "replace" subjectO)) + +(def: (text//replace-once [subjectO paramO extraO]) + Trinary + (python.send (list paramO extraO (python.int 1)) "replace" subjectO)) + +(def: (text//clip [subjectO paramO extraO]) + Trinary + (runtimeT.text//clip subjectO paramO extraO)) + +(def: (text//index [textO partO startO]) + Trinary + (runtimeT.text//index textO partO startO)) + +(def: text-procs + Bundle + (<| (prefix "text") + (|> (dict.new text.Hash<Text>) + (install "=" (binary text//=)) + (install "<" (binary text//<)) + (install "concat" (binary text//concat)) + (install "index" (trinary text//index)) + (install "size" (unary (apply1 (python.global "len")))) + (install "hash" (unary (apply1 (python.global "hash")))) + (install "replace-once" (trinary text//replace-once)) + (install "replace-all" (trinary text//replace-all)) + (install "char" (binary text//char)) + (install "clip" (trinary text//clip)) + (install "upper" (unary (send0 "upper"))) + (install "lower" (unary (send0 "lower"))) + ))) + +## [[Math]] +(def: (math//pow [subject param]) + Binary + (|> subject (python.** param))) + +(def: math-procs + Bundle + (<| (prefix "math") + (|> (dict.new text.Hash<Text>) + (install "cos" (unary runtimeT.math//cos)) + (install "sin" (unary runtimeT.math//sin)) + (install "tan" (unary runtimeT.math//tan)) + (install "acos" (unary runtimeT.math//acos)) + (install "asin" (unary runtimeT.math//asin)) + (install "atan" (unary runtimeT.math//atan)) + (install "exp" (unary runtimeT.math//exp)) + (install "log" (unary runtimeT.math//log)) + (install "ceil" (unary runtimeT.math//ceil)) + (install "floor" (unary runtimeT.math//floor)) + (install "pow" (binary math//pow)) + ))) + +## [[IO]] +(def: io-procs + Bundle + (<| (prefix "io") + (|> (dict.new text.Hash<Text>) + (install "log" (unary runtimeT.io//log!)) + (install "error" (unary runtimeT.io//throw!)) + (install "exit" (unary runtimeT.io//exit!)) + (install "current-time" (nullary (function [_] + (runtimeT.io//current-time! runtimeT.unit))))))) + +## [[Atoms]] +(def: atom//new + Unary + (|>> [(python.string runtimeT.atom//field)] (list) python.dict)) + +(def: atom//read + Unary + (python.nth (python.string runtimeT.atom//field))) + +(def: (atom//compare-and-swap [atomO oldO newO]) + Trinary + (runtimeT.atom//compare-and-swap atomO oldO newO)) + +(def: atom-procs + Bundle + (<| (prefix "atom") + (|> (dict.new text.Hash<Text>) + (install "new" (unary atom//new)) + (install "read" (unary atom//read)) + (install "compare-and-swap" (trinary atom//compare-and-swap))))) + +## [[Box]] +(def: box//new + Unary + (|>> (list) python.list)) + +(def: box//read + Unary + (python.nth (python.int 0))) + +(def: (box//write [valueO boxO]) + Binary + (runtimeT.box//write valueO boxO)) + +(def: box-procs + Bundle + (<| (prefix "box") + (|> (dict.new text.Hash<Text>) + (install "new" (unary box//new)) + (install "read" (unary box//read)) + (install "write" (binary box//write))))) + +## [[Processes]] +(def: (process//concurrency-level []) + Nullary + (python.int 1)) + +(def: (process//schedule [milli-secondsO procedureO]) + Binary + (runtimeT.process//schedule milli-secondsO procedureO)) + +(def: process-procs + Bundle + (<| (prefix "process") + (|> (dict.new text.Hash<Text>) + (install "concurrency-level" (nullary process//concurrency-level)) + (install "future" (unary runtimeT.process//future)) + (install "schedule" (binary process//schedule)) + ))) + +## [Bundles] +(def: #export procedures + Bundle + (<| (prefix "lux") + (|> lux-procs + (dict.merge bit-procs) + (dict.merge nat-procs) + (dict.merge int-procs) + (dict.merge deg-procs) + (dict.merge frac-procs) + (dict.merge text-procs) + (dict.merge array-procs) + (dict.merge math-procs) + (dict.merge io-procs) + (dict.merge atom-procs) + (dict.merge box-procs) + (dict.merge process-procs) + ))) diff --git a/new-luxc/source/luxc/lang/translation/python/procedure/host.jvm.lux b/new-luxc/source/luxc/lang/translation/python/procedure/host.jvm.lux new file mode 100644 index 000000000..c1b43da2f --- /dev/null +++ b/new-luxc/source/luxc/lang/translation/python/procedure/host.jvm.lux @@ -0,0 +1,89 @@ +(.module: + lux + (lux (control [monad #+ do]) + (data [text] + text/format + (coll [list "list/" Functor<List>] + [dict #+ Dict])) + [macro "macro/" Monad<Meta>]) + (luxc ["&" lang] + (lang ["la" analysis] + ["ls" synthesis] + (host [ruby #+ Ruby Expression Statement]))) + [///] + (/// [".T" runtime]) + (// ["@" common])) + +## (do-template [<name> <lua>] +## [(def: (<name> _) @.Nullary <lua>)] + +## [lua//nil "nil"] +## [lua//table "{}"] +## ) + +## (def: (lua//global proc translate inputs) +## (-> Text @.Proc) +## (case inputs +## (^ (list [_ (#.Text name)])) +## (do macro.Monad<Meta> +## [] +## (wrap name)) + +## _ +## (&.throw @.Wrong-Syntax (@.wrong-syntax proc inputs)))) + +## (def: (lua//call proc translate inputs) +## (-> Text @.Proc) +## (case inputs +## (^ (list& functionS argsS+)) +## (do macro.Monad<Meta> +## [functionO (translate functionS) +## argsO+ (monad.map @ translate argsS+)] +## (wrap (lua.apply functionO argsO+))) + +## _ +## (&.throw @.Wrong-Syntax (@.wrong-syntax proc inputs)))) + +## (def: lua-procs +## @.Bundle +## (|> (dict.new text.Hash<Text>) +## (@.install "nil" (@.nullary lua//nil)) +## (@.install "table" (@.nullary lua//table)) +## (@.install "global" lua//global) +## (@.install "call" lua//call))) + +## (def: (table//call proc translate inputs) +## (-> Text @.Proc) +## (case inputs +## (^ (list& tableS [_ (#.Text field)] argsS+)) +## (do macro.Monad<Meta> +## [tableO (translate tableS) +## argsO+ (monad.map @ translate argsS+)] +## (wrap (lua.method field tableO argsO+))) + +## _ +## (&.throw @.Wrong-Syntax (@.wrong-syntax proc inputs)))) + +## (def: (table//get [fieldO tableO]) +## @.Binary +## (runtimeT.lua//get tableO fieldO)) + +## (def: (table//set [fieldO valueO tableO]) +## @.Trinary +## (runtimeT.lua//set tableO fieldO valueO)) + +## (def: table-procs +## @.Bundle +## (<| (@.prefix "table") +## (|> (dict.new text.Hash<Text>) +## (@.install "call" table//call) +## (@.install "get" (@.binary table//get)) +## (@.install "set" (@.trinary table//set))))) + +(def: #export procedures + @.Bundle + (<| (@.prefix "lua") + (dict.new text.Hash<Text>) + ## (|> lua-procs + ## (dict.merge table-procs)) + )) diff --git a/new-luxc/source/luxc/lang/translation/python/reference.jvm.lux b/new-luxc/source/luxc/lang/translation/python/reference.jvm.lux new file mode 100644 index 000000000..1f29da34a --- /dev/null +++ b/new-luxc/source/luxc/lang/translation/python/reference.jvm.lux @@ -0,0 +1,42 @@ +(.module: + lux + (lux [macro] + (data [text] + text/format)) + (luxc ["&" lang] + (lang [".L" variable #+ Variable Register] + (host [python #+ Expression Statement SVar @@]))) + [//] + (// [".T" runtime])) + +(do-template [<register> <translation> <prefix>] + [(def: #export (<register> register) + (-> Register SVar) + (python.var (format <prefix> (%i (nat-to-int register))))) + + (def: #export (<translation> register) + (-> Register (Meta Expression)) + (:: macro.Monad<Meta> wrap (@@ (<register> register))))] + + [closure translate-captured "c"] + [variable translate-local "v"]) + +(def: #export (local var) + (-> Variable SVar) + (if (variableL.captured? var) + (closure (variableL.captured-register var)) + (variable (int-to-nat var)))) + +(def: #export (translate-variable var) + (-> Variable (Meta Expression)) + (if (variableL.captured? var) + (translate-captured (variableL.captured-register var)) + (translate-local (int-to-nat var)))) + +(def: #export global + (-> Ident SVar) + (|>> //.definition-name python.var)) + +(def: #export (translate-definition name) + (-> Ident (Meta Expression)) + (:: macro.Monad<Meta> wrap (@@ (global name)))) diff --git a/new-luxc/source/luxc/lang/translation/python/runtime.jvm.lux b/new-luxc/source/luxc/lang/translation/python/runtime.jvm.lux new file mode 100644 index 000000000..e8f564745 --- /dev/null +++ b/new-luxc/source/luxc/lang/translation/python/runtime.jvm.lux @@ -0,0 +1,583 @@ +(.module: + lux + (lux (control ["p" parser "p/" Monad<Parser>] + [monad #+ do]) + (data text/format + (coll [list "list/" Monad<List>])) + [macro] + (macro [code] + ["s" syntax #+ syntax:]) + [io #+ Process]) + [//] + (luxc [lang] + (lang (host [python #+ Expression Statement @@])))) + +(def: prefix Text "LuxRuntime") + +(def: #export unit Expression (python.string //.unit)) + +(def: (flag value) + (-> Bool Expression) + (if value + (python.string "") + python.none)) + +(def: (variant' tag last? value) + (-> Expression Expression Expression Expression) + (python.dict (list [(python.string //.variant-tag-field) tag] + [(python.string //.variant-flag-field) last?] + [(python.string //.variant-value-field) value]))) + +(def: #export (variant tag last? value) + (-> Nat Bool Expression Expression) + (variant' (python.int (nat-to-int tag)) + (flag last?) + value)) + +(def: #export none + Expression + (variant +0 false unit)) + +(def: #export some + (-> Expression Expression) + (variant +1 true)) + +(def: #export left + (-> Expression Expression) + (variant +0 false)) + +(def: #export right + (-> Expression Expression) + (variant +1 true)) + +(type: Runtime Statement) + +(def: declaration + (s.Syntax [Text (List Text)]) + (p.either (p.seq s.local-symbol (p/wrap (list))) + (s.form (p.seq s.local-symbol (p.some s.local-symbol))))) + +(syntax: (runtime: [[name args] declaration] + definition) + (let [implementation (code.local-symbol (format "@@" name)) + runtime (format "__" prefix "__" (lang.normalize-name name)) + $runtime (` (python.var (~ (code.text runtime)))) + @runtime (` (@@ (~ $runtime))) + argsC+ (list/map code.local-symbol args) + argsLC+ (list/map (|>> lang.normalize-name code.text (~) (python.var) (`)) + args) + declaration (` ((~ (code.local-symbol name)) + (~+ argsC+))) + type (` (-> (~+ (list.repeat (list.size argsC+) (` python.Expression))) + python.Expression))] + (wrap (list (` (def: (~' #export) (~ declaration) + (~ type) + (python.apply (list (~+ argsC+)) (~ @runtime)))) + (` (def: (~ implementation) + python.Statement + (~ (case argsC+ + #.Nil + (` (python.set! (list (~ $runtime)) (~ definition))) + + _ + (` (let [(~+ (|> (list.zip2 argsC+ argsLC+) + (list/map (function [[left right]] + (list left (` (@@ (~ right)))))) + list/join))] + (python.def! (~ $runtime) + (list (~+ argsLC+)) + (~ definition)))))))))))) + +(syntax: (with-vars [vars (s.tuple (p.many s.local-symbol))] + body) + (wrap (list (` (let [(~+ (|> vars + (list/map (function [var] + (list (code.local-symbol var) + (` (python.var (~ (code.text (lang.normalize-name var)))))))) + list/join))] + (~ body)))))) + +(runtime: (lux//try op) + (let [$error (python.var "error") + $value (python.var "value")] + (python.try! ($_ python.then! + (python.set! (list $value) (python.apply (list unit) op)) + (python.return! (right (@@ $value)))) + (list [(list "Exception") $error + (python.return! (left (python.apply (list (@@ $error)) (python.global "str"))))])))) + +(runtime: (lux//program-args program-args) + (let [$inputs (python.var "inputs") + $value (python.var "value")] + ($_ python.then! + (python.set! (list $inputs) none) + (<| (python.for-in! $value program-args) + (python.set! (list $inputs) + (some (python.tuple (list (@@ $value) (@@ $inputs)))))) + (python.return! (@@ $inputs))))) + +(def: runtime//lux + Runtime + ($_ python.then! + @@lux//try + @@lux//program-args)) + +(runtime: (io//log! message) + ($_ python.then! + (python.print! message) + (python.return! ..unit))) + +(def: (exception message) + (-> Expression Expression) + (python.apply (list message) (python.global "Exception"))) + +(runtime: (io//throw! message) + ($_ python.then! + (python.raise! (exception message)) + (python.return! ..unit))) + +(runtime: (io//exit! code) + ($_ python.then! + (python.import! "sys") + (python.do! (|> (python.global "sys") (python.send (list code) "exit"))) + (python.return! ..unit))) + +(runtime: (io//current-time! _) + ($_ python.then! + (python.import! "time") + (python.return! (let [time (|> (python.global "time") + (python.send (list) "time") + (python.* (python.int 1_000)))] + (python.apply (list time) (python.global "int")))))) + +(def: runtime//io + Runtime + ($_ python.then! + @@io//log! + @@io//throw! + @@io//exit! + @@io//current-time!)) + +(runtime: (product//left product index) + (let [$index_min_length (python.var "index_min_length")] + ($_ python.then! + (python.set! (list $index_min_length) (python.+ (python.int 1) index)) + (python.if! (python.> (@@ $index_min_length) (python.length product)) + ## No need for recursion + (python.return! (python.nth index product)) + ## Needs recursion + (python.return! (product//left (python.nth (python.- (python.int 1) + (python.length product)) + product) + (python.- (python.length product) + (@@ $index_min_length)))))))) + +(runtime: (product//right product index) + (let [$index_min_length (python.var "index_min_length")] + ($_ python.then! + (python.set! (list $index_min_length) (python.+ (python.int 1) index)) + (python.cond! (list [(python.= (@@ $index_min_length) (python.length product)) + ## Last element. + (python.return! (python.nth index product))] + [(python.< (@@ $index_min_length) (python.length product)) + ## Needs recursion + (python.return! (product//right (python.nth (python.- (python.int 1) + (python.length product)) + product) + (python.- (python.length product) + (@@ $index_min_length))))]) + ## Must slice + (python.return! (python.slice-from index product)))))) + +(runtime: (sum//get sum wantedTag wantsLast) + (let [no-match! (python.return! python.none) + sum-tag (python.nth (python.string //.variant-tag-field) sum) + sum-flag (python.nth (python.string //.variant-flag-field) sum) + sum-value (python.nth (python.string //.variant-value-field) sum) + is-last? (python.= (python.string "") sum-flag) + test-recursion! (python.if! is-last? + ## Must recurse. + (python.return! (sum//get sum-value (python.- sum-tag wantedTag) wantsLast)) + no-match!)] + (python.cond! (list [(python.= sum-tag wantedTag) + (python.if! (python.= wantsLast sum-flag) + (python.return! sum-value) + test-recursion!)] + + [(python.> sum-tag wantedTag) + test-recursion!] + + [(python.and (python.< sum-tag wantedTag) + (python.= (python.string "") wantsLast)) + (python.return! (variant' (python.- wantedTag sum-tag) sum-flag sum-value))]) + + no-match!))) + +(def: runtime//adt + Runtime + ($_ python.then! + @@product//left + @@product//right + @@sum//get)) + +(def: full-32-bits (python.code "0xFFFFFFFF")) + +(runtime: (bit//32 input) + (with-vars [capped] + (python.cond! (list [(|> input (python.> full-32-bits)) + (python.return! (|> input (python.bit-and full-32-bits) bit//32))] + [(|> input (python.> (python.code "0x7FFFFFFF"))) + ($_ python.then! + (python.set! (list capped) + (python.apply (list (|> (python.code "0x100000000") + (python.- input))) + (python.global "int"))) + (python.if! (|> (@@ capped) (python.<= (python.int 2147483647))) + (python.return! (|> (@@ capped) (python.* (python.int -1)))) + (python.return! (python.int -2147483648))))]) + (python.return! input)))) + +(def: full-64-bits (python.code "0xFFFFFFFFFFFFFFFF")) + +(runtime: (bit//64 input) + (with-vars [capped] + (python.cond! (list [(|> input (python.> full-64-bits)) + (python.return! (|> input (python.bit-and full-64-bits) bit//64))] + [(|> input (python.> (python.code "0x7FFFFFFFFFFFFFFF"))) + ($_ python.then! + (python.set! (list capped) + (python.apply (list (|> (python.code "0x10000000000000000") + (python.- input))) + (python.global "int"))) + (python.if! (|> (@@ capped) (python.<= (python.code "9223372036854775807L"))) + (python.return! (|> (@@ capped) (python.* (python.int -1)))) + (python.return! (python.code "-9223372036854775808L"))))]) + (python.return! input)))) + +(runtime: (bit//count subject) + (with-vars [count remaining] + ($_ python.then! + (python.set! (list count) (python.int 0)) + (python.set! (list remaining) subject) + (python.while! (|> (@@ remaining) (python.> (python.int 0))) + ($_ python.then! + (let [last-bit (|> (@@ remaining) (python.% (python.int 2)))] + (python.set! (list count) (|> (@@ count) (python.+ last-bit)))) + (python.set! (list remaining) (|> (@@ remaining) (python./ (python.int 2)))))) + (python.return! (@@ count))))) + +(runtime: (bit//shift-right param subject) + (let [mask (|> (python.int 1) + (python.bit-shl (python.- param (python.int 64))) + (python.- (python.int 1)))] + (python.return! (|> subject + (python.bit-shr param) + (python.bit-and mask))))) + +(def: runtime//bit + Runtime + ($_ python.then! + @@bit//32 + @@bit//64 + @@bit//count + @@bit//shift-right)) + +(def: high (-> Expression Expression) (bit//shift-right (python.int 32))) +(def: low (-> Expression Expression) (python.bit-and full-32-bits)) + +(runtime: (nat//< param subject) + (with-vars [ph sh] + ($_ python.then! + (python.set! (list ph) (..high param)) + (python.set! (list sh) (..high subject)) + (python.return! (python.or (python.< (@@ ph) (@@ sh)) + (python.and (python.= (@@ ph) (@@ sh)) + (python.< (low param) (low subject)))))))) + +(runtime: (nat/// param subject) + (with-vars [quotient remainder] + (python.if! (python.< (python.int 0) param) + (python.if! (nat//< param subject) + (python.return! (python.int 0)) + (python.return! (python.int 1))) + ($_ python.then! + (python.set! (list quotient) (|> subject + (python.bit-shr (python.int 1)) + (python./ param) + (python.bit-shl (python.int 1)))) + (let [remainder (python.- (python.* param (@@ quotient)) + subject)] + (python.if! (python.not (nat//< param remainder)) + (python.return! (python.+ (python.int 1) (@@ quotient))) + (python.return! (@@ quotient)))))))) + +(runtime: (nat//% param subject) + (let [flat (|> subject + (nat/// param) + (python.* param))] + (python.return! (|> subject (python.- flat))))) + +(def: runtime//nat + Runtime + ($_ python.then! + @@nat//< + @@nat/// + @@nat//%)) + +(runtime: (deg//* param subject) + (with-vars [$sL $sH $pL $pH $bottom $middle $top] + ($_ python.then! + (python.set! (list $sL) (..low subject)) + (python.set! (list $sH) (high subject)) + (python.set! (list $pL) (..low param)) + (python.set! (list $pH) (high param)) + (python.set! (list $bottom) (bit//shift-right (python.int 32) + (python.* (@@ $pL) (@@ $sL)))) + (python.set! (list $middle) (python.+ (python.* (@@ $pL) (@@ $sH)) + (python.* (@@ $pH) (@@ $sL)))) + (python.set! (list $top) (python.* (@@ $pH) (@@ $sH))) + (python.return! (|> (@@ $bottom) + (python.+ (@@ $middle)) + high + (python.+ (@@ $top))))))) + +(runtime: (deg//leading-zeroes input) + (with-vars [zeroes remaining] + ($_ python.then! + (python.set! (list zeroes) (python.int 64)) + (python.set! (list remaining) input) + (python.while! (python.not (python.= (python.int 0) (@@ remaining))) + ($_ python.then! + (python.set! (list zeroes) (python.- (python.int 1) (@@ zeroes))) + (python.set! (list remaining) (bit//shift-right (python.int 1) (@@ remaining))))) + (python.return! (@@ zeroes))))) + +(runtime: (deg/// param subject) + (with-vars [min-shift] + (python.if! (python.= param subject) + (python.return! (python.int -1)) + ($_ python.then! + (python.set! (list min-shift) + (python.apply (list (deg//leading-zeroes param) + (deg//leading-zeroes subject)) + (python.global "min"))) + (python.return! (|> (python.bit-shl (@@ min-shift) subject) + (python./ (|> param (python.bit-shl (@@ min-shift)) ..low)) + (python.bit-shl (python.int 32)))))))) + +(def: (float-to-int float) + (-> Expression Expression) + (python.apply (list float) (python.global "int"))) + +(runtime: (deg//from-frac input) + (with-vars [two32 shifted] + ($_ python.then! + (python.set! (list two32) (|> (python.float 2.0) + (python.** (python.float 32.0)))) + (python.set! (list shifted) (|> input + (python.% (python.float 1.0)) + (python.* (@@ two32)))) + (let [low (|> (@@ shifted) + (python.% (python.float 1.0)) + (python.* (@@ two32)) + float-to-int) + high (|> (@@ shifted) float-to-int (python.bit-shl (python.int 32)))] + (python.return! (|> low (python.+ high))))))) + +(def: runtime//deg + Runtime + ($_ python.then! + @@deg//* + @@deg//leading-zeroes + @@deg/// + @@deg//from-frac)) + +(runtime: (frac//decode input) + (let [$ex (python.var "ex")] + (python.try! + (python.return! (..some (python.apply (list input) (python.global "float")))) + (list [(list "Exception") $ex + (python.return! ..none)])))) + +(def: runtime//frac + Runtime + ($_ python.then! + @@frac//decode)) + +(runtime: (text//index subject param start) + (with-vars [idx] + ($_ python.then! + (python.set! (list idx) (python.send (list param start) "find" subject)) + (python.if! (python.= (python.int -1) (@@ idx)) + (python.return! ..none) + (python.return! (..some (@@ idx))))))) + +(def: inc (|>> (python.+ (python.int 1)))) + +(do-template [<name> <top-cmp>] + [(def: (<name> top value) + (-> Expression Expression Expression) + (python.and (|> value (python.>= (python.int 0))) + (|> value (<top-cmp> top))))] + + [within? python.<] + [up-to? python.<=] + ) + +(runtime: (text//clip @text @from @to) + (with-vars [length] + ($_ python.then! + (python.set! (list length) (python.length @text)) + (python.if! ($_ python.and + (|> @to (within? (@@ length))) + (|> @from (up-to? @to))) + (python.return! (..some (|> @text (python.slice @from (inc @to))))) + (python.return! ..none))))) + +(runtime: (text//char text idx) + (python.if! (|> idx (within? (python.length text))) + (python.return! (..some (python.apply (list (|> text (python.slice idx (inc idx)))) + (python.global "ord")))) + (python.return! ..none))) + +(def: runtime//text + Runtime + ($_ python.then! + @@text//index + @@text//clip + @@text//char)) + +(def: (check-index-out-of-bounds array idx body!) + (-> Expression Expression Statement Statement) + (python.if! (|> idx (python.<= (python.length array))) + body! + (python.raise! (exception (python.string "Array index out of bounds!"))))) + +(runtime: (array//get array idx) + (with-vars [temp] + (<| (check-index-out-of-bounds array idx) + ($_ python.then! + (python.set! (list temp) (python.nth idx array)) + (python.if! (python.= python.none (@@ temp)) + (python.return! ..none) + (python.return! (..some (@@ temp)))))))) + +(runtime: (array//put array idx value) + (<| (check-index-out-of-bounds array idx) + ($_ python.then! + (python.set-nth! idx value array) + (python.return! array)))) + +(def: runtime//array + Runtime + ($_ python.then! + @@array//get + @@array//put)) + +(def: #export atom//field Text "_lux_atom") + +(runtime: (atom//compare-and-swap atom old new) + (let [atom//field (python.string atom//field)] + (python.if! (python.= old (python.nth atom//field atom)) + ($_ python.then! + (python.set-nth! atom//field new atom) + (python.return! (python.bool true))) + (python.return! (python.bool false))))) + +(def: runtime//atom + Runtime + ($_ python.then! + @@atom//compare-and-swap)) + +(runtime: (box//write value box) + ($_ python.then! + (python.set-nth! (python.int 0) value box) + (python.return! ..unit))) + +(def: runtime//box + Runtime + ($_ python.then! + @@box//write)) + +(runtime: (process//future procedure) + ($_ python.then! + (python.import! "threading") + (let [params (python.dict (list [(python.string "target") procedure]))] + (python.do! (|> (python.global "threading") + (python.send-keyword (list) params "Thread") + (python.send (list) "start")))) + (python.return! ..unit))) + +(runtime: (process//schedule milli-seconds procedure) + ($_ python.then! + (python.import! "threading") + (let [seconds (|> milli-seconds (python./ (python.float 1_000.0)))] + (python.do! (|> (python.global "threading") + (python.send (list seconds procedure) "Timer") + (python.send (list) "start")))) + (python.return! ..unit))) + +(def: runtime//process + Runtime + ($_ python.then! + @@process//future + @@process//schedule)) + +(do-template [<name> <method>] + [(runtime: (<name> input) + ($_ python.then! + (python.import! "math") + (python.return! (|> (python.global "math") (python.send (list input) <method>)))))] + + [math//cos "cos"] + [math//sin "sin"] + [math//tan "tan"] + [math//acos "acos"] + [math//asin "asin"] + [math//atan "atan"] + [math//exp "exp"] + [math//log "log"] + [math//ceil "ceil"] + [math//floor "floor"] + ) + +(def: runtime//math + Runtime + ($_ python.then! + @@math//cos + @@math//sin + @@math//tan + @@math//acos + @@math//asin + @@math//atan + @@math//exp + @@math//log + @@math//ceil + @@math//floor)) + +(def: runtime + Runtime + ($_ python.then! + runtime//lux + runtime//adt + runtime//bit + runtime//nat + runtime//deg + runtime//frac + runtime//text + runtime//array + runtime//atom + runtime//box + runtime//io + runtime//process + runtime//math + )) + +(def: #export artifact Text (format prefix ".py")) + +(def: #export translate + (Meta (Process Unit)) + (do macro.Monad<Meta> + [_ //.init-module-buffer + _ (//.save runtime)] + (//.save-module! artifact))) diff --git a/new-luxc/source/luxc/lang/translation/python/statement.jvm.lux b/new-luxc/source/luxc/lang/translation/python/statement.jvm.lux new file mode 100644 index 000000000..36fe472d3 --- /dev/null +++ b/new-luxc/source/luxc/lang/translation/python/statement.jvm.lux @@ -0,0 +1,48 @@ +(.module: + lux + (lux (control [monad #+ do]) + [macro] + (data text/format)) + (luxc (lang [".L" module] + (host [python #+ Expression Statement @@]))) + [//] + (// [".T" runtime] + [".T" reference] + [".T" eval])) + +(def: #export (translate-def name expressionT expressionO metaV) + (-> Text Type Expression Code (Meta Unit)) + (do macro.Monad<Meta> + [current-module macro.current-module-name + #let [def-ident [current-module name]]] + (case (macro.get-symbol-ann (ident-for #.alias) metaV) + (#.Some real-def) + (do @ + [[realT realA realV] (macro.find-def real-def) + _ (moduleL.define def-ident [realT metaV realV])] + (wrap [])) + + _ + (do @ + [#let [def-name (referenceT.global def-ident)] + _ (//.save (python.set! (list def-name) expressionO)) + expressionV (evalT.eval (@@ def-name)) + _ (moduleL.define def-ident [expressionT metaV expressionV]) + _ (if (macro.type? metaV) + (case (macro.declared-tags metaV) + #.Nil + (wrap []) + + tags + (moduleL.declare-tags tags (macro.export? metaV) (:! Type expressionV))) + (wrap [])) + #let [_ (log! (format "DEF " (%ident def-ident)))]] + (wrap [])) + ))) + +(def: #export (translate-program programO) + (-> Expression (Meta Statement)) + (macro.fail "translate-program NOT IMPLEMENTED YET") + ## (hostT.save (format "var " (referenceT.variable +0) " = " runtimeT.lux//program-args "();" + ## "(" programO ")(null);")) + ) diff --git a/new-luxc/source/luxc/lang/translation/python/structure.jvm.lux b/new-luxc/source/luxc/lang/translation/python/structure.jvm.lux new file mode 100644 index 000000000..0452ef504 --- /dev/null +++ b/new-luxc/source/luxc/lang/translation/python/structure.jvm.lux @@ -0,0 +1,31 @@ +(.module: + lux + (lux (control [monad #+ do]) + (data [text] + text/format) + [macro]) + (luxc ["&" lang] + (lang [synthesis #+ Synthesis] + (host [python #+ Expression Statement]))) + [//] + (// [".T" runtime])) + +(def: #export (translate-tuple translate elemsS+) + (-> (-> Synthesis (Meta Expression)) (List Synthesis) (Meta Expression)) + (case elemsS+ + #.Nil + (:: macro.Monad<Meta> wrap runtimeT.unit) + + (#.Cons singletonS #.Nil) + (translate singletonS) + + _ + (do macro.Monad<Meta> + [elemsT+ (monad.map @ translate elemsS+)] + (wrap (python.tuple elemsT+))))) + +(def: #export (translate-variant translate tag tail? valueS) + (-> (-> Synthesis (Meta Expression)) Nat Bool Synthesis (Meta Expression)) + (do macro.Monad<Meta> + [valueT (translate valueS)] + (wrap (runtimeT.variant tag tail? valueT)))) diff --git a/new-luxc/source/luxc/lang/translation/ruby/primitive.jvm.lux b/new-luxc/source/luxc/lang/translation/ruby/primitive.jvm.lux index 15e68d8c6..1e76ef9e4 100644 --- a/new-luxc/source/luxc/lang/translation/ruby/primitive.jvm.lux +++ b/new-luxc/source/luxc/lang/translation/ruby/primitive.jvm.lux @@ -25,13 +25,13 @@ (def: #export translate-frac (-> Frac (Meta Expression)) (|>> (cond> [(f/= number.positive-infinity)] - [(new> "(1/0)")] + [(new> "(1.0/0.0)")] [(f/= number.negative-infinity)] - [(new> "(-1/0)")] + [(new> "(-1.0/0.0)")] [(f/= number.not-a-number)] - [(new> "(0/0)")] + [(new> "(0.0/0.0)")] ## else [%f]) |