diff options
author | Eduardo Julian | 2019-03-26 19:22:42 -0400 |
---|---|---|
committer | Eduardo Julian | 2019-03-26 19:22:42 -0400 |
commit | 5ce3411d68cf11daa0ff3e5171afced429696480 (patch) | |
tree | 03c923233d24623e0c9dfed53acc91b64b5ed683 | |
parent | 91cd93a50347d39c286366c32c723fd861c5975e (diff) |
WIP: Moved Python code-generation machinery over to stdlib.
35 files changed, 1747 insertions, 1903 deletions
diff --git a/new-luxc/source/luxc/lang/host/python.lux b/new-luxc/source/luxc/lang/host/python.lux deleted file mode 100644 index aafa07161..000000000 --- a/new-luxc/source/luxc/lang/host/python.lux +++ /dev/null @@ -1,340 +0,0 @@ -(.module: - [lux #- not or and list if] - (lux (control pipe) - (data [text] - text/format - [number] - (coll [list "list/" Functor<List> Fold<List>])) - (type abstract))) - -(abstract: #export Single {} Any) -(abstract: #export Poly {} Any) -(abstract: #export Keyword {} Any) - -(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 - (-> Bit Expression) - (|>> (case> #0 "False" - #1 "True") - :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 text.new-line) - (text.replace-all text.new-line (format text.new-line text.tab)))) - - (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!) - text.new-line "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!) - text.new-line - (: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 text.new-line)) - - (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 text.new-line "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/python/case.jvm.lux b/new-luxc/source/luxc/lang/translation/python/case.jvm.lux deleted file mode 100644 index 809b32c23..000000000 --- a/new-luxc/source/luxc/lang/translation/python/case.jvm.lux +++ /dev/null @@ -1,266 +0,0 @@ -(.module: - lux - (lux (control [monad #+ do] - ["ex" exception #+ exception:]) - (data [number] - [text] - text/format - (coll [list "list/" Functor<List> Fold<List>] - (set ["set" unordered #+ 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 Bit]) - (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 (:coerce 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 error) (python.global "Exception"))) - -(def: fail-pm! (python.raise! (new-Exception pm-error))) - -(def: $temp (python.var "temp")) - -(exception: #export (Unrecognized-Path {message Text}) - message) - -(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 (:coerce Int))] - [#.Int python.int] - [#.Rev (<| python.int (:coerce Int))] - [#.Bit python.bool] - [#.Frac python.float] - [#.Text python.string]) - - (^template [<pm> <getter>] - (^code (<pm> (~ [_ (#.Nat idx)]))) - (meta/wrap (push-cursor! (<getter> cursor-top (python.int (:coerce 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 (:coerce Int idx)) <flag>)) - (python.if! (python.= python.none (@@ $temp)) - fail-pm! - (push-cursor! (@@ $temp)))))) - (["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 (.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)]) (~ [_ (#.Bit 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 (.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/expression.jvm.lux b/new-luxc/source/luxc/lang/translation/python/expression.jvm.lux deleted file mode 100644 index 0bbfb2f2c..000000000 --- a/new-luxc/source/luxc/lang/translation/python/expression.jvm.lux +++ /dev/null @@ -1,87 +0,0 @@ -(.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])) - -(do-template [<name>] - [(exception: #export (<name> {message Text}) - message)] - - [Invalid-Function-Syntax] - [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)) - ([#.Bit primitiveT.translate-bit] - [#.Nat primitiveT.translate-nat] - [#.Int primitiveT.translate-int] - [#.Rev primitiveT.translate-rev] - [#.Frac primitiveT.translate-frac] - [#.Text primitiveT.translate-text]) - - (^code ((~ [_ (#.Nat tag)]) (~ [_ (#.Bit last?)]) (~ valueS))) - (structureT.translate-variant translate tag last? valueS) - - (^code [(~+ members)]) - (structureT.translate-tuple translate members) - - (^ [_ (#.Form (list [_ (#.Int var)]))]) - (referenceT.translate-variable var) - - [_ (#.Identifier 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 deleted file mode 100644 index d081dd52b..000000000 --- a/new-luxc/source/luxc/lang/translation/python/function.jvm.lux +++ /dev/null @@ -1,99 +0,0 @@ -(.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 (inc register))) - (python.nth (|> register .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 (dec arity)) - (list/map input-declaration) - (case> #.Nil - python.no-op! - - (#.Cons head tail) - (list/fold python.then! head tail))) - arityO (|> arity .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 #1) - (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 deleted file mode 100644 index f6e3ca4c3..000000000 --- a/new-luxc/source/luxc/lang/translation/python/loop.jvm.lux +++ /dev/null @@ -1,36 +0,0 @@ -(.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 (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 deleted file mode 100644 index f88c34fce..000000000 --- a/new-luxc/source/luxc/lang/translation/python/primitive.jvm.lux +++ /dev/null @@ -1,20 +0,0 @@ -(.module: - lux - (lux [macro "meta/" Monad<Meta>]) - (luxc (lang (host [python #+ Expression Statement])))) - -(def: #export translate-bit - (-> Bit (Meta Expression)) - (|>> python.bool meta/wrap)) - -(def: #export translate-int - (-> Int (Meta Expression)) - (|>> 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/common.jvm.lux b/new-luxc/source/luxc/lang/translation/python/procedure/common.jvm.lux deleted file mode 100644 index 8ffe03f49..000000000 --- a/new-luxc/source/luxc/lang/translation/python/procedure/common.jvm.lux +++ /dev/null @@ -1,341 +0,0 @@ -(.module: - lux - (lux (control [monad #+ do] - ["ex" exception #+ exception:] - ["p" parser]) - (data ["e" error] - [text] - text/format - [number] - (coll [list "list/" Functor<List>] - (dictionary ["dict" unordered #+ 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 .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<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)) - -(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<Text>) - (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//left-shift [subjectO paramO]) - Binary - (|> (python.bit-shl paramO subjectO) - runtimeT.bit//64)) - -(do-template [<name> <op>] - [(def: (<name> [subjectO paramO]) - Binary - (<op> paramO subjectO))] - - [bit//arithmetic-right-shift python.bit-shr] - [bit//logical-right-shift runtimeT.bit//logical-right-shift] - ) - -(def: bit-procs - Bundle - (<| (prefix "bit") - (|> (dict.new text.Hash<Text>) - (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)) - -(do-template [<name> <const> <encode>] - [(def: (<name> _) - Nullary - (<encode> <const>))] - - [frac//smallest Double::MIN_VALUE python.float] - [frac//min (f/* -1.0 Double::MAX_VALUE) python.float] - [frac//max Double::MAX_VALUE python.float] - ) - -(do-template [<name> <op>] - [(def: (<name> [subjectO paramO]) - Binary - (|> subjectO - (<op> paramO) - runtimeT.bit//64))] - - [int//add python.+] - [int//sub python.-] - [int//mul python.*] - ) - -(do-template [<name> <op>] - [(def: (<name> [subjectO paramO]) - Binary - (|> subjectO - (<op> paramO)))] - - [int//div python./] - [int//rem 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))] - - [int//= python.=] - [int//< python.<] - ) - -(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))) - -(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 "to-frac" (unary (apply1 (python.global "float")))) - (install "char" (unary (apply1 (python.global "chr"))))))) - -(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 "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//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 "char" (binary text//char)) - (install "clip" (trinary text//clip)) - ))) - -## [[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))))))) - -## [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) - ))) 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 deleted file mode 100644 index af82491b6..000000000 --- a/new-luxc/source/luxc/lang/translation/python/procedure/host.jvm.lux +++ /dev/null @@ -1,89 +0,0 @@ -(.module: - lux - (lux (control [monad #+ do]) - (data [text] - text/format - (coll [list "list/" Functor<List>] - (dictionary ["dict" unordered #+ 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 deleted file mode 100644 index e8bcae522..000000000 --- a/new-luxc/source/luxc/lang/translation/python/reference.jvm.lux +++ /dev/null @@ -1,42 +0,0 @@ -(.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 (.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 (.nat var)))) - -(def: #export (translate-variable var) - (-> Variable (Meta Expression)) - (if (variableL.captured? var) - (translate-captured (variableL.captured-register var)) - (translate-local (.nat var)))) - -(def: #export global - (-> Name SVar) - (|>> //.definition-name python.var)) - -(def: #export (translate-definition name) - (-> Name (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 deleted file mode 100644 index e5beb9872..000000000 --- a/new-luxc/source/luxc/lang/translation/python/runtime.jvm.lux +++ /dev/null @@ -1,365 +0,0 @@ -(.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) - (-> Bit 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 Bit Expression Expression) - (variant' (python.int (.int tag)) - (flag last?) - value)) - -(def: #export none - Expression - (variant +0 #0 unit)) - -(def: #export some - (-> Expression Expression) - (variant +1 #1)) - -(def: #export left - (-> Expression Expression) - (variant +0 #0)) - -(def: #export right - (-> Expression Expression) - (variant +1 #1)) - -(type: Runtime Statement) - -(def: declaration - (s.Syntax [Text (List Text)]) - (p.either (p.seq s.local-identifier (p/wrap (list))) - (s.form (p.seq s.local-identifier (p.some s.local-identifier))))) - -(syntax: (runtime: {[name args] declaration} - definition) - (let [implementation (code.local-identifier (format "@@" name)) - runtime (format "__" prefix "__" (lang.normalize-name name)) - $runtime (` (python.var (~ (code.text runtime)))) - @runtime (` (@@ (~ $runtime))) - argsC+ (list/map code.local-identifier args) - argsLC+ (list/map (|>> lang.normalize-name code.text (~) (python.var) (`)) - args) - declaration (` ((~ (code.local-identifier 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-identifier))} - body) - (wrap (list (` (let [(~+ (|> vars - (list/map (function (_ var) - (list (code.local-identifier 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-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//logical-right-shift 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//64 - @@bit//logical-right-shift)) - -(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)) - -(runtime: (box//write value box) - ($_ python.then! - (python.set-nth! (python.int 0) value box) - (python.return! ..unit))) - -(def: runtime//box - Runtime - @@box//write) - -(def: runtime - Runtime - ($_ python.then! - runtime//lux - runtime//adt - runtime//bit - runtime//frac - runtime//text - runtime//array - runtime//box - runtime//io - )) - -(def: #export artifact Text (format prefix ".py")) - -(def: #export translate - (Meta (Process Any)) - (do macro.Monad<Meta> - [_ //.init-module-buffer - _ (//.save runtime)] - (//.save-module! artifact))) diff --git a/new-luxc/source/luxc/lang/translation/python/structure.jvm.lux b/new-luxc/source/luxc/lang/translation/python/structure.jvm.lux deleted file mode 100644 index 158cf3a2c..000000000 --- a/new-luxc/source/luxc/lang/translation/python/structure.jvm.lux +++ /dev/null @@ -1,31 +0,0 @@ -(.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 Bit Synthesis (Meta Expression)) - (do macro.Monad<Meta> - [valueT (translate valueS)] - (wrap (runtimeT.variant tag tail? valueT)))) diff --git a/stdlib/source/lux/data/text/format.lux b/stdlib/source/lux/data/text/format.lux index 83701c972..f6a53358d 100644 --- a/stdlib/source/lux/data/text/format.lux +++ b/stdlib/source/lux/data/text/format.lux @@ -1,7 +1,7 @@ (.module: [lux #* [control - [monad (#+ do Monad)] + [monad (#+ do)] ["p" parser]] [data ["." bit] @@ -16,7 +16,7 @@ ["." xml] ["." json]] [collection - ["." list ("#;." monad)]]] + ["." list ("#@." monad)]]] [time ["." instant] ["." duration] @@ -25,7 +25,7 @@ ["." modular]] ["." macro ["." code] - ["s" syntax (#+ syntax: Syntax)]] + ["s" syntax (#+ Syntax syntax:)]] ["." type]]) ## [Syntax] @@ -85,4 +85,4 @@ "(list)" _ - (format "(list " (text.join-with " " (list;map formatter values)) ")")))) + (format "(list " (text.join-with " " (list@map formatter values)) ")")))) diff --git a/stdlib/source/lux/host/js.lux b/stdlib/source/lux/host/js.lux index 45f3d42c6..be8759a35 100644 --- a/stdlib/source/lux/host/js.lux +++ b/stdlib/source/lux/host/js.lux @@ -123,27 +123,6 @@ (format (:representation function)) :abstraction)) - (do-template [<apply> <arg>+ <type>+ <function>+] - [(`` (def: #export (<apply> function) - (-> Expression (~~ (template.splice <type>+)) Computation) - (.function (_ (~~ (template.splice <arg>+))) - (..apply/* function (list (~~ (template.splice <arg>+))))))) - - (`` (do-template [<definition> <function>] - [(def: #export <definition> (<apply> (..var <function>)))] - - (~~ (template.splice <function>+))))] - - [apply/1 [_0] [Expression] - [[not-a-number? "isNaN"]]] - - [apply/2 [_0 _1] [Expression Expression] - []] - - [apply/3 [_0 _1 _2] [Expression Expression Expression] - []] - ) - (def: #export (do method inputs object) (-> Text (List Expression) Expression Computation) (apply/* (..the method object) inputs)) @@ -395,3 +374,24 @@ (..if test then! next!)) else! (list.reverse clauses))) + +(do-template [<apply> <arg>+ <type>+ <function>+] + [(`` (def: #export (<apply> function) + (-> Expression (~~ (template.splice <type>+)) Computation) + (.function (_ (~~ (template.splice <arg>+))) + (..apply/* function (list (~~ (template.splice <arg>+))))))) + + (`` (do-template [<definition> <function>] + [(def: #export <definition> (<apply> (..var <function>)))] + + (~~ (template.splice <function>+))))] + + [apply/1 [_0] [Expression] + [[not-a-number? "isNaN"]]] + + [apply/2 [_0 _1] [Expression Expression] + []] + + [apply/3 [_0 _1 _2] [Expression Expression Expression] + []] + ) diff --git a/stdlib/source/lux/host/python.lux b/stdlib/source/lux/host/python.lux new file mode 100644 index 000000000..afdb923fc --- /dev/null +++ b/stdlib/source/lux/host/python.lux @@ -0,0 +1,402 @@ +(.module: + [lux (#- Code not or and list if cond int) + [control + pipe] + [data + [number + ["." frac]] + ["." text + format] + [collection + ["." list ("#@." functor fold)]]] + [macro + ["." template] + ["." code] + ["s" syntax (#+ syntax:)]] + [type + abstract]]) + +(def: expression (-> Text Text) (text.enclose ["(" ")"])) + +(def: nest + (-> Text Text) + (|>> (format text.new-line) + (text.replace-all text.new-line (format text.new-line text.tab)))) + +(abstract: #export (Code brand) + {} + + Text + + (def: #export manual + (-> Text Code) + (|>> :abstraction)) + + (def: #export code + (-> (Code Any) Text) + (|>> :representation)) + + (do-template [<type> <super>] + [(with-expansions [<brand> (template.identifier [<type> "'"])] + (`` (abstract: #export (<brand> brand) {} Any)) + (`` (type: #export (<type> brand) + (<super> (<brand> brand)))))] + + [Expression Code] + [Computation Expression] + [Location Computation] + [Var Location] + [Statement Code] + ) + + (do-template [<type> <super>] + [(with-expansions [<brand> (template.identifier [<type> "'"])] + (`` (abstract: #export <brand> {} Any)) + (`` (type: #export <type> (<super> <brand>))))] + + [Literal Computation] + [Access Location] + [Loop Statement] + [Label Code] + ) + + (abstract: #export Single {} Any) + (abstract: #export Poly {} Any) + (abstract: #export Keyword {} Any) + + (type: #export SVar (Var Single)) + (type: #export PVar (Var Poly)) + (type: #export KVar (Var Keyword)) + + (def: #export var + (-> Text SVar) + (|>> :abstraction)) + + (do-template [<name> <kind> <prefix>] + [(def: #export <name> + (-> SVar (Var <kind>)) + (|>> :representation (format <prefix>) :abstraction))] + + [poly Poly "*"] + [keyword Keyword "**"] + ) + + (def: #export none + Literal + (:abstraction "None")) + + (def: #export bool + (-> Bit Literal) + (|>> (case> #0 "False" + #1 "True") + :abstraction)) + + (def: #export int + (-> Int Literal) + (|>> %i :abstraction)) + + (def: #export float + (-> Frac Literal) + (`` (|>> (cond> (~~ (do-template [<lux> <python>] + [[(f/= <lux>)] + [(new> (format "float(" text.double-quote <python> text.double-quote ")") [])]] + + [frac.positive-infinity "inf"] + [frac.negative-infinity "-inf"] + [frac.not-a-number "nan"] + )) + + ## else + [%f]) + :abstraction))) + + (def: #export string + (-> Text Literal) + (|>> (text.enclose' text.double-quote) :abstraction)) + + (def: (composite-literal left-delimiter right-delimiter entry-serializer) + (All [a] + (-> Text Text (-> a Text) + (-> (List a) Literal))) + (function (_ entries) + (<| :abstraction + ..expression + (format left-delimiter + (|> entries (list@map entry-serializer) (text.join-with ",")) + right-delimiter)))) + + (do-template [<name> <pre> <post>] + [(def: #export <name> + (-> (List (Expression Any)) Literal) + (composite-literal <pre> <post> ..code))] + + [tuple "(" ")"] + [list "[" "]"] + ) + + (def: #export (slice from to list) + (-> (Expression Any) (Expression Any) (Expression Any) Access) + (<| :abstraction + ..expression + (format (:representation list) "[" (:representation from) ":" (:representation to) "]"))) + + (def: #export (slice-from from list) + (-> (Expression Any) (Expression Any) Access) + (<| :abstraction + ..expression + (format (:representation list) "[" (:representation from) ":]"))) + + (def: #export dict + (-> (List [(Expression Any) (Expression Any)]) (Computation Any)) + (composite-literal "{" "}" (.function (_ [k v]) (format (:representation k) " : " (:representation v))))) + + (def: #export (apply/* func args) + (-> (Expression Any) (List (Expression Any)) (Computation Any)) + (<| :abstraction + ..expression + (format (:representation func) "(" (text.join-with "," (list@map ..code args)) ")"))) + + (do-template [<name> <kind> <prefix>] + [(def: (<name> var) + (-> (Expression Any) Text) + (format <prefix> (:representation var)))] + + [splat-poly Poly "*"] + [splat-keyword Keyword "**"] + ) + + (do-template [<name> <splat>] + [(def: #export (<name> args extra func) + (-> (List (Expression Any)) (Expression Any) (Expression Any) (Computation Any)) + (<| :abstraction + ..expression + (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 (the name object) + (-> Text (Expression Any) (Computation Any)) + (:abstraction (format (:representation object) "." name))) + + (def: #export (do method args object) + (-> Text (List (Expression Any)) (Expression Any) (Computation Any)) + (..apply/* (..the method object) args)) + + (do-template [<name> <apply>] + [(def: #export (<name> args extra method) + (-> (List (Expression Any)) (Expression Any) Text + (-> (Expression Any) (Computation Any))) + (|>> (..the method) (<apply> args extra)))] + + [do-poly apply-poly] + [do-keyword apply-keyword] + ) + + (def: #export (nth idx array) + (-> (Expression Any) (Expression Any) Location) + (:abstraction (format (:representation array) "[" (:representation idx) "]"))) + + (def: #export (? test then else) + (-> (Expression Any) (Expression Any) (Expression Any) (Computation Any)) + (<| :abstraction + ..expression + (format (:representation then) " if " (:representation test) " else " (:representation else)))) + + (do-template [<name> <op>] + [(def: #export (<name> param subject) + (-> (Expression Any) (Expression Any) (Computation Any)) + (<| :abstraction + ..expression + (format (:representation subject) " " <op> " " (:representation param))))] + + [is "is"] + [= "=="] + [< "<"] + [<= "<="] + [> ">"] + [>= ">="] + [+ "+"] + [- "-"] + [* "*"] + [/ "/"] + [% "%"] + [** "**"] + [bit-or "|"] + [bit-and "&"] + [bit-xor "^"] + [bit-shl "<<"] + [bit-shr ">>"] + + [or "or"] + [and "and"] + ) + + (def: #export (not subject) + (-> (Expression Any) (Computation Any)) + (<| :abstraction + ..expression + (format "not " (:representation subject)))) + + (def: #export (lambda arguments body) + (-> (List (Var Any)) (Expression Any) (Computation Any)) + (<| :abstraction + ..expression + (format "lambda " (|> arguments (list@map ..code) (text.join-with ", ")) ": " + (:representation body)))) + + (def: #export (set vars value) + (-> (List (Location Any)) (Expression Any) (Statement Any)) + (:abstraction + (format (|> vars (list@map ..code) (text.join-with ", ")) + " = " + (:representation value)))) + + (def: #export (delete where) + (-> (Location Any) (Statement Any)) + (:abstraction (format "del " (:representation where)))) + + (def: #export (if test then! else!) + (-> (Expression Any) (Statement Any) (Statement Any) (Statement Any)) + (:abstraction + (format "if " (:representation test) ":" + (..nest (:representation then!)) + text.new-line "else:" + (..nest (:representation else!))))) + + (def: #export (when test then!) + (-> (Expression Any) (Statement Any) (Statement Any)) + (:abstraction + (format "if " (:representation test) ":" + (..nest (:representation then!))))) + + (def: #export (then pre! post!) + (-> (Statement Any) (Statement Any) (Statement Any)) + (:abstraction + (format (:representation pre!) + text.new-line + (:representation post!)))) + + (do-template [<keyword> <0>] + [(def: #export <0> + Statement + (:abstraction <keyword>))] + + ["break" break] + ["continue" continue] + ) + + (def: #export (while test body!) + (-> (Expression Any) (Statement Any) Loop) + (:abstraction + (format "while " (:representation test) ":" + (..nest (:representation body!))))) + + (def: #export (for-in var inputs body!) + (-> SVar (Expression Any) (Statement Any) Loop) + (:abstraction + (format "for " (:representation var) " in " (:representation inputs) ":" + (..nest (:representation body!))))) + + (def: #export (statement expression) + (-> (Expression Any) (Statement Any)) + (:abstraction + (format (:representation expression) ";"))) + + (def: #export no-op! + (Statement Any) + (:abstraction text.new-line)) + + (type: #export Except + {#classes (List SVar) + #exception SVar + #handler (Statement Any)}) + + (def: #export (try body! excepts) + (-> (Statement Any) (List Except) (Statement Any)) + (:abstraction + (format "try:" + (..nest (:representation body!)) + (|> excepts + (list@map (function (_ [classes exception catch!]) + (format text.new-line "except (" (text.join-with "," (list@map ..code classes)) + ") as " (:representation exception) ":" + (..nest (:representation catch!))))) + (text.join-with ""))))) + + (do-template [<name> <keyword>] + [(def: #export (<name> message) + (-> (Expression Any) (Statement Any)) + (:abstraction + (format <keyword> " " (:representation message))))] + + [raise "raise"] + [return "return"] + [print "print"] + ) + + (def: #export (def name args body) + (-> SVar (List (Ex [k] (Var k))) (Statement Any) (Statement Any)) + (:abstraction + (format "def " (:representation name) + "(" (|> args (list@map ..code) (text.join-with ",")) "):" + (..nest (:representation body))))) + + (def: #export (import module-name) + (-> Text (Statement Any)) + (:abstraction (format "import " module-name))) + ) + +(def: #export (cond clauses else!) + (-> (List [(Expression Any) (Statement Any)]) (Statement Any) (Statement Any)) + (list@fold (.function (_ [test then!] next!) + (..if test then! next!)) + else! + (list.reverse clauses))) + +(syntax: (arity-inputs {arity s.nat}) + (wrap (case arity + 0 (.list) + _ (|> (dec arity) + (list.n/range 0) + (list@map (|>> %n code.local-identifier)))))) + +(syntax: (arity-types {arity s.nat}) + (wrap (list.repeat arity (` (Expression Any))))) + +(do-template [<arity> <function>+] + [(with-expansions [<apply> (template.identifier ["apply/" <arity>]) + <inputs> (arity-inputs <arity>) + <types> (arity-types <arity>) + <definitions> (template.splice <function>+)] + (def: #export (<apply> function <inputs>) + (-> (Expression Any) <types> (Computation Any)) + (..apply/* function (.list <inputs>))) + + (do-template [<function>] + [(`` (def: #export (~~ (template.identifier [<function> "/" <arity>])) + (<apply> (..var <function>))))] + + <definitions>))] + + [1 + [["str"] + ["ord"] + ["float"] + ["int"] + ["len"] + ["chr"] + ["repr"] + ["Exception"]]] + + [2 + []] + + [3 + []] + ) diff --git a/stdlib/source/lux/macro/template.lux b/stdlib/source/lux/macro/template.lux index 1f098ff4a..d0e9714a2 100644 --- a/stdlib/source/lux/macro/template.lux +++ b/stdlib/source/lux/macro/template.lux @@ -2,11 +2,17 @@ [lux #* [control ["." monad (#+ do)] - ["p" parser]] + ["p" parser ("#@." functor)]] [data + ["." bit ("#@." codec)] ["." text] + [number + ["." nat ("#@." decimal)] + ["." int ("#@." decimal)] + ["." rev ("#@." decimal)] + ["." frac ("#@." decimal)]] [collection - ["." list ("#;." monad)]]]] + ["." list ("#@." monad)]]]] ["." // ["." code] ["s" syntax (#+ Syntax syntax:)]]) @@ -21,9 +27,9 @@ (list.repeat (list.size locals)) (monad.seq @))] (wrap (list (` (.with-expansions [(~+ (|> (list.zip2 locals g!locals) - (list;map (function (_ [name identifier]) + (list@map (function (_ [name identifier]) (list (code.local-identifier name) (as-is identifier)))) - list;join))] + list@join))] (~ body))))))) (def: snippet @@ -31,7 +37,13 @@ ($_ p.either s.text s.local-identifier - s.local-tag)) + s.local-tag + (p@map bit@encode s.bit) + (p@map nat@encode s.nat) + (p@map int@encode s.int) + (p@map rev@encode s.rev) + (p@map frac@encode s.frac) + )) (def: part (Syntax (List Text)) diff --git a/stdlib/source/lux/tool/compiler/phase/generation/extension.lux b/stdlib/source/lux/tool/compiler/phase/generation/extension.lux new file mode 100644 index 000000000..681fd35f8 --- /dev/null +++ b/stdlib/source/lux/tool/compiler/phase/generation/extension.lux @@ -0,0 +1,58 @@ +(.module: + [lux #* + [control + ["." monad (#+ do)]] + [data + [collection + ["." list ("#@." functor)]]] + ["." macro (#+ with-gensyms) + ["." code] + ["s" syntax (#+ syntax:)]]] + ["." // + ["#/" // + ["#." extension] + [// + [synthesis (#+ Synthesis)]]]]) + +(syntax: (Vector {size s.nat} elemT) + (wrap (list (` [(~+ (list.repeat size elemT))])))) + +(type: #export (Nullary of) (-> (Vector 0 of) of)) +(type: #export (Unary of) (-> (Vector 1 of) of)) +(type: #export (Binary of) (-> (Vector 2 of) of)) +(type: #export (Trinary of) (-> (Vector 3 of) of)) +(type: #export (Variadic of) (-> (List of) of)) + +(syntax: (arity: {arity s.nat} {name s.local-identifier} type) + (with-gensyms [g!_ g!extension g!name g!phase g!inputs g!of g!anchor g!expression g!statement] + (do @ + [g!input+ (monad.seq @ (list.repeat arity (macro.gensym "input")))] + (wrap (list (` (def: #export ((~ (code.local-identifier name)) (~ g!extension)) + (All [(~ g!anchor) (~ g!expression) (~ g!statement)] + (-> ((~ type) (~ g!expression)) (//.Handler (~ g!anchor) (~ g!expression) (~ g!statement)))) + (function ((~ g!_) (~ g!name) (~ g!phase) (~ g!inputs)) + (case (~ g!inputs) + (^ (list (~+ g!input+))) + (do ///.monad + [(~+ (|> g!input+ + (list@map (function (_ g!input) + (list g!input (` ((~ g!phase) (~ g!input)))))) + list.concat))] + ((~' wrap) ((~ g!extension) [(~+ g!input+)]))) + + (~' _) + (///.throw ///extension.incorrect-arity [(~ g!name) 1 (list.size (~ g!inputs))])))))))))) + +(arity: 0 nullary ..Nullary) +(arity: 1 unary ..Unary) +(arity: 2 binary ..Binary) +(arity: 3 trinary ..Trinary) + +(def: #export (variadic extension) + (All [anchor expression statement] + (-> (Variadic expression) (//.Handler anchor expression statement))) + (function (_ extension-name) + (function (_ phase inputsS) + (do ///.monad + [inputsI (monad.map @ phase inputsS)] + (wrap (extension inputsI)))))) diff --git a/stdlib/source/lux/tool/compiler/phase/generation/js.lux b/stdlib/source/lux/tool/compiler/phase/generation/js.lux index 5da2a016e..29c95ff43 100644 --- a/stdlib/source/lux/tool/compiler/phase/generation/js.lux +++ b/stdlib/source/lux/tool/compiler/phase/generation/js.lux @@ -6,7 +6,7 @@ [runtime (#+ Phase)] ["." primitive] ["." structure] - ["." reference ("#;." system)] + ["." reference ("#@." system)] ["." function] ["." case] ["." loop] @@ -33,7 +33,7 @@ (structure.tuple generate members) (#synthesis.Reference value) - (reference;reference value) + (reference@reference value) (^ (synthesis.branch/case case)) (case.case generate case) diff --git a/stdlib/source/lux/tool/compiler/phase/generation/js/case.lux b/stdlib/source/lux/tool/compiler/phase/generation/js/case.lux index ed2c74a4b..4a28ccb3f 100644 --- a/stdlib/source/lux/tool/compiler/phase/generation/js/case.lux +++ b/stdlib/source/lux/tool/compiler/phase/generation/js/case.lux @@ -4,11 +4,10 @@ [monad (#+ do)] ["ex" exception (#+ exception:)]] [data - ["." number] ["." text format] [collection - ["." list ("#;." functor fold)]]] + ["." list ("#@." functor fold)]]] [host ["_" js (#+ Expression Computation Var Statement)]]] ["." // #_ @@ -17,7 +16,9 @@ ["#." primitive] ["#/" // #_ ["#." reference] - ["#/" // ("#;." monad) + ["#/" // ("#@." monad) + [synthesis + ["." case]] ["#/" // #_ [reference (#+ Register)] ["#." synthesis (#+ Synthesis Path)]]]]]) @@ -32,18 +33,16 @@ [valueO (generate valueS) bodyO (generate bodyS)] ## TODO: Find some way to do 'let' without paying the price of the closure. - (wrap (_.apply/* (<| (_.closure (list)) - ($_ _.then - (_.define (..register register) valueO) - (_.return bodyO))) - (list))))) + (wrap (_.apply/* (_.closure (list (..register register)) + (_.return bodyO)) + (list valueO))))) (def: #export (record-get generate valueS pathP) (-> Phase Synthesis (List [Nat Bit]) (Operation Expression)) (do ////.monad [valueO (generate valueS)] - (wrap (list;fold (function (_ [idx tail?] source) + (wrap (list@fold (function (_ [idx tail?] source) (.let [method (.if tail? //runtime.product//right //runtime.product//left)] @@ -63,7 +62,6 @@ (def: @savepoint (_.var "lux_pm_cursor_savepoint")) (def: @cursor (_.var "lux_pm_cursor")) (def: @temp (_.var "lux_pm_temp")) -(def: @alt-error (_.var "alt_error")) (def: (push-cursor! value) (-> Expression Statement) @@ -98,17 +96,7 @@ (def: fail-pm! _.break) -(def: (count-pops path) - (-> Path [Nat Path]) - (.case path - (^ ($_ /////synthesis.path/seq - #/////synthesis.Pop - path')) - (.let [[pops post-pops] (count-pops path')] - [(inc pops) post-pops]) - - _ - [0 path])) +(exception: #export unrecognized-path) (def: (multi-pop-cursor! pops) (-> Nat Statement) @@ -116,8 +104,6 @@ (_.statement (|> @cursor (_.do "splice" (list (|> @cursor ..length (_.- popsJS)) popsJS)))))) -(exception: #export unrecognized-path) - (def: (pattern-matching' generate pathP) (-> Phase Path (Operation Statement)) (.case pathP @@ -127,14 +113,14 @@ (wrap (_.return body!))) #/////synthesis.Pop - (////;wrap pop-cursor!) + (////@wrap pop-cursor!) (#/////synthesis.Bind register) - (////;wrap (_.define (..register register) ..peek-cursor)) + (////@wrap (_.define (..register register) ..peek-cursor)) (^template [<tag> <format> <=>] (^ (<tag> value)) - (////;wrap (_.when (|> value <format> (<=> ..peek-cursor) _.not) + (////@wrap (_.when (|> value <format> (<=> ..peek-cursor) _.not) fail-pm!))) ([/////synthesis.path/bit //primitive.bit _.=] [/////synthesis.path/i64 (<| //primitive.i64 .int) //runtime.i64//=] @@ -143,7 +129,7 @@ (^template [<pm> <flag> <prep>] (^ (<pm> idx)) - (////;wrap ($_ _.then + (////@wrap ($_ _.then (_.set @temp (|> idx <prep> .int _.i32 (//runtime.sum//get ..peek-cursor <flag>))) (_.if (_.= _.null @temp) fail-pm! @@ -153,7 +139,7 @@ (^template [<pm> <getter> <prep>] (^ (<pm> idx)) - (////;wrap (|> idx <prep> .int _.i32 (<getter> ..peek-cursor) push-cursor!))) + (////@wrap (|> idx <prep> .int _.i32 (<getter> ..peek-cursor) push-cursor!))) ([/////synthesis.member/left //runtime.product//left (<|)] [/////synthesis.member/right //runtime.product//right inc]) @@ -163,7 +149,7 @@ thenP)) (do ////.monad [then! (pattern-matching' generate thenP)] - (////;wrap ($_ _.then + (////@wrap ($_ _.then (_.define (..register register) ..peek-and-pop-cursor) then!))) @@ -171,10 +157,10 @@ #/////synthesis.Pop #/////synthesis.Pop nextP)) - (.let [[extra-pops nextP'] (count-pops nextP)] + (.let [[extra-pops nextP'] (case.count-pops nextP)] (do ////.monad [next! (pattern-matching' generate nextP')] - (////;wrap ($_ _.then + (////@wrap ($_ _.then (multi-pop-cursor! (n/+ 2 extra-pops)) next!)))) @@ -204,7 +190,7 @@ (wrap ($_ _.then (_.do-while _.false pattern-matching!) - (_.throw (_.string "Invalid expression for pattern-matching.")))))) + (_.throw (_.string case.pattern-matching-error)))))) (def: #export (case generate [valueS pathP]) (-> Phase [Synthesis Path] (Operation Computation)) diff --git a/stdlib/source/lux/tool/compiler/phase/generation/js/extension/common.lux b/stdlib/source/lux/tool/compiler/phase/generation/js/extension/common.lux index dfd0e4aee..2e661dc29 100644 --- a/stdlib/source/lux/tool/compiler/phase/generation/js/extension/common.lux +++ b/stdlib/source/lux/tool/compiler/phase/generation/js/extension/common.lux @@ -1,77 +1,29 @@ (.module: [lux #* [control - ["." monad (#+ do)] - ["ex" exception (#+ exception:)]] + ["." monad (#+ do)]] [data - ["e" error] ["." product] - [number (#+ hex)] [collection - ["." list ("#;." functor)] ["." dictionary]]] - ["." macro (#+ with-gensyms) - ["." code] - ["s" syntax (#+ syntax:)]] [host (#+ import:) - ["_" js (#+ Expression Computation)]]] + ["_" js (#+ Expression)]]] ["." /// #_ ["#." runtime (#+ Operation Phase Handler Bundle)] ["#." primitive] - ["#//" /// - ["#." extension - ["." bundle]] - ["#/" // #_ - [synthesis (#+ Synthesis)]]]]) - -(syntax: (Vector {size s.nat} elemT) - (wrap (list (` [(~+ (list.repeat size elemT))])))) - -(type: #export Nullary (-> (Vector 0 Expression) Computation)) -(type: #export Unary (-> (Vector 1 Expression) Computation)) -(type: #export Binary (-> (Vector 2 Expression) Computation)) -(type: #export Trinary (-> (Vector 3 Expression) Computation)) -(type: #export Variadic (-> (List Expression) Computation)) - -(syntax: (arity: {name s.local-identifier} {arity s.nat}) - (with-gensyms [g!_ g!extension g!name g!phase g!inputs] - (do @ - [g!input+ (monad.seq @ (list.repeat arity (macro.gensym "input")))] - (wrap (list (` (def: #export ((~ (code.local-identifier name)) (~ g!extension)) - (-> (-> (..Vector (~ (code.nat arity)) Expression) Computation) - Handler) - (function ((~ g!_) (~ g!name) (~ g!phase) (~ g!inputs)) - (case (~ g!inputs) - (^ (list (~+ g!input+))) - (do /////.monad - [(~+ (|> g!input+ - (list;map (function (_ g!input) - (list g!input (` ((~ g!phase) (~ g!input)))))) - list.concat))] - ((~' wrap) ((~ g!extension) [(~+ g!input+)]))) - - (~' _) - (/////.throw /////extension.incorrect-arity [(~ g!name) 1 (list.size (~ g!inputs))])))))))))) - -(arity: nullary 0) -(arity: unary 1) -(arity: binary 2) -(arity: trinary 3) - -(def: #export (variadic extension) - (-> Variadic Handler) - (function (_ extension-name) - (function (_ phase inputsS) - (do /////.monad - [inputsI (monad.map @ phase inputsS)] - (wrap (extension inputsI)))))) + [// + [extension (#+ Nullary Unary Binary Trinary + nullary unary binary trinary)] + [// + [extension + ["." bundle]]]]]) ## [Procedures] ## [[Bits]] (do-template [<name> <op>] - [(def: (<name> [paramJS subjectJS]) - Binary - (<op> subjectJS (///runtime.i64//to-number paramJS)))] + [(def: (<name> [paramG subjectG]) + (Binary Expression) + (<op> subjectG (///runtime.i64//to-number paramG)))] [i64//left-shift ///runtime.i64//left-shift] [i64//arithmetic-right-shift ///runtime.i64//arithmetic-right-shift] @@ -85,7 +37,7 @@ (do-template [<name> <const>] [(def: (<name> _) - Nullary + (Nullary Expression) (///primitive.f64 <const>))] [frac//smallest (java/lang/Double::MIN_VALUE)] @@ -94,7 +46,7 @@ ) (def: frac//decode - Unary + (Unary Expression) (|>> list (_.apply/* (_.var "parseFloat")) _.return @@ -102,34 +54,34 @@ ///runtime.lux//try)) (def: int//char - Unary + (Unary Expression) (|>> ///runtime.i64//to-number (list) (_.apply/* (_.var "String.fromCharCode")))) ## [[Text]] -(def: (text//concat [subjectJS paramJS]) - Binary - (|> subjectJS (_.do "concat" (list paramJS)))) +(def: (text//concat [subjectG paramG]) + (Binary Expression) + (|> subjectG (_.do "concat" (list paramG)))) (do-template [<name> <runtime>] - [(def: (<name> [subjectJS paramJS extraJS]) - Trinary - (<runtime> subjectJS paramJS extraJS))] + [(def: (<name> [subjectG paramG extraG]) + (Trinary Expression) + (<runtime> subjectG paramG extraG))] [text//clip ///runtime.text//clip] [text//index ///runtime.text//index] ) ## [[IO]] -(def: (io//log messageJS) - Unary +(def: (io//log messageG) + (Unary Expression) ($_ _., - (///runtime.io//log messageJS) + (///runtime.io//log messageG) ///runtime.unit)) -(def: (io//exit codeJS) - Unary +(def: (io//exit codeG) + (Unary Expression) (let [@@process (_.var "process") @@window (_.var "window") @@location (_.var "location")] @@ -137,12 +89,12 @@ ($_ _.and (_.not (_.= _.undefined (_.type-of @@process))) (_.the "exit" @@process) - (_.do "exit" (list (///runtime.i64//to-number codeJS)) @@process)) + (_.do "exit" (list (///runtime.i64//to-number codeG)) @@process)) (_.do "close" (list) @@window) (_.do "reload" (list) @@location)))) (def: (io//current-time _) - Nullary + (Nullary Expression) (|> (_.new (_.var "Date") (list)) (_.do "getTime" (list)) ///runtime.i64//from-number)) diff --git a/stdlib/source/lux/tool/compiler/phase/generation/js/extension/host.lux b/stdlib/source/lux/tool/compiler/phase/generation/js/extension/host.lux index f623242a0..aed6c4711 100644 --- a/stdlib/source/lux/tool/compiler/phase/generation/js/extension/host.lux +++ b/stdlib/source/lux/tool/compiler/phase/generation/js/extension/host.lux @@ -7,19 +7,20 @@ [collection ["." dictionary]]] [host - ["_" js]]] - ["." // #_ - ["#." common (#+ Nullary Binary Trinary Variadic)] + ["_" js (#+ Expression)]]] + ["." /// #_ + ["#." runtime (#+ Handler Bundle)] ["#/" // #_ - ["#." runtime (#+ Handler Bundle)] - ["#//" /// + ["#." extension (#+ Nullary Unary Binary Trinary Variadic + nullary unary binary trinary variadic)] + ["#/" // ["#." extension ["." bundle]] ["#/" // #_ ["#." synthesis]]]]]) (do-template [<name> <js>] - [(def: (<name> _) Nullary <js>)] + [(def: (<name> _) (Nullary Expression) <js>)] [js//null _.null] [js//undefined _.undefined] @@ -50,10 +51,10 @@ (def: js Bundle (|> bundle.empty - (bundle.install "null" (//common.nullary js//null)) - (bundle.install "undefined" (//common.nullary js//undefined)) - (bundle.install "object" (//common.nullary js//object)) - (bundle.install "array" (//common.variadic _.array)) + (bundle.install "null" (nullary js//null)) + (bundle.install "undefined" (nullary js//undefined)) + (bundle.install "object" (nullary js//object)) + (bundle.install "array" (variadic _.array)) (bundle.install "global" js//global) (bundle.install "call" js//call))) @@ -85,7 +86,7 @@ (/////.throw /////extension.incorrect-syntax name))) (def: (object//set [fieldJS valueJS objectJS]) - Trinary + (Trinary Expression) (///runtime.js//set objectJS fieldJS valueJS)) (def: object @@ -94,23 +95,23 @@ (|> bundle.empty (bundle.install "new" object//new) (bundle.install "call" object//call) - (bundle.install "read" (//common.binary (product.uncurry ///runtime.js//get))) - (bundle.install "write" (//common.trinary object//set)) - (bundle.install "delete" (//common.binary (product.uncurry ///runtime.js//delete))) + (bundle.install "read" (binary (product.uncurry ///runtime.js//get))) + (bundle.install "write" (trinary object//set)) + (bundle.install "delete" (binary (product.uncurry ///runtime.js//delete))) ))) (def: (array//write [indexJS valueJS arrayJS]) - Trinary + (Trinary Expression) (///runtime.array//write indexJS valueJS arrayJS)) (def: array Bundle (<| (bundle.prefix "array") (|> bundle.empty - (bundle.install "read" (//common.binary (product.uncurry ///runtime.array//read))) - (bundle.install "write" (//common.trinary array//write)) - (bundle.install "delete" (//common.binary (product.uncurry ///runtime.array//delete))) - (bundle.install "length" (//common.unary (_.the "length"))) + (bundle.install "read" (binary (product.uncurry ///runtime.array//read))) + (bundle.install "write" (trinary array//write)) + (bundle.install "delete" (binary (product.uncurry ///runtime.array//delete))) + (bundle.install "length" (unary (_.the "length"))) ))) (def: #export bundle diff --git a/stdlib/source/lux/tool/compiler/phase/generation/js/function.lux b/stdlib/source/lux/tool/compiler/phase/generation/js/function.lux index a99546957..10a53986f 100644 --- a/stdlib/source/lux/tool/compiler/phase/generation/js/function.lux +++ b/stdlib/source/lux/tool/compiler/phase/generation/js/function.lux @@ -8,7 +8,7 @@ [text format] [collection - ["." list ("#;." functor fold)]]] + ["." list ("#@." functor fold)]]] [host ["_" js (#+ Expression Computation Var)]]] ["." // #_ @@ -17,7 +17,7 @@ ["#." case] ["#/" // ["#." reference] - ["#/" // ("#;." monad) + ["#/" // ("#@." monad) ["." // #_ [reference (#+ Register Variable)] [analysis (#+ Variant Tuple Environment Arity Abstraction Application Analysis)] @@ -35,14 +35,14 @@ (def: (with-closure inits function-definition) (-> (List Expression) Computation (Operation Computation)) - (////;wrap + (////@wrap (case inits #.Nil function-definition _ (let [closure (_.closure (|> (list.enumerate inits) - (list;map (|>> product.left ..capture))) + (list@map (|>> product.left ..capture))) (_.return function-definition))] (_.apply/* closure inits))))) @@ -69,7 +69,7 @@ apply-poly (.function (_ args func) (|> func (_.do "apply" (list _.null args)))) initialize-self! (_.define (//case.register 0) @self) - initialize! (list;fold (.function (_ post pre!) + initialize! (list@fold (.function (_ post pre!) ($_ _.then pre! (_.define (..input post) (_.at (_.i32 (.int post)) @@arguments)))) diff --git a/stdlib/source/lux/tool/compiler/phase/generation/js/runtime.lux b/stdlib/source/lux/tool/compiler/phase/generation/js/runtime.lux index cb65b8b85..b5ef432f6 100644 --- a/stdlib/source/lux/tool/compiler/phase/generation/js/runtime.lux +++ b/stdlib/source/lux/tool/compiler/phase/generation/js/runtime.lux @@ -89,16 +89,13 @@ (def: runtime-name (-> Text Var) (|>> /////name.normalize - (format prefix "$") + (format ..prefix "$") _.var)) (def: (feature name definition) (-> Var (-> Var Expression) Statement) (_.define name (definition name))) -(syntax: (code-name {definition-name s.local-identifier}) - (wrap (list (code.local-identifier (format "@" definition-name))))) - (syntax: #export (with-vars {vars (s.tuple (p.some s.local-identifier))} body) (wrap (list (` (let [(~+ (|> vars diff --git a/stdlib/source/lux/tool/compiler/phase/generation/python.lux b/stdlib/source/lux/tool/compiler/phase/generation/python.lux new file mode 100644 index 000000000..29c95ff43 --- /dev/null +++ b/stdlib/source/lux/tool/compiler/phase/generation/python.lux @@ -0,0 +1,60 @@ +(.module: + [lux #* + [control + [monad (#+ do)]]] + [/ + [runtime (#+ Phase)] + ["." primitive] + ["." structure] + ["." reference ("#@." system)] + ["." function] + ["." case] + ["." loop] + ["." /// + ["." extension] + [// + ["." synthesis]]]]) + +(def: #export (generate synthesis) + Phase + (case synthesis + (^template [<tag> <generator>] + (^ (<tag> value)) + (:: ///.monad wrap (<generator> value))) + ([synthesis.bit primitive.bit] + [synthesis.i64 primitive.i64] + [synthesis.f64 primitive.f64] + [synthesis.text primitive.text]) + + (^ (synthesis.variant variantS)) + (structure.variant generate variantS) + + (^ (synthesis.tuple members)) + (structure.tuple generate members) + + (#synthesis.Reference value) + (reference@reference value) + + (^ (synthesis.branch/case case)) + (case.case generate case) + + (^ (synthesis.branch/let let)) + (case.let generate let) + + (^ (synthesis.branch/if if)) + (case.if generate if) + + (^ (synthesis.loop/scope scope)) + (loop.scope generate scope) + + (^ (synthesis.loop/recur updates)) + (loop.recur generate updates) + + (^ (synthesis.function/abstraction abstraction)) + (function.function generate abstraction) + + (^ (synthesis.function/apply application)) + (function.apply generate application) + + (#synthesis.Extension extension) + (extension.apply generate extension))) diff --git a/stdlib/source/lux/tool/compiler/phase/generation/python/case.lux b/stdlib/source/lux/tool/compiler/phase/generation/python/case.lux new file mode 100644 index 000000000..82a96836d --- /dev/null +++ b/stdlib/source/lux/tool/compiler/phase/generation/python/case.lux @@ -0,0 +1,218 @@ +(.module: + [lux (#- case let if) + [control + [monad (#+ do)] + ["ex" exception (#+ exception:)]] + [data + ["." text + format] + [collection + ["." list ("#@." functor fold)] + ["." set]]] + [host + ["_" python (#+ Expression SVar Statement)]]] + ["." // #_ + ["#." runtime (#+ Operation Phase)] + ["#." reference] + ["#." primitive] + ["#/" // + ["#." reference] + ["#/" // ("#@." monad) + [synthesis + ["." case]] + ["#/" // #_ + ["." reference (#+ Register)] + ["#." synthesis (#+ Synthesis Path)]]]]]) + +(def: #export register + (///reference.local _.var)) + +(def: #export capture + (///reference.foreign _.var)) + +(def: #export (let generate [valueS register bodyS]) + (-> Phase [Synthesis Register Synthesis] + (Operation (Expression Any))) + (do ////.monad + [valueO (generate valueS) + bodyO (generate bodyS)] + ## TODO: Find some way to do 'let' without paying the price of the closure. + (wrap (_.apply/* (_.lambda (list (..register register)) + bodyO) + (list valueO))))) + +(def: #export (record-get generate valueS pathP) + (-> Phase Synthesis (List [Nat Bit]) + (Operation (Expression Any))) + (do ////.monad + [valueO (generate valueS)] + (wrap (list@fold (function (_ [idx tail?] source) + (.let [method (.if tail? + //runtime.product//right + //runtime.product//left)] + (method source (_.int (.int idx))))) + valueO + pathP)))) + +(def: #export (if generate [testS thenS elseS]) + (-> Phase [Synthesis Synthesis Synthesis] + (Operation (Expression Any))) + (do ////.monad + [testO (generate testS) + thenO (generate thenS) + elseO (generate elseS)] + (wrap (_.? testO thenO elseO)))) + +(def: @savepoint (_.var "lux_pm_cursor_savepoint")) +(def: @cursor (_.var "lux_pm_cursor")) +(def: @temp (_.var "lux_pm_temp")) + +(def: (push-cursor! value) + (-> (Expression Any) (Statement Any)) + (_.statement (|> @cursor (_.do "append" (list value))))) + +(def: peek-and-pop-cursor + (Expression Any) + (|> @cursor (_.do "pop" (list)))) + +(def: pop-cursor! + (Statement Any) + (_.statement ..peek-and-pop-cursor)) + +(def: peek-cursor + (Expression Any) + (_.nth (_.int -1) @cursor)) + +(def: save-cursor! + (Statement Any) + (.let [cursor (_.slice-from (_.int +0) @cursor)] + (_.statement (|> @savepoint (_.do "append" (list cursor)))))) + +(def: restore-cursor! + (Statement Any) + (_.set (list @cursor) (|> @savepoint (_.do "pop" (list))))) + +(def: fail-pm! _.break) + +(exception: #export unrecognized-path) + +(def: (multi-pop-cursor! pops) + (-> Nat (Statement Any)) + (_.delete (_.slice-from (_.int (i/* -1 (.int pops))) @cursor))) + +(def: (pattern-matching' generate pathP) + (-> Phase Path (Operation (Statement Any))) + (.case pathP + (^ (/////synthesis.path/then bodyS)) + (do ////.monad + [body! (generate bodyS)] + (wrap (_.return body!))) + + #/////synthesis.Pop + (////@wrap pop-cursor!) + + (#/////synthesis.Bind register) + (////@wrap (_.set (list (..register register)) ..peek-cursor)) + + (^template [<tag> <format>] + (^ (<tag> value)) + (////@wrap (_.when (|> value <format> (_.= ..peek-cursor) _.not) + fail-pm!))) + ([/////synthesis.path/bit //primitive.bit] + [/////synthesis.path/i64 //primitive.i64] + [/////synthesis.path/f64 //primitive.f64] + [/////synthesis.path/text //primitive.text]) + + (^template [<pm> <flag> <prep>] + (^ (<pm> idx)) + (////@wrap ($_ _.then + (_.set (list @temp) (|> idx <prep> .int _.int (//runtime.sum//get ..peek-cursor <flag>))) + (_.if (_.= _.none @temp) + fail-pm! + (push-cursor! @temp))))) + ([/////synthesis.side/left _.none (<|)] + [/////synthesis.side/right (_.string "") inc]) + + (^template [<pm> <getter> <prep>] + (^ (<pm> idx)) + (////@wrap (|> idx <prep> .int _.int (<getter> ..peek-cursor) push-cursor!))) + ([/////synthesis.member/left //runtime.product//left (<|)] + [/////synthesis.member/right //runtime.product//right inc]) + + (^ ($_ /////synthesis.path/seq + (#/////synthesis.Bind register) + #/////synthesis.Pop + thenP)) + (do ////.monad + [then! (pattern-matching' generate thenP)] + (////@wrap ($_ _.then + (_.set (list (..register register)) ..peek-and-pop-cursor) + then!))) + + (^ ($_ /////synthesis.path/seq + #/////synthesis.Pop + #/////synthesis.Pop + nextP)) + (.let [[extra-pops nextP'] (case.count-pops nextP)] + (do ////.monad + [next! (pattern-matching' generate nextP')] + (////@wrap ($_ _.then + (multi-pop-cursor! (n/+ 2 extra-pops)) + next!)))) + + (^template [<tag> <computation>] + (^ (<tag> leftP rightP)) + (do ////.monad + [left! (pattern-matching' generate leftP) + right! (pattern-matching' generate rightP)] + (wrap <computation>))) + ([/////synthesis.path/seq (_.then left! right!)] + [/////synthesis.path/alt ($_ _.then + (_.while (_.bool true) + ($_ _.then + ..save-cursor! + left!)) + ($_ _.then + ..restore-cursor! + right!))]) + + _ + (////.throw unrecognized-path []))) + +(def: (pattern-matching generate pathP) + (-> Phase Path (Operation (Statement Any))) + (do ////.monad + [pattern-matching! (pattern-matching' generate pathP)] + (wrap ($_ _.then + (_.while (_.bool true) + pattern-matching!) + (_.raise (_.Exception/1 (_.string case.pattern-matching-error))))))) + +(def: (gensym prefix) + (-> Text (Operation SVar)) + (:: ////.monad map (|>> %n (format prefix) _.var) ///.next)) + +(def: #export (case generate [valueS pathP]) + (-> Phase [Synthesis Path] (Operation (Expression Any))) + (do ////.monad + [initG (generate valueS) + pattern-matching! (pattern-matching generate pathP) + @case (..gensym "case") + @init (..gensym "init") + #let [@dependencies+ (|> (case.storage pathP) + (get@ #case.dependencies) + set.to-list + (list@map (function (_ variable) + (.case variable + (#reference.Local register) + (..register register) + + (#reference.Foreign register) + (..capture register)))))] + _ (///.save! ["" (_.code @case)] + (_.def @case (list& @init @dependencies+) + ($_ _.then + (_.set (list @cursor) (_.list (list @init))) + (_.set (list @savepoint) (_.list (list))) + pattern-matching!)))] + (wrap (_.apply/* @case (list& initG @dependencies+))))) diff --git a/stdlib/source/lux/tool/compiler/phase/generation/python/extension.lux b/stdlib/source/lux/tool/compiler/phase/generation/python/extension.lux new file mode 100644 index 000000000..a40b4953f --- /dev/null +++ b/stdlib/source/lux/tool/compiler/phase/generation/python/extension.lux @@ -0,0 +1,15 @@ +(.module: + [lux #* + [data + [collection + ["." dictionary]]]] + [// + [runtime (#+ Bundle)]] + [/ + ["." common] + ["." host]]) + +(def: #export bundle + Bundle + (|> common.bundle + (dictionary.merge host.bundle))) diff --git a/stdlib/source/lux/tool/compiler/phase/generation/python/extension/common.lux b/stdlib/source/lux/tool/compiler/phase/generation/python/extension/common.lux new file mode 100644 index 000000000..48fd005fb --- /dev/null +++ b/stdlib/source/lux/tool/compiler/phase/generation/python/extension/common.lux @@ -0,0 +1,130 @@ +(.module: + [lux #* + ["." function] + [control + ["." monad (#+ do)]] + [data + ["." product] + [collection + ["." dictionary]]] + [host (#+ import:) + ["_" python (#+ Expression)]]] + ["." /// #_ + ["#." runtime (#+ Operation Phase Handler Bundle)] + ["#." primitive] + [// + [extension (#+ Nullary Unary Binary Trinary + nullary unary binary trinary)] + [// + [extension + ["." bundle]]]]]) + +(def: lux-procs + Bundle + (|> bundle.empty + (bundle.install "is" (binary (product.uncurry _.is))) + (bundle.install "try" (unary ///runtime.lux//try)))) + +(def: i64-procs + Bundle + (<| (bundle.prefix "i64") + (|> bundle.empty + (bundle.install "and" (binary (product.uncurry _.bit-and))) + (bundle.install "or" (binary (product.uncurry _.bit-or))) + (bundle.install "xor" (binary (product.uncurry _.bit-xor))) + (bundle.install "left-shift" (binary (|>> (product.uncurry _.bit-shl) ///runtime.i64//64))) + (bundle.install "logical-right-shift" (binary (product.uncurry (function.flip ///runtime.i64//logic-right-shift)))) + (bundle.install "arithmetic-right-shift" (binary (product.uncurry (function.flip _.bit-shr)))) + (bundle.install "=" (binary (product.uncurry _.=))) + (bundle.install "+" (binary (product.uncurry _.+))) + (bundle.install "-" (binary (product.uncurry (function.flip _.-)))) + ))) + +(import: #long java/lang/Double + (#static MIN_VALUE Double) + (#static MAX_VALUE Double)) + +(do-template [<name> <const>] + [(def: (<name> _) + (Nullary (Expression Any)) + (_.float <const>))] + + [frac//smallest (java/lang/Double::MIN_VALUE)] + [frac//min (f/* -1.0 (java/lang/Double::MAX_VALUE))] + [frac//max (java/lang/Double::MAX_VALUE)] + ) + +(def: int-procs + Bundle + (<| (bundle.prefix "int") + (|> bundle.empty + (bundle.install "<" (binary (product.uncurry (function.flip _.<)))) + (bundle.install "*" (binary (product.uncurry _.*))) + (bundle.install "/" (binary (product.uncurry (function.flip _./)))) + (bundle.install "%" (binary (product.uncurry (function.flip _.%)))) + (bundle.install "frac" (unary _.float/1)) + (bundle.install "char" (unary _.chr/1))))) + +(def: frac-procs + Bundle + (<| (bundle.prefix "frac") + (|> bundle.empty + (bundle.install "+" (binary (product.uncurry _.+))) + (bundle.install "-" (binary (product.uncurry (function.flip _.-)))) + (bundle.install "*" (binary (product.uncurry _.*))) + (bundle.install "/" (binary (product.uncurry (function.flip _./)))) + (bundle.install "%" (binary (product.uncurry (function.flip _.%)))) + (bundle.install "=" (binary (product.uncurry _.=))) + (bundle.install "<" (binary (product.uncurry (function.flip _.<)))) + (bundle.install "smallest" (nullary frac//smallest)) + (bundle.install "min" (nullary frac//min)) + (bundle.install "max" (nullary frac//max)) + (bundle.install "int" (unary _.int/1)) + (bundle.install "encode" (unary _.repr/1)) + (bundle.install "decode" (unary ///runtime.frac//decode))))) + +(def: (text//char [subjectO paramO]) + (Binary (Expression Any)) + (///runtime.text//char subjectO paramO)) + +(def: (text//clip [subjectO paramO extraO]) + (Trinary (Expression Any)) + (///runtime.text//clip subjectO paramO extraO)) + +(def: (text//index [textO partO startO]) + (Trinary (Expression Any)) + (///runtime.text//index textO partO startO)) + +(def: text-procs + Bundle + (<| (bundle.prefix "text") + (|> bundle.empty + (bundle.install "=" (binary (product.uncurry _.=))) + (bundle.install "<" (binary (product.uncurry (function.flip _.<)))) + (bundle.install "concat" (binary (product.uncurry (function.flip _.+)))) + (bundle.install "index" (trinary text//index)) + (bundle.install "size" (unary _.len/1)) + (bundle.install "char" (binary (product.uncurry ///runtime.text//char))) + (bundle.install "clip" (trinary text//clip)) + ))) + +(def: io-procs + Bundle + (<| (bundle.prefix "io") + (|> bundle.empty + (bundle.install "log" (unary ///runtime.io//log!)) + (bundle.install "error" (unary ///runtime.io//throw!)) + (bundle.install "exit" (unary ///runtime.io//exit!)) + (bundle.install "current-time" (nullary (function (_ _) + (///runtime.io//current-time! ///runtime.unit))))))) + +(def: #export bundle + Bundle + (<| (bundle.prefix "lux") + (|> lux-procs + (dictionary.merge i64-procs) + (dictionary.merge int-procs) + (dictionary.merge frac-procs) + (dictionary.merge text-procs) + (dictionary.merge io-procs) + ))) diff --git a/stdlib/source/lux/tool/compiler/phase/generation/python/extension/host.lux b/stdlib/source/lux/tool/compiler/phase/generation/python/extension/host.lux new file mode 100644 index 000000000..92887899b --- /dev/null +++ b/stdlib/source/lux/tool/compiler/phase/generation/python/extension/host.lux @@ -0,0 +1,25 @@ +(.module: + [lux #* + [control + ["." monad (#+ do)]] + [data + ["." product] + [collection + ["." dictionary]]] + [host + ["_" python (#+ Expression)]]] + ["." /// #_ + ["#." runtime (#+ Handler Bundle)] + ["#/" // #_ + ["#." extension (#+ Nullary Unary Binary Trinary Variadic + nullary unary binary trinary variadic)] + ["#/" // + ["#." extension + ["." bundle]] + ["#/" // #_ + ["#." synthesis]]]]]) + +(def: #export bundle + Bundle + (<| (bundle.prefix "python") + bundle.empty)) diff --git a/stdlib/source/lux/tool/compiler/phase/generation/python/function.lux b/stdlib/source/lux/tool/compiler/phase/generation/python/function.lux new file mode 100644 index 000000000..c92f6dd37 --- /dev/null +++ b/stdlib/source/lux/tool/compiler/phase/generation/python/function.lux @@ -0,0 +1,107 @@ +(.module: + [lux (#- function) + [control + ["." monad (#+ do)] + pipe] + [data + ["." product] + [text + format] + [collection + ["." list ("#@." functor fold)]]] + [host + ["_" python (#+ Expression Statement)]]] + ["." // #_ + [runtime (#+ Operation Phase)] + ["#." reference] + ["#." case] + ["#/" // + ["#." reference] + ["#/" // + ["." // #_ + [reference (#+ Register Variable)] + [analysis (#+ Variant Tuple Environment Arity Abstraction Application Analysis)] + [synthesis (#+ Synthesis)]]]]]) + +(def: #export (apply generate [functionS argsS+]) + (-> Phase (Application Synthesis) (Operation (Expression Any))) + (do ////.monad + [functionO (generate functionS) + argsO+ (monad.map @ generate argsS+)] + (wrap (_.apply/* functionO argsO+)))) + +(def: #export capture + (///reference.foreign _.var)) + +(def: (with-closure function-name inits function-definition) + (-> Text (List (Expression Any)) (Statement Any) (Operation (Expression Any))) + (case inits + #.Nil + (do ////.monad + [_ (///.save! ["" function-name] + function-definition)] + (wrap (_.apply/* (_.var function-name) inits))) + + _ + (do ////.monad + [@closure (:: @ map (|>> %n (format "closure") _.var) ///.next) + _ (///.save! ["" (_.code @closure)] + (_.def @closure + (|> (list.enumerate inits) + (list@map (|>> product.left ..capture))) + ($_ _.then + function-definition + (_.return (_.var function-name)))))] + (wrap (_.apply/* @closure inits))))) + +(def: @curried (_.var "curried")) + +(def: input + (|>> inc //case.register)) + +(def: #export (function generate [environment arity bodyS]) + (-> Phase (Abstraction Synthesis) (Operation (Expression Any))) + (do ////.monad + [[function-name bodyO] (///.with-context + (do @ + [function-name ///.context] + (///.with-anchor (_.var function-name) + (generate bodyS)))) + closureO+ (: (Operation (List (Expression Any))) + (monad.map @ (:: //reference.system variable) environment)) + #let [arityO (|> arity .int _.int) + @num-args (_.var "num_args") + @self (_.var function-name) + apply-poly (.function (_ args func) + (_.apply-poly (list) args func)) + initialize-self! (_.set (list (//case.register 0)) @self) + initialize! (list@fold (.function (_ post pre!) + ($_ _.then + pre! + (_.set (list (..input post)) (_.nth (|> post .int _.int) @curried)))) + initialize-self! + (list.indices arity))]] + (with-closure function-name closureO+ + (_.def @self (list) + ($_ _.then + (_.set (list @num-args) (_.len/1 @curried)) + (_.cond (list [(|> @num-args (_.= arityO)) + ($_ _.then + initialize! + (_.return bodyO))] + [(|> @num-args (_.> arityO)) + (let [arity-inputs (_.slice (_.int +0) arityO @curried) + extra-inputs (_.slice arityO @num-args @curried)] + (_.return (|> @self + (apply-poly arity-inputs) + (apply-poly extra-inputs))))]) + ## (|> @num-args (_.< arityO)) + (let [@next (_.var "next") + @missing (_.var "missing")] + ($_ _.then + (_.def @next (list (_.poly @missing)) + (_.return (|> @self (apply-poly (|> @curried (_.+ @missing)))))) + (_.return @next) + ))) + ))) + )) diff --git a/stdlib/source/lux/tool/compiler/phase/generation/python/loop.lux b/stdlib/source/lux/tool/compiler/phase/generation/python/loop.lux new file mode 100644 index 000000000..7666319bf --- /dev/null +++ b/stdlib/source/lux/tool/compiler/phase/generation/python/loop.lux @@ -0,0 +1,40 @@ +(.module: + [lux (#- Scope) + [control + ["." monad (#+ do)]] + [data + ["." product] + [text + format] + [collection + ["." list ("#@." functor)]]] + [host + ["_" python (#+ Expression)]]] + ["." // #_ + [runtime (#+ Operation Phase)] + ["#." case] + ["#/" // + ["#/" // + [// + [synthesis (#+ Scope Synthesis)]]]]]) + +(def: #export (scope generate [start initsS+ bodyS]) + (-> Phase (Scope Synthesis) (Operation (Expression Any))) + (do ////.monad + [@loop (:: @ map (|>> %n (format "loop") _.var) ///.next) + initsO+ (monad.map @ generate initsS+) + bodyO (///.with-anchor @loop + (generate bodyS)) + _ (///.save! ["" (_.code @loop)] + (_.def @loop (|> initsS+ + list.enumerate + (list@map (|>> product.left (n/+ start) //case.register))) + (_.return bodyO)))] + (wrap (_.apply/* @loop initsO+)))) + +(def: #export (recur generate argsS+) + (-> Phase (List Synthesis) (Operation (Expression Any))) + (do ////.monad + [@scope ///.anchor + argsO+ (monad.map @ generate argsS+)] + (wrap (_.apply/* @scope argsO+)))) diff --git a/stdlib/source/lux/tool/compiler/phase/generation/python/primitive.lux b/stdlib/source/lux/tool/compiler/phase/generation/python/primitive.lux new file mode 100644 index 000000000..1ddd3950e --- /dev/null +++ b/stdlib/source/lux/tool/compiler/phase/generation/python/primitive.lux @@ -0,0 +1,27 @@ +(.module: + [lux (#- i64) + [control + [pipe (#+ cond> new>)]] + [data + [number + ["." frac]]] + [host + ["_" python (#+ Expression)]]] + ["." // #_ + ["#." runtime]]) + +(def: #export bit + (-> Bit (Expression Any)) + _.bool) + +(def: #export i64 + (-> (I64 Any) (Expression Any)) + (|>> .int _.int)) + +(def: #export f64 + (-> Frac (Expression Any)) + _.float) + +(def: #export text + (-> Text (Expression Any)) + _.string) diff --git a/stdlib/source/lux/tool/compiler/phase/generation/python/reference.lux b/stdlib/source/lux/tool/compiler/phase/generation/python/reference.lux new file mode 100644 index 000000000..acc09c784 --- /dev/null +++ b/stdlib/source/lux/tool/compiler/phase/generation/python/reference.lux @@ -0,0 +1,11 @@ +(.module: + [lux #* + [host + ["_" python (#+ Expression)]]] + [// + [// + ["." reference]]]) + +(def: #export system + (reference.system (: (-> Text (Expression Any)) _.var) + (: (-> Text (Expression Any)) _.var))) diff --git a/stdlib/source/lux/tool/compiler/phase/generation/python/runtime.lux b/stdlib/source/lux/tool/compiler/phase/generation/python/runtime.lux new file mode 100644 index 000000000..fd847af16 --- /dev/null +++ b/stdlib/source/lux/tool/compiler/phase/generation/python/runtime.lux @@ -0,0 +1,392 @@ +(.module: + [lux (#- inc) + ["." function] + [control + [monad (#+ do)] + ["p" parser]] + [data + [number (#+ hex) + ["." i64]] + ["." text + format] + [collection + ["." list ("#@." functor)]]] + ["." macro + ["." code] + ["s" syntax (#+ syntax:)]] + [host + ["_" python (#+ Expression SVar Computation Literal Statement)]]] + ["." /// + ["//." // + [// + ["/////." name] + ["." synthesis]]]] + ) + +(do-template [<name> <base>] + [(type: #export <name> + (<base> SVar (Expression Any) (Statement Any)))] + + [Operation ///.Operation] + [Phase ///.Phase] + [Handler ///.Handler] + [Bundle ///.Bundle] + ) + +(def: #export variant-tag-field "_lux_tag") +(def: #export variant-flag-field "_lux_flag") +(def: #export variant-value-field "_lux_value") + +(def: prefix Text "LuxRuntime") + +(def: #export unit (_.string synthesis.unit)) + +(def: (flag value) + (-> Bit (Computation Any)) + (if value + (_.string "") + _.none)) + +(def: (variant' tag last? value) + (-> (Expression Any) (Expression Any) (Expression Any) (Computation Any)) + (_.dict (list [(_.string ..variant-tag-field) tag] + [(_.string ..variant-flag-field) last?] + [(_.string ..variant-value-field) value]))) + +(def: #export (variant tag last? value) + (-> Nat Bit (Expression Any) (Computation Any)) + (variant' (_.int (.int tag)) + (flag last?) + value)) + +(def: #export none + (Computation Any) + (..variant 0 #0 unit)) + +(def: #export some + (-> (Expression Any) (Computation Any)) + (..variant 1 #1)) + +(def: #export left + (-> (Expression Any) (Computation Any)) + (..variant 0 #0)) + +(def: #export right + (-> (Expression Any) (Computation Any)) + (..variant 1 #1)) + +(def: runtime-name + (-> Text SVar) + (|>> /////name.normalize + (format ..prefix "$") + _.var)) + +(def: (feature name definition) + (-> SVar (-> SVar (Statement Any)) (Statement Any)) + (_.def name (list) (definition name))) + +(syntax: #export (with-vars {vars (s.tuple (p.some s.local-identifier))} + body) + (wrap (list (` (let [(~+ (|> vars + (list@map (function (_ var) + (list (code.local-identifier var) + (` (_.var (~ (code.text (/////name.normalize var)))))))) + list.concat))] + (~ body)))))) + +(syntax: (runtime: {declaration (p.or s.local-identifier + (s.form (p.and s.local-identifier + (p.some s.local-identifier))))} + code) + (case declaration + (#.Left name) + (macro.with-gensyms [g!_] + (let [nameC (code.local-identifier name) + code-nameC (code.local-identifier (format "@" name)) + runtime-nameC (` (runtime-name (~ (code.text name))))] + (wrap (list (` (def: #export (~ nameC) SVar (~ runtime-nameC))) + (` (def: (~ code-nameC) + (Statement Any) + (..feature (~ runtime-nameC) + (function ((~ g!_) (~ nameC)) + (~ code))))))))) + + (#.Right [name inputs]) + (macro.with-gensyms [g!_] + (let [nameC (code.local-identifier name) + code-nameC (code.local-identifier (format "@" name)) + runtime-nameC (` (runtime-name (~ (code.text name)))) + inputsC (list@map code.local-identifier inputs) + inputs-typesC (list@map (function.constant (` (_.Expression Any))) + inputs)] + (wrap (list (` (def: #export ((~ nameC) (~+ inputsC)) + (-> (~+ inputs-typesC) (Computation Any)) + (_.apply/* (~ runtime-nameC) (list (~+ inputsC))))) + (` (def: (~ code-nameC) + (Statement Any) + (..feature (~ runtime-nameC) + (function ((~ g!_) (~ g!_)) + (..with-vars [(~+ inputsC)] + (_.def (~ g!_) (list (~+ inputsC)) + (~ code))))))))))))) + +(runtime: (lux//try op) + (with-vars [error value] + (_.try ($_ _.then + (_.set (list value) (_.apply/* op (list unit))) + (_.return (right value))) + (list [(list (_.var "Exception")) error + (_.return (left (_.str/1 error)))])))) + +(runtime: (lux//program-args program-args) + (with-vars [inputs value] + ($_ _.then + (_.set (list inputs) none) + (<| (_.for-in value program-args) + (_.set (list inputs) + (some (_.tuple (list value inputs))))) + (_.return inputs)))) + +(def: runtime//lux + (Statement Any) + ($_ _.then + @lux//try + @lux//program-args)) + +(runtime: (io//log! message) + ($_ _.then + (_.print message) + (_.return ..unit))) + +(runtime: (io//throw! message) + ($_ _.then + (_.raise (_.Exception/1 message)) + (_.return ..unit))) + +(runtime: (io//exit! code) + ($_ _.then + (_.import "sys") + (_.statement (|> (_.var "sys") (_.do "exit" (list code)))) + (_.return ..unit))) + +(runtime: (io//current-time! _) + ($_ _.then + (_.import "time") + (_.return (|> (_.var "time") + (_.do "time" (list)) + (_.* (_.int +1,000)) + _.int/1)))) + +(def: runtime//io + (Statement Any) + ($_ _.then + @io//log! + @io//throw! + @io//exit! + @io//current-time!)) + +(runtime: (product//left product index) + (with-vars [index-min-length] + ($_ _.then + (_.set (list index-min-length) (_.+ (_.int +1) index)) + (_.if (_.> index-min-length (_.len/1 product)) + ## No need for recursion + (_.return (_.nth index product)) + ## Needs recursion + (_.return (product//left (_.nth (_.- (_.int +1) + (_.len/1 product)) + product) + (_.- (_.len/1 product) + index-min-length))))))) + +(runtime: (product//right product index) + (with-vars [index-min-length] + ($_ _.then + (_.set (list index-min-length) (_.+ (_.int +1) index)) + (_.cond (list [(_.= index-min-length (_.len/1 product)) + ## Last element. + (_.return (_.nth index product))] + [(_.< index-min-length (_.len/1 product)) + ## Needs recursion + (_.return (product//right (_.nth (_.- (_.int +1) + (_.len/1 product)) + product) + (_.- (_.len/1 product) + index-min-length)))]) + ## Must slice + (_.return (_.slice-from index product)))))) + +(runtime: (sum//get sum wantedTag wantsLast) + (let [no-match! (_.return _.none) + sum-tag (_.nth (_.string ..variant-tag-field) sum) + sum-flag (_.nth (_.string ..variant-flag-field) sum) + sum-value (_.nth (_.string ..variant-value-field) sum) + is-last? (_.= (_.string "") sum-flag) + test-recursion! (_.if is-last? + ## Must recurse. + (_.return (sum//get sum-value (_.- sum-tag wantedTag) wantsLast)) + no-match!)] + (_.cond (list [(_.= sum-tag wantedTag) + (_.if (_.= wantsLast sum-flag) + (_.return sum-value) + test-recursion!)] + + [(_.> sum-tag wantedTag) + test-recursion!] + + [(_.and (_.< sum-tag wantedTag) + (_.= (_.string "") wantsLast)) + (_.return (variant' (_.- wantedTag sum-tag) sum-flag sum-value))]) + + no-match!))) + +(def: runtime//adt + (Statement Any) + ($_ _.then + @product//left + @product//right + @sum//get)) + +(def: full-64-bits + Literal + (_.manual "0xFFFFFFFFFFFFFFFF")) + +(runtime: (i64//64 input) + (with-vars [capped] + (_.cond (list [(|> input (_.> full-64-bits)) + (_.return (|> input (_.bit-and full-64-bits) i64//64))] + [(|> input (_.> (: Literal (_.manual "0x7FFFFFFFFFFFFFFF")))) + ($_ _.then + (_.set (list capped) + (_.int/1 (|> (: Literal (_.manual "0x10000000000000000")) + (_.- input)))) + (_.if (|> capped (_.<= (: Literal (_.manual "9223372036854775807L")))) + (_.return (|> capped (_.* (_.int -1)))) + (_.return (: Literal (_.manual "-9223372036854775808L")))))]) + (_.return input)))) + +(runtime: (i64//logic-right-shift param subject) + (let [mask (|> (_.int +1) + (_.bit-shl (_.- param (_.int +64))) + (_.- (_.int +1)))] + (_.return (|> subject + (_.bit-shr param) + (_.bit-and mask))))) + +(def: runtime//i64 + (Statement Any) + ($_ _.then + @i64//64 + @i64//logic-right-shift)) + +(runtime: (frac//decode input) + (with-vars [ex] + (_.try + (_.return (..some (_.float/1 input))) + (list [(list (_.var "Exception")) ex + (_.return ..none)])))) + +(def: runtime//frac + (Statement Any) + ($_ _.then + @frac//decode)) + +(runtime: (text//index subject param start) + (with-vars [idx] + ($_ _.then + (_.set (list idx) (|> subject (_.do "find" (list param start)))) + (_.if (_.= (_.int -1) idx) + (_.return ..none) + (_.return (..some idx)))))) + +(def: inc (|>> (_.+ (_.int +1)))) + +(do-template [<name> <top-cmp>] + [(def: (<name> top value) + (-> (Expression Any) (Expression Any) (Computation Any)) + (_.and (|> value (_.>= (_.int +0))) + (|> value (<top-cmp> top))))] + + [within? _.<] + [up-to? _.<=] + ) + +(runtime: (text//clip @text @from @to) + (with-vars [length] + ($_ _.then + (_.set (list length) (_.len/1 @text)) + (_.if ($_ _.and + (|> @to (within? length)) + (|> @from (up-to? @to))) + (_.return (..some (|> @text (_.slice @from (inc @to))))) + (_.return ..none))))) + +(runtime: (text//char text idx) + (_.if (|> idx (within? (_.len/1 text))) + (_.return (..some (_.ord/1 (|> text (_.slice idx (inc idx)))))) + (_.return ..none))) + +(def: runtime//text + (Statement Any) + ($_ _.then + @text//index + @text//clip + @text//char)) + +(def: (check-index-out-of-bounds array idx body!) + (-> (Expression Any) (Expression Any) (Statement Any) (Statement Any)) + (_.if (|> idx (_.<= (_.len/1 array))) + body! + (_.raise (_.Exception/1 (_.string "Array index out of bounds!"))))) + +(runtime: (array//get array idx) + (with-vars [temp] + (<| (check-index-out-of-bounds array idx) + ($_ _.then + (_.set (list temp) (_.nth idx array)) + (_.if (_.= _.none temp) + (_.return ..none) + (_.return (..some temp))))))) + +(runtime: (array//put array idx value) + (<| (check-index-out-of-bounds array idx) + ($_ _.then + (_.set (list (_.nth idx array)) value) + (_.return array)))) + +(def: runtime//array + (Statement Any) + ($_ _.then + @array//get + @array//put)) + +(runtime: (box//write value box) + ($_ _.then + (_.set (list (_.nth (_.int +0) box)) value) + (_.return ..unit))) + +(def: runtime//box + (Statement Any) + @box//write) + +(def: runtime + (Statement Any) + ($_ _.then + runtime//lux + runtime//adt + runtime//i64 + runtime//frac + runtime//text + runtime//array + runtime//box + runtime//io + )) + +(def: #export artifact ..prefix) + +(def: #export generate + (Operation Any) + (///.with-buffer + (do ////.monad + [_ (///.save! ["" ..prefix] ..runtime)] + (///.save-buffer! ..artifact)))) diff --git a/stdlib/source/lux/tool/compiler/phase/generation/python/structure.lux b/stdlib/source/lux/tool/compiler/phase/generation/python/structure.lux new file mode 100644 index 000000000..1415251df --- /dev/null +++ b/stdlib/source/lux/tool/compiler/phase/generation/python/structure.lux @@ -0,0 +1,36 @@ +(.module: + [lux #* + [control + ["." monad (#+ do)]] + [host + ["_" python (#+ Expression)]]] + ["." // #_ + ["#." runtime (#+ Operation Phase)] + ["#." primitive] + ["#//" /// + ["#/" // #_ + [analysis (#+ Variant Tuple)] + ["#." synthesis (#+ Synthesis)]]]]) + +(def: #export (tuple generate elemsS+) + (-> Phase (Tuple Synthesis) (Operation (Expression Any))) + (case elemsS+ + #.Nil + (:: ////.monad wrap (//primitive.text /////synthesis.unit)) + + (#.Cons singletonS #.Nil) + (generate singletonS) + + _ + (do ////.monad + [elemsT+ (monad.map @ generate elemsS+)] + (wrap (_.tuple elemsT+))))) + +(def: #export (variant generate [lefts right? valueS]) + (-> Phase (Variant Synthesis) (Operation (Expression Any))) + (:: ////.monad map + (//runtime.variant (if right? + (inc lefts) + lefts) + right?) + (generate valueS))) diff --git a/stdlib/source/lux/tool/compiler/phase/synthesis/case.lux b/stdlib/source/lux/tool/compiler/phase/synthesis/case.lux index 8dd7c342e..841846351 100644 --- a/stdlib/source/lux/tool/compiler/phase/synthesis/case.lux +++ b/stdlib/source/lux/tool/compiler/phase/synthesis/case.lux @@ -6,16 +6,17 @@ ["." monad (#+ do)]] [data ["." product] - ["." bit ("#;." equivalence)] - ["." text ("#;." equivalence) + ["." bit ("#@." equivalence)] + ["." text ("#@." equivalence) format] [number - ["." frac ("#;." equivalence)]] + ["." frac ("#@." equivalence)]] [collection - ["." list ("#;." fold monoid)]]]] - ["." /// ("#;." monad) + ["." list ("#@." functor fold monoid)] + ["." set (#+ Set)]]]] + ["." /// ("#@." monad) ["#/" // - ["#." reference] + ["#." reference (#+ Variable)] ["#." analysis (#+ Pattern Match Analysis)] ["/" synthesis (#+ Path Synthesis Operation Phase)]]]) @@ -33,7 +34,7 @@ (^template [<from> <to>] (<from> value) - (///;map (|>> (#/.Seq (#/.Test (|> value <to>)))) + (///@map (|>> (#/.Seq (#/.Test (|> value <to>)))) thenC)) ([#////analysis.Bit #/.Bit] [#////analysis.Nat (<| #/.I64 .i64)] @@ -48,23 +49,23 @@ thenC) (#////analysis.Complex (#////analysis.Variant [lefts right? value-pattern])) - (<| (///;map (|>> (#/.Seq (#/.Access (#/.Side (if right? + (<| (///@map (|>> (#/.Seq (#/.Access (#/.Side (if right? (#.Right lefts) (#.Left lefts))))))) (path' value-pattern end?) - (when> [(new> (not end?) [])] [(///;map ..clean-up)]) + (when> [(new> (not end?) [])] [(///@map ..clean-up)]) thenC) (#////analysis.Complex (#////analysis.Tuple tuple)) (let [tuple::last (dec (list.size tuple))] - (list;fold (function (_ [tuple::lefts tuple::member] nextC) + (list@fold (function (_ [tuple::lefts tuple::member] nextC) (let [right? (n/= tuple::last tuple::lefts) end?' (and end? right?)] - (<| (///;map (|>> (#/.Seq (#/.Access (#/.Member (if right? + (<| (///@map (|>> (#/.Seq (#/.Access (#/.Member (if right? (#.Right (dec tuple::lefts)) (#.Left tuple::lefts))))))) (path' tuple::member end?') - (when> [(new> (not end?') [])] [(///;map ..clean-up)]) + (when> [(new> (not end?') [])] [(///@map ..clean-up)]) nextC))) thenC (list.reverse (list.enumerate tuple)))) @@ -72,7 +73,7 @@ (def: #export (path synthesize pattern bodyA) (-> Phase Pattern Analysis (Operation Path)) - (path' pattern true (///;map (|>> #/.Then) (synthesize bodyA)))) + (path' pattern true (///@map (|>> #/.Then) (synthesize bodyA)))) (def: #export (weave leftP rightP) (-> Path Path Path) @@ -96,10 +97,10 @@ (if (<eq> leftV rightV) rightP <default>)) - ([#/.Bit bit;=] + ([#/.Bit bit@=] [#/.I64 "lux i64 ="] - [#/.F64 frac;=] - [#/.Text text;=]) + [#/.F64 frac@=] + [#/.Text text@=]) (^template [<access> <side>] [(#/.Access (<access> (<side> leftL))) @@ -157,14 +158,101 @@ list.reverse (case> (#.Cons [lastP lastA] prevsPA) [[lastP lastA] prevsPA] - + _ (undefined)))] (do @ [lastSP (path synthesize^ lastP lastA) prevsSP+ (monad.map @ (product.uncurry (path synthesize^)) prevsPA)] - (wrap (/.branch/case [inputS (list;fold weave lastSP prevsSP+)])))))] + (wrap (/.branch/case [inputS (list@fold weave lastSP prevsSP+)])))))] (case [headB tailB+] <let> <if> <case>)))) + +(def: #export (count-pops path) + (-> Path [Nat Path]) + (case path + (^ (/.path/seq #/.Pop path')) + (let [[pops post-pops] (count-pops path')] + [(inc pops) post-pops]) + + _ + [0 path])) + +(def: #export pattern-matching-error + "Invalid expression for pattern-matching.") + +(type: #export Storage + {#bindings (Set Variable) + #dependencies (Set Variable)}) + +(def: empty + Storage + {#bindings (set.new ////reference.hash) + #dependencies (set.new ////reference.hash)}) + +## TODO: Use this to declare all local variables at the beginning of +## script functions. +## That way, it should be possible to do cheap "let" expressions, +## since the variable will exist before hand so no closure will need +## to be created for it. +## Apply this trick to JS, Python et al. +(def: #export (storage path) + (-> Path Storage) + (loop for-path + [path path + path-storage ..empty] + (case path + (^ (/.path/bind register)) + (update@ #bindings (set.add (#////reference.Local register)) + path-storage) + + (^or (^ (/.path/seq left right)) + (^ (/.path/alt left right))) + (list@fold for-path path-storage (list left right)) + + (^ (/.path/then bodyS)) + (loop for-synthesis + [bodyS bodyS + synthesis-storage path-storage] + (case bodyS + (^ (/.variant [lefts right? valueS])) + (for-synthesis valueS synthesis-storage) + + (^ (/.tuple members)) + (list@fold for-synthesis synthesis-storage members) + + (#/.Reference (#////reference.Variable var)) + (if (set.member? (get@ #bindings synthesis-storage) var) + synthesis-storage + (update@ #dependencies (set.add var) synthesis-storage)) + + (^ (/.function/apply [functionS argsS])) + (list@fold for-synthesis synthesis-storage (#.Cons functionS argsS)) + + (^ (/.function/abstraction [environment arity bodyS])) + (list@fold (function (_ variable storage) + (for-synthesis (#/.Reference (#////reference.Variable variable)) + storage)) + synthesis-storage + environment) + + (^ (/.branch/let [inputS register exprS])) + (list@fold for-synthesis + (update@ #bindings (set.add (#////reference.Local register)) + synthesis-storage) + (list inputS exprS)) + + (^ (/.branch/case [inputS pathS])) + (|> synthesis-storage (for-synthesis inputS) (for-path pathS)) + + (#/.Extension [extension argsS]) + (list@fold for-synthesis synthesis-storage argsS) + + _ + synthesis-storage)) + + _ + path-storage + ))) diff --git a/stdlib/source/test/lux.lux b/stdlib/source/test/lux.lux index d0dc4f257..30abe1b37 100644 --- a/stdlib/source/test/lux.lux +++ b/stdlib/source/test/lux.lux @@ -40,14 +40,17 @@ [markdown (#+)]]] [host [js (#+)] + [python (#+)] [scheme (#+)]] [tool [compiler [phase [generation - [scheme (#+) - <host-modules>] [js (#+) + <host-modules>] + [python (#+) + <host-modules>] + [scheme (#+) <host-modules>]]]]] ## [control ## ["._" contract] |