(.module: lux (lux (control ["ex" exception #+ exception:]) (data [bit] [maybe] ["e" error #+ Error] text/format (coll [array])) [host]) (luxc [lang] (lang (host [ruby #+ Ruby Expression Statement]))) [//]) (do-template [] [(exception: #export ( {message Text}) message)] [Not-A-Variant] [Unknown-Kind-Of-Host-Object] [Null-Has-No-Lux-Representation] [Cannot-Evaluate] ) (host.import: java/lang/Object (toString [] String) (getClass [] (Class Object))) (host.import: java/lang/Long (intValue [] Integer)) (host.import: org/jruby/RubyArray (getLength [] int) (get [int] #? Object)) (host.import: org/jruby/RubyHash (get [Object] #? Object)) (def: (tuple lux-object host-object) (-> (-> Object (Error Any)) RubyArray (Error Any)) (let [size (:coerce Nat (RubyArray::getLength [] host-object))] (loop [idx +0 output (:coerce (Array Any) (array.new size))] (if (n/< size idx) (case (RubyArray::get [(:coerce Int idx)] host-object) #.None (recur (inc idx) output) (#.Some value) (case (lux-object value) (#e.Error error) (#e.Error error) (#e.Success lux-value) (recur (inc idx) (array.write idx lux-value output)))) (#e.Success output))))) (def: (variant lux-object host-object) (-> (-> Object (Error Any)) RubyHash (Error Any)) (case [(RubyHash::get [(:coerce Object //.variant-tag-field)] host-object) (RubyHash::get [(:coerce Object //.variant-flag-field)] host-object) (RubyHash::get [(:coerce Object //.variant-value-field)] host-object)] (^multi [(#.Some tag) ?flag (#.Some value)] [(lux-object value) (#.Some value)]) (#e.Success [(Long::intValue [] (:coerce Long tag)) (: Any (case ?flag (#.Some _) "" #.None (host.null))) value]) _ (ex.throw Not-A-Variant ""))) (def: (lux-object host-object) (-> Object (Error Any)) (`` (cond (host.null? host-object) (ex.throw Null-Has-No-Lux-Representation "") (or (host.instance? java/lang/Boolean host-object) (host.instance? java/lang/Long host-object) (host.instance? java/lang/Double host-object) (host.instance? java/lang/String host-object)) (ex.return host-object) (host.instance? org/jruby/RubyArray host-object) (tuple lux-object (:coerce RubyArray host-object)) (host.instance? org/jruby/RubyHash host-object) (case (variant lux-object (:coerce RubyHash host-object)) (#e.Success value) (#e.Success value) _ (let [object-class (:coerce Text (Object::toString [] (Object::getClass [] (:coerce Object host-object)))) text-representation (:coerce Text (Object::toString [] (:coerce Object host-object)))] (ex.throw Unknown-Kind-Of-Host-Object (format object-class " --- " text-representation)))) ## else (let [object-class (:coerce Text (Object::toString [] (Object::getClass [] (:coerce Object host-object)))) text-representation (:coerce Text (Object::toString [] (:coerce Object host-object)))] (ex.throw Unknown-Kind-Of-Host-Object (format object-class " --- " text-representation))) ))) (def: #export (eval code) (-> Expression (Meta Any)) (function (_ compiler) (let [interpreter (|> compiler (get@ #.host) (:coerce //.Host) (get@ #//.interpreter))] (case (interpreter code) (#e.Error error) (exec (log! (format "eval #e.Error\n" "<< " code "\n" error)) ((lang.throw Cannot-Evaluate error) compiler)) (#e.Success output) (case (lux-object (:coerce Object output)) (#e.Success parsed-output) (exec ## (log! (format "eval #e.Success\n" ## "<< " code)) (#e.Success [compiler parsed-output])) (#e.Error error) (exec (log! (format "eval #e.Error\n" "<< " code "\n" error)) ((lang.throw Cannot-Evaluate error) compiler)))))))