diff options
author | Eduardo Julian | 2019-02-13 18:44:02 -0400 |
---|---|---|
committer | Eduardo Julian | 2019-02-13 18:44:02 -0400 |
commit | c60426c60a137b454f6177dcb2d563a942dde75f (patch) | |
tree | 7459ca78a034157e0005dad440657842a5e14be6 /new-luxc/source/luxc | |
parent | 48f11e1d8394b516b778a0e76c5d29bf64492261 (diff) |
- WIP: Moved some of the JS compiler machinery over to stdlib.
- DRYed the reference translation machinery.
Diffstat (limited to '')
4 files changed, 0 insertions, 777 deletions
diff --git a/new-luxc/source/luxc/lang/translation/js/primitive.jvm.lux b/new-luxc/source/luxc/lang/translation/js/primitive.jvm.lux deleted file mode 100644 index e69291007..000000000 --- a/new-luxc/source/luxc/lang/translation/js/primitive.jvm.lux +++ /dev/null @@ -1,41 +0,0 @@ -(.module: - lux - (lux (control pipe) - (data [bit] - [number] - text/format) - [macro "meta/" Monad<Meta>]) - [//] - (// [".T" runtime]) - (luxc (lang (host [js #+ JS Expression Statement])))) - -(def: #export translate-bit - (-> Bit (Meta Expression)) - (|>> %b meta/wrap)) - -(def: low-mask Nat (dec (bit.left-shift +32 +1))) - -(def: #export (translate-int value) - (-> Int (Meta Expression)) - (let [high (|> value (bit.logical-right-shift +32) %i) - low (|> value (bit.and low-mask) %i)] - (meta/wrap (format runtimeT.int//new "(" high "," low ")")))) - -(def: #export translate-frac - (-> Frac (Meta Expression)) - (|>> (cond> [(f/= number.positive-infinity)] - [(new> "Infinity")] - - [(f/= number.negative-infinity)] - [(new> "-Infinity")] - - [(f/= number.not-a-number)] - [(new> "NaN")] - - ## else - [%f]) - meta/wrap)) - -(def: #export translate-text - (-> Text (Meta Expression)) - (|>> %t meta/wrap)) diff --git a/new-luxc/source/luxc/lang/translation/js/reference.jvm.lux b/new-luxc/source/luxc/lang/translation/js/reference.jvm.lux deleted file mode 100644 index 69a0075b1..000000000 --- a/new-luxc/source/luxc/lang/translation/js/reference.jvm.lux +++ /dev/null @@ -1,36 +0,0 @@ -(.module: - lux - (lux [macro] - (data [text] - text/format)) - (luxc ["&" lang] - (lang [".L" variable #+ Variable Register] - (host [js #+ JS Expression Statement]))) - [//] - (// [".T" runtime])) - -(do-template [<register> <translation> <prefix>] - [(def: #export (<register> register) - (-> Register Expression) - (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 (translate-variable var) - (-> Variable (Meta Expression)) - (if (variableL.captured? var) - (translate-captured (variableL.captured-register var)) - (translate-local (.nat var)))) - -(def: #export global - (-> Name Expression) - //.definition-name) - -(def: #export (translate-definition name) - (-> Name (Meta Expression)) - (:: macro.Monad<Meta> wrap (global name))) diff --git a/new-luxc/source/luxc/lang/translation/js/runtime.jvm.lux b/new-luxc/source/luxc/lang/translation/js/runtime.jvm.lux deleted file mode 100644 index af47bffce..000000000 --- a/new-luxc/source/luxc/lang/translation/js/runtime.jvm.lux +++ /dev/null @@ -1,669 +0,0 @@ -(.module: - lux - (lux (control [monad #+ do]) - (data text/format) - [macro] - (macro [code] - ["s" syntax #+ syntax:]) - [io #+ Process]) - [//] - (luxc (lang (host [js #+ JS Expression Statement])))) - -(def: prefix Text "LuxRuntime") - -(def: #export unit Expression (%t //.unit)) - -(def: (flag value) - (-> Bit JS) - (if value - (%t "") - "null")) - -(def: (variant' tag last? value) - (-> Expression Expression Expression Expression) - (js.object (list [//.variant-tag-field tag] - [//.variant-flag-field last?] - [//.variant-value-field value]))) - -(def: #export (variant tag last? value) - (-> Nat Bit Expression Expression) - (variant' (%i (.int tag)) (flag last?) value)) - -(def: none - Expression - (variant +0 #0 unit)) - -(def: some - (-> Expression Expression) - (variant +1 #1)) - -(def: left - (-> Expression Expression) - (variant +0 #0)) - -(def: right - (-> Expression Expression) - (variant +1 #1)) - -(type: Runtime JS) - -(def: (runtime-name name) - (-> Text Text) - (format prefix "$" name)) - -(def: (feature name definition) - (-> Text (-> Text Expression) Statement) - (format "var " name " = " (definition name) ";\n")) - -(syntax: (runtime-implementation-name {runtime-name s.local-identifier}) - (wrap (list (code.local-identifier (format "__" runtime-name))))) - -(template: (runtime: <lux-name> <js-name> <js-definition>) - (def: #export <lux-name> Text (runtime-name <js-name>)) - (`` (def: ((~' ~~) (runtime-implementation-name <lux-name>)) - Runtime - (feature <lux-name> - (function ((~' _) (~' @)) - <js-definition>))))) - -(def: #export (int value) - (-> Int Expression) - (format "({" - //.int-high-field " : " (|> value .nat //.high .int %i) - ", " - //.int-low-field " : " (|> value .nat //.low .int %i) - "})")) - -(def: #export frac - (-> Frac Expression) - js.number) - -(runtime: lux//try "runTry" - (format "(function " @ "(op) {" - (format "try {" - (format "return " (right "op(null)") ";") - "}" - "catch(ex) {" - (format "return " (left "ex.toString()") ";") - "}") - "})")) - -(runtime: lux//program-args "programArgs" - (format "(function " @ "() {" - (format "if(typeof process !== 'undefined' && process.argv) {" - (format (format "var result = " none ";") - "for(var idx = process.argv.length-1; idx >= 0; idx--) {" - (format "result = " (some "[process.argv[idx],result]") ";") - "}") - (format "return result;") - "}" - "else {" - (format "return " none ";") - "}") - "})")) - -(def: runtime//lux - Runtime - (format __lux//try - __lux//program-args)) - -(runtime: product//left "product_left" - (format "(function " @ "(product,index) {" - "var index_min_length = (index+1);" - "if(product.length > index_min_length) {" - ## No need for recursion - "return product[index];" - "}" - "else {" - ## Needs recursion - "return " @ "(product[product.length - 1], (index_min_length - product.length));" - "}" - "})")) - -(runtime: product//right "product_right" - (format "(function " @ "(product,index) {" - "var index_min_length = (index+1);" - "if(product.length === index_min_length) {" - ## Last element. - "return product[index];" - "}" - "else if(product.length < index_min_length) {" - ## Needs recursion - "return " @ "(product[product.length - 1], (index_min_length - product.length));" - "}" - "else {" - ## Must slice - "return product.slice(index);" - "}" - "})")) - -(runtime: sum//get "sum_get" - (let [no-match "return null;" - sum-tag (format "sum." //.variant-tag-field) - sum-flag (format "sum." //.variant-flag-field) - sum-value (format "sum." //.variant-value-field) - is-last? (format sum-flag " === ''") - extact-match (format "return " sum-value ";") - test-recursion (format "if(" is-last? ") {" - ## Must recurse. - "return " @ "(" sum-value ", (wantedTag - " sum-tag "), wantsLast);" - "}" - "else { " no-match " }")] - (format "(function " @ "(sum,wantedTag,wantsLast) {" - "if(wantedTag === " sum-tag ") {" - (format "if(" sum-flag " === wantsLast) {" extact-match "}" - "else {" test-recursion "}") - "}" - (format "else if(wantedTag > " sum-tag ") {" test-recursion "}") - (format "else if(wantedTag < " sum-tag " && wantsLast === '') {" - (let [updated-sum (variant' (format "(" sum-tag " - wantedTag)") sum-flag sum-value)] - (format "return " updated-sum ";")) - "}") - "else { " no-match " }" - "})"))) - -(def: runtime//adt - Runtime - (format __product//left - __product//right - __sum//get)) - -(runtime: int//new "makeI64" - (format "(function " @ "(high,low) {" - "return { H: (high|0), L: (low|0)};" - "})")) - -(runtime: int//2^16 "TWO_PWR_16" - "(1 << 16)") - -(runtime: int//2^32 "TWO_PWR_32" - (format "(" int//2^16 " * " int//2^16 ")")) - -(runtime: int//2^64 "TWO_PWR_64" - (format "(" int//2^32 " * " int//2^32 ")")) - -(runtime: int//2^63 "TWO_PWR_63" - (format "(" int//2^64 " / 2)")) - -(runtime: int//unsigned-low "getLowBitsUnsigned" - (format "(function " @ "(i64) {" - "return (i64.L >= 0) ? i64.L : (" int//2^32 " + i64.L);" - "})")) - -(runtime: int//to-number "toNumberI64" - (format "(function " @ "(i64) {" - "return (i64.H * " int//2^32 ") + " int//unsigned-low "(i64);" - "})")) - -(runtime: int//zero "ZERO" - "{ H: (0|0), L: (0|0)}") - -(runtime: int//min "MIN_VALUE_I64" - "{ H: (0x80000000|0), L: (0|0)}") - -(runtime: int//max "MAX_VALUE_I64" - "{ H: (0x7FFFFFFF|0), L: (0xFFFFFFFF|0)}") - -(runtime: int//one "ONE" - "{ H: (0|0), L: (1|0)}") - -(runtime: int//= "eqI64" - (format "(function " @ "(l,r) {" - "return (l.H === r.H) && (l.L === r.L);" - "})")) - -(runtime: int//+ "addI64" - (format "(function " @ "(l,r) {" - "var l48 = l.H >>> 16;" - "var l32 = l.H & 0xFFFF;" - "var l16 = l.L >>> 16;" - "var l00 = l.L & 0xFFFF;" - - "var r48 = r.H >>> 16;" - "var r32 = r.H & 0xFFFF;" - "var r16 = r.L >>> 16;" - "var r00 = r.L & 0xFFFF;" - - "var x48 = 0, x32 = 0, x16 = 0, x00 = 0;" - "x00 += l00 + r00;" - "x16 += x00 >>> 16;" - "x00 &= 0xFFFF;" - "x16 += l16 + r16;" - "x32 += x16 >>> 16;" - "x16 &= 0xFFFF;" - "x32 += l32 + r32;" - "x48 += x32 >>> 16;" - "x32 &= 0xFFFF;" - "x48 += l48 + r48;" - "x48 &= 0xFFFF;" - - "return " int//new "((x48 << 16) | x32, (x16 << 16) | x00);" - "})")) - -(template: (bit-operation: <lux-name> <js-name> <op>) - (runtime: <lux-name> <js-name> - (format "(function " (~' @) "(input,mask) {" - "return " int//new "(input.H " <op> " mask.H, input.L " <op> " mask.L);" - "})"))) - -(bit-operation: bit//and "andI64" "&") -(bit-operation: bit//or "orI64" "|") -(bit-operation: bit//xor "xorI64" "^") - -(runtime: bit//not "notI64" - (format "(function " @ "(i64) {" - "return " int//new "(~i64.H,~i64.L);" - "})")) - -(runtime: int//negate "negateI64" - (format "(function " @ "(i64) {" - (format "if(" int//= "(" int//min ",i64)) {" - "return " int//min ";" - "}") - (format "else {" - "return " int//+ "(" bit//not "(i64)," int//one ");" - "}") - "})")) - -(runtime: int//-one "NEG_ONE" - (js.apply int//negate (list int//one))) - -(runtime: int//from-number "fromNumberI64" - (format "(function " @ "(num) {" - (format "if(isNaN(num)) {" - "return " int//zero ";" - "}") - (format "else if(num <= -" int//2^63 ") {" - "return " int//min ";" - "}") - (format "else if((num + 1) >= " int//2^63 ") {" - "return " int//max ";" - "}") - (format "else if(num < 0) {" - "return " int//negate "(" @ "(-num));" - "}") - (format "else {" - "return " int//new "((num / " int//2^32 "), (num % " int//2^32 "));" - "}") - "})")) - -(runtime: bit//left-shift "shlI64" - (format "(function " @ "(input,shift) {" - "shift &= 63;" - (format "if(shift === 0) {" - "return input;" - "}" - "else {" - (format "if (shift < 32) {" - "var high = (input.H << shift) | (input.L >>> (32 - shift));" - "var low = input.L << shift;" - "return " int//new "(high, low);" - "}" - "else {" - "var high = (input.L << (shift - 32));" - "return " int//new "(high, 0);" - "}") - "}") - "})")) - -(runtime: bit//arithmetic-right-shift "shrI64" - (format "(function " @ "(input,shift) {" - "shift &= 63;" - (format "if(shift === 0) {" - "return input;" - "}" - "else {" - (format "if (shift < 32) {" - "var high = input.H >> shift;" - "var low = (input.L >>> shift) | (input.H << (32 - shift));" - "return " int//new "(high, low);" - "}" - "else {" - "var low = (input.H >> (shift - 32));" - "var high = input.H >= 0 ? 0 : -1;" - "return " int//new "(high, low);" - "}") - "}") - "})")) - -(runtime: bit//logical-right-shift "ushrI64" - (format "(function " @ "(input,shift) {" - "shift &= 63;" - (format "if(shift === 0) {" - "return input;" - "}" - "else {" - (format "if (shift < 32) {" - "var high = input.H >>> shift;" - "var low = (input.L >>> shift) | (input.H << (32 - shift));" - "return " int//new "(high, low);" - "}" - "else if(shift === 32) {" - "return " int//new "(0, input.H);" - "}" - "else {" - "var low = (input.H >>> (shift - 32));" - "return " int//new "(0, low);" - "}") - "}") - "})")) - -(def: runtime//bit - Runtime - (format __bit//and - __bit//or - __bit//xor - __bit//not - __bit//left-shift - __bit//arithmetic-right-shift - __bit//logical-right-shift)) - -(runtime: int//- "subI64" - (format "(function " @ "(l,r) {" - "return " int//+ "(l, " int//negate "(r));" - "})")) - -(runtime: int//* "mulI64" - (format "(function " @ "(l,r) {" - "if (l.H < 0) {" - (format "if (r.H < 0) {" - ## Both are negative - "return " @ "( " int//negate "(l), " int//negate "(r));" - "}" - "else {" - ## Left is negative - "return " int//negate "(" @ "( " int//negate "(l),r));" - "}") - "}" - "else if (r.H < 0) {" - ## Right is negative - "return " int//negate "(" @ "(l, " int//negate "(r)));" - "}" - ## Both are positive - "else {" - "var l48 = l.H >>> 16;" - "var l32 = l.H & 0xFFFF;" - "var l16 = l.L >>> 16;" - "var l00 = l.L & 0xFFFF;" - - "var r48 = r.H >>> 16;" - "var r32 = r.H & 0xFFFF;" - "var r16 = r.L >>> 16;" - "var r00 = r.L & 0xFFFF;" - - "var x48 = 0, x32 = 0, x16 = 0, x00 = 0;" - "x00 += l00 * r00;" - "x16 += x00 >>> 16;" - "x00 &= 0xFFFF;" - "x16 += l16 * r00;" - "x32 += x16 >>> 16;" - "x16 &= 0xFFFF;" - "x16 += l00 * r16;" - "x32 += x16 >>> 16;" - "x16 &= 0xFFFF;" - "x32 += l32 * r00;" - "x48 += x32 >>> 16;" - "x32 &= 0xFFFF;" - "x32 += l16 * r16;" - "x48 += x32 >>> 16;" - "x32 &= 0xFFFF;" - "x32 += l00 * r32;" - "x48 += x32 >>> 16;" - "x32 &= 0xFFFF;" - "x48 += (l48 * r00) + (l32 * r16) + (l16 * r32) + (l00 * r48);" - "x48 &= 0xFFFF;" - - "return " int//new "((x48 << 16) | x32, (x16 << 16) | x00);" - "}" - "})")) - -(runtime: int//< "ltI64" - (format "(function " @ "(l,r) {" - "var ln = l.H < 0;" - "var rn = r.H < 0;" - "if(ln && !rn) { return true; }" - "if(!ln && rn) { return false; }" - "return (" int//- "(l,r).H < 0);" - "})")) - -(def: (<I param subject) - (-> Expression Expression Expression) - (js.apply int//< (list subject param))) - -(def: (<=I param subject) - (-> Expression Expression Expression) - (js.or (js.apply int//< (list subject param)) - (js.apply int//= (list subject param)))) - -(def: (>I param subject) - (-> Expression Expression Expression) - (js.apply int//< (list param subject))) - -(def: (>=I param subject) - (-> Expression Expression Expression) - (js.or (js.apply int//< (list param subject)) - (js.apply int//= (list subject param)))) - -(def: (=I reference sample) - (-> Expression Expression Expression) - (js.apply int//= (list sample reference))) - -(runtime: int/// "divI64" - (let [negate (|>> (list) (js.apply int//negate)) - negative? (function (_ value) - (js.apply int//< (list value int//zero))) - valid-division-check [(=I int//zero "parameter") - (js.throw! (js.string "Cannot divide by zero!"))] - short-circuit-check [(=I int//zero "subject") - (js.return! int//zero)] - recur (function (_ subject parameter) - (js.apply @ (list subject parameter)))] - (js.function @ (list "subject" "parameter") - (list (js.cond! (list valid-division-check - short-circuit-check - - [(=I int//min "subject") - (js.cond! (list [(js.or (=I int//one "parameter") - (=I int//-one "parameter")) - (js.return! int//min)] - [(=I int//min "parameter") - (js.return! int//one)]) - (js.block! (list (js.var! "approximation" - (#.Some (js.apply bit//left-shift - (list (recur (js.apply bit//arithmetic-right-shift - (list "subject" (js.number 1.0))) - "parameter") - (js.number 1.0))))) - (js.if! (=I int//zero "approximation") - (js.return! (js.? (negative? "parameter") - int//one - int//-one)) - (let [remainder (js.apply int//- (list "subject" - (js.apply int//* (list "parameter" - "approximation")))) - result (js.apply int//+ (list "approximation" - (recur remainder - "parameter")))] - (js.return! result))))))] - [(=I int//min "parameter") - (js.return! int//zero)] - - [(negative? "subject") - (js.return! (js.? (negative? "parameter") - (recur (negate "subject") - (negate "parameter")) - (negate (recur (negate "subject") - "parameter"))))] - - [(negative? "parameter") - (js.return! (negate (recur "subject" (negate "parameter"))))]) - (js.block! (list (js.var! "result" (#.Some int//zero)) - (js.var! "remainder" (#.Some "subject")) - (js.while! (>=I "parameter" "remainder") - (let [rough-estimate (js.apply "Math.floor" (list (js./ (js.apply int//to-number (list "parameter")) - (js.apply int//to-number (list "remainder"))))) - log2 (js./ "Math.LN2" - (js.apply "Math.log" (list "approximate"))) - approx-result (js.apply int//from-number (list "approximate")) - approx-remainder (js.apply int//* (list "approximate_result" "parameter"))] - (list (js.var! "approximate" (#.Some (js.apply "Math.max" (list (js.number 1.0) - rough-estimate)))) - (js.var! "log2" (#.Some (js.apply "Math.ceil" (list log2)))) - (js.var! "delta" (#.Some (js.? (js.<= (js.number 48.0) "log2") - (js.number 1.0) - (js.apply "Math.pow" (list (js.number 2.0) - (js.- (js.number 48.0) - "log2")))))) - (js.var! "approximate_result" (#.Some approx-result)) - (js.var! "approximate_remainder" (#.Some approx-remainder)) - (js.while! (js.or (negative? "approximate_remainder") - (>I "remainder" - "approximate_remainder")) - (list (js.set! "approximate" (js.- "delta" "approximate")) - (js.set! "approximate_result" approx-result) - (js.set! "approximate_remainder" approx-remainder))) - (js.block! (list (js.set! "result" (js.apply int//+ (list "result" - (js.? (=I int//zero "approximate_result") - int//one - "approximate_result")))) - (js.set! "remainder" (js.apply int//- (list "remainder" "approximate_remainder")))))))) - (js.return! "result"))) - ))))) - -(runtime: int//% "remI64" - (js.function @ (list "subject" "parameter") - (list (let [flat (js.apply int//* (list (js.apply int/// (list "subject" "parameter")) - "parameter"))] - (js.return! (js.apply int//- (list "subject" flat))))))) - -(def: runtime//int - Runtime - (format __int//2^16 - __int//2^32 - __int//2^64 - __int//2^63 - __int//unsigned-low - __int//zero - __int//new - __int//min - __int//max - __int//one - __int//= - __int//+ - __int//negate - __int//to-number - __int//from-number - __int//- - __int//* - __int//< - __int/// - __int//%)) - -(runtime: text//index "index" - (format "(function " @ "(text,part,start) {" - "var idx = text.indexOf(part," int//to-number "(start));" - (format (format "if(idx === -1) {" - "return " none ";" - "}") - (format "else {" - (format "return " (some (format int//from-number "(idx)")) ";") - "}")) - "})")) - -(runtime: text//clip "clip" - (format "(function " @ "(text,from,to) {" - (format "if(from.L > text.length || to.L > text.length) {" - (format "return " none ";") - "}" - "else {" - (format "return " (some "text.substring(from.L,to.L)") ";") - "}") - "})")) - -(runtime: text//char "textChar" - (format "(function " @ "(text,idx) {" - "var result = text.charCodeAt(idx.L);" - (format "if(result === NaN) {" - (format "return " none ";") - "}" - "else {" - (format "return " (some (format int//from-number "(result)")) ";") - "}") - "})")) - -(def: runtime//text - Runtime - (format __text//index - __text//clip - __text//char)) - -(runtime: io//log "log" - (format "(function " @ "(message) {" - "if(typeof console !== \"undefined\" && console.log) { console.log(message); }" - "else if(typeof print !== \"undefined\") { print(message); }" - "return " unit ";" - "})")) - -(runtime: io//error "error" - (format "(function " @ "(message) {" - "throw new Error(message);" - "})")) - -(def: runtime//io - Runtime - (format __io//log - __io//error)) - -(runtime: js//get "jsGetField" - (format "(function " @ "(object, field) {" - "var temp = object[field];" - (format "if(temp !== undefined) {" - (format "return " (some "temp") ";") - "}" - "else {" - (format "return " none ";") - "}") - "})")) - -(runtime: js//set "jsSetField" - (format "(function " @ "(object, field, input) {" - "object[field] = input;" - "return object;" - "})")) - -(runtime: js//delete "jsDeleteField" - (format "(function " @ "(object, field) {" - "delete object[field];" - "return object;" - "})")) - -(runtime: js//call "jsObjectCall" - (format "(function " @ "(object, method, args) {" - "return object[method].apply(object, args);" - "})")) - -(def: runtime//js - Runtime - (format __js//get - __js//set - __js//delete - __js//call)) - -(def: runtime - Runtime - (format runtime//lux - runtime//adt - runtime//bit - runtime//int - runtime//text - runtime//io - runtime//js)) - -(def: #export artifact Text (format prefix ".js")) - -(def: #export translate - (Meta (Process Any)) - (do macro.Monad<Meta> - [_ //.init-module-buffer - _ (//.save-js runtime)] - (//.save-module! artifact))) diff --git a/new-luxc/source/luxc/lang/translation/js/structure.jvm.lux b/new-luxc/source/luxc/lang/translation/js/structure.jvm.lux deleted file mode 100644 index 580f48807..000000000 --- a/new-luxc/source/luxc/lang/translation/js/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 [js #+ JS 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 (format "[" (text.join-with "," 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)))) |