xo-reader: integer arithmetic + parser + pretty-printing adds
This commit is contained in:
parent
75b74918b7
commit
8d5a9c825f
25 changed files with 408 additions and 26 deletions
|
|
@ -35,6 +35,19 @@ namespace xo {
|
|||
static rp<Apply> make_cmp_ne_i64(const rp<Expression> & lhs,
|
||||
const rp<Expression> & rhs);
|
||||
|
||||
/** create apply-expression to add two 64-bit integers **/
|
||||
static rp<Apply> make_add2_i64(const rp<Expression> & lhs,
|
||||
const rp<Expression> & rhs);
|
||||
/** create apply-expression to subtract two 64-bit integers **/
|
||||
static rp<Apply> make_sub2_i64(const rp<Expression> & lhs,
|
||||
const rp<Expression> & rhs);
|
||||
/** create apply-expression to multiply two 64-bit integers **/
|
||||
static rp<Apply> make_mul2_i64(const rp<Expression> & lhs,
|
||||
const rp<Expression> & rhs);
|
||||
/** create apply-expression to divide two 64-bit integers **/
|
||||
static rp<Apply> make_div2_i64(const rp<Expression> & lhs,
|
||||
const rp<Expression> & rhs);
|
||||
|
||||
/** create apply-expression to add two 64-bit floating-point numbers **/
|
||||
static rp<Apply> make_add2_f64(const rp<Expression> & lhs,
|
||||
const rp<Expression> & rhs);
|
||||
|
|
|
|||
|
|
@ -191,6 +191,9 @@ namespace xo {
|
|||
return Primitive<FunctionPointer>::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<bool (*)(std::int64_t, std::int64_t)> {
|
||||
public:
|
||||
|
|
@ -203,6 +206,22 @@ namespace xo {
|
|||
static rp<PrimitiveType> make_cmp_ne2_i64();
|
||||
};
|
||||
|
||||
/** builtin primitives :: i64 x i64 -> i64 **/
|
||||
class Primitive_i64 : public Primitive<std::int64_t (*)(std::int64_t, std::int64_t)> {
|
||||
public:
|
||||
using PrimitiveType = Primitive<std::int64_t (*)(std::int64_t, std::int64_t)>;
|
||||
|
||||
public:
|
||||
/** add2_i64: add two 64-bit integers **/
|
||||
static rp<PrimitiveType> make_add2_i64();
|
||||
/** sub2_i64: subtract two 64-bit integers **/
|
||||
static rp<PrimitiveType> make_sub2_i64();
|
||||
/** mul2_i64: multiply two 64-bit integers **/
|
||||
static rp<PrimitiveType> make_mul2_i64();
|
||||
/** div2_i64: divide two 64-bit integers **/
|
||||
static rp<PrimitiveType> make_div2_i64();
|
||||
};
|
||||
|
||||
/** builtin primitives :: f64 x f64 -> f64 **/
|
||||
class Primitive_f64 : public Primitive<double (*)(double, double)> {
|
||||
public:
|
||||
|
|
|
|||
|
|
@ -37,6 +37,8 @@ namespace xo {
|
|||
* NSW stands for 'no signed wrap' -> poison value if overflow (costs more)
|
||||
* NUW stands for 'no unsigned wrap' -> poison value if overflow (costs more)
|
||||
* @endnote
|
||||
*
|
||||
* See: xo-jit/src/jit/MachPipeline.cpp
|
||||
**/
|
||||
enum class llvmintrinsic {
|
||||
// see /nix/store/x5yz...llvm-18.1.5-dev/include/llvm/IR/IRBuilder.h
|
||||
|
|
@ -82,16 +84,16 @@ namespace xo {
|
|||
|
||||
// TODO: unsigned comparisons
|
||||
|
||||
/** -> IRBuilder::CreateFadd (add 2 floating-point numbers) **/
|
||||
/** -> IRBuilder::CreateFAdd (add 2 floating-point numbers) **/
|
||||
fp_add,
|
||||
|
||||
/** -> IRBuilder::CreateFsub (subtract 2 floating-pointer numbers) **/
|
||||
/** -> IRBuilder::CreateFSub (subtract 2 floating-pointer numbers) **/
|
||||
fp_sub,
|
||||
|
||||
/** -> IRBuilder::CreateFmul (multiply 2 floating-point numbers) **/
|
||||
/** -> IRBuilder::CreateFMul (multiply 2 floating-point numbers) **/
|
||||
fp_mul,
|
||||
|
||||
/** -> IRBuilder::CreateFdiv (divide 2 floating-point numbers) **/
|
||||
/** -> IRBuilder::CreateFDiv (divide 2 floating-point numbers) **/
|
||||
fp_div,
|
||||
|
||||
// TODO: floating-point comparisons
|
||||
|
|
|
|||
|
|
@ -30,6 +30,8 @@ namespace xo {
|
|||
return new Apply(fn_retval_type, fn, argv);
|
||||
}
|
||||
|
||||
// ----- integer comparison -----
|
||||
|
||||
rp<Apply>
|
||||
Apply::make_cmp_eq_i64(const rp<Expression> & lhs,
|
||||
const rp<Expression> & rhs)
|
||||
|
|
@ -46,6 +48,42 @@ namespace xo {
|
|||
{lhs, rhs});
|
||||
}
|
||||
|
||||
// ----- integer arithmetic -----
|
||||
|
||||
rp<Apply>
|
||||
Apply::make_add2_i64(const rp<Expression> & lhs,
|
||||
const rp<Expression> & rhs)
|
||||
{
|
||||
return Apply::make(Primitive_i64::make_add2_i64(),
|
||||
{lhs, rhs});
|
||||
}
|
||||
|
||||
rp<Apply>
|
||||
Apply::make_sub2_i64(const rp<Expression> & lhs,
|
||||
const rp<Expression> & rhs)
|
||||
{
|
||||
return Apply::make(Primitive_i64::make_sub2_i64(),
|
||||
{lhs, rhs});
|
||||
}
|
||||
|
||||
rp<Apply>
|
||||
Apply::make_mul2_i64(const rp<Expression> & lhs,
|
||||
const rp<Expression> & rhs)
|
||||
{
|
||||
return Apply::make(Primitive_i64::make_mul2_i64(),
|
||||
{lhs, rhs});
|
||||
}
|
||||
|
||||
rp<Apply>
|
||||
Apply::make_div2_i64(const rp<Expression> & lhs,
|
||||
const rp<Expression> & rhs)
|
||||
{
|
||||
return Apply::make(Primitive_i64::make_div2_i64(),
|
||||
{lhs, rhs});
|
||||
}
|
||||
|
||||
// ----- floating point arithmetic -----
|
||||
|
||||
rp<Apply>
|
||||
Apply::make_add2_f64(const rp<Expression> & lhs,
|
||||
const rp<Expression> & rhs)
|
||||
|
|
|
|||
|
|
@ -3,6 +3,7 @@
|
|||
* author: Roland Conybeare, Jul 2025
|
||||
*/
|
||||
|
||||
#include "xo/indentlog/print/ppdetail_atomic.hpp"
|
||||
#include "GlobalEnv.hpp"
|
||||
#include "Expression.hpp"
|
||||
|
||||
|
|
|
|||
|
|
@ -1,8 +1,17 @@
|
|||
/* @file Primitive.cpp */
|
||||
|
||||
#include "Primitive.hpp"
|
||||
#include <cstdint>
|
||||
|
||||
extern "C" {
|
||||
/** code here is used in two context:
|
||||
* 1. Fallback implementation under llvm.
|
||||
* In practice will use llvm intrinsic instead.
|
||||
* See xo-jit/src/jit/MachPipeline.cpp
|
||||
* 2. Schematika interpreter (aspirational asof jul 2025)
|
||||
*
|
||||
**/
|
||||
|
||||
bool
|
||||
cmp_eq2_i64(std::int64_t x, std::int64_t y) {
|
||||
return x == y;
|
||||
|
|
@ -13,6 +22,26 @@ extern "C" {
|
|||
return x != y;
|
||||
}
|
||||
|
||||
std::int64_t
|
||||
add2_i64(std::int64_t x, std::int64_t y) {
|
||||
return x + y;
|
||||
}
|
||||
|
||||
std::int64_t
|
||||
sub2_i64(std::int64_t x, std::int64_t y) {
|
||||
return x - y;
|
||||
}
|
||||
|
||||
std::int64_t
|
||||
mul2_i64(std::int64_t x, std::int64_t y) {
|
||||
return x * y;
|
||||
}
|
||||
|
||||
std::int64_t
|
||||
div2_i64(std::int64_t x, std::int64_t y) {
|
||||
return x / y;
|
||||
}
|
||||
|
||||
double
|
||||
add2_f64(double x, double y) {
|
||||
return x + y;
|
||||
|
|
@ -64,6 +93,65 @@ namespace xo {
|
|||
return s_retval;
|
||||
}
|
||||
|
||||
/* TODO: remaining integer arithmetic */
|
||||
|
||||
auto
|
||||
Primitive_i64::make_add2_i64() -> rp<PrimitiveType>
|
||||
{
|
||||
static rp<PrimitiveType> s_retval;
|
||||
|
||||
if (!s_retval)
|
||||
s_retval = Primitive::make("add2_i64",
|
||||
&add2_i64,
|
||||
true /*explicit_symbol_def*/,
|
||||
llvmintrinsic::i_add);
|
||||
|
||||
return s_retval;
|
||||
}
|
||||
|
||||
auto
|
||||
Primitive_i64::make_sub2_i64() -> rp<PrimitiveType>
|
||||
{
|
||||
static rp<PrimitiveType> s_retval;
|
||||
|
||||
if (!s_retval)
|
||||
s_retval = Primitive::make("sub2_i64",
|
||||
&sub2_i64,
|
||||
true /*explicit_symbol_def*/,
|
||||
llvmintrinsic::i_sub);
|
||||
|
||||
return s_retval;
|
||||
}
|
||||
|
||||
auto
|
||||
Primitive_i64::make_mul2_i64() -> rp<PrimitiveType>
|
||||
{
|
||||
static rp<PrimitiveType> s_retval;
|
||||
|
||||
if (!s_retval)
|
||||
s_retval = Primitive::make("mul2_i64",
|
||||
&mul2_i64,
|
||||
true /*explicit_symbol_def*/,
|
||||
llvmintrinsic::i_mul);
|
||||
|
||||
return s_retval;
|
||||
}
|
||||
|
||||
auto
|
||||
Primitive_i64::make_div2_i64() -> rp<PrimitiveType>
|
||||
{
|
||||
static rp<PrimitiveType> s_retval;
|
||||
|
||||
if (!s_retval)
|
||||
s_retval = Primitive::make("div2_i64",
|
||||
&div2_i64,
|
||||
true /*explicit_symbol+def*/,
|
||||
llvmintrinsic::i_sdiv);
|
||||
return s_retval;
|
||||
}
|
||||
|
||||
// ----- floating-point arithmetic -----
|
||||
|
||||
auto
|
||||
Primitive_f64::make_add2_f64() -> rp<PrimitiveType>
|
||||
{
|
||||
|
|
|
|||
|
|
@ -112,6 +112,7 @@ namespace xo {
|
|||
|
||||
PPDETAIL_ATOMIC(bool);
|
||||
PPDETAIL_ATOMIC(char);
|
||||
PPDETAIL_ATOMIC(unsigned long);
|
||||
PPDETAIL_ATOMIC(std::int64_t);
|
||||
PPDETAIL_ATOMIC(std::uint64_t);
|
||||
PPDETAIL_ATOMIC(std::int32_t);
|
||||
|
|
|
|||
|
|
@ -107,7 +107,7 @@ namespace xo {
|
|||
|
||||
/** pretty-print empty struct **/
|
||||
template <typename StructName, typename... Members>
|
||||
std::uint32_t pretty_struct(const ppindentinfo & ppii, StructName && structname, Members&&...);
|
||||
bool pretty_struct(const ppindentinfo & ppii, StructName && structname, Members&&...);
|
||||
|
||||
/** auxiliary function supporting @ref pretty_stuct .
|
||||
* pretty-print a single member name on behalf of a struct/class.
|
||||
|
|
@ -224,7 +224,7 @@ namespace xo {
|
|||
};
|
||||
|
||||
template <typename StructName, typename... Members>
|
||||
std::uint32_t
|
||||
bool
|
||||
ppstate::pretty_struct(const ppindentinfo & ppii, StructName && structname, Members&&... members)
|
||||
{
|
||||
if (ppii.upto()) {
|
||||
|
|
|
|||
|
|
@ -106,8 +106,11 @@ namespace xo {
|
|||
/** evaluates to the arguments to pass to @ref fn_ **/
|
||||
std::vector<rp<Expression>> args_expr_v_;
|
||||
};
|
||||
|
||||
} /*namespace scm */
|
||||
|
||||
namespace print {
|
||||
PPDETAIL_ATOMIC(xo::scm::applyexprstatetype);
|
||||
}
|
||||
} /*namespace xo*/
|
||||
|
||||
/* end apply_xs.hpp */
|
||||
|
|
|
|||
|
|
@ -107,6 +107,7 @@ namespace xo {
|
|||
parserstatemachine * p_psm) override;
|
||||
|
||||
virtual void print(std::ostream & os) const override;
|
||||
virtual bool pretty_print(const print::ppindentinfo & ppii) const override;
|
||||
|
||||
private:
|
||||
static std::unique_ptr<define_xs> make();
|
||||
|
|
|
|||
|
|
@ -57,6 +57,8 @@ namespace xo {
|
|||
parserstatemachine * p_psm) override;
|
||||
virtual void on_i64_token(const token_type & tk,
|
||||
parserstatemachine * p_psm) override;
|
||||
virtual void on_f64_token(const token_type & tk,
|
||||
parserstatemachine * p_psm) override;
|
||||
|
||||
// ----- victory methods -----
|
||||
|
||||
|
|
|
|||
|
|
@ -7,6 +7,7 @@
|
|||
|
||||
#include "xo/expression/Expression.hpp"
|
||||
#include "xo/tokenizer/token.hpp"
|
||||
#include "xo/indentlog/print/ppdetail_atomic.hpp"
|
||||
#include <stack>
|
||||
//#include <cstdint>
|
||||
|
||||
|
|
@ -145,6 +146,9 @@ namespace xo {
|
|||
/** print human-readable representation on @p os **/
|
||||
virtual void print(std::ostream & os) const;
|
||||
|
||||
/** pretty-print using @p ppii **/
|
||||
virtual bool pretty_print(const print::ppindentinfo & ppii) const;
|
||||
|
||||
// ----- input methods -----
|
||||
|
||||
/** handle incoming 'def' token **/
|
||||
|
|
|
|||
|
|
@ -91,7 +91,10 @@ namespace xo {
|
|||
|
||||
};
|
||||
} /*namespace scm*/
|
||||
|
||||
namespace print {
|
||||
PPDETAIL_ATOMIC(xo::scm::ifexprstatetype);
|
||||
}
|
||||
} /*namespace xo*/
|
||||
|
||||
|
||||
/** end if_else_xs.hpp **/
|
||||
/* end if_else_xs.hpp */
|
||||
|
|
|
|||
|
|
@ -83,6 +83,7 @@ namespace xo {
|
|||
parserstatemachine * p_psm) override;
|
||||
|
||||
virtual void print(std::ostream & os) const override;
|
||||
virtual bool pretty_print(const print::ppindentinfo & ppii) const override;
|
||||
|
||||
private:
|
||||
static std::unique_ptr<lambda_xs> make();
|
||||
|
|
@ -105,6 +106,10 @@ namespace xo {
|
|||
|
||||
};
|
||||
} /*namespace scm*/
|
||||
|
||||
namespace print {
|
||||
PPDETAIL_ATOMIC(xo::scm::lambdastatetype);
|
||||
}
|
||||
} /*namespace xo*/
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -10,6 +10,13 @@
|
|||
|
||||
namespace xo {
|
||||
namespace print {
|
||||
template <>
|
||||
struct ppdetail<const xo::scm::envframestack*> {
|
||||
static inline bool print_pretty(const ppindentinfo & ppii, const xo::scm::envframestack * p) {
|
||||
return p->pretty_print(ppii);
|
||||
}
|
||||
};
|
||||
|
||||
template <>
|
||||
struct ppdetail<xo::scm::envframestack*> {
|
||||
static inline bool print_pretty(const ppindentinfo & ppii, const xo::scm::envframestack * p) {
|
||||
|
|
|
|||
|
|
@ -16,5 +16,19 @@ namespace xo {
|
|||
return p->pretty_print(ppii);
|
||||
}
|
||||
};
|
||||
|
||||
template <>
|
||||
struct ppdetail<const xo::scm::exprstatestack*> {
|
||||
static inline bool print_pretty(const ppindentinfo & ppii, const xo::scm::exprstatestack * p) {
|
||||
return p->pretty_print(ppii);
|
||||
}
|
||||
};
|
||||
|
||||
template <>
|
||||
struct ppdetail<xo::scm::exprstate*> {
|
||||
static inline bool print_pretty(const ppindentinfo & ppii, const xo::scm::exprstate * p) {
|
||||
return p->pretty_print(ppii);
|
||||
}
|
||||
};
|
||||
} /*namespace print*/
|
||||
} /*namespace xo*/
|
||||
|
|
|
|||
|
|
@ -6,6 +6,7 @@
|
|||
#pragma once
|
||||
|
||||
#include "exprstate.hpp"
|
||||
#include "xo/reflect/TypeDescr.hpp"
|
||||
#include <iostream>
|
||||
//#include <cstdint>
|
||||
|
||||
|
|
@ -90,6 +91,12 @@ namespace xo {
|
|||
|
||||
bool admits_f64() const;
|
||||
|
||||
void apply_type_error(const char * self_name,
|
||||
optype op,
|
||||
bp<Expression> expr1,
|
||||
bp<Expression> expr2,
|
||||
parserstatemachine * p_psm) const;
|
||||
|
||||
virtual const char * get_expect_str() const override;
|
||||
|
||||
virtual void on_expr(bp<Expression> expr,
|
||||
|
|
@ -113,6 +120,8 @@ namespace xo {
|
|||
parserstatemachine * p_psm) override;
|
||||
virtual void on_rightparen_token(const token_type & tk,
|
||||
parserstatemachine * p_psm) override;
|
||||
virtual void on_rightbrace_token(const token_type & tk,
|
||||
parserstatemachine * p_psm) override;
|
||||
virtual void on_then_token(const token_type & tk,
|
||||
parserstatemachine * p_psm) override;
|
||||
virtual void on_else_token(const token_type & tk,
|
||||
|
|
@ -132,6 +141,7 @@ namespace xo {
|
|||
parserstatemachine * p_psm) override;
|
||||
|
||||
virtual void print(std::ostream & os) const override;
|
||||
virtual bool pretty_print(const print::ppindentinfo & ppii) const override;
|
||||
|
||||
private:
|
||||
static std::unique_ptr<progress_xs> make(rp<Expression> valex,
|
||||
|
|
|
|||
|
|
@ -351,11 +351,17 @@ namespace xo {
|
|||
void
|
||||
define_xs::print(std::ostream & os) const {
|
||||
os << "<define_xs"
|
||||
<< xtag("this", (void*)this)
|
||||
//<< xtag("type", exs_type_)
|
||||
<< xtag("defxs_type", defxs_type_);
|
||||
os << ">";
|
||||
}
|
||||
|
||||
bool
|
||||
define_xs::pretty_print(const xo::print::ppindentinfo & ppii) const
|
||||
{
|
||||
return ppii.pps()->pretty_struct(ppii, "define_xs",
|
||||
refrtag("defxs_type", defxs_type_));
|
||||
}
|
||||
|
||||
} /*namespace scm*/
|
||||
} /*namespace xo*/
|
||||
|
||||
|
|
|
|||
|
|
@ -152,8 +152,7 @@ namespace xo {
|
|||
{
|
||||
using xo::ast::Constant;
|
||||
|
||||
constexpr bool c_debug_flag = true;
|
||||
scope log(XO_DEBUG(c_debug_flag));
|
||||
scope log(XO_DEBUG(p_psm->debug_flag()));
|
||||
|
||||
constexpr const char * c_self_name = "exprseq_xs::on_i64_token";
|
||||
|
||||
|
|
@ -173,6 +172,32 @@ namespace xo {
|
|||
}
|
||||
}
|
||||
|
||||
void
|
||||
exprseq_xs::on_f64_token(const token_type & tk,
|
||||
parserstatemachine * p_psm)
|
||||
{
|
||||
using xo::ast::Constant;
|
||||
|
||||
scope log(XO_DEBUG(p_psm->debug_flag()));
|
||||
|
||||
constexpr const char * c_self_name = "exprseq_xs::on_i64_token";
|
||||
|
||||
if (xseqtype_ == exprseqtype::toplevel_interactive)
|
||||
{
|
||||
progress_xs::start(Constant<double>::make(tk.f64_value()), p_psm);
|
||||
} else {
|
||||
/* policy: don't allow literals as toplevel expressions
|
||||
* unless interactive session.
|
||||
*/
|
||||
const char * exp = get_expect_str();
|
||||
|
||||
this->illegal_input_on_token(c_self_name,
|
||||
tk,
|
||||
exp,
|
||||
p_psm);
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
exprseq_xs::on_typedescr(TypeDescr /*td*/,
|
||||
parserstatemachine * /*p_psm*/)
|
||||
|
|
|
|||
|
|
@ -21,6 +21,7 @@ namespace xo {
|
|||
//using xo::ast::Constant;
|
||||
//using xo::reflect::Reflect;
|
||||
using xo::reflect::TypeDescr;
|
||||
using xo::print::ppindentinfo;
|
||||
|
||||
namespace scm {
|
||||
const char *
|
||||
|
|
@ -552,6 +553,13 @@ namespace xo {
|
|||
os << ">";
|
||||
}
|
||||
|
||||
bool
|
||||
exprstate::pretty_print(const ppindentinfo & ppii) const
|
||||
{
|
||||
return ppii.pps()->pretty_struct(ppii, "exprstate",
|
||||
refrtag("type", exs_type_));
|
||||
}
|
||||
|
||||
void
|
||||
exprstate::illegal_input_error(const char * self_name,
|
||||
const token_type & tk) const
|
||||
|
|
|
|||
|
|
@ -7,6 +7,7 @@
|
|||
//#include "exprstatestack.hpp"
|
||||
#include "parserstatemachine.hpp"
|
||||
#include "expect_expr_xs.hpp"
|
||||
#include "xo/indentlog/print/ppdetail_atomic.hpp"
|
||||
|
||||
namespace xo {
|
||||
namespace scm {
|
||||
|
|
|
|||
|
|
@ -212,6 +212,13 @@ namespace xo {
|
|||
<< ">";
|
||||
}
|
||||
|
||||
bool
|
||||
lambda_xs::pretty_print(const xo::print::ppindentinfo & ppii) const
|
||||
{
|
||||
return ppii.pps()->pretty_struct(ppii, "lambda_xs",
|
||||
refrtag("lmxs_type", lmxs_type_));
|
||||
}
|
||||
|
||||
} /*namespace scm*/
|
||||
} /*namespace xo*/
|
||||
|
||||
|
|
|
|||
|
|
@ -124,6 +124,21 @@ namespace xo {
|
|||
this->illegal_input_on_token(c_self_name, tk, exp, p_psm);
|
||||
}
|
||||
|
||||
void
|
||||
progress_xs::apply_type_error(const char * self_name,
|
||||
optype op,
|
||||
bp<Expression> expr1,
|
||||
bp<Expression> expr2,
|
||||
parserstatemachine * p_psm) const
|
||||
{
|
||||
std::string errmsg = tostr("incompatible argument types T1,T2 to op",
|
||||
xtag("op", op),
|
||||
xtag("T1", expr1->valuetype()),
|
||||
xtag("T2", expr2->valuetype()));
|
||||
|
||||
p_psm->on_error(self_name, std::move(errmsg));
|
||||
}
|
||||
|
||||
rp<Expression>
|
||||
progress_xs::assemble_expr(parserstatemachine * p_psm) {
|
||||
/* need to defer building Apply incase expr followed by higher-precedence operator:
|
||||
|
|
@ -177,16 +192,56 @@ namespace xo {
|
|||
assert(false);
|
||||
|
||||
case optype::op_add:
|
||||
return Apply::make_add2_f64(lhs_, rhs_);
|
||||
|
||||
// TODO: upconvert integer->double
|
||||
if (lhs_->valuetype()->is_i64() && rhs_->valuetype()->is_i64()) {
|
||||
return Apply::make_add2_i64(lhs_, rhs_);
|
||||
} else if (lhs_->valuetype()->is_f64() && rhs_->valuetype()->is_f64()) {
|
||||
return Apply::make_add2_f64(lhs_, rhs_);
|
||||
} else {
|
||||
this->apply_type_error(c_self_name,
|
||||
op_type_, lhs_, rhs_, p_psm);
|
||||
return nullptr;
|
||||
}
|
||||
break;
|
||||
case optype::op_subtract:
|
||||
return Apply::make_sub2_f64(lhs_, rhs_);
|
||||
// TODO: upconvert integer->double
|
||||
if (lhs_->valuetype()->is_i64() && rhs_->valuetype()->is_i64()) {
|
||||
return Apply::make_sub2_i64(lhs_, rhs_);
|
||||
} else if (lhs_->valuetype()->is_f64() && rhs_->valuetype()->is_f64()) {
|
||||
return Apply::make_sub2_f64(lhs_, rhs_);
|
||||
} else {
|
||||
this->apply_type_error(c_self_name,
|
||||
op_type_, lhs_, rhs_, p_psm);
|
||||
return nullptr;
|
||||
}
|
||||
break;
|
||||
|
||||
case optype::op_multiply:
|
||||
return Apply::make_mul2_f64(lhs_, rhs_);
|
||||
// TODO: upconvert integer->double
|
||||
if (lhs_->valuetype()->is_i64() && rhs_->valuetype()->is_i64()) {
|
||||
return Apply::make_mul2_i64(lhs_, rhs_);
|
||||
} else if (lhs_->valuetype()->is_f64() && rhs_->valuetype()->is_f64()) {
|
||||
return Apply::make_mul2_f64(lhs_, rhs_);
|
||||
} else {
|
||||
this->apply_type_error(c_self_name,
|
||||
op_type_, lhs_, rhs_, p_psm);
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
break;
|
||||
|
||||
case optype::op_divide:
|
||||
return Apply::make_div2_f64(lhs_, rhs_);
|
||||
// TODO: upconvert integer->double
|
||||
if (lhs_->valuetype()->is_i64() && rhs_->valuetype()->is_i64()) {
|
||||
return Apply::make_div2_i64(lhs_, rhs_);
|
||||
} else if (lhs_->valuetype()->is_f64() && rhs_->valuetype()->is_f64()) {
|
||||
return Apply::make_div2_f64(lhs_, rhs_);
|
||||
} else {
|
||||
this->apply_type_error(c_self_name,
|
||||
op_type_, lhs_, rhs_, p_psm);
|
||||
return nullptr;
|
||||
}
|
||||
break;
|
||||
|
||||
case optype::n_optype:
|
||||
/* unreachable */
|
||||
|
|
@ -250,9 +305,11 @@ namespace xo {
|
|||
|
||||
rp<Expression> expr2 = this->assemble_expr(p_psm);
|
||||
|
||||
std::unique_ptr<exprstate> self = p_psm->pop_exprstate();
|
||||
if (expr2) {
|
||||
std::unique_ptr<exprstate> self = p_psm->pop_exprstate();
|
||||
|
||||
p_psm->on_expr_with_semicolon(expr2);
|
||||
p_psm->on_expr_with_semicolon(expr2);
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
|
|
@ -438,6 +495,27 @@ namespace xo {
|
|||
*/
|
||||
}
|
||||
|
||||
void
|
||||
progress_xs::on_rightbrace_token(const token_type & tk,
|
||||
parserstatemachine * p_psm)
|
||||
{
|
||||
scope log(XO_DEBUG(p_psm->debug_flag()));
|
||||
|
||||
rp<Expression> expr = this->assemble_expr(p_psm);
|
||||
|
||||
log && log(xtag("assembled-expr", expr));
|
||||
|
||||
std::unique_ptr<exprstate> self = p_psm->pop_exprstate();
|
||||
|
||||
p_psm->on_expr(expr);
|
||||
p_psm->on_rightbrace_token(tk);
|
||||
|
||||
/* control here on input like:
|
||||
*
|
||||
* { n * n }
|
||||
*/
|
||||
}
|
||||
|
||||
namespace {
|
||||
optype
|
||||
tk2op(const tokentype & tktype) {
|
||||
|
|
@ -599,6 +677,27 @@ namespace xo {
|
|||
os << ">";
|
||||
}
|
||||
|
||||
bool
|
||||
progress_xs::pretty_print(const xo::print::ppindentinfo & ppii) const
|
||||
{
|
||||
if (ppii.upto()) {
|
||||
return (ppii.pps()->print_upto("<progress_xs")
|
||||
&& (lhs_ ? ppii.pps()->print_upto(refrtag("lhs", lhs_)) : true)
|
||||
&& (op_type_ != optype::invalid ? ppii.pps()->print_upto(refrtag("op", op_type_)) : true)
|
||||
&& (rhs_ ? ppii.pps()->print_upto(refrtag("rhs", rhs_)) : true)
|
||||
&& ppii.pps()->print_upto(">"));
|
||||
} else {
|
||||
ppii.pps()->write("<progress_xs");
|
||||
if (lhs_)
|
||||
ppii.pps()->pretty(refrtag("lhs", lhs_));
|
||||
if (op_type_ != optype::invalid)
|
||||
ppii.pps()->pretty(refrtag("op", op_type_));
|
||||
if (rhs_)
|
||||
ppii.pps()->pretty(refrtag("rhs", rhs_));
|
||||
ppii.pps()->write(">");
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
} /*namespace scm*/
|
||||
} /*namespace xo*/
|
||||
|
|
|
|||
|
|
@ -240,13 +240,13 @@ namespace xo {
|
|||
TypeDescrExtra * tdextra() const { return tdextra_.get(); }
|
||||
Metatype metatype() const { return tdextra_->metatype(); }
|
||||
|
||||
/* true iff the type represented by *this is the same as the type
|
||||
* represented by T.
|
||||
/** true iff the type represented by _c *this is the same as the type
|
||||
* represented by @tparam T
|
||||
*
|
||||
* Warning: comparing typeinfo address can give false negatives.
|
||||
* suspect this is caused by problems coalescing linker symbols
|
||||
* in the clang toolchain.
|
||||
*/
|
||||
* Warning: comparing typeinfo address can give false negatives.
|
||||
* suspect this is caused by problems coalescing linker symbols
|
||||
* in the clang toolchain.
|
||||
**/
|
||||
template<typename T>
|
||||
[[deprecated]]
|
||||
bool is_native() const {
|
||||
|
|
@ -317,6 +317,10 @@ namespace xo {
|
|||
}
|
||||
} /*recover_native2*/
|
||||
|
||||
bool is_i128() const;
|
||||
bool is_i64() const;
|
||||
bool is_f64() const;
|
||||
|
||||
bool is_pointer() const { return this->tdextra_->is_pointer(); }
|
||||
bool is_vector() const { return this->tdextra_->is_vector(); }
|
||||
bool is_struct() const { return this->tdextra_->is_struct(); }
|
||||
|
|
|
|||
|
|
@ -254,6 +254,22 @@ namespace xo {
|
|||
{
|
||||
}
|
||||
|
||||
bool
|
||||
TypeDescrBase::is_i64() const
|
||||
{
|
||||
static_assert(sizeof(long long) == 8);
|
||||
|
||||
return Reflect::is_native<long long>(this);
|
||||
}
|
||||
|
||||
bool
|
||||
TypeDescrBase::is_f64() const
|
||||
{
|
||||
static_assert(sizeof(double) == 8);
|
||||
|
||||
return Reflect::is_native<double>(this);
|
||||
}
|
||||
|
||||
TaggedPtr
|
||||
TypeDescrBase::most_derived_self_tp(void * object) const
|
||||
{
|
||||
|
|
@ -311,6 +327,11 @@ namespace xo {
|
|||
#endif
|
||||
|
||||
TypeDescrTable::TypeDescrTable() {
|
||||
/* want long == i64 */
|
||||
static_assert(sizeof(long) == 8);
|
||||
/* want double == f64 */
|
||||
static_assert(sizeof(double) == 8);
|
||||
|
||||
Reflect::require<bool>();
|
||||
Reflect::require<char>();
|
||||
Reflect::require<short>();
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue