From 787fc34a8f7c66746046a8ce0c16403cf6c2bf6c Mon Sep 17 00:00:00 2001 From: Eduardo Julian Date: Wed, 4 Apr 2018 00:56:16 -0400 Subject: - Initial Python back-end implementation. --- new-luxc/source/luxc/lang/host.jvm.lux | 2 +- new-luxc/source/luxc/lang/host/python.lux | 340 ++++++++++++ .../lang/translation/jvm/procedure/common.jvm.lux | 1 - new-luxc/source/luxc/lang/translation/python.lux | 208 ++++++++ .../luxc/lang/translation/python/case.jvm.lux | 265 ++++++++++ .../luxc/lang/translation/python/eval.jvm.lux | 146 ++++++ .../lang/translation/python/expression.jvm.lux | 82 +++ .../luxc/lang/translation/python/function.jvm.lux | 99 ++++ .../luxc/lang/translation/python/loop.jvm.lux | 36 ++ .../luxc/lang/translation/python/primitive.jvm.lux | 28 + .../luxc/lang/translation/python/procedure.jvm.lux | 28 + .../translation/python/procedure/common.jvm.lux | 572 ++++++++++++++++++++ .../lang/translation/python/procedure/host.jvm.lux | 89 ++++ .../luxc/lang/translation/python/reference.jvm.lux | 42 ++ .../luxc/lang/translation/python/runtime.jvm.lux | 583 +++++++++++++++++++++ .../luxc/lang/translation/python/statement.jvm.lux | 48 ++ .../luxc/lang/translation/python/structure.jvm.lux | 31 ++ .../luxc/lang/translation/ruby/primitive.jvm.lux | 6 +- 18 files changed, 2601 insertions(+), 5 deletions(-) create mode 100644 new-luxc/source/luxc/lang/host/python.lux create mode 100644 new-luxc/source/luxc/lang/translation/python.lux create mode 100644 new-luxc/source/luxc/lang/translation/python/case.jvm.lux create mode 100644 new-luxc/source/luxc/lang/translation/python/eval.jvm.lux create mode 100644 new-luxc/source/luxc/lang/translation/python/expression.jvm.lux create mode 100644 new-luxc/source/luxc/lang/translation/python/function.jvm.lux create mode 100644 new-luxc/source/luxc/lang/translation/python/loop.jvm.lux create mode 100644 new-luxc/source/luxc/lang/translation/python/primitive.jvm.lux create mode 100644 new-luxc/source/luxc/lang/translation/python/procedure.jvm.lux create mode 100644 new-luxc/source/luxc/lang/translation/python/procedure/common.jvm.lux create mode 100644 new-luxc/source/luxc/lang/translation/python/procedure/host.jvm.lux create mode 100644 new-luxc/source/luxc/lang/translation/python/reference.jvm.lux create mode 100644 new-luxc/source/luxc/lang/translation/python/runtime.jvm.lux create mode 100644 new-luxc/source/luxc/lang/translation/python/statement.jvm.lux create mode 100644 new-luxc/source/luxc/lang/translation/python/structure.jvm.lux (limited to 'new-luxc/source') diff --git a/new-luxc/source/luxc/lang/host.jvm.lux b/new-luxc/source/luxc/lang/host.jvm.lux index f22bf3302..58b79cfa4 100644 --- a/new-luxc/source/luxc/lang/host.jvm.lux +++ b/new-luxc/source/luxc/lang/host.jvm.lux @@ -183,4 +183,4 @@ (def: #export runtime-class Text "LuxRuntime") (def: #export function-class Text "LuxFunction") (def: #export runnable-class Text "LuxRunnable") -(def: #export unit Text "\u0000") +(def: #export unit Text "") diff --git a/new-luxc/source/luxc/lang/host/python.lux b/new-luxc/source/luxc/lang/host/python.lux new file mode 100644 index 000000000..335d418a3 --- /dev/null +++ b/new-luxc/source/luxc/lang/host/python.lux @@ -0,0 +1,340 @@ +(.module: + [lux #- not or and list if is] + (lux (control pipe) + (data [text] + text/format + [number] + (coll [list "list/" Functor Fold])) + (type abstract))) + +(abstract: #export Single {} Unit) +(abstract: #export Poly {} Unit) +(abstract: #export Keyword {} Unit) + +(abstract: #export (Var kind) + {} + + Text + + (def: name (All [k] (-> (Var k) Text)) (|>> @representation)) + + (def: #export var (-> Text (Var Single)) (|>> @abstraction)) + + (do-template [ ] + [(def: #export + (-> (Var Single) (Var )) + (|>> @representation (format ) @abstraction))] + + [poly Poly "*"] + [keyword Keyword "**"] + ) + ) + +(type: #export SVar (Var Single)) +(type: #export PVar (Var Poly)) +(type: #export KVar (Var Keyword)) + +(abstract: #export Expression + {} + + Text + + (def: #export expression (-> Expression Text) (|>> @representation)) + + (def: #export code (-> Text Expression) (|>> @abstraction)) + + (def: #export none + Expression + (@abstraction "None")) + + (def: #export bool + (-> Bool Expression) + (|>> (case> true "True" + false "False") + @abstraction)) + + (def: #export int + (-> Int Expression) + (|>> %i @abstraction)) + + (def: #export float + (-> Frac Expression) + (|>> (cond> [(f/= number.positive-infinity)] + [(new> "float(\"inf\")")] + + [(f/= number.negative-infinity)] + [(new> "float(\"-inf\")")] + + [(f/= number.not-a-number)] + [(new> "float(\"nan\")")] + + ## else + [%f]) + @abstraction)) + + (def: #export string + (-> Text Expression) + (|>> %t @abstraction)) + + (def: (composite-literal left-delimiter right-delimiter entry-serializer) + (All [a] (-> Text Text (-> a Text) + (-> (List a) Expression))) + (function [entries] + (@abstraction (format "(" left-delimiter + (|> entries (list/map entry-serializer) (text.join-with ",")) + right-delimiter ")")))) + + (do-template [
 ]
+    [(def: #export 
+       (-> (List Expression) Expression)
+       (composite-literal 
  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 [  ]
+    [(def: ( var)
+       (-> Expression Text)
+       (format  (@representation var)))]
+
+    [splat-poly    Poly    "*"]
+    [splat-keyword Keyword "**"]
+    )
+
+  (do-template [ ]
+    [(def: #export ( args extra func)
+       (-> (List Expression) Expression Expression Expression)
+       (@abstraction (format "(" (@representation func)
+                             (format "(" (|> args
+                                             (list/map (function [arg] (format (@representation arg) ", ")))
+                                             (text.join-with ""))
+                                     ( 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 [ ]
+    [(def: #export ( args extra method)
+       (-> (List Expression) Expression Text
+           (-> Expression Expression))
+       (|>> (field method) ( 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 [ ]
+    [(def: #export ( param subject)
+       (-> Expression Expression Expression)
+       (@abstraction (format "(" (@representation subject)
+                             " "  " "
+                             (@representation param) ")")))]
+
+    [is      "is"]
+    [=       "=="]
+    [<       "<"]
+    [<=      "<="]
+    [>       ">"]
+    [>=      ">="]
+    [+       "+"]
+    [-       "-"]
+    [*       "*"]
+    [/       "/"]
+    [%       "%"]
+    [**      "**"]
+    [bit-or  "|"]
+    [bit-and "&"]
+    [bit-xor "^"]
+    [bit-shl "<<"]
+    [bit-shr ">>"]
+    )
+
+  (do-template [ ]
+    [(def: #export ( param subject)
+       (-> Expression Expression Expression)
+       (@abstraction (format "(" (@representation param)
+                             " "  " "
+                             (@representation subject) ")")))]
+
+    [or      "or"]
+    [and     "and"]
+    )
+
+  (def: #export (not subject)
+    (-> Expression Expression)
+    (@abstraction (format "(not " (@representation subject) ")")))
+
+  (def: #export (@@ var)
+    (All [k] (-> (Var k) Expression))
+    (@abstraction (format "(" (..name var) ")")))
+
+  (def: #export (lambda arguments body)
+    (-> (List (Ex [k] (Var k))) Expression Expression)
+    (@abstraction (format "(" "lambda " (|> arguments (list/map ..name) (text.join-with ", ")) ": "
+                          (@representation body) ")")))
+
+  (def: #export global
+    (-> Text Expression)
+    (|>> var @@))
+
+  (def: #export (length sequence)
+    (-> Expression Expression)
+    (apply (.list sequence) (global "len")))
+  )
+
+(abstract: #export Statement
+  {}
+  
+  Text
+
+  (def: #export statement (-> Statement Text) (|>> @representation))
+
+  (def: nest
+    (-> Statement Text)
+    (|>> @representation
+         (format "\n")
+         (text.replace-all "\n" "\n  ")))
+
+  (def: #export (set-nth! idx value array)
+    (-> Expression Expression Expression Statement)
+    (@abstraction (format (expression array) "[" (expression idx) "] = " (expression value))))
+
+  (def: #export (set! vars value)
+    (-> (List (Var Single)) Expression Statement)
+    (@abstraction
+     (format (|> vars (list/map ..name) (text.join-with ", "))
+             " = "
+             (expression value))))
+
+  (def: #export (if! test then! else!)
+    (-> Expression Statement Statement Statement)
+    (@abstraction
+     (format "if " (expression test) ":"
+             (nest then!)
+             "\n" "else:"
+             (nest else!))))
+
+  (def: #export (when! test then!)
+    (-> Expression Statement Statement)
+    (@abstraction
+     (format "if " (expression test) ":"
+             (nest then!))))
+
+  (def: #export (cond! clauses else!)
+    (-> (List [Expression Statement]) Statement Statement)
+    (list/fold (.function [[test then!] next!]
+                 (if! test then! next!))
+               else!
+               (list.reverse clauses)))
+
+  (def: #export (then! pre! post!)
+    (-> Statement Statement Statement)
+    (@abstraction
+     (format (@representation pre!)
+             "\n"
+             (@representation post!))))
+
+  (def: #export (while! test body!)
+    (-> Expression Statement Statement)
+    (@abstraction
+     (format "while " (expression test) ":"
+             (nest body!))))
+
+  (def: #export (for-in! var inputs body!)
+    (-> SVar Expression Statement Statement)
+    (@abstraction
+     (format "for " (..name var) " in " (expression inputs) ":"
+             (nest body!))))
+
+  (def: #export (do! expression)
+    (-> Expression Statement)
+    (@abstraction
+     (format (..expression expression) ";")))
+
+  (def: #export no-op!
+    Statement
+    (@abstraction "\n"))
+
+  (type: #export Except
+    {#classes (List Text)
+     #exception SVar
+     #handler Statement})
+  
+  (def: #export (try! body! excepts)
+    (-> Statement (List Except) Statement)
+    (@abstraction
+     (format "try:"
+             (nest body!)
+             (|> excepts
+                 (list/map (function [[classes exception catch!]]
+                             (format "\n" "except (" (text.join-with "," classes)
+                                     ") as " (..name exception) ":"
+                                     (nest catch!))))
+                 (text.join-with "")))))
+
+  (do-template [ ]
+    [(def: #export ( message)
+       (-> Expression Statement)
+       (@abstraction
+        (format  " " (expression message))))]
+
+    [raise!  "raise"]
+    [return! "return"]
+    [print!  "print"]
+    )
+  
+  (def: #export (def! name args body)
+    (-> (Var Single) (List (Ex [k] (Var k))) Statement Statement)
+    (@abstraction
+     (format "def " (..name name)
+             "(" (|> args (list/map ..name) (text.join-with ",")) "):"
+             (nest body))))
+
+  (def: #export (import! module-name)
+    (-> Text Statement)
+    (@abstraction (format "import " module-name)))
+  )
diff --git a/new-luxc/source/luxc/lang/translation/jvm/procedure/common.jvm.lux b/new-luxc/source/luxc/lang/translation/jvm/procedure/common.jvm.lux
index 422d9da1d..abd2d49c8 100644
--- a/new-luxc/source/luxc/lang/translation/jvm/procedure/common.jvm.lux
+++ b/new-luxc/source/luxc/lang/translation/jvm/procedure/common.jvm.lux
@@ -381,7 +381,6 @@
 
   [text//size  "java.lang.String" "length"      lux-intI $t.int]
   [text//hash  "java.lang.Object" "hashCode"    lux-intI $t.int]
-  [text//trim  "java.lang.String" "trim"        id       $String]
   [text//upper "java.lang.String" "toUpperCase" id       $String]
   [text//lower "java.lang.String" "toLowerCase" id       $String]
   )
diff --git a/new-luxc/source/luxc/lang/translation/python.lux b/new-luxc/source/luxc/lang/translation/python.lux
new file mode 100644
index 000000000..7304ea560
--- /dev/null
+++ b/new-luxc/source/luxc/lang/translation/python.lux
@@ -0,0 +1,208 @@
+(.module:
+  lux
+  (lux (control ["ex" exception #+ exception:]
+                pipe
+                [monad #+ do])
+       (data [bit]
+             [maybe]
+             ["e" error #+ Error]
+             [text "text/" Eq]
+             text/format
+             (coll [array]))
+       [macro]
+       [io #+ IO Process io]
+       [host #+ class: interface: object]
+       (world [file #+ File]))
+  (luxc [lang]
+        (lang [".L" variable #+ Register]
+              (host [python #+ Expression Statement]))
+        [".C" io]))
+
+(host.import java/lang/Object)
+
+(host.import java/lang/String
+  (getBytes [String] #try (Array byte)))
+
+(host.import java/lang/CharSequence)
+
+(host.import java/lang/Appendable
+  (append [CharSequence] Appendable))
+
+(host.import java/lang/StringBuilder
+  (new [])
+  (toString [] String))
+
+(host.import org/python/core/PyObject)
+
+(host.import org/python/util/PythonInterpreter
+  (new [])
+  (exec [String] void)
+  (eval [String] PyObject))
+
+(type: #export Anchor [Text Register])
+
+(type: #export Host
+  {#context [Text Nat]
+   #anchor (Maybe Anchor)
+   #loader (-> Statement (Error Unit))
+   #interpreter (-> Expression (Error PyObject))
+   #module-buffer (Maybe StringBuilder)
+   #program-buffer StringBuilder})
+
+(def: #export init
+  (IO Host)
+  (io (let [interpreter (PythonInterpreter::new [])]
+        {#context ["" +0]
+         #anchor #.None
+         #loader (function [code]
+                   ("lux try" (io (PythonInterpreter::exec [(python.statement code)] interpreter))))
+         #interpreter (function [code]
+                        ("lux try" (io (PythonInterpreter::eval [(python.expression code)] interpreter))))
+         #module-buffer #.None
+         #program-buffer (StringBuilder::new [])})))
+
+(def: #export python-module-name Text "module.py")
+
+(def: #export init-module-buffer
+  (Meta Unit)
+  (function [compiler]
+    (#e.Success [(update@ #.host
+                          (|>> (:! Host)
+                               (set@ #module-buffer (#.Some (StringBuilder::new [])))
+                               (:! Void))
+                          compiler)
+                 []])))
+
+(exception: #export No-Active-Module-Buffer)
+(exception: #export Cannot-Execute)
+
+(def: #export (with-sub-context expr)
+  (All [a] (-> (Meta a) (Meta [Text a])))
+  (function [compiler]
+    (let [old (:! Host (get@ #.host compiler))
+          [old-name old-sub] (get@ #context old)
+          new-name (format old-name "___" (%i (nat-to-int old-sub)))]
+      (case (expr (set@ #.host
+                        (:! Void (set@ #context [new-name +0] old))
+                        compiler))
+        (#e.Success [compiler' output])
+        (#e.Success [(update@ #.host
+                              (|>> (:! Host)
+                                   (set@ #context [old-name (n/inc old-sub)])
+                                   (:! Void))
+                              compiler')
+                     [new-name output]])
+
+        (#e.Error error)
+        (#e.Error error)))))
+
+(def: #export context
+  (Meta Text)
+  (function [compiler]
+    (#e.Success [compiler
+                 (|> (get@ #.host compiler)
+                     (:! Host)
+                     (get@ #context)
+                     (let> [name sub]
+                           name))])))
+
+(def: #export (with-anchor anchor expr)
+  (All [a] (-> Anchor (Meta a) (Meta a)))
+  (function [compiler]
+    (let [old (:! Host (get@ #.host compiler))]
+      (case (expr (set@ #.host
+                        (:! Void (set@ #anchor (#.Some anchor) old))
+                        compiler))
+        (#e.Success [compiler' output])
+        (#e.Success [(update@ #.host
+                              (|>> (:! Host)
+                                   (set@ #anchor (get@ #anchor old))
+                                   (:! Void))
+                              compiler')
+                     output])
+
+        (#e.Error error)
+        (#e.Error error)))))
+
+(exception: #export No-Anchor)
+
+(def: #export anchor
+  (Meta Anchor)
+  (function [compiler]
+    (case (|> compiler (get@ #.host) (:! Host) (get@ #anchor))
+      (#.Some anchor)
+      (#e.Success [compiler anchor])
+
+      #.None
+      ((lang.throw No-Anchor "") compiler))))
+
+(def: #export module-buffer
+  (Meta StringBuilder)
+  (function [compiler]
+    (case (|> compiler (get@ #.host) (:! Host) (get@ #module-buffer))
+      #.None
+      ((lang.fail (No-Active-Module-Buffer "")) compiler)
+      
+      (#.Some module-buffer)
+      (#e.Success [compiler module-buffer]))))
+
+(def: #export program-buffer
+  (Meta StringBuilder)
+  (function [compiler]
+    (#e.Success [compiler (|> compiler (get@ #.host) (:! Host) (get@ #program-buffer))])))
+
+(do-template [   ]
+  [(def: ( code)
+     (->  (Meta ))
+     (function [compiler]
+       (let [runner (|> compiler (get@ #.host) (:! Host) (get@ ))]
+         (case (runner code)
+           (#e.Error error)
+           ((lang.fail (Cannot-Execute error)) compiler)
+           
+           (#e.Success output)
+           (#e.Success [compiler output])))))]
+
+  [load!     #loader      Statement  Unit]
+  [interpret #interpreter Expression PyObject]
+  )
+
+(exception: #export Unknown-Member)
+
+(def: #export variant-tag-field "_lux_tag")
+(def: #export variant-flag-field "_lux_flag")
+(def: #export variant-value-field "_lux_value")
+
+(def: #export unit Text "")
+
+(def: #export (definition-name [module name])
+  (-> Ident Text)
+  (lang.normalize-name (format module "$" name)))
+
+(do-template [    ]
+  [(def: #export ( code)
+     (->  (Meta ))
+     (do macro.Monad
+       [module-buffer module-buffer
+        #let [_ (Appendable::append [(:! CharSequence ( code))]
+                                    module-buffer)]]
+       ( code)))]
+
+  [save load!     python.statement  Statement  Unit]
+  [run  interpret python.expression Expression PyObject]
+  )
+
+(def: #export (save-module! target)
+  (-> File (Meta (Process Unit)))
+  (do macro.Monad
+    [module macro.current-module-name
+     module-buffer module-buffer
+     program-buffer program-buffer
+     #let [module-code (StringBuilder::toString [] module-buffer)
+           _ (Appendable::append [(:! CharSequence (format module-code "\n"))]
+                                 program-buffer)]]
+    (wrap (ioC.write target
+                     (format (lang.normalize-name module) "/" python-module-name)
+                     (|> module-code
+                         (String::getBytes ["UTF-8"])
+                         e.assume)))))
diff --git a/new-luxc/source/luxc/lang/translation/python/case.jvm.lux b/new-luxc/source/luxc/lang/translation/python/case.jvm.lux
new file mode 100644
index 000000000..2218c1994
--- /dev/null
+++ b/new-luxc/source/luxc/lang/translation/python/case.jvm.lux
@@ -0,0 +1,265 @@
+(.module:
+  lux
+  (lux (control [monad #+ do]
+                ["ex" exception #+ exception:])
+       (data [number]
+             [text]
+             text/format
+             (coll [list "list/" Functor Fold]
+                   [set #+ Set]))
+       [macro #+ "meta/" Monad]
+       (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
+    [valueO (translate valueS)
+     bodyO (translate bodyS)
+     #let [$register (referenceT.variable register)]]
+    (wrap (|> bodyO
+              (python.lambda (list $register))
+              (python.apply (list valueO))))))
+
+(def: #export (translate-record-get translate valueS pathP)
+  (-> (-> Synthesis (Meta Expression)) Synthesis (List [Nat Bool])
+      (Meta Expression))
+  (do macro.Monad
+    [valueO (translate valueS)]
+    (wrap (list/fold (function [[idx tail?] source]
+                       (let [method (if tail?
+                                      runtimeT.product//right
+                                      runtimeT.product//left)]
+                         (method source (python.int (:! Int idx)))))
+                     valueO
+                     pathP))))
+
+(def: #export (translate-if testO thenO elseO)
+  (-> Expression Expression Expression Expression)
+  (python.if testO thenO elseO))
+
+(def: $savepoint (python.var "pm_cursor_savepoint"))
+(def: $cursor (python.var "pm_cursor"))
+
+(def: (push-cursor! value)
+  (-> Expression Statement)
+  (python.do!
+   (python.send (list value)
+                "append" (@@ $cursor))))
+
+(def: save-cursor!
+  Statement
+  (python.do!
+   (python.send (list (python.slice-from (python.int 0) (@@ $cursor)))
+                "append" (@@ $savepoint))))
+
+(def: restore-cursor!
+  Statement
+  (python.set! (list $cursor)
+               (python.send (list) "pop" (@@ $savepoint))))
+
+(def: cursor-top
+  Expression
+  (python.nth (python.int -1) (@@ $cursor)))
+
+(def: pop-cursor!
+  Statement
+  (python.do!
+   (python.send (list) "pop" (@@ $cursor))))
+
+(def: pm-error (python.string "PM-ERROR"))
+
+(def: (new-Exception error)
+  (-> Expression Expression)
+  (python.apply (list pm-error) (python.global "Exception")))
+
+(def: fail-pm! (python.raise! (new-Exception pm-error)))
+
+(def: $temp (python.var "temp"))
+
+(exception: #export Unrecognized-Path)
+
+(def: $alt_error (python.var "alt_error"))
+
+(def: (pm-catch! handler!)
+  (-> Statement Except)
+  [(list "Exception") $alt_error
+   (python.if! (python.= pm-error (python.apply (list (@@ $alt_error)) (python.global "str")))
+               handler!
+               (python.raise! (@@ $alt_error)))])
+
+(def: (translate-pattern-matching' translate pathP)
+  (-> (-> Synthesis (Meta Expression)) Path (Meta Statement))
+  (case pathP
+    (^code ("lux case exec" (~ bodyS)))
+    (do macro.Monad
+      [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 [ ]
+      [_ ( value)]
+      (meta/wrap (python.when! (python.not (python.= (|> value ) cursor-top))
+                               fail-pm!)))
+    ([#.Nat  (<| python.int (:! Int))]
+     [#.Int  python.int]
+     [#.Deg  (<| python.int (:! Int))]
+     [#.Bool python.bool]
+     [#.Frac python.float]
+     [#.Text python.string])
+
+    (^template [ ]
+      (^code ( (~ [_ (#.Nat idx)])))
+      (meta/wrap (push-cursor! ( cursor-top (python.int (:! Int idx))))))
+    (["lux case tuple left" runtimeT.product//left]
+     ["lux case tuple right" runtimeT.product//right])
+
+    (^template [ ]
+      (^code ( (~ [_ (#.Nat idx)])))
+      (meta/wrap ($_ python.then!
+                     (python.set! (list $temp) (runtimeT.sum//get cursor-top (python.int (:! Int idx)) ))
+                     (python.if! (python.not (python.= python.none (@@ $temp)))
+                                 (push-cursor! (@@ $temp))
+                                 fail-pm!))))
+    (["lux case variant left" python.none]
+     ["lux case variant right" (python.string "")])
+
+    (^code ("lux case seq" (~ leftP) (~ rightP)))
+    (do macro.Monad
+      [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
+      [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
+    [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))
+
+(type: Storage
+  {#bindings (Set Variable)
+   #dependencies (Set Variable)})
+
+(def: (path-variables pathP)
+  (-> Path Storage)
+  (loop [pathP pathP
+         outer-variables {#bindings empty
+                          #dependencies empty}]
+    ## TODO: Remove (let [outer recur]) once loops can have names.
+    (let [outer recur]
+      (case pathP
+        (^code ("lux case bind" (~ [_ (#.Nat register)])))
+        (update@ #bindings (set.add (nat-to-int register))
+                 outer-variables)
+
+        (^or (^code ("lux case seq" (~ leftP) (~ rightP)))
+             (^code ("lux case alt" (~ leftP) (~ rightP))))
+        (list/fold outer outer-variables (list leftP rightP))
+
+        (^code ("lux case exec" (~ bodyS)))
+        (loop [bodyS bodyS
+               inner-variables outer-variables]
+          ## TODO: Remove (let [inner recur]) once loops can have names.
+          (let [inner recur]
+            (case bodyS
+              (^code ((~ [_ (#.Nat tag)]) (~ [_ (#.Bool last?)]) (~ valueS)))
+              (inner valueS inner-variables)
+
+              (^code [(~+ members)])
+              (list/fold inner inner-variables members)
+
+              (^ [_ (#.Form (list [_ (#.Int var)]))])
+              (if (set.member? (get@ #bindings inner-variables) var)
+                inner-variables
+                (update@ #dependencies (set.add var) inner-variables))
+
+              (^code ("lux call" (~ functionS) (~+ argsS)))
+              (list/fold inner inner-variables (#.Cons functionS argsS))
+
+              (^code ("lux function" (~ [_ (#.Nat arity)]) [(~+ environment)] (~ bodyS)))
+              (|> environment
+                  (list/map (|>> (list) code.form))
+                  (list/fold inner inner-variables))
+
+              (^code ("lux let" (~ [_ (#.Nat register)]) (~ inputS) (~ exprS)))
+              (list/fold inner (update@ #bindings (set.add (nat-to-int register))
+                                        inner-variables)
+                         (list inputS exprS))
+
+              (^code ("lux case" (~ inputS) (~ pathPS)))
+              (|> inner-variables (inner inputS) (outer pathPS))
+
+              (^code ((~ [_ (#.Text procedure)]) (~+ argsS)))
+              (list/fold inner inner-variables argsS)
+
+              _
+              inner-variables)))
+
+        _
+        outer-variables))))
+
+(def: generated-name
+  (-> Text (Meta SVar))
+  (|>> macro.gensym
+       (:: macro.Monad map (|>> %code
+                                      lang.normalize-name
+                                      python.var))))
+
+(def: #export (translate-case translate valueS pathP)
+  (-> (-> Synthesis (Meta Expression)) Synthesis Path (Meta Expression))
+  (do macro.Monad
+    [valueO (translate valueS)
+     $case (generated-name "case")
+     $value (generated-name "value")
+     #let [$dependencies+ (|> (path-variables pathP)
+                              (get@ #dependencies)
+                              set.to-list
+                              (list/map referenceT.local))
+           @dependencies+ (list/map @@ $dependencies+)]
+     pattern-matching! (translate-pattern-matching translate pathP)
+     _ (//.save (python.def! $case (list& $value $dependencies+)
+                             ($_ python.then!
+                                 (initialize-pattern-matching! (@@ $value))
+                                 pattern-matching!)))]
+    (wrap (python.apply (list& valueO @dependencies+) (@@ $case)))))
diff --git a/new-luxc/source/luxc/lang/translation/python/eval.jvm.lux b/new-luxc/source/luxc/lang/translation/python/eval.jvm.lux
new file mode 100644
index 000000000..bc6e1a342
--- /dev/null
+++ b/new-luxc/source/luxc/lang/translation/python/eval.jvm.lux
@@ -0,0 +1,146 @@
+(.module:
+  lux
+  (lux (control ["ex" exception #+ exception:])
+       (data [bit]
+             [maybe]
+             ["e" error #+ Error]
+             text/format
+             (coll [array]))
+       [host])
+  (luxc [lang]
+        (lang (host [python #+ Expression Statement])))
+  [//])
+
+(host.import java/lang/Object
+  (toString [] String)
+  (getClass [] (Class Object)))
+
+(host.import java/lang/Long
+  (intValue [] Integer))
+
+(host.import org/python/core/PyType
+  (getName [] String))
+
+(host.import org/python/core/PyString
+  (new [String]))
+
+(host.import org/python/core/PyObject
+  (asLong [] long)
+  (asDouble [] double)
+  (asString [] String)
+  (__nonzero__ [] boolean)
+  (__getitem__ [int] #try PyObject)
+  (__getitem__ #as __getitem__dict [PyObject] #try PyObject)
+  (__len__ [] int)
+  (getType [] PyType))
+
+(def: (tuple lux-object host-object)
+  (-> (-> PyObject (Error Top)) PyObject (Error Top))
+  (let [size (:! Nat (PyObject::__len__ [] host-object))]
+    (loop [idx +0
+           output (:! (Array Top) (array.new size))]
+      (if (n/< size idx)
+        (case (PyObject::__getitem__ [(:! Int idx)] host-object)
+          (#e.Error error)
+          (#e.Error error)
+          
+          (#e.Success value)
+          (case (lux-object value)
+            (#e.Error error)
+            (#e.Error error)
+
+            (#e.Success lux-value)
+            (recur (n/inc idx) (array.write idx lux-value output))))
+        (#e.Success output)))))
+
+(def: python-type
+  (-> PyObject Text)
+  (|>> (PyObject::getType []) (PyType::getName []) (:! Text)))
+
+(exception: #export Not-A-Variant)
+
+(def: tag-field (PyString::new [//.variant-tag-field]))
+(def: flag-field (PyString::new [//.variant-flag-field]))
+(def: value-field (PyString::new [//.variant-value-field]))
+
+(def: (variant lux-object host-object)
+  (-> (-> PyObject (Error Top)) PyObject (Error Top))
+  (case [(PyObject::__getitem__dict [tag-field] host-object)
+         (PyObject::__getitem__dict [flag-field] host-object)
+         (PyObject::__getitem__dict [value-field] host-object)]
+    (^or [(#e.Error error) _ _] [_ (#e.Error error) _] [_ _ (#e.Error error)])
+    (#e.Error error)
+    
+    (^multi [(#e.Success tag) (#e.Success flag) (#e.Success value)]
+            [(lux-object tag)
+             (#e.Success tag)]
+            [(lux-object value)
+             (#e.Success value)])
+    (#e.Success [(Long::intValue [] (:! Long tag))
+                 (: Top
+                    (case (python-type (:! PyObject flag))
+                      "NoneType"
+                      (host.null)
+
+                      _
+                      ""))
+                 value])
+
+    _
+    (ex.throw Not-A-Variant (Object::toString [] host-object))))
+
+(exception: #export Unknown-Kind-Of-Host-Object)
+(exception: #export Null-Has-No-Lux-Representation)
+
+(def: (lux-object host-object)
+  (-> PyObject (Error Top))
+  (case (python-type host-object)
+    "str"
+    (#e.Success (PyObject::asString [] host-object))
+    
+    "bool"
+    (#e.Success (PyObject::__nonzero__ [] host-object))
+
+    "float"
+    (#e.Success (PyObject::asDouble [] host-object))
+
+    (^or "int" "long")
+    (#e.Success (PyObject::asLong [] host-object))
+
+    "tuple"
+    (tuple lux-object host-object)
+
+    "dict"
+    (variant lux-object host-object)
+
+    "NoneType"
+    (#e.Success [])
+    
+    type
+    (ex.throw Unknown-Kind-Of-Host-Object (format type " " (Object::toString [] host-object)))))
+
+(exception: #export Cannot-Evaluate)
+
+(def: #export (eval code)
+  (-> Expression (Meta Top))
+  (function [compiler]
+    (let [interpreter (|> compiler (get@ #.host) (:! //.Host) (get@ #//.interpreter))]
+      (case (interpreter code)
+        (#e.Error error)
+        (exec (log! (format "eval #e.Error\n"
+                            "<< " (python.expression code) "\n"
+                            error))
+          ((lang.throw Cannot-Evaluate error) compiler))
+
+        (#e.Success output)
+        (case (lux-object output)
+          (#e.Success parsed-output)
+          (exec ## (log! (format "eval #e.Success\n"
+                ##               "<< " (python.expression code)))
+            (#e.Success [compiler parsed-output]))
+
+          (#e.Error error)
+          (exec (log! (format "eval #e.Error\n"
+                              "<< " (python.expression code) "\n"
+                              error))
+            ((lang.throw Cannot-Evaluate error) compiler)))))))
diff --git a/new-luxc/source/luxc/lang/translation/python/expression.jvm.lux b/new-luxc/source/luxc/lang/translation/python/expression.jvm.lux
new file mode 100644
index 000000000..6a7497c22
--- /dev/null
+++ b/new-luxc/source/luxc/lang/translation/python/expression.jvm.lux
@@ -0,0 +1,82 @@
+(.module:
+  lux
+  (lux (control [monad #+ do]
+                ["ex" exception #+ exception:]
+                ["p" parser])
+       (data ["e" error]
+             text/format)
+       [macro]
+       (macro ["s" syntax]))
+  (luxc ["&" lang]
+        (lang [".L" variable #+ Variable Register]
+              [".L" extension]
+              ["ls" synthesis]
+              (host [python #+ Expression Statement])))
+  [//]
+  (// [".T" runtime]
+      [".T" primitive]
+      [".T" structure]
+      [".T" function]
+      [".T" reference]
+      [".T" case]
+      [".T" procedure]))
+
+(exception: #export Invalid-Function-Syntax)
+(exception: #export Unrecognized-Synthesis)
+
+(def: #export (translate synthesis)
+  (-> ls.Synthesis (Meta Expression))
+  (case synthesis
+    (^code [])
+    (:: macro.Monad wrap runtimeT.unit)
+
+    (^code [(~ singleton)])
+    (translate singleton)
+
+    (^template [ ]
+      [_ ( value)]
+      ( value))
+    ([#.Bool primitiveT.translate-bool]
+     [#.Nat  primitiveT.translate-nat]
+     [#.Int  primitiveT.translate-int]
+     [#.Deg  primitiveT.translate-deg]
+     [#.Frac primitiveT.translate-frac]
+     [#.Text primitiveT.translate-text])
+
+    (^code ((~ [_ (#.Nat tag)]) (~ [_ (#.Bool last?)]) (~ valueS)))
+    (structureT.translate-variant translate tag last? valueS)
+
+    (^code [(~+ members)])
+    (structureT.translate-tuple translate members)
+
+    (^ [_ (#.Form (list [_ (#.Int var)]))])
+    (referenceT.translate-variable var)
+
+    [_ (#.Symbol definition)]
+    (referenceT.translate-definition definition)
+
+    (^code ("lux let" (~ [_ (#.Nat register)]) (~ inputS) (~ exprS)))
+    (caseT.translate-let translate register inputS exprS)
+
+    (^code ("lux case" (~ inputS) (~ pathPS)))
+    (caseT.translate-case translate inputS pathPS)
+
+    (^code ("lux function" (~ [_ (#.Nat arity)]) [(~+ environment)] (~ bodyS)))
+    (case (s.run environment (p.some s.int))
+      (#e.Success environment)
+      (functionT.translate-function translate environment arity bodyS)
+
+      _
+      (&.throw Invalid-Function-Syntax (%code synthesis)))
+
+    (^code ("lux call" (~ functionS) (~+ argsS)))
+    (functionT.translate-apply translate functionS argsS)
+
+    (^code ((~ [_ (#.Text procedure)]) (~+ argsS)))
+    (procedureT.translate-procedure translate procedure argsS)
+    ## (do macro.Monad
+    ##   [translation (extensionL.find-translation procedure)]
+    ##   (translation argsS))
+
+    _
+    (&.throw Unrecognized-Synthesis (%code synthesis))))
diff --git a/new-luxc/source/luxc/lang/translation/python/function.jvm.lux b/new-luxc/source/luxc/lang/translation/python/function.jvm.lux
new file mode 100644
index 000000000..97b936fc4
--- /dev/null
+++ b/new-luxc/source/luxc/lang/translation/python/function.jvm.lux
@@ -0,0 +1,99 @@
+(.module:
+  lux
+  (lux (control [monad #+ do]
+                pipe)
+       (data [product]
+             [text]
+             text/format
+             (coll [list "list/" Functor Fold]))
+       [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
+    [functionO (translate functionS)
+     argsO+ (monad.map @ translate argsS+)]
+    (wrap (python.apply argsO+ functionO))))
+
+(def: $curried (python.var "curried"))
+
+(def: (input-declaration register)
+  (python.set! (list (referenceT.variable (n/inc register)))
+               (python.nth (|> register nat-to-int python.int)
+                           (@@ $curried))))
+
+(def: (with-closure function-name inits function-definition)
+  (-> Text (List Expression) Statement (Meta Expression))
+  (let [$closure (python.var (format function-name "___CLOSURE"))]
+    (case inits
+      #.Nil
+      (do macro.Monad
+        [_ (//.save function-definition)]
+        (wrap (python.global function-name)))
+
+      _
+      (do macro.Monad
+        [_ (//.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
+    [[function-name bodyO] (//.with-sub-context
+                             (do @
+                               [function-name //.context]
+                               (//.with-anchor [function-name +1]
+                                 (translate bodyS))))
+     closureO+ (monad.map @ referenceT.translate-variable env)
+     #let [args-initsO+ (|> (list.n/range +0 (n/dec arity))
+                            (list/map input-declaration)
+                            (case> #.Nil
+                                   python.no-op!
+
+                                   (#.Cons head tail)
+                                   (list/fold python.then! head tail)))
+           arityO (|> arity nat-to-int python.int)
+           @curried (@@ $curried)
+           $num_args (python.var "num_args")
+           @num_args (@@ $num_args)
+           $function (python.var function-name)
+           @function (@@ $function)]]
+    (with-closure function-name closureO+
+      (python.def! $function (list (python.poly $curried))
+                   ($_ python.then!
+                       (let [@len (python.global "len")]
+                         (python.set! (list $num_args) (python.apply (list @curried) @len)))
+                       (python.if! (python.= arityO @num_args)
+                                   ($_ python.then!
+                                       (python.set! (list (referenceT.variable +0)) @function)
+                                       args-initsO+
+                                       (python.while! (python.bool true)
+                                                      (python.return! bodyO)))
+                                   (python.if! (python.> arityO @num_args)
+                                               (let [arity-args (python.slice (python.int 0) arityO @curried)
+                                                     output-func-args (python.slice arityO @num_args @curried)]
+                                                 (python.return! (|> @function
+                                                                     (python.apply-poly (list) arity-args)
+                                                                     (python.apply-poly (list) output-func-args))))
+                                               (let [$next (python.var "next")
+                                                     $missing (python.var "missing")]
+                                                 ($_ python.then!
+                                                     (python.def! $next (list (python.poly $missing))
+                                                                  (python.return! (|> @function
+                                                                                      (python.apply-poly (list) (|> @curried
+                                                                                                                    (python.+ (@@ $missing)))))))
+                                                     (python.return! (@@ $next)))))))))
+    ))
diff --git a/new-luxc/source/luxc/lang/translation/python/loop.jvm.lux b/new-luxc/source/luxc/lang/translation/python/loop.jvm.lux
new file mode 100644
index 000000000..e490033bf
--- /dev/null
+++ b/new-luxc/source/luxc/lang/translation/python/loop.jvm.lux
@@ -0,0 +1,36 @@
+(.module:
+  lux
+  (lux (control [monad #+ do])
+       (data [text]
+             text/format
+             (coll [list "list/" Functor]))
+       [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
+    [loop-name (|> (macro.gensym "loop")
+                   (:: @ map (|>> %code lang.normalize-name)))
+     initsO+ (monad.map @ translate initsS+)
+     bodyO (//.with-anchor [loop-name offset]
+             (translate bodyS))
+     #let [$loop-name (python.var loop-name)
+           @loop-name (@@ $loop-name)]
+     _ (//.save (python.def! $loop-name (|> (list.n/range +0 (n/dec (list.size initsS+)))
+                                            (list/map (|>> (n/+ offset) referenceT.variable)))
+                             (python.return! bodyO)))]
+    (wrap (python.apply initsO+ @loop-name))))
+
+(def: #export (translate-recur translate argsS+)
+  (-> (-> ls.Synthesis (Meta Expression)) (List ls.Synthesis)
+      (Meta Expression))
+  (do macro.Monad
+    [[loop-name offset] //.anchor
+     argsO+ (monad.map @ translate argsS+)]
+    (wrap (python.apply argsO+ (python.global loop-name)))))
diff --git a/new-luxc/source/luxc/lang/translation/python/primitive.jvm.lux b/new-luxc/source/luxc/lang/translation/python/primitive.jvm.lux
new file mode 100644
index 000000000..7b2ba1786
--- /dev/null
+++ b/new-luxc/source/luxc/lang/translation/python/primitive.jvm.lux
@@ -0,0 +1,28 @@
+(.module:
+  lux
+  (lux [macro "meta/" Monad])
+  (luxc (lang (host [python #+ Expression Statement]))))
+
+(def: #export translate-bool
+  (-> Bool (Meta Expression))
+  (|>> python.bool meta/wrap))
+
+(def: #export translate-int
+  (-> Int (Meta Expression))
+  (|>> python.int meta/wrap))
+
+(def: #export translate-nat
+  (-> Nat (Meta Expression))
+  (|>> (:! Int) python.int meta/wrap))
+
+(def: #export translate-deg
+  (-> Deg (Meta Expression))
+  (|>> (:! Int) python.int meta/wrap))
+
+(def: #export translate-frac
+  (-> Frac (Meta Expression))
+  (|>> python.float meta/wrap))
+
+(def: #export translate-text
+  (-> Text (Meta Expression))
+  (|>> python.string meta/wrap))
diff --git a/new-luxc/source/luxc/lang/translation/python/procedure.jvm.lux b/new-luxc/source/luxc/lang/translation/python/procedure.jvm.lux
new file mode 100644
index 000000000..a46778503
--- /dev/null
+++ b/new-luxc/source/luxc/lang/translation/python/procedure.jvm.lux
@@ -0,0 +1,28 @@
+(.module:
+  lux
+  (lux (control [monad #+ do]
+                ["ex" exception #+ exception:])
+       (data [maybe]
+             text/format
+             (coll [dict])))
+  (luxc ["&" lang]
+        (lang ["ls" synthesis]
+              (host [python #+ Expression Statement])))
+  [//]
+  (/ ["/." common]
+     ["/." host]))
+
+(exception: #export Unknown-Procedure)
+
+(def: procedures
+  /common.Bundle
+  (|> /common.procedures
+      (dict.merge /host.procedures)))
+
+(def: #export (translate-procedure translate name args)
+  (-> (-> ls.Synthesis (Meta Expression)) Text (List ls.Synthesis)
+      (Meta Expression))
+  (<| (maybe.default (&.throw Unknown-Procedure (%t name)))
+      (do maybe.Monad
+        [proc (dict.get name procedures)]
+        (wrap (proc translate args)))))
diff --git a/new-luxc/source/luxc/lang/translation/python/procedure/common.jvm.lux b/new-luxc/source/luxc/lang/translation/python/procedure/common.jvm.lux
new file mode 100644
index 000000000..6205d22a7
--- /dev/null
+++ b/new-luxc/source/luxc/lang/translation/python/procedure/common.jvm.lux
@@ -0,0 +1,572 @@
+(.module:
+  lux
+  (lux (control [monad #+ do]
+                ["ex" exception #+ exception:]
+                ["p" parser])
+       (data ["e" error]
+             [text]
+             text/format
+             [number]
+             (coll [list "list/" Functor]
+                   [dict #+ Dict]))
+       [macro #+ with-gensyms]
+       (macro [code]
+              ["s" syntax #+ syntax:])
+       [host])
+  (luxc ["&" lang]
+        (lang ["la" analysis]
+              ["ls" synthesis]
+              (host [python #+ Expression Statement])))
+  [///]
+  (/// [".T" runtime]
+       [".T" case]
+       [".T" function]
+       [".T" loop]))
+
+## [Types]
+(type: #export Translator
+  (-> ls.Synthesis (Meta Expression)))
+
+(type: #export Proc
+  (-> Translator (List ls.Synthesis) (Meta Expression)))
+
+(type: #export Bundle
+  (Dict Text Proc))
+
+(syntax: (Vector [size s.nat] elemT)
+  (wrap (list (` [(~+ (list.repeat size elemT))]))))
+
+(type: #export Nullary (-> (Vector +0 Expression) Expression))
+(type: #export Unary   (-> (Vector +1 Expression) Expression))
+(type: #export Binary  (-> (Vector +2 Expression) Expression))
+(type: #export Trinary (-> (Vector +3 Expression) Expression))
+(type: #export Variadic (-> (List Expression) Expression))
+
+## [Utils]
+(def: #export (install name unnamed)
+  (-> Text (-> Text Proc)
+      (-> Bundle Bundle))
+  (dict.put name (unnamed name)))
+
+(def: #export (prefix prefix bundle)
+  (-> Text Bundle Bundle)
+  (|> bundle
+      dict.entries
+      (list/map (function [[key val]] [(format prefix " " key) val]))
+      (dict.from-list text.Hash)))
+
+(def: (wrong-arity proc expected actual)
+  (-> Text Nat Nat Text)
+  (format "Wrong number of arguments for " (%t proc) "\n"
+          "Expected: " (|> expected nat-to-int %i) "\n"
+          "  Actual: " (|> actual nat-to-int %i)))
+
+(syntax: (arity: [name s.local-symbol] [arity s.nat])
+  (with-gensyms [g!proc g!name g!translate g!inputs]
+    (do @
+      [g!input+ (monad.seq @ (list.repeat arity (macro.gensym "input")))]
+      (wrap (list (` (def: #export ((~ (code.local-symbol name)) (~ g!proc))
+                       (-> (-> (..Vector (~ (code.nat arity)) Expression) Expression)
+                           (-> Text ..Proc))
+                       (function [(~ g!name)]
+                         (function [(~ g!translate) (~ g!inputs)]
+                           (case (~ g!inputs)
+                             (^ (list (~+ g!input+)))
+                             (do macro.Monad
+                               [(~+ (|> g!input+
+                                        (list/map (function [g!input]
+                                                    (list g!input (` ((~ g!translate) (~ g!input))))))
+                                        list.concat))]
+                               ((~' wrap) ((~ g!proc) [(~+ g!input+)])))
+
+                             (~' _)
+                             (macro.fail (wrong-arity (~ g!name) +1 (list.size (~ g!inputs))))))))))))))
+
+(arity: nullary +0)
+(arity: unary +1)
+(arity: binary +2)
+(arity: trinary +3)
+
+(def: #export (variadic proc)
+  (-> Variadic (-> Text Proc))
+  (function [proc-name]
+    (function [translate inputsS]
+      (do macro.Monad
+        [inputsI (monad.map @ translate inputsS)]
+        (wrap (proc inputsI))))))
+
+## [Procedures]
+## [[Lux]]
+(def: (lux//is [leftO rightO])
+  Binary
+  (python.is leftO rightO))
+
+(def: (lux//if [testO thenO elseO])
+  Trinary
+  (caseT.translate-if testO thenO elseO))
+
+(def: (lux//try riskyO)
+  Unary
+  (runtimeT.lux//try riskyO))
+
+(def: (lux//noop valueO)
+  Unary
+  valueO)
+
+(exception: #export Wrong-Syntax)
+(def: #export (wrong-syntax procedure args)
+  (-> Text (List ls.Synthesis) Text)
+  (format "Procedure: " procedure "\n"
+          "Arguments: " (%code (code.tuple args))))
+
+(def: lux//loop
+  (-> Text Proc)
+  (function [proc-name]
+    (function [translate inputsS]
+      (case (s.run inputsS ($_ p.seq s.nat (s.tuple (p.many s.any)) s.any))
+        (#e.Success [offset initsS+ bodyS])
+        (loopT.translate-loop translate offset initsS+ bodyS)
+
+        (#e.Error error)
+        (&.throw Wrong-Syntax (wrong-syntax proc-name inputsS)))
+      )))
+
+(def: lux//recur
+  (-> Text Proc)
+  (function [proc-name]
+    (function [translate inputsS]
+      (loopT.translate-recur translate inputsS))))
+
+(def: lux-procs
+  Bundle
+  (|> (dict.new text.Hash)
+      (install "noop" (unary lux//noop))
+      (install "is" (binary lux//is))
+      (install "try" (unary lux//try))
+      (install "if" (trinary lux//if))
+      (install "loop" lux//loop)
+      (install "recur" lux//recur)
+      ))
+
+## [[Bits]]
+(do-template [ ]
+  [(def: ( [subjectO paramO])
+     Binary
+     ( paramO subjectO))]
+
+  [bit//and python.bit-and]
+  [bit//or  python.bit-or]
+  [bit//xor python.bit-xor]
+  )
+
+(def: (bit//shift-left [subjectO paramO])
+  Binary
+  (|> (python.bit-shl paramO subjectO)
+      runtimeT.bit//64))
+
+(do-template [ ]
+  [(def: ( [subjectO paramO])
+     Binary
+     ( paramO subjectO))]
+
+  [bit//shift-right          python.bit-shr]
+  [bit//unsigned-shift-right runtimeT.bit//shift-right]
+  )
+
+(def: bit-procs
+  Bundle
+  (<| (prefix "bit")
+      (|> (dict.new text.Hash)
+          (install "count" (unary runtimeT.bit//count))
+          (install "and" (binary bit//and))
+          (install "or" (binary bit//or))
+          (install "xor" (binary bit//xor))
+          (install "shift-left" (binary bit//shift-left))
+          (install "unsigned-shift-right" (binary bit//unsigned-shift-right))
+          (install "shift-right" (binary bit//shift-right))
+          )))
+
+## [[Arrays]]
+(def: (array//new sizeO)
+  Unary
+  (|> python.none
+      list python.list
+      (python.* sizeO)))
+
+(def: (array//get [arrayO idxO])
+  Binary
+  (runtimeT.array//get arrayO idxO))
+
+(def: (array//put [arrayO idxO elemO])
+  Trinary
+  (runtimeT.array//put arrayO idxO elemO))
+
+(def: (array//remove [arrayO idxO])
+  Binary
+  (runtimeT.array//put arrayO idxO python.none))
+
+(def: array-procs
+  Bundle
+  (<| (prefix "array")
+      (|> (dict.new text.Hash)
+          (install "new" (unary array//new))
+          (install "get" (binary array//get))
+          (install "put" (trinary array//put))
+          (install "remove" (binary array//remove))
+          (install "size" (unary python.length))
+          )))
+
+## [[Numbers]]
+(host.import java/lang/Double
+  (#static MIN_VALUE Double)
+  (#static MAX_VALUE Double))
+
+(do-template [  ]
+  [(def: ( _)
+     Nullary
+     ( ))]
+
+  [nat//min                 0                           python.int]
+  [nat//max                -1                           python.int]
+
+  [frac//smallest          Double::MIN_VALUE            python.float]
+  [frac//min               (f/* -1.0 Double::MAX_VALUE) python.float]
+  [frac//max               Double::MAX_VALUE            python.float]
+
+  [deg//min                 0                           python.int]
+  [deg//max                -1                           python.int]
+  )
+
+(do-template [ ]
+  [(def: ( _)
+     Nullary
+     )]
+
+  [int//min (|> (python.int -2) (python.** (python.int 63)))]
+  [int//max (|> (python.int 2) (python.** (python.int 63)) (python.- (python.int 1)))]
+  )
+
+(do-template [