diff --git a/xo-expression/example/ex1/ex1.cpp b/xo-expression/example/ex1/ex1.cpp index 470941af..a8e6e72e 100644 --- a/xo-expression/example/ex1/ex1.cpp +++ b/xo-expression/example/ex1/ex1.cpp @@ -1,7 +1,7 @@ /** @file ex1.cpp **/ #include "xo/expression/Constant.hpp" -#include "xo/expression/Primitive.hpp" +#include "xo/expression/PrimitiveExpr.hpp" #include "xo/expression/llvmintrinsic.hpp" #include #include diff --git a/xo-expression/include/xo/expression/Primitive.hpp b/xo-expression/include/xo/expression/PrimitiveExpr.hpp similarity index 77% rename from xo-expression/include/xo/expression/Primitive.hpp rename to xo-expression/include/xo/expression/PrimitiveExpr.hpp index e53bbcb9..6050e8db 100644 --- a/xo-expression/include/xo/expression/Primitive.hpp +++ b/xo-expression/include/xo/expression/PrimitiveExpr.hpp @@ -1,4 +1,4 @@ -/** @file Primitive.hpp +/** @file PrimitiveExpr.hpp * * Author: Roland Conybeare **/ @@ -20,7 +20,7 @@ extern "C" { namespace xo { namespace scm { - /** @class Primitive + /** @class PrimitiveExpr * @brief syntax for a constant that refers to a known function. * * Two cases here: @@ -38,7 +38,7 @@ namespace xo { * won't work here. **/ template - class Primitive: public PrimitiveExprInterface { + class PrimitiveExpr: public PrimitiveExprInterface { public: using Reflect = xo::reflect::Reflect; using TaggedPtr = xo::reflect::TaggedPtr; @@ -46,13 +46,13 @@ namespace xo { using fptr_type = FunctionPointer; public: - static rp make(const std::string & name, + static rp make(const std::string & name, FunctionPointer fnptr, bool explicit_symbol_def, llvmintrinsic intrinsic) { TypeDescr fn_type = Reflect::require(); - return new Primitive(fn_type, name, fnptr, explicit_symbol_def, intrinsic); + return new PrimitiveExpr(fn_type, name, fnptr, explicit_symbol_def, intrinsic); } /** see classes below for intrinsics **/ @@ -68,7 +68,7 @@ namespace xo { return TaggedPtr(value_td_, erased_ptr); } - // ----- PrimitiveInterface ----- + // ----- PrimitiveExprInterface ----- virtual llvmintrinsic intrinsic() const override { return intrinsic_; } virtual bool explicit_symbol_def() const override { return explicit_symbol_def_; } @@ -84,7 +84,7 @@ namespace xo { // ----- Expression ----- virtual void display(std::ostream & os) const override { - os << "value_td()->short_name()) << xtag("value", this->value()) @@ -99,14 +99,14 @@ namespace xo { * we don't have pretty printer for native function pointers anyway * + simplifies ppdetail_atomic */ - return ppii.pps()->pretty_struct(ppii, "Primitive", + return ppii.pps()->pretty_struct(ppii, "PrimitiveExpr", refrtag("name", name_), rtag("type", print::quot(this->valuetype()->short_name())), refrtag("value", (void*)(this->value()))); } private: - Primitive(TypeDescr fn_type, + PrimitiveExpr(TypeDescr fn_type, const std::string & name, FunctionPointer fnptr, bool explicit_symbol_def, @@ -119,9 +119,9 @@ namespace xo { intrinsic_{intrinsic} { if (!value_td_->is_function()) - throw std::runtime_error("Primitive: expected function pointer"); + throw std::runtime_error("PrimitiveExpr: expected function pointer"); if (!value_td_->fn_retval()) - throw std::runtime_error("Primitive: expected non-null function return value"); + throw std::runtime_error("PrimitiveExpr: expected non-null function return value"); } @@ -145,75 +145,75 @@ namespace xo { * all others: generate direct use of LLVM intrinsic **/ llvmintrinsic intrinsic_; - }; /*Primitive*/ + }; /*PrimitiveExpr*/ /** adopt function @p x as a callable primitive function named @p name **/ template - rp> + rp> make_primitive(const std::string & name, FunctionPointer x, bool explicit_symbol_def, llvmintrinsic intrinsic) { - return Primitive::make(name, x, explicit_symbol_def, intrinsic); + return PrimitiveExpr::make(name, x, explicit_symbol_def, intrinsic); } // NOTE: see xo-reader/src/reader/progress_xs.cpp // binding operators to primitive applications. /** builtin primitives :: i64 x i64 -> bool **/ - class Primitive_cmp_i64 : public Primitive { + class PrimitiveExpr_cmp_i64 : public PrimitiveExpr { public: - using PrimitiveType = Primitive; + using PrimitiveExprType = PrimitiveExpr; public: /** eq2_i64: compare two 64-bit integers for equality **/ - static rp make_cmp_eq2_i64(); + static rp make_cmp_eq2_i64(); /** ne2_i64: compare two 64-bit integers for inequality **/ - static rp make_cmp_ne2_i64(); + static rp make_cmp_ne2_i64(); /** lt2_i64: compare two 64-bit integers for lessthan **/ - static rp make_cmp_lt2_i64(); + static rp make_cmp_lt2_i64(); /** lt2_i64: compare two 64-bit integers for lessthanorequal **/ - static rp make_cmp_le2_i64(); + static rp make_cmp_le2_i64(); /** gt2_i64: compare two 64-bit integers for greaterthan **/ - static rp make_cmp_gt2_i64(); + static rp make_cmp_gt2_i64(); /** ge2_i64: compare two 64-bit integers for greaterthan **/ - static rp make_cmp_ge2_i64(); + static rp make_cmp_ge2_i64(); }; /** builtin primitives :: i64 x i64 -> i64 **/ - class Primitive_i64 : public Primitive { + class PrimitiveExpr_i64 : public PrimitiveExpr { public: - using PrimitiveType = Primitive; + using PrimitiveExprType = PrimitiveExpr; public: /** add2_i64: add two 64-bit integers **/ - static rp make_add2_i64(); + static rp make_add2_i64(); /** sub2_i64: subtract two 64-bit integers **/ - static rp make_sub2_i64(); + static rp make_sub2_i64(); /** mul2_i64: multiply two 64-bit integers **/ - static rp make_mul2_i64(); + static rp make_mul2_i64(); /** div2_i64: divide two 64-bit integers **/ - static rp make_div2_i64(); + static rp make_div2_i64(); }; /** builtin primitives :: f64 x f64 -> f64 **/ - class Primitive_f64 : public Primitive { + class PrimitiveExpr_f64 : public PrimitiveExpr { public: - using PrimitiveType = Primitive; + using PrimitiveExprType = PrimitiveExpr; public: /** add2_f64: add two 64-bit floating-point numbers **/ - static rp make_add2_f64(); + static rp make_add2_f64(); /** sub2_f64: subtract two 64-bit floating-point numbers **/ - static rp make_sub2_f64(); + static rp make_sub2_f64(); /** mul2_f64: multiply two 64-bit floating-point numbers **/ - static rp make_mul2_f64(); + static rp make_mul2_f64(); /** div2_f64: divide two 64-bit floating-point numbers **/ - static rp make_div2_f64(); + static rp make_div2_f64(); }; } /*namespace scm*/ } /*namespace xo*/ -/** end Primitive.hpp **/ +/** end PrimitiveExpr.hpp **/ diff --git a/xo-expression/src/expression/Apply.cpp b/xo-expression/src/expression/Apply.cpp index 1a205b86..7ab1089c 100644 --- a/xo-expression/src/expression/Apply.cpp +++ b/xo-expression/src/expression/Apply.cpp @@ -1,7 +1,7 @@ /* @file Apply.cpp */ #include "Apply.hpp" -#include "Primitive.hpp" +#include "PrimitiveExpr.hpp" #include "exprtype.hpp" #include "pretty_expression.hpp" #include "xo/indentlog/print/vector.hpp" @@ -36,7 +36,7 @@ namespace xo { Apply::make_cmp_eq_i64(const rp & lhs, const rp & rhs) { - return Apply::make(Primitive_cmp_i64::make_cmp_eq2_i64(), + return Apply::make(PrimitiveExpr_cmp_i64::make_cmp_eq2_i64(), {lhs, rhs}); } @@ -44,7 +44,7 @@ namespace xo { Apply::make_cmp_ne_i64(const rp & lhs, const rp & rhs) { - return Apply::make(Primitive_cmp_i64::make_cmp_ne2_i64(), + return Apply::make(PrimitiveExpr_cmp_i64::make_cmp_ne2_i64(), {lhs, rhs}); } @@ -52,7 +52,7 @@ namespace xo { Apply::make_cmp_lt_i64(const rp & lhs, const rp & rhs) { - return Apply::make(Primitive_cmp_i64::make_cmp_lt2_i64(), + return Apply::make(PrimitiveExpr_cmp_i64::make_cmp_lt2_i64(), {lhs, rhs}); } @@ -60,7 +60,7 @@ namespace xo { Apply::make_cmp_le_i64(const rp & lhs, const rp & rhs) { - return Apply::make(Primitive_cmp_i64::make_cmp_le2_i64(), + return Apply::make(PrimitiveExpr_cmp_i64::make_cmp_le2_i64(), {lhs, rhs}); } @@ -68,7 +68,7 @@ namespace xo { Apply::make_cmp_gt_i64(const rp & lhs, const rp & rhs) { - return Apply::make(Primitive_cmp_i64::make_cmp_gt2_i64(), + return Apply::make(PrimitiveExpr_cmp_i64::make_cmp_gt2_i64(), {lhs, rhs}); } @@ -76,7 +76,7 @@ namespace xo { Apply::make_cmp_ge_i64(const rp & lhs, const rp & rhs) { - return Apply::make(Primitive_cmp_i64::make_cmp_ge2_i64(), + return Apply::make(PrimitiveExpr_cmp_i64::make_cmp_ge2_i64(), {lhs, rhs}); } @@ -86,7 +86,7 @@ namespace xo { Apply::make_add2_i64(const rp & lhs, const rp & rhs) { - return Apply::make(Primitive_i64::make_add2_i64(), + return Apply::make(PrimitiveExpr_i64::make_add2_i64(), {lhs, rhs}); } @@ -94,7 +94,7 @@ namespace xo { Apply::make_sub2_i64(const rp & lhs, const rp & rhs) { - return Apply::make(Primitive_i64::make_sub2_i64(), + return Apply::make(PrimitiveExpr_i64::make_sub2_i64(), {lhs, rhs}); } @@ -102,7 +102,7 @@ namespace xo { Apply::make_mul2_i64(const rp & lhs, const rp & rhs) { - return Apply::make(Primitive_i64::make_mul2_i64(), + return Apply::make(PrimitiveExpr_i64::make_mul2_i64(), {lhs, rhs}); } @@ -110,7 +110,7 @@ namespace xo { Apply::make_div2_i64(const rp & lhs, const rp & rhs) { - return Apply::make(Primitive_i64::make_div2_i64(), + return Apply::make(PrimitiveExpr_i64::make_div2_i64(), {lhs, rhs}); } @@ -120,7 +120,7 @@ namespace xo { Apply::make_add2_f64(const rp & lhs, const rp & rhs) { - return Apply::make(Primitive_f64::make_add2_f64(), + return Apply::make(PrimitiveExpr_f64::make_add2_f64(), {lhs, rhs}); } @@ -128,7 +128,7 @@ namespace xo { Apply::make_sub2_f64(const rp & lhs, const rp & rhs) { - return Apply::make(Primitive_f64::make_sub2_f64(), + return Apply::make(PrimitiveExpr_f64::make_sub2_f64(), {lhs, rhs}); } @@ -136,7 +136,7 @@ namespace xo { Apply::make_mul2_f64(const rp & lhs, const rp & rhs) { - return Apply::make(Primitive_f64::make_mul2_f64(), + return Apply::make(PrimitiveExpr_f64::make_mul2_f64(), {lhs, rhs}); } @@ -144,7 +144,7 @@ namespace xo { Apply::make_div2_f64(const rp & lhs, const rp & rhs) { - return Apply::make(Primitive_f64::make_div2_f64(), + return Apply::make(PrimitiveExpr_f64::make_div2_f64(), {lhs, rhs}); } diff --git a/xo-expression/src/expression/CMakeLists.txt b/xo-expression/src/expression/CMakeLists.txt index d2a9a7e1..a07efea3 100644 --- a/xo-expression/src/expression/CMakeLists.txt +++ b/xo-expression/src/expression/CMakeLists.txt @@ -14,7 +14,7 @@ set(SELF_SRCS GlobalSymtab.cpp LocalSymtab.cpp ConvertExpr.cpp - Primitive.cpp + PrimitiveExpr.cpp typeinf/type_ref.cpp typeinf/type_unifier.cpp typeinf/TypeBlueprint.cpp diff --git a/xo-expression/src/expression/Primitive.cpp b/xo-expression/src/expression/PrimitiveExpr.cpp similarity index 68% rename from xo-expression/src/expression/Primitive.cpp rename to xo-expression/src/expression/PrimitiveExpr.cpp index 4a69ef8e..09246a62 100644 --- a/xo-expression/src/expression/Primitive.cpp +++ b/xo-expression/src/expression/PrimitiveExpr.cpp @@ -1,6 +1,6 @@ -/* @file Primitive.cpp */ +/* @file PrimitiveExpr.cpp */ -#include "Primitive.hpp" +#include "PrimitiveExpr.hpp" #include extern "C" { @@ -86,12 +86,12 @@ extern "C" { namespace xo { namespace scm { auto - Primitive_cmp_i64::make_cmp_eq2_i64() -> rp + PrimitiveExpr_cmp_i64::make_cmp_eq2_i64() -> rp { - static rp s_retval; + static rp s_retval; if (!s_retval) - s_retval = Primitive::make("cmp_eq2_i64", + s_retval = PrimitiveExpr::make("cmp_eq2_i64", &cmp_eq2_i64, true /*explicit_symbol_def*/, llvmintrinsic::i_eq); @@ -100,12 +100,12 @@ namespace xo { } auto - Primitive_cmp_i64::make_cmp_ne2_i64() -> rp + PrimitiveExpr_cmp_i64::make_cmp_ne2_i64() -> rp { - static rp s_retval; + static rp s_retval; if (!s_retval) - s_retval = Primitive::make("cmp_ne2_i64", + s_retval = PrimitiveExpr::make("cmp_ne2_i64", &cmp_ne2_i64, true /*explicit_symbol_def*/, llvmintrinsic::i_ne); @@ -114,12 +114,12 @@ namespace xo { } auto - Primitive_cmp_i64::make_cmp_lt2_i64() -> rp + PrimitiveExpr_cmp_i64::make_cmp_lt2_i64() -> rp { - static rp s_retval; + static rp s_retval; if (!s_retval) - s_retval = Primitive::make("cmp_lt2_i64", + s_retval = PrimitiveExpr::make("cmp_lt2_i64", &cmp_lt2_i64, true /*explicit_symbol_def*/, llvmintrinsic::i_slt); @@ -128,12 +128,12 @@ namespace xo { } auto - Primitive_cmp_i64::make_cmp_le2_i64() -> rp + PrimitiveExpr_cmp_i64::make_cmp_le2_i64() -> rp { - static rp s_retval; + static rp s_retval; if (!s_retval) - s_retval = Primitive::make("cmp_le2_i64", + s_retval = PrimitiveExpr::make("cmp_le2_i64", &cmp_le2_i64, true /*explicit_symbol_def*/, llvmintrinsic::i_sle); @@ -142,12 +142,12 @@ namespace xo { } auto - Primitive_cmp_i64::make_cmp_gt2_i64() -> rp + PrimitiveExpr_cmp_i64::make_cmp_gt2_i64() -> rp { - static rp s_retval; + static rp s_retval; if (!s_retval) - s_retval = Primitive::make("cmp_gt2_i64", + s_retval = PrimitiveExpr::make("cmp_gt2_i64", &cmp_gt2_i64, true /*explicit_symbol_def*/, llvmintrinsic::i_sgt); @@ -156,12 +156,12 @@ namespace xo { } auto - Primitive_cmp_i64::make_cmp_ge2_i64() -> rp + PrimitiveExpr_cmp_i64::make_cmp_ge2_i64() -> rp { - static rp s_retval; + static rp s_retval; if (!s_retval) - s_retval = Primitive::make("cmp_ge2_i64", + s_retval = PrimitiveExpr::make("cmp_ge2_i64", &cmp_ge2_i64, true /*explicit_symbol_def*/, llvmintrinsic::i_sge); @@ -172,12 +172,12 @@ namespace xo { /* TODO: remaining integer arithmetic */ auto - Primitive_i64::make_add2_i64() -> rp + PrimitiveExpr_i64::make_add2_i64() -> rp { - static rp s_retval; + static rp s_retval; if (!s_retval) - s_retval = Primitive::make("add2_i64", + s_retval = PrimitiveExpr::make("add2_i64", &add2_i64, true /*explicit_symbol_def*/, llvmintrinsic::i_add); @@ -186,12 +186,12 @@ namespace xo { } auto - Primitive_i64::make_sub2_i64() -> rp + PrimitiveExpr_i64::make_sub2_i64() -> rp { - static rp s_retval; + static rp s_retval; if (!s_retval) - s_retval = Primitive::make("sub2_i64", + s_retval = PrimitiveExpr::make("sub2_i64", &sub2_i64, true /*explicit_symbol_def*/, llvmintrinsic::i_sub); @@ -200,12 +200,12 @@ namespace xo { } auto - Primitive_i64::make_mul2_i64() -> rp + PrimitiveExpr_i64::make_mul2_i64() -> rp { - static rp s_retval; + static rp s_retval; if (!s_retval) - s_retval = Primitive::make("mul2_i64", + s_retval = PrimitiveExpr::make("mul2_i64", &mul2_i64, true /*explicit_symbol_def*/, llvmintrinsic::i_mul); @@ -214,12 +214,12 @@ namespace xo { } auto - Primitive_i64::make_div2_i64() -> rp + PrimitiveExpr_i64::make_div2_i64() -> rp { - static rp s_retval; + static rp s_retval; if (!s_retval) - s_retval = Primitive::make("div2_i64", + s_retval = PrimitiveExpr::make("div2_i64", &div2_i64, true /*explicit_symbol+def*/, llvmintrinsic::i_sdiv); @@ -229,12 +229,12 @@ namespace xo { // ----- floating-point arithmetic ----- auto - Primitive_f64::make_add2_f64() -> rp + PrimitiveExpr_f64::make_add2_f64() -> rp { - static rp s_retval; + static rp s_retval; if (!s_retval) - s_retval = Primitive::make("add2_f64", + s_retval = PrimitiveExpr::make("add2_f64", &add2_f64, true /*explicit_symbol_def*/, llvmintrinsic::fp_add); @@ -243,12 +243,12 @@ namespace xo { } auto - Primitive_f64::make_sub2_f64() -> rp + PrimitiveExpr_f64::make_sub2_f64() -> rp { - static rp s_retval; + static rp s_retval; if (!s_retval) - s_retval = Primitive::make("sub2_f64", + s_retval = PrimitiveExpr::make("sub2_f64", &sub2_f64, true /*explicit_symbol_def*/, llvmintrinsic::fp_sub); @@ -257,12 +257,12 @@ namespace xo { } auto - Primitive_f64::make_mul2_f64() -> rp + PrimitiveExpr_f64::make_mul2_f64() -> rp { - static rp s_retval; + static rp s_retval; if (!s_retval) - s_retval = Primitive::make("mul2_f64", + s_retval = PrimitiveExpr::make("mul2_f64", &mul2_f64, true /*explicit_symbol_def*/, llvmintrinsic::fp_mul); @@ -271,12 +271,12 @@ namespace xo { } auto - Primitive_f64::make_div2_f64() -> rp + PrimitiveExpr_f64::make_div2_f64() -> rp { - static rp s_retval; + static rp s_retval; if (!s_retval) - s_retval = Primitive::make("div2_f64", + s_retval = PrimitiveExpr::make("div2_f64", &div2_f64, true /*explicit_symbol_def*/, llvmintrinsic::fp_div); @@ -288,4 +288,4 @@ namespace xo { } /*namespace xo*/ -/* end Primitive.cpp */ +/* end PrimitiveExpr.cpp */ diff --git a/xo-interpreter/include/xo/interpreter/BuiltinPrimitives.hpp b/xo-interpreter/include/xo/interpreter/BuiltinPrimitives.hpp new file mode 100644 index 00000000..3b23be69 --- /dev/null +++ b/xo-interpreter/include/xo/interpreter/BuiltinPrimitives.hpp @@ -0,0 +1,18 @@ +/** @file BuiltinPrimitives.hpp + * + * @author Roland Conybeare, Nov 2025 + **/ + +#include "xo/alloc/IAlloc.hpp" +#include "GlobalEnv.hpp" + +namespace xo { + namespace scm { + struct BuiltinPrimitives { + public: + static void install(gc::IAlloc * mm, gp env); + }; + } +} + +/* end BuiltinPrimitives.hpp */ diff --git a/xo-interpreter/include/xo/interpreter/LocalEnv.hpp b/xo-interpreter/include/xo/interpreter/LocalEnv.hpp index c2a90ee0..be6e2f0a 100644 --- a/xo-interpreter/include/xo/interpreter/LocalEnv.hpp +++ b/xo-interpreter/include/xo/interpreter/LocalEnv.hpp @@ -87,7 +87,7 @@ namespace xo { **/ rp symtab_; /** environment contents **/ - CVector> slot_v_; + obj::CVector> slot_v_; }; } /*namespace scm*/ } /*namespace xo*/ diff --git a/xo-interpreter/include/xo/interpreter/VsmStackFrame.hpp b/xo-interpreter/include/xo/interpreter/VsmStackFrame.hpp index c6efc699..222def45 100644 --- a/xo-interpreter/include/xo/interpreter/VsmStackFrame.hpp +++ b/xo-interpreter/include/xo/interpreter/VsmStackFrame.hpp @@ -6,7 +6,7 @@ #pragma once #include "VsmInstr.hpp" -#include "CVector.hpp" +#include "xo/object/CVector.hpp" #include "xo/alloc/Object.hpp" namespace xo { @@ -73,7 +73,7 @@ namespace xo { gp parent_; /** stored state **/ - CVector> slot_v_; + obj::CVector> slot_v_; /** proceed to this continuation when popping this frame **/ const VsmInstr * cont_ = nullptr; diff --git a/xo-interpreter/src/interpreter/BuiltinPrimitives.cpp b/xo-interpreter/src/interpreter/BuiltinPrimitives.cpp new file mode 100644 index 00000000..f9dc96cc --- /dev/null +++ b/xo-interpreter/src/interpreter/BuiltinPrimitives.cpp @@ -0,0 +1,39 @@ +/** @file BuiltinPrimitives.cpp + * + * @author Roland Conybeare, Nov 2025 + **/ + +#include "BuiltinPrimitives.hpp" +#include "ObjectConversion.hpp" +#include "Integer.hpp" +#include "Primitive.hpp" +#include "xo/reflect/Reflect.hpp" +#include + +namespace xo { + using xo::reflect::Reflect; + using xo::reflect::TypeDescr; + + namespace scm { + int64_t + add64(int64_t x, int64_t y) + { + return x + y; + } + + void + BuiltinPrimitives::install(gc::IAlloc * mm, gp env) + { + { + gp rhs = xo::obj::make_primitive(mm, add64); + TypeDescr td = Reflect::require(); + rp lhs = Variable::make("add", td); + gp * addr = env->establish_var(lhs.borrow()); + + *addr = rhs; + } + } + } +} + +/* end BuiltinPrimitives.cpp */ diff --git a/xo-interpreter/src/interpreter/CMakeLists.txt b/xo-interpreter/src/interpreter/CMakeLists.txt index a483676c..912d4a93 100644 --- a/xo-interpreter/src/interpreter/CMakeLists.txt +++ b/xo-interpreter/src/interpreter/CMakeLists.txt @@ -4,6 +4,7 @@ set(SELF_LIB xo_interpreter) set(SELF_SRCS init_interpreter.cpp Schematika.cpp + BuiltinPrimitives.cpp LocalEnv.cpp GlobalEnv.cpp VirtualSchematikaMachine.cpp diff --git a/xo-interpreter/src/interpreter/LocalEnv.cpp b/xo-interpreter/src/interpreter/LocalEnv.cpp index 413f6a69..8085f126 100644 --- a/xo-interpreter/src/interpreter/LocalEnv.cpp +++ b/xo-interpreter/src/interpreter/LocalEnv.cpp @@ -162,7 +162,7 @@ namespace xo { * * note: placement here works b/c CVector not used anywhere else */ - using VectorType = CVector>; + using VectorType = obj::CVector>; /* custom reflection for array of Object pointers. * Can use StlVectorTdx here, treating CVector as a vector diff --git a/xo-interpreter/src/interpreter/Schematika.cpp b/xo-interpreter/src/interpreter/Schematika.cpp index d290f001..942ea685 100644 --- a/xo-interpreter/src/interpreter/Schematika.cpp +++ b/xo-interpreter/src/interpreter/Schematika.cpp @@ -5,6 +5,7 @@ #include "Schematika.hpp" #include "VirtualSchematikaMachine.hpp" +#include "BuiltinPrimitives.hpp" #include "GlobalEnv.hpp" #include "xo/reader/reader.hpp" #include @@ -69,7 +70,9 @@ namespace xo { { up mm = GC::make(cfg.gc_config_); rp symtab = GlobalSymtab::make_empty(); - gp env = GlobalEnv::make_empty(mm.get(), symtab); + gp env = GlobalEnv::make_empty(mm.get(), symtab); + + BuiltinPrimitives::install(mm.get(), env); return std::make_unique(cfg, std::move(mm), env); } diff --git a/xo-interpreter/src/interpreter/VsmStackFrame.cpp b/xo-interpreter/src/interpreter/VsmStackFrame.cpp index b189745f..09af308a 100644 --- a/xo-interpreter/src/interpreter/VsmStackFrame.cpp +++ b/xo-interpreter/src/interpreter/VsmStackFrame.cpp @@ -140,7 +140,7 @@ namespace xo { /* reflect CVector>. * duplicates similar code in LocalEnv::reflect_self() */ - using VectorType = CVector>; + using VectorType = obj::CVector>; /* custom reflection for array of Object pointers. * Can use StlVectorTdx here, treating CVector as a vector diff --git a/xo-jit/example/ex1/ex1.cpp b/xo-jit/example/ex1/ex1.cpp index cc642dcb..761c79fc 100644 --- a/xo-jit/example/ex1/ex1.cpp +++ b/xo-jit/example/ex1/ex1.cpp @@ -2,7 +2,7 @@ #include "xo/jit/MachPipeline.hpp" #include "xo/expression/Constant.hpp" -#include "xo/expression/Primitive.hpp" +#include "xo/expression/PrimitiveExpr.hpp" #include "xo/expression/Apply.hpp" #include "xo/expression/Lambda.hpp" #include "xo/expression/Variable.hpp" diff --git a/xo-jit/example/ex2_jit/ex2_jit.cpp b/xo-jit/example/ex2_jit/ex2_jit.cpp index b0f32643..08a0bc16 100644 --- a/xo-jit/example/ex2_jit/ex2_jit.cpp +++ b/xo-jit/example/ex2_jit/ex2_jit.cpp @@ -3,7 +3,7 @@ #include "xo/jit/MachPipeline.hpp" #include "xo/jit/activation_record.hpp" #include "xo/expression/Constant.hpp" -#include "xo/expression/Primitive.hpp" +#include "xo/expression/PrimitiveExpr.hpp" #include "xo/expression/Apply.hpp" #include "xo/expression/Lambda.hpp" #include "xo/expression/Variable.hpp" diff --git a/xo-object/include/xo/object/CVector.hpp b/xo-object/include/xo/object/CVector.hpp index 9dc74810..d8c27e60 100644 --- a/xo-object/include/xo/object/CVector.hpp +++ b/xo-object/include/xo/object/CVector.hpp @@ -9,7 +9,7 @@ #include namespace xo { - namespace scm { + namespace obj { /** gc-only vector. * Used in both LocalEnv and VsmStackFrame **/ @@ -33,18 +33,13 @@ namespace xo { ElementType operator[](std::size_t i) const { return v_[i]; } ElementType & operator[](std::size_t i) { return v_[i]; } - friend class LocalEnv; - friend class VsmStackFrame; - - private: + public: /** number of elements in @ref v_ **/ std::size_t n_ = 0; /** contiguous array of pointers **/ ElementType * v_ = nullptr; }; - - - } /*namespace scm*/ + } /*namespace obj*/ } /*namespace xo*/ /* end CVector.hpp */ diff --git a/xo-object/include/xo/object/Integer.hpp b/xo-object/include/xo/object/Integer.hpp index 48756ea9..2efec19d 100644 --- a/xo-object/include/xo/object/Integer.hpp +++ b/xo-object/include/xo/object/Integer.hpp @@ -6,6 +6,8 @@ #pragma once #include "Number.hpp" +#include "ObjectConversion.hpp" +#include "xo/indentlog/print/tag.hpp" namespace xo { namespace obj { @@ -37,6 +39,29 @@ namespace xo { private: int_type value_ = 0; }; + + template + struct ObjectConversion_Integer { + static gp to_object(gc::IAlloc * mm, IntType x) { + return new (MMPtr(mm)) Integer(x); + } + static IntType from_object(gc::IAlloc *, gp x) { + gp x_int = Integer::from(x); + if (x_int.get()) { + return x_int->value(); + } else { + throw std::runtime_error(tostr("ObjectConversion_Integer: x found where Integer expected", xtag("x", x))); + } + } + }; + + template <> + struct ObjectConversion : public ObjectConversion_Integer {}; + template <> + struct ObjectConversion : public ObjectConversion_Integer {}; + template <> + struct ObjectConversion : public ObjectConversion_Integer {}; + } /*namespace obj*/ } /*namespace xo*/ diff --git a/xo-object/include/xo/object/ObjectConversion.hpp b/xo-object/include/xo/object/ObjectConversion.hpp new file mode 100644 index 00000000..99c1bae5 --- /dev/null +++ b/xo-object/include/xo/object/ObjectConversion.hpp @@ -0,0 +1,20 @@ +/** @file ObjectConversion.hpp + * + * @author Roland Conybeare, Nov 2025 + **/ + +#pragma once + +#include "Object.hpp" + +namespace xo { + namespace obj { + template + struct ObjectConversion { + static gp to_object(gc::IAlloc * mm, const T & x) = delete; + static T from_object(gc::IAlloc * mm, gp x) = delete; + }; + } +} + +/* end ObjectConversion.hpp */ diff --git a/xo-object/include/xo/object/Primitive.hpp b/xo-object/include/xo/object/Primitive.hpp index 64583e3d..70257f87 100644 --- a/xo-object/include/xo/object/Primitive.hpp +++ b/xo-object/include/xo/object/Primitive.hpp @@ -6,7 +6,8 @@ #pragma once #include "Procedure.hpp" -#include "CVector.hpp" +#include "ObjectConversion.hpp" +#include "xo/reflect/Reflect.hpp" namespace xo { namespace obj { @@ -25,15 +26,14 @@ namespace xo { using function_type = Fn; public: - explicit PrimitiveBase(Converter & cvt, Fn impl) : converter_{cvt}, impl_{std::move(impl)} {} + explicit PrimitiveBase(Fn impl) : impl_{std::move(impl)} {} // inherited from Procedure.. virtual std::size_t n_args() const override = 0; - virtual gp apply_nocheck(const CVector> & args) override = 0; + virtual gp apply_nocheck(gc::IAlloc * mm, const CVector> & args) override = 0; protected: - Converter & converter_; Fn impl_; }; @@ -41,29 +41,60 @@ namespace xo { class Primitive : public PrimitiveBase { }; - template + template class Primitive : public PrimitiveBase { public: using Super = PrimitiveBase; using function_type = Ret (*)(Arg1, Arg2); + using TaggedPtr = xo::reflect::TaggedPtr; public: - explicit Primitive(Converter & cvt, function_type fn) : PrimitiveBase{cvt, fn} {} + explicit Primitive(function_type fn) : PrimitiveBase{fn} {} // inherited from Procedure.. virtual std::size_t n_args() const final override { return 2; } - virtual gp apply_nocheck(const CVector> & args) final override { - /* note: args[0] will be this procedure. actual i'th function argument in args[i+1] - */ - args[1] + virtual gp apply_nocheck(gc::IAlloc * mm, + const CVector> & args) final override { + /* note: args[0] will be this procedure. + * actual i'th function argument in args[i+1] + */ + Arg1 arg1 = ObjectConversion::from_object(mm, args[1]); + Arg2 arg2 = ObjectConversion::from_object(mm, args[2]); + + Ret retval = (*Super::impl_)(arg1, arg2); + + return ObjectConversion::to_object(mm, retval); } - private: + // inherited from Object.. + virtual TaggedPtr self_tp() const final override { + using xo::reflect::Reflect; + return Reflect::make_tp(const_cast(this)); + } + virtual void display(std::ostream & os) const final override { + os << ""; + } + virtual std::size_t _shallow_size() const final override { + return sizeof(*this); + } + virtual Object *_shallow_copy(gc::IAlloc * mm) const final override { + Cpof cpof(mm, this); + return new (cpof) Primitive(*this); + } + std::size_t _forward_children(gc::IAlloc *) final override { + return _shallow_size(); + } }; + + template + gp> + make_primitive(gc::IAlloc * mm, Fn fn) { + return new (MMPtr(mm)) Primitive(fn); + } } } diff --git a/xo-object/include/xo/object/Procedure.hpp b/xo-object/include/xo/object/Procedure.hpp index 5a0cb824..2ab78ab2 100644 --- a/xo-object/include/xo/object/Procedure.hpp +++ b/xo-object/include/xo/object/Procedure.hpp @@ -6,8 +6,11 @@ #pragma once #include "Object.hpp" +#include "CVector.hpp" namespace xo { + namespace gc { class IAlloc; }; // see xo-alloc: xo/alloc/IAlloc.hpp + namespace obj { /** @class ProcedureInterface * @brief Interface to a dynamically-typed procedure @@ -15,7 +18,7 @@ namespace xo { class Procedure : public Object { public: virtual std::size_t n_args() const = 0; - virtual gp apply_nocheck(const CVector> & args) = 0; + virtual gp apply_nocheck(gc::IAlloc * mm, const CVector> & args) = 0; // inherited from Object.. diff --git a/xo-pyexpression/src/pyexpression/pyexpression.cpp b/xo-pyexpression/src/pyexpression/pyexpression.cpp index d6a22c1c..7e37e044 100644 --- a/xo-pyexpression/src/pyexpression/pyexpression.cpp +++ b/xo-pyexpression/src/pyexpression/pyexpression.cpp @@ -5,7 +5,7 @@ #include "xo/expression/Expression.hpp" #include "xo/expression/Apply.hpp" #include "xo/expression/PrimitiveExprInterface.hpp" -#include "xo/expression/Primitive.hpp" +#include "xo/expression/PrimitiveExpr.hpp" #include "xo/expression/ConstantInterface.hpp" #include "xo/expression/Constant.hpp" #include "xo/expression/Variable.hpp" @@ -22,7 +22,7 @@ namespace xo { using xo::scm::Expression; using xo::scm::make_apply; using xo::scm::PrimitiveExprInterface; - using xo::scm::Primitive; + using xo::scm::PrimitiveExpr; using xo::scm::make_primitive; using xo::scm::ConstantInterface; using xo::scm::Constant; @@ -106,14 +106,14 @@ namespace xo { using int32_t = std::int32_t; - py::class_, + py::class_, PrimitiveExprInterface, - rp>>(m, "Primitive_i32_i32") + rp>>(m, "PrimitiveExpr_i32_i32") ; - py::class_, + py::class_, PrimitiveExprInterface, - rp>>(m, "Primitive_double_double") + rp>>(m, "PrimitiveExpr_double_double") ; using Fn_dbl_dbl_type = double (*)(double); @@ -135,9 +135,9 @@ namespace xo { llvmintrinsic::fp_cos); }, py::doc("create primitive representing the ::cos() function")); - py::class_, + py::class_, PrimitiveExprInterface, - rp>>(m, "Primitive_double_double_double") + rp>>(m, "PrimitiveExpr_double_double_double") ; m.def("make_pow_pm", diff --git a/xo-pyjit/src/pyjit/pyjit.cpp b/xo-pyjit/src/pyjit/pyjit.cpp index 7d0e25c1..650ba149 100644 --- a/xo-pyjit/src/pyjit/pyjit.cpp +++ b/xo-pyjit/src/pyjit/pyjit.cpp @@ -4,7 +4,7 @@ #include "xo/pyexpression/pyexpression.hpp" #include "xo/jit/MachPipeline.hpp" #include "xo/jit/intrinsics.hpp" -#include "xo/expression/Primitive.hpp" +#include "xo/expression/PrimitiveExpr.hpp" #include "xo/pyutil/pycaller.hpp" #include "xo/pyutil/pyutil.hpp" #include diff --git a/xo-reflect/include/xo/reflect/TypeDescr.hpp b/xo-reflect/include/xo/reflect/TypeDescr.hpp index 8896ed3a..d39d64e8 100644 --- a/xo-reflect/include/xo/reflect/TypeDescr.hpp +++ b/xo-reflect/include/xo/reflect/TypeDescr.hpp @@ -99,21 +99,28 @@ namespace xo { * * Example * T * p = new T(...); - * DestructorAux::dtor(p); + * InvokerAux::dtor(p); **/ template struct InvokerAux : public Invoker { virtual void dtor(void * addr) const override { - T * obj = static_cast(addr); + T * obj = reinterpret_cast(addr); obj->~T(); } }; + /** no dtor for void **/ template<> struct InvokerAux : public Invoker { virtual void dtor(void *) const override {} }; + + /** no dtor for function types **/ + template + struct InvokerAux : public Invoker { + virtual void dtor(void *) const override {} + }; } /*namespace detail*/ } /*namespace reflect*/ } /*namespace xo*/