(.module: lux (lux (control ["ex" exception #+ exception:] [monad #+ do]) (data [bit] [maybe] ["e" error #+ Error] [text "text/" Eq] text/format (coll [array])) [host]) (luxc [lang] (lang (host ["_" common-lisp #+ Expression]))) [//]) (host.import: java/lang/Object (toString [] String) (getClass [] (Class Object))) (host.import: java/lang/Long (intValue [] Integer)) (host.import: (java/lang/Class ?) (#static forName [String] #try (Class Object))) (def: _0 Any (case (Class::forName "org.armedbear.lisp.Symbol") (#e.Success _) (log! "LOADED") (#e.Error error) (log! error))) (do-template [] [(exception: #export ( {message Text}) message)] [Null-Has-No-Lux-Representation] [Cannot-Evaluate] [invalid-variant] ) (exception: #export (Unknown-Kind-Of-Host-Object {host-object Object}) (let [object-class (:coerce Text (Object::toString [] (Object::getClass [] (:coerce Object host-object)))) text-representation (:coerce Text (Object::toString [] (:coerce Object host-object)))] (format object-class " --- " text-representation))) (host.import: org/armedbear/lisp/LispObject) (host.import: org/armedbear/lisp/SimpleString (getStringValue [] String)) (host.import: org/armedbear/lisp/Symbol (#static T Symbol) (getName [] String)) (host.import: org/armedbear/lisp/DoubleFloat (doubleValue [] double)) (host.import: org/armedbear/lisp/Bignum (longValue [] long)) (host.import: org/armedbear/lisp/Fixnum (longValue [] long)) (host.import: org/armedbear/lisp/Nil) (host.import: org/armedbear/lisp/SimpleVector (length [] int) (elt [int] LispObject)) (def: (parse-tuple lux-object host-object) (-> (-> Object (Error Any)) SimpleVector (Error Any)) (let [size (:coerce Nat (SimpleVector::length [] host-object))] (loop [idx +0 output (:coerce (Array Any) (array.new size))] (if (n/< size idx) (case (lux-object (SimpleVector::elt [(:coerce Int idx)] host-object)) (#e.Error error) (#e.Error error) (#e.Success lux-value) (recur (inc idx) (array.write idx (:coerce Any lux-value) output))) (#e.Success output))))) (def: (variant tag flag value) (-> Nat Bit Any Any) [(Long::intValue [] (:coerce Long tag)) (: Any (if flag //.unit (host.null))) value]) (host.import: org/armedbear/lisp/Cons (car LispObject) (cdr LispObject)) (def: (parse-variant lux-object host-object) (-> (-> Object (Error Any)) Cons (Error Any)) (let [variant-tag (Cons::car host-object)] (if (and (host.instance? org/armedbear/lisp/Symbol variant-tag) (text/= //.variant-tag (Symbol::getName [] (:coerce Symbol variant-tag)))) (do e.Monad [#let [host-object (:coerce Cons (Cons::cdr host-object))] tag (lux-object (Cons::car host-object)) #let [host-object (:coerce Cons (Cons::cdr host-object))] #let [flag (host.instance? org/armedbear/lisp/SimpleString (Cons::car host-object))] value (lux-object (Cons::cdr host-object))] (wrap (..variant (:coerce Nat tag) flag value))) (ex.throw invalid-variant (:coerce Text (Object::toString [] (:coerce Object host-object))))))) (def: (lux-object host-object) (-> Object (Error Any)) (cond (host.instance? org/armedbear/lisp/Bignum host-object) (#e.Success (Bignum::longValue [] (:coerce Bignum host-object))) (host.instance? org/armedbear/lisp/Fixnum host-object) (#e.Success (Fixnum::longValue [] (:coerce Fixnum host-object))) (host.instance? org/armedbear/lisp/DoubleFloat host-object) (#e.Success (DoubleFloat::doubleValue [] (:coerce DoubleFloat host-object))) (host.instance? org/armedbear/lisp/Nil host-object) (#e.Success false) (host.instance? org/armedbear/lisp/Symbol host-object) (if (is? Symbol::T (:coerce Symbol host-object)) (#e.Success true) (ex.throw Unknown-Kind-Of-Host-Object (:coerce Object host-object))) (host.instance? org/armedbear/lisp/SimpleString host-object) (#e.Success (SimpleString::getStringValue [] (:coerce SimpleString host-object))) (host.instance? org/armedbear/lisp/SimpleVector host-object) (parse-tuple lux-object (:coerce SimpleVector host-object)) (host.instance? org/armedbear/lisp/Cons host-object) (parse-variant lux-object (:coerce Cons host-object)) ## else (ex.throw Unknown-Kind-Of-Host-Object (:coerce Object host-object)))) (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" "<< " (_.expression code) "\n" error)) ((lang.throw Cannot-Evaluate error) compiler)) (#e.Success output) (case (lux-object output) (#e.Success parsed-output) (#e.Success [compiler parsed-output]) (#e.Error error) (exec (log! (format "eval #e.Error\n" "<< " (_.expression code) "\n" error)) ((lang.throw Cannot-Evaluate error) compiler)))))))