From 0dd20865adaf872d63aea1037034d22a3b906aba Mon Sep 17 00:00:00 2001 From: Eduardo Julian Date: Thu, 4 Nov 2021 02:16:46 -0400 Subject: Ruby compilation that is compatible with DragonRuby. --- stdlib/source/library/lux/target/ruby.lux | 127 ++++++++++++--------- .../lux/phase/extension/generation/ruby/common.lux | 12 +- .../lux/phase/extension/generation/ruby/host.lux | 6 +- .../language/lux/phase/generation/ruby/case.lux | 78 ++++++------- .../lux/phase/generation/ruby/function.lux | 98 ++++++++-------- .../language/lux/phase/generation/ruby/runtime.lux | 21 +++- 6 files changed, 189 insertions(+), 153 deletions(-) (limited to 'stdlib') diff --git a/stdlib/source/library/lux/target/ruby.lux b/stdlib/source/library/lux/target/ruby.lux index 3a5ac1901..5d4971a0d 100644 --- a/stdlib/source/library/lux/target/ruby.lux +++ b/stdlib/source/library/lux/target/ruby.lux @@ -1,30 +1,30 @@ (.using - [library - [lux {"-" Location Code static int if cond function or and not comment local global symbol} - ["@" target] - [abstract - [equivalence {"+" Equivalence}] - [hash {"+" Hash}] - ["[0]" enum]] - [control - [pipe {"+" case> cond> new>}] - [parser - ["<[0]>" code]]] - [data - ["[0]" text - ["%" format {"+" format}]] - [collection - ["[0]" list ("[1]#[0]" functor mix)]]] - [macro - [syntax {"+" syntax:}] - ["[0]" template] - ["[0]" code]] - [math - [number - ["n" nat] - ["f" frac]]] - [type - abstract]]]) + [library + [lux {"-" Location Code static int if cond function or and not comment local global symbol} + ["@" target] + [abstract + [equivalence {"+" Equivalence}] + [hash {"+" Hash}] + ["[0]" enum]] + [control + [pipe {"+" case> cond> new>}] + [parser + ["<[0]>" code]]] + [data + ["[0]" text + ["%" format {"+" format}]] + [collection + ["[0]" list ("[1]#[0]" functor mix)]]] + [macro + [syntax {"+" syntax:}] + ["[0]" template] + ["[0]" code]] + [math + [number + ["n" nat] + ["f" frac]]] + [type + abstract]]]) (def: input_separator ", ") (def: statement_suffix ";") @@ -211,14 +211,35 @@ (text.enclosed ["{" "}"]) :abstraction)) - (def: .public (apply/* args func) - (-> (List Expression) Expression Computation) - (|> args - (list#each (|>> :representation)) - (text.interposed ..input_separator) - (text.enclosed ["(" ")"]) - (format (:representation func)) - :abstraction)) + (type: .public Input + (Variant + {#Arguments (List Expression)} + {#Block Statement})) + + (def: (control_structure content) + (-> Text Text) + (format content + text.new_line "end" ..statement_suffix)) + + (def: .public (apply/* input func) + (-> Input Expression Computation) + (case input + {#Arguments args} + (|> args + (list#each (|>> :representation)) + (text.interposed ..input_separator) + (text.enclosed ["(" ")"]) + (format (:representation func)) + :abstraction) + + {#Block body!} + (|> body! + :representation + ..nested + (format "do") + ..control_structure + (format (:representation func) " ") + :abstraction))) (def: .public (the field object) (-> Text Expression Access) @@ -260,26 +281,21 @@ (text.interposed ..input_separator)) " = " (:representation value) ..statement_suffix))) - (def: (block content) - (-> Text Text) - (format content - text.new_line "end" ..statement_suffix)) - (def: .public (if test then! else!) (-> Expression Statement Statement Statement) (<| :abstraction - ..block + ..control_structure (format "if " (:representation test) (..nested (:representation then!)) text.new_line "else" (..nested (:representation else!))))) - (template [ ] + (template [ ] [(def: .public ( test then!) (-> Expression Statement Statement) (<| :abstraction - ..block - (format " " (:representation test) + ..control_structure + (format " " (:representation test) (..nested (:representation then!)))))] [when "if"] @@ -289,7 +305,7 @@ (def: .public (for_in var array iteration!) (-> LVar Expression Statement Statement) (<| :abstraction - ..block + ..control_structure (format "for " (:representation var) " in " (:representation array) " do " @@ -304,7 +320,7 @@ (def: .public (begin body! rescues) (-> Statement (List Rescue) Statement) (<| :abstraction - ..block + ..control_structure (format "begin" (..nested (:representation body!)) (|> rescues (list#each (.function (_ [classes exception rescue]) @@ -316,7 +332,7 @@ (def: .public (catch expectation body!) (-> Expression Statement Statement) (<| :abstraction - ..block + ..control_structure (format "catch(" (:representation expectation) ") do" (..nested (:representation body!))))) @@ -343,7 +359,7 @@ (def: .public (function name args body!) (-> LVar (List LVar) Statement Statement) (<| :abstraction - ..block + ..control_structure (format "def " (:representation name) (|> args (list#each (|>> :representation)) @@ -412,13 +428,13 @@ (:representation on)))) ) -(def: .public (do method args object) - (-> Text (List Expression) Expression Computation) - (|> object (..the method) (..apply/* args))) +(def: .public (do method input object) + (-> Text Input Expression Computation) + (|> object (..the method) (..apply/* input))) (def: .public (apply_lambda/* args lambda) (-> (List Expression) Expression Computation) - (..do "call" args lambda)) + (..do "call" {#Arguments args} lambda)) (def: .public (cond clauses else!) (-> (List [Expression Statement]) Statement Statement) @@ -444,7 +460,7 @@ (template.spliced +)] (def: .public ( function ) (-> Expression Computation) - (..apply/* (.list ) function)) + (..apply/* {#Arguments (.list )} function)) (template [] [(`` (def: .public (~~ (template.symbol [ "/" ])) @@ -454,10 +470,13 @@ [1 [["print"] - ["require"]]] + ["include"] + ["require"] + ["defined?"]]] [2 - [["print"]]] + [["print"] + ["alias_method"]]] [3 [["print"]]] diff --git a/stdlib/source/library/lux/tool/compiler/language/lux/phase/extension/generation/ruby/common.lux b/stdlib/source/library/lux/tool/compiler/language/lux/phase/extension/generation/ruby/common.lux index 738405014..a32f4ad15 100644 --- a/stdlib/source/library/lux/tool/compiler/language/lux/phase/extension/generation/ruby/common.lux +++ b/stdlib/source/library/lux/tool/compiler/language/lux/phase/extension/generation/ruby/common.lux @@ -144,7 +144,7 @@ (|> /.empty (/.install "syntax char case!" lux::syntax_char_case!) (/.install "is" (binary (function (_ [reference subject]) - (_.do "equal?" (list reference) subject)))) + (_.do "equal?" {_.#Arguments (list reference)} subject)))) (/.install "try" (unary //runtime.lux//try)))) (def: (capped operation parameter subject) @@ -169,10 +169,10 @@ (/.install "*" (binary (product.uncurried (..capped _.*)))) (/.install "/" (binary (product.uncurried //runtime.i64//division))) (/.install "%" (binary (function (_ [parameter subject]) - (_.do "remainder" (list parameter) subject)))) + (_.do "remainder" {_.#Arguments (list parameter)} subject)))) (/.install "f64" (unary (_./ (_.float +1.0)))) - (/.install "char" (unary (_.do "chr" (list (_.string "UTF-8"))))) + (/.install "char" (unary (_.do "chr" {_.#Arguments (list (_.string "UTF-8"))}))) ))) (def: f64_procs @@ -184,11 +184,11 @@ (/.install "*" (binary (product.uncurried _.*))) (/.install "/" (binary (product.uncurried _./))) (/.install "%" (binary (function (_ [parameter subject]) - (_.do "remainder" (list parameter) subject)))) + (_.do "remainder" {_.#Arguments (list parameter)} subject)))) (/.install "=" (binary (product.uncurried _.=))) (/.install "<" (binary (product.uncurried _.<))) - (/.install "i64" (unary (_.do "floor" (list)))) - (/.install "encode" (unary (_.do "to_s" (list)))) + (/.install "i64" (unary (_.do "floor" {_.#Arguments (list)}))) + (/.install "encode" (unary (_.do "to_s" {_.#Arguments (list)}))) (/.install "decode" (unary //runtime.f64//decode))))) (def: (text//char [subjectO paramO]) diff --git a/stdlib/source/library/lux/tool/compiler/language/lux/phase/extension/generation/ruby/host.lux b/stdlib/source/library/lux/tool/compiler/language/lux/phase/extension/generation/ruby/host.lux index 92a23f403..99c008a2f 100644 --- a/stdlib/source/library/lux/tool/compiler/language/lux/phase/extension/generation/ruby/host.lux +++ b/stdlib/source/library/lux/tool/compiler/language/lux/phase/extension/generation/ruby/host.lux @@ -35,7 +35,7 @@ (def: (array::new [size]) (Unary Expression) - (_.do "new" (list size) (_.local "Array"))) + (_.do "new" {_.#Arguments (list size)} (_.local "Array"))) (def: array::length (Unary Expression) @@ -81,7 +81,7 @@ (do [! ////////phase.monad] [objectG (phase archive objectS) inputsG (monad.each ! (phase archive) inputsS)] - (in (_.do methodS inputsG objectG))))])) + (in (_.do methodS {_.#Arguments inputsG} objectG))))])) (template [ ] [(def: (Nullary Expression) (function.constant )) @@ -113,7 +113,7 @@ (do [! ////////phase.monad] [abstractionG (phase archive abstractionS) inputsG (monad.each ! (phase archive) inputsS)] - (in (_.apply/* inputsG abstractionG))))])) + (in (_.apply/* {_.#Arguments inputsG} abstractionG))))])) (def: ruby::import (custom diff --git a/stdlib/source/library/lux/tool/compiler/language/lux/phase/generation/ruby/case.lux b/stdlib/source/library/lux/tool/compiler/language/lux/phase/generation/ruby/case.lux index 499bc7c36..8b60ef65a 100644 --- a/stdlib/source/library/lux/tool/compiler/language/lux/phase/generation/ruby/case.lux +++ b/stdlib/source/library/lux/tool/compiler/language/lux/phase/generation/ruby/case.lux @@ -1,40 +1,40 @@ (.using - [library - [lux {"-" case let if symbol} - [abstract - ["[0]" monad {"+" do}]] - [control - [exception {"+" exception:}]] - [data - ["[0]" text - ["%" format {"+" format}]] - [collection - ["[0]" list ("[1]#[0]" functor mix)] - ["[0]" set]]] - [math - [number - ["n" nat] - ["i" int]]] - [target - ["_" ruby {"+" Expression LVar Statement}]]]] - ["[0]" // "_" - ["[1][0]" runtime {"+" Operation Phase Generator Phase! Generator!}] + [library + [lux {"-" case let if symbol} + [abstract + ["[0]" monad {"+" do}]] + [control + [exception {"+" exception:}]] + [data + ["[0]" text + ["%" format {"+" format}]] + [collection + ["[0]" list ("[1]#[0]" functor mix)] + ["[0]" set]]] + [math + [number + ["n" nat] + ["i" int]]] + [target + ["_" ruby {"+" Expression LVar Statement}]]]] + ["[0]" // "_" + ["[1][0]" runtime {"+" Operation Phase Generator Phase! Generator!}] + ["[1][0]" reference] + ["[1][0]" primitive] + ["/[1]" // "_" ["[1][0]" reference] - ["[1][0]" primitive] ["/[1]" // "_" - ["[1][0]" reference] + [synthesis + ["[0]" case]] ["/[1]" // "_" - [synthesis - ["[0]" case]] - ["/[1]" // "_" - ["[1][0]" synthesis {"+" Member Synthesis Path}] - ["[1][0]" generation] - ["//[1]" /// "_" - [reference - ["[1][0]" variable {"+" Register}]] - ["[1][0]" phase ("[1]#[0]" monad)] - [meta - [archive {"+" Archive}]]]]]]]) + ["[1][0]" synthesis {"+" Member Synthesis Path}] + ["[1][0]" generation] + ["//[1]" /// "_" + [reference + ["[1][0]" variable {"+" Register}]] + ["[1][0]" phase ("[1]#[0]" monad)] + [meta + [archive {"+" Archive}]]]]]]]) (def: .public (symbol prefix) (-> Text (Operation LVar)) @@ -107,11 +107,11 @@ (def: (push! value) (-> Expression Statement) - (_.statement (|> @cursor (_.do "push" (list value))))) + (_.statement (|> @cursor (_.do "push" {_.#Arguments (list value)})))) (def: peek_and_pop Expression - (|> @cursor (_.do "pop" (list)))) + (|> @cursor (_.do "pop" {_.#Arguments (list)}))) (def: pop! Statement @@ -124,18 +124,18 @@ (def: save! Statement (.let [cursor (_.array_range (_.int +0) (_.int -1) @cursor)] - (_.statement (|> @savepoint (_.do "push" (list cursor)))))) + (_.statement (|> @savepoint (_.do "push" {_.#Arguments (list cursor)}))))) (def: restore! Statement - (_.set (list @cursor) (|> @savepoint (_.do "pop" (list))))) + (_.set (list @cursor) (|> @savepoint (_.do "pop" {_.#Arguments (list)})))) (def: fail! _.break) (def: (multi_pop! pops) (-> Nat Statement) - (_.statement (_.do "slice!" (list (_.int (i.* -1 (.int pops))) - (_.int (.int pops))) + (_.statement (_.do "slice!" {_.#Arguments (list (_.int (i.* -1 (.int pops))) + (_.int (.int pops)))} @cursor))) (template [ ] diff --git a/stdlib/source/library/lux/tool/compiler/language/lux/phase/generation/ruby/function.lux b/stdlib/source/library/lux/tool/compiler/language/lux/phase/generation/ruby/function.lux index fd1962b3a..2053b6628 100644 --- a/stdlib/source/library/lux/tool/compiler/language/lux/phase/generation/ruby/function.lux +++ b/stdlib/source/library/lux/tool/compiler/language/lux/phase/generation/ruby/function.lux @@ -1,35 +1,35 @@ (.using - [library - [lux {"-" Variant Tuple function} - [abstract - ["[0]" monad {"+" do}]] - [data - ["[0]" product] - [text - ["%" format {"+" format}]] - [collection - ["[0]" list ("[1]#[0]" functor mix)]]] - [target - ["_" ruby {"+" LVar GVar Expression Statement}]]]] - ["[0]" // "_" - [runtime {"+" Operation Phase Generator Phase! Generator!}] + [library + [lux {"-" Variant Tuple function} + [abstract + ["[0]" monad {"+" do}]] + [data + ["[0]" product] + [text + ["%" format {"+" format}]] + [collection + ["[0]" list ("[1]#[0]" functor mix)]]] + [target + ["_" ruby {"+" LVar GVar Expression Statement}]]]] + ["[0]" // "_" + [runtime {"+" Operation Phase Generator Phase! Generator!}] + ["[1][0]" reference] + ["[1][0]" case] + ["[1][0]" loop] + ["/[1]" // "_" ["[1][0]" reference] - ["[1][0]" case] - ["[1][0]" loop] - ["/[1]" // "_" - ["[1][0]" reference] + ["//[1]" /// "_" + [analysis {"+" Variant Tuple Environment Abstraction Application Analysis}] + [synthesis {"+" Synthesis}] + ["[1][0]" generation {"+" Context}] ["//[1]" /// "_" - [analysis {"+" Variant Tuple Environment Abstraction Application Analysis}] - [synthesis {"+" Synthesis}] - ["[1][0]" generation {"+" Context}] - ["//[1]" /// "_" - [arity {"+" Arity}] - ["[1][0]" phase] - [reference - [variable {"+" Register Variable}]] - [meta - [archive {"+" Archive} - ["[0]" artifact]]]]]]]) + [arity {"+" Arity}] + ["[1][0]" phase] + [reference + [variable {"+" Register Variable}]] + [meta + [archive {"+" Archive} + ["[0]" artifact]]]]]]]) (def: .public (apply expression archive [functionS argsS+]) (Generator (Application Synthesis)) @@ -44,21 +44,21 @@ (def: (with_closure inits self function_definition) (-> (List Expression) Text Expression [Statement Expression]) - (case inits - {.#End} - (let [@self (_.global self)] + (let [@self (_.global self)] + (case inits + {.#End} [(_.set (list @self) function_definition) - @self]) + @self] - _ - (let [@self (_.local self)] - [(_.function @self - (|> (list.enumeration inits) - (list#each (|>> product.left ..capture))) - ($_ _.then - (_.set (list @self) function_definition) - (_.return @self))) - (_.apply/* inits @self)]))) + _ + [(_.set (list @self) (_.lambda {.#None} + (|> (list.enumeration inits) + (list#each (|>> product.left ..capture))) + (let [@self (_.local self)] + ($_ _.then + (_.set (list @self) function_definition) + (_.return @self))))) + (_.apply_lambda/* inits @self)]))) (def: input (|>> ++ //case.register)) @@ -75,7 +75,13 @@ arityO (|> arity .int _.int) limitO (|> arity -- .int _.int) @num_args (_.local "num_args") - @self (_.local function_name) + @self (: _.Location + (case closureO+ + {.#End} + (_.global function_name) + + _ + (_.local function_name))) initialize_self! (_.set (list (//case.register 0)) @self) initialize! (list#mix (.function (_ post pre!) ($_ _.then @@ -84,7 +90,7 @@ initialize_self! (list.indices arity)) [declaration instatiation] (with_closure closureO+ function_name - (_.lambda {.#Some @self} (list (_.variadic @curried)) + (_.lambda {.#None} (list (_.variadic @curried)) ($_ _.then (_.set (list @num_args) (_.the "length" @curried)) (_.cond (list [(|> @num_args (_.= arityO)) @@ -104,8 +110,8 @@ (_.return (_.lambda {.#None} (list (_.variadic @missing)) (_.return (|> @self (_.apply_lambda/* (list (_.splat (|> (_.array (list)) - (_.do "concat" (list @curried)) - (_.do "concat" (list @missing)))))))))))) + (_.do "concat" {_.#Arguments (list @curried)}) + (_.do "concat" {_.#Arguments (list @missing)}))))))))))) )))] _ (/////generation.execute! declaration) _ (/////generation.save! function_artifact {.#None} declaration)] diff --git a/stdlib/source/library/lux/tool/compiler/language/lux/phase/generation/ruby/runtime.lux b/stdlib/source/library/lux/tool/compiler/language/lux/phase/generation/ruby/runtime.lux index adf786058..e0c33442d 100644 --- a/stdlib/source/library/lux/tool/compiler/language/lux/phase/generation/ruby/runtime.lux +++ b/stdlib/source/library/lux/tool/compiler/language/lux/phase/generation/ruby/runtime.lux @@ -114,7 +114,8 @@ inputs)] (in (list (` (def: .public ((~ g!name) (~+ inputsC)) (-> (~+ inputs_typesC) Computation) - (_.apply/* (list (~+ inputsC)) (~ runtime_name)))) + (_.apply/* {_.#Arguments (list (~+ inputsC))} + (~ runtime_name)))) (` (def: (~ (code.local_symbol (format "@" name))) Statement @@ -303,7 +304,7 @@ ) (runtime: (i64//division parameter subject) - (let [extra (_.do "remainder" (list parameter) subject)] + (let [extra (_.do "remainder" {_.#Arguments (list parameter)} subject)] (_.return (|> subject (_.- extra) (_./ parameter))))) @@ -325,7 +326,7 @@ (with_vars [@input @temp] ($_ _.then (_.set (list @input) inputG) - (_.set (list @temp) (_.do "to_f" (list) @input)) + (_.set (list @temp) (_.do "to_f" {_.#Arguments (list)} @input)) (_.if ($_ _.or (_.not (_.= (_.float +0.0) @temp)) (_.= (_.string "0") @input) @@ -343,7 +344,7 @@ (runtime: (text//index subject param start) (with_vars [idx] ($_ _.then - (_.set (list idx) (|> subject (_.do "index" (list param start)))) + (_.set (list idx) (|> subject (_.do "index" {_.#Arguments (list param start)}))) (_.if (_.= _.nil idx) (_.return ..none) (_.return (..some idx)))))) @@ -360,7 +361,7 @@ (runtime: (text//char idx text) (_.if (|> idx (within? (_.the "length" text))) - (_.return (|> text (_.array_range idx idx) (_.do "ord" (list)))) + (_.return (|> text (_.array_range idx idx) (_.do "ord" {_.#Arguments (list)}))) (_.statement (_.raise (_.string "[Lux Error] Cannot get char from text."))))) (def: runtime//text @@ -385,6 +386,16 @@ (def: runtime Statement ($_ _.then + (_.when (_.and (_.not (_.do "method_defined?" {_.#Arguments (list (_.string "remainder"))} + (_.local "Numeric"))) + (_.do "method_defined?" {_.#Arguments (list (_.string "remainder_of_divide"))} + (_.local "Numeric"))) + ... We're in DragonRuby territory. + (_.statement + (_.do "class_eval" {_.#Block (_.statement + (_.alias_method/2 (_.string "remainder") + (_.string "remainder_of_divide")))} + (_.local "Numeric")))) runtime//adt runtime//lux runtime//i64 -- cgit v1.2.3