xo-interpreter: expose builtin primitives to interpreter

This commit is contained in:
Roland Conybeare 2025-11-29 11:39:34 -05:00
commit 212a1fdc8c
6 changed files with 135 additions and 44 deletions

View file

@ -65,6 +65,8 @@ extern "C" {
return x / y;
}
// ----------------------------------------------------------------
double
add2_f64(double x, double y) {
return x + y;
@ -94,7 +96,7 @@ namespace xo {
static rp<PrimitiveExprType> s_retval;
if (!s_retval)
s_retval = PrimitiveExpr::make("cmp_eq2_i64",
s_retval = PrimitiveExpr::make("@cmp_eq2_i64",
&cmp_eq2_i64,
true /*explicit_symbol_def*/,
llvmintrinsic::i_eq);
@ -108,7 +110,7 @@ namespace xo {
static rp<PrimitiveExprType> s_retval;
if (!s_retval)
s_retval = PrimitiveExpr::make("cmp_ne2_i64",
s_retval = PrimitiveExpr::make("@cmp_ne2_i64",
&cmp_ne2_i64,
true /*explicit_symbol_def*/,
llvmintrinsic::i_ne);
@ -122,7 +124,7 @@ namespace xo {
static rp<PrimitiveExprType> s_retval;
if (!s_retval)
s_retval = PrimitiveExpr::make("cmp_lt2_i64",
s_retval = PrimitiveExpr::make("@cmp_lt2_i64",
&cmp_lt2_i64,
true /*explicit_symbol_def*/,
llvmintrinsic::i_slt);
@ -136,7 +138,7 @@ namespace xo {
static rp<PrimitiveExprType> s_retval;
if (!s_retval)
s_retval = PrimitiveExpr::make("cmp_le2_i64",
s_retval = PrimitiveExpr::make("@cmp_le2_i64",
&cmp_le2_i64,
true /*explicit_symbol_def*/,
llvmintrinsic::i_sle);
@ -150,7 +152,7 @@ namespace xo {
static rp<PrimitiveExprType> s_retval;
if (!s_retval)
s_retval = PrimitiveExpr::make("cmp_gt2_i64",
s_retval = PrimitiveExpr::make("@cmp_gt2_i64",
&cmp_gt2_i64,
true /*explicit_symbol_def*/,
llvmintrinsic::i_sgt);
@ -164,7 +166,7 @@ namespace xo {
static rp<PrimitiveExprType> s_retval;
if (!s_retval)
s_retval = PrimitiveExpr::make("cmp_ge2_i64",
s_retval = PrimitiveExpr::make("@cmp_ge2_i64",
&cmp_ge2_i64,
true /*explicit_symbol_def*/,
llvmintrinsic::i_sge);
@ -194,7 +196,7 @@ namespace xo {
static rp<PrimitiveExprType> s_retval;
if (!s_retval)
s_retval = PrimitiveExpr::make("sub2_i64",
s_retval = PrimitiveExpr::make("@sub2_i64",
&sub2_i64,
true /*explicit_symbol_def*/,
llvmintrinsic::i_sub);
@ -222,7 +224,7 @@ namespace xo {
static rp<PrimitiveExprType> s_retval;
if (!s_retval)
s_retval = PrimitiveExpr::make("div2_i64",
s_retval = PrimitiveExpr::make("@div2_i64",
&div2_i64,
true /*explicit_symbol+def*/,
llvmintrinsic::i_sdiv);
@ -237,7 +239,7 @@ namespace xo {
static rp<PrimitiveExprType> s_retval;
if (!s_retval)
s_retval = PrimitiveExpr::make("add2_f64",
s_retval = PrimitiveExpr::make("@add2_f64",
&add2_f64,
true /*explicit_symbol_def*/,
llvmintrinsic::fp_add);
@ -251,7 +253,7 @@ namespace xo {
static rp<PrimitiveExprType> s_retval;
if (!s_retval)
s_retval = PrimitiveExpr::make("sub2_f64",
s_retval = PrimitiveExpr::make("@sub2_f64",
&sub2_f64,
true /*explicit_symbol_def*/,
llvmintrinsic::fp_sub);
@ -265,7 +267,7 @@ namespace xo {
static rp<PrimitiveExprType> s_retval;
if (!s_retval)
s_retval = PrimitiveExpr::make("mul2_f64",
s_retval = PrimitiveExpr::make("@mul2_f64",
&mul2_f64,
true /*explicit_symbol_def*/,
llvmintrinsic::fp_mul);
@ -279,7 +281,7 @@ namespace xo {
static rp<PrimitiveExprType> s_retval;
if (!s_retval)
s_retval = PrimitiveExpr::make("div2_f64",
s_retval = PrimitiveExpr::make("@div2_f64",
&div2_f64,
true /*explicit_symbol_def*/,
llvmintrinsic::fp_div);

View file

@ -46,20 +46,53 @@ namespace xo {
*addr = rhs;
}
// i64 comparisons
// @cmp_eq2_i64
install_pm(mm, PrimitiveExpr_cmp_i64::make_cmp_eq2_i64(), env);
// @cmp_ne2_i64
install_pm(mm, PrimitiveExpr_cmp_i64::make_cmp_ne2_i64(), env);
// @cmp_lt2_i64
install_pm(mm, PrimitiveExpr_cmp_i64::make_cmp_lt2_i64(), env);
// @cmp_le2_i64
install_pm(mm, PrimitiveExpr_cmp_i64::make_cmp_le2_i64(), env);
// @cmp_gt2_i64
install_pm(mm, PrimitiveExpr_cmp_i64::make_cmp_gt2_i64(), env);
// @cmp_ge2_i64
install_pm(mm, PrimitiveExpr_cmp_i64::make_cmp_ge2_i64(), env);
// i64 arithmetic
// @add2_i64
{
auto pm_expr = PrimitiveExpr_i64::make_add2_i64();
install_pm(mm, PrimitiveExpr_i64::make_add2_i64(), env);
gp<Object> rhs = xo::obj::make_primitive(mm, pm_expr->name(), pm_expr->value());
rp<Variable> lhs = Variable::make(pm_expr->name(), pm_expr->value_td());
gp<Object> * addr = env->establish_var(lhs.borrow());
*addr = rhs;
}
// @sub2_i64
install_pm(mm, PrimitiveExpr_i64::make_sub2_i64(), env);
// @mul2_i64
install_pm(mm, PrimitiveExpr_i64::make_mul2_i64(), env);
// @div2_i64
install_pm(mm, PrimitiveExpr_i64::make_div2_i64(), env);
// ----------------------------------------------------------------
// @add2_f64
install_pm(mm, PrimitiveExpr_f64::make_add2_f64(), env);
// @sub2_f64
install_pm(mm, PrimitiveExpr_f64::make_sub2_f64(), env);
// @mul2_f64
install_pm(mm, PrimitiveExpr_f64::make_mul2_f64(), env);
// @div2_f64
install_pm(mm, PrimitiveExpr_f64::make_div2_f64(), env);
}
}
}

View file

@ -3,7 +3,11 @@
* author: Roland Conybeare, Aug 2025
*/
#pragma once
#include "xo/alloc/Object.hpp"
#include "ObjectConversion.hpp"
#include "xo/indentlog/print/tag.hpp"
namespace xo {
namespace obj {
@ -34,6 +38,24 @@ namespace xo {
private:
bool value_;
};
template <typename BoolType>
struct ObjectConversion_Boolean {
static gp<Object> to_object(gc::IAlloc * /*mm*/, BoolType x) {
return Boolean::boolean_obj(x);
}
static BoolType from_object(gc::IAlloc *, gp<Object> x) {
gp<Boolean> x_bool = Boolean::from(x);
if (x_bool.get()) {
return x_bool->value();
} else {
throw std::runtime_error(tostr("ObjectConversion_Boolean: x found where Boolean expected", xtag("x", x)));
}
}
};
template <>
struct ObjectConversion<bool> : public ObjectConversion_Boolean<bool> {};
}
}

View file

@ -6,6 +6,8 @@
#pragma once
#include "Number.hpp"
#include "ObjectConversion.hpp"
#include "xo/indentlog/print/tag.hpp"
namespace xo {
namespace obj {
@ -35,6 +37,26 @@ namespace xo {
private:
float_type value_ = 0.0;
};
template <typename FloatType>
struct ObjectConversion_Float {
static gp<Object> to_object(gc::IAlloc * mm, FloatType x) {
return new (MMPtr(mm)) Float(x);
}
static FloatType from_object(gc::IAlloc *, gp<Object> x) {
gp<Float> x_int = Float::from(x);
if (x_int.get()) {
return x_int->value();
} else {
throw std::runtime_error(tostr("ObjectConversion_Float: x found where Float expected", xtag("x", x)));
}
}
};
template <>
struct ObjectConversion<double> : public ObjectConversion_Float<double> {};
template <>
struct ObjectConversion<float> : public ObjectConversion_Float<float> {};
}
}

View file

@ -14,6 +14,16 @@ namespace xo {
static gp<Object> to_object(gc::IAlloc * mm, const T & x) = delete;
static T from_object(gc::IAlloc * mm, gp<Object> x) = delete;
};
/** see specializations:
* ObjectConversion<bool>
* in object/Boolean.hpp
*
* ObjectConversion<int64_t>
* ObjectConversion<int32_t>
* ObjectConversion<int16_t>
* in object/Integer.hpp
**/
}
}

View file

@ -6,7 +6,9 @@
#pragma once
#include "Procedure.hpp"
#include "Float.hpp"
#include "String.hpp"
#include "Boolean.hpp"
#include "ObjectConversion.hpp"
#include "xo/reflect/Reflect.hpp"