xo-expression2: + DIfElseExpr + utest
This commit is contained in:
parent
3bae8cbb57
commit
e243264511
18 changed files with 1047 additions and 6 deletions
|
|
@ -150,6 +150,32 @@ xo_add_genfacetimpl(
|
|||
|
||||
# ----------------------------------------------------------------
|
||||
|
||||
# note: manual target; generated code committed to git
|
||||
xo_add_genfacetimpl(
|
||||
TARGET xo-expression2-facetimpl-expression-ifelseexpr
|
||||
FACET_PKG xo_expression2
|
||||
FACET Expression
|
||||
REPR IfElseExpr
|
||||
INPUT idl/IExpression_DIfElseExpr.json5
|
||||
OUTPUT_HPP_DIR include/xo/expression2
|
||||
OUTPUT_IMPL_SUBDIR detail
|
||||
OUTPUT_CPP_DIR src/expression2
|
||||
)
|
||||
|
||||
# note: manual target; generated code committed to git
|
||||
xo_add_genfacetimpl(
|
||||
TARGET xo-expression2-facetimpl-printable-ifelseexpr
|
||||
FACET_PKG xo_printable2
|
||||
FACET Printable
|
||||
REPR IfElseExpr
|
||||
INPUT idl/IPrintable_DIfElseExpr.json5
|
||||
OUTPUT_HPP_DIR include/xo/expression2
|
||||
OUTPUT_IMPL_SUBDIR detail
|
||||
OUTPUT_CPP_DIR src/expression2
|
||||
)
|
||||
|
||||
# ----------------------------------------------------------------
|
||||
|
||||
# note: manual target; generated code committed to git
|
||||
xo_add_genfacetimpl(
|
||||
TARGET xo-expression2-facetimpl-gcobject-uniquestring
|
||||
|
|
|
|||
12
xo-expression2/idl/IExpression_DIfElseExpr.json5
Normal file
12
xo-expression2/idl/IExpression_DIfElseExpr.json5
Normal file
|
|
@ -0,0 +1,12 @@
|
|||
{
|
||||
mode: "implementation",
|
||||
includes: [ "\"Expression.hpp\"" ],
|
||||
local_types: [ ],
|
||||
namespace1: "xo",
|
||||
namespace2: "scm",
|
||||
facet_idl: "idl/Expression.json5",
|
||||
brief: "provide AExpression interface for DIfElseExpr state",
|
||||
using_doxygen: true,
|
||||
repr: "DIfElseExpr",
|
||||
doc: ["doc for IExpression+DIfElseExpr" ],
|
||||
}
|
||||
13
xo-expression2/idl/IPrintable_DIfElseExpr.json5
Normal file
13
xo-expression2/idl/IPrintable_DIfElseExpr.json5
Normal file
|
|
@ -0,0 +1,13 @@
|
|||
{
|
||||
mode: "implementation",
|
||||
includes: [ "<xo/printable2/Printable.hpp>",
|
||||
"<xo/printable2/detail/IPrintable_Xfer.hpp>" ],
|
||||
local_types: [ ],
|
||||
namespace1: "xo",
|
||||
namespace2: "scm",
|
||||
facet_idl: "idl/Printable.json5",
|
||||
brief: "provide APrintable interface for DIfElseExpr",
|
||||
using_doxygen: true,
|
||||
repr: "DIfElseExpr",
|
||||
doc: [ "implement APrintable for DIfElseExpr" ],
|
||||
}
|
||||
230
xo-expression2/include/xo/expression2/DIfElseExpr.hpp
Normal file
230
xo-expression2/include/xo/expression2/DIfElseExpr.hpp
Normal file
|
|
@ -0,0 +1,230 @@
|
|||
/** @file DIfElseExpr.hpp
|
||||
*
|
||||
* @author Roland Conybeare, Jan 2026
|
||||
**/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "Expression.hpp"
|
||||
#include "TypeRef.hpp"
|
||||
#include "exprtype.hpp"
|
||||
#include <xo/alloc2/Allocator.hpp>
|
||||
//#include <vector>
|
||||
#include <string>
|
||||
//#include <cstdint>
|
||||
|
||||
namespace xo {
|
||||
namespace scm {
|
||||
|
||||
/** @class DIfExpr
|
||||
* @brief abstract syntax tree for a function definition
|
||||
**/
|
||||
class DIfElseExpr {
|
||||
public:
|
||||
using AAllocator = xo::mm::AAllocator;
|
||||
using TypeDescr = xo::reflect::TypeDescr;
|
||||
using ppindentinfo = xo::print::ppindentinfo;
|
||||
|
||||
public:
|
||||
/** @defgroup scm-ifelseexpr-constructors **/
|
||||
///@{
|
||||
|
||||
/**
|
||||
* @p ifexpr_type type for value produced by if-expression.
|
||||
* same as both when_true->valuetype() and
|
||||
* when_false->valuetype().
|
||||
* @p test test-expression; always execute
|
||||
* @p when_true then-branch; executes only when test succeeds
|
||||
* @p when_false else-branch; executes only when test fails
|
||||
**/
|
||||
DIfElseExpr(TypeRef ifexpr_type,
|
||||
obj<AExpression> test_expr,
|
||||
obj<AExpression> when_true,
|
||||
obj<AExpression> when_false);
|
||||
|
||||
/** create if-else expression using memory from @p mm.
|
||||
* @p when_false can be null
|
||||
**/
|
||||
static obj<AExpression,DIfElseExpr> make(obj<AAllocator> mm,
|
||||
obj<AExpression> test,
|
||||
obj<AExpression> when_true,
|
||||
obj<AExpression> when_false);
|
||||
|
||||
/** create expression for conditional execution of
|
||||
* @p when_true or @p when_false, depending on result
|
||||
* of evaluating expression @p test
|
||||
**/
|
||||
static DIfElseExpr * _make(obj<AAllocator> mm,
|
||||
obj<AExpression> test,
|
||||
obj<AExpression> when_true,
|
||||
obj<AExpression> when_false);
|
||||
|
||||
///@}
|
||||
/** @defgroup scm-ifelseexpr-access-methods **/
|
||||
///@{
|
||||
|
||||
obj<AExpression> test() const noexcept { return test_; }
|
||||
obj<AExpression> when_true() const noexcept { return when_true_; }
|
||||
obj<AExpression> when_false() const noexcept { return when_false_; }
|
||||
|
||||
///@}
|
||||
/** @defgroup scm-ifelseexpr-expression-facet **/
|
||||
///@{
|
||||
|
||||
exprtype extype() const noexcept { return exprtype::ifexpr; }
|
||||
TypeRef typeref() const noexcept { return typeref_; }
|
||||
TypeDescr valuetype() const noexcept { return typeref_.td(); }
|
||||
void assign_valuetype(TypeDescr td) noexcept;
|
||||
|
||||
///@}
|
||||
/** @defgroup scm-ifelseexpr-printable-facet **/
|
||||
///@{
|
||||
|
||||
bool pretty(const ppindentinfo & ppii) const;
|
||||
|
||||
///@}
|
||||
|
||||
#ifdef NOT_YET
|
||||
virtual std::set<std::string> get_free_variables() const override {
|
||||
std::set<std::string> retval = test_->get_free_variables();
|
||||
|
||||
std::set<std::string> free_vars;
|
||||
free_vars = when_true_->get_free_variables();
|
||||
for (const auto & s : free_vars)
|
||||
retval.insert(s);
|
||||
|
||||
free_vars = when_false_->get_free_variables();
|
||||
for (const auto & s : free_vars)
|
||||
retval.insert(s);
|
||||
|
||||
return retval;
|
||||
}
|
||||
|
||||
virtual std::size_t visit_preorder(VisitFn visitor_fn) override {
|
||||
std::size_t n = 1;
|
||||
|
||||
visitor_fn(this);
|
||||
|
||||
n += this->test_->visit_preorder(visitor_fn);
|
||||
n += this->when_true_->visit_preorder(visitor_fn);
|
||||
n += this->when_false_->visit_preorder(visitor_fn);
|
||||
|
||||
return n;
|
||||
}
|
||||
|
||||
virtual std::size_t visit_layer(VisitFn visitor_fn) override {
|
||||
std::size_t n = 1;
|
||||
|
||||
visitor_fn(this);
|
||||
|
||||
n += this->test_->visit_layer(visitor_fn);
|
||||
n += this->when_true_->visit_layer(visitor_fn);
|
||||
n += this->when_false_->visit_layer(visitor_fn);
|
||||
|
||||
return n;
|
||||
}
|
||||
|
||||
virtual rp<Expression> xform_layer(TransformFn xform_fn) override {
|
||||
this->test_ = this->test_->xform_layer(xform_fn);
|
||||
this->when_true_ = this->when_true_->xform_layer(xform_fn);
|
||||
this->when_false_= this->when_false_->xform_layer(xform_fn);
|
||||
|
||||
return xform_fn(this);
|
||||
}
|
||||
|
||||
virtual void attach_envs(bp<SymbolTable> p) override {
|
||||
test_->attach_envs(p);
|
||||
when_true_->attach_envs(p);
|
||||
when_false_->attach_envs(p);
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef NOT_USING
|
||||
virtual std::int32_t find_free_vars(std::set<bp<Variable>> * p_set) override {
|
||||
return (test_->find_free_vars(p_set)
|
||||
+ when_true_->find_free_vars(p_set)
|
||||
+ when_false_->find_free_vars(p_set));
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef NOPE
|
||||
virtual void display(std::ostream & os) const override;
|
||||
virtual std::uint32_t pretty_print(const ppindentinfo & ppi) const override;
|
||||
#endif
|
||||
|
||||
protected:
|
||||
#ifdef NOT_YET
|
||||
/**
|
||||
* @p ifexpr_type type for value produced by if-expression.
|
||||
* same as both when_true->valuetype() and
|
||||
* when_false->valuetype().
|
||||
* @p test test-expression; always execute
|
||||
* @p when_true then-branch; executes only when test succeeds
|
||||
* @p when_false else-branch; executes only when test fails
|
||||
**/
|
||||
IfExpr(TypeDescr ifexpr_type,
|
||||
rp<Expression> test,
|
||||
rp<Expression> when_true,
|
||||
rp<Expression> when_false)
|
||||
: Expression(exprtype::ifexpr, ifexpr_type),
|
||||
test_{std::move(test)},
|
||||
when_true_{std::move(when_true)},
|
||||
when_false_{std::move(when_false)} {}
|
||||
|
||||
static TypeDescr check_consistent_valuetype(const rp<Expression> & when_true,
|
||||
const rp<Expression> & when_false);
|
||||
|
||||
/** determine if-expr valuetype **/
|
||||
void establish_valuetype();
|
||||
#endif
|
||||
|
||||
private:
|
||||
/** expression value always has type consistent
|
||||
* with this description
|
||||
**/
|
||||
TypeRef typeref_;
|
||||
/** if:
|
||||
* (if x y z)
|
||||
*
|
||||
* executes x; if true execute y; otherwise execute z
|
||||
**/
|
||||
obj<AExpression> test_;
|
||||
obj<AExpression> when_true_;
|
||||
obj<AExpression> when_false_;
|
||||
}; /*IfExpr*/
|
||||
|
||||
#ifdef NOPE
|
||||
inline rp<IfExpr>
|
||||
make_ifexpr(const rp<Expression> & test,
|
||||
const rp<Expression> & when_true,
|
||||
const rp<Expression> & when_false)
|
||||
{
|
||||
return IfExpr::make(test, when_true, when_false);
|
||||
}
|
||||
|
||||
class IfExprAccess : public IfExpr {
|
||||
public:
|
||||
static rp<IfExprAccess> make(rp<Expression> test,
|
||||
rp<Expression> when_true,
|
||||
rp<Expression> when_false);
|
||||
static rp<IfExprAccess> make_empty();
|
||||
|
||||
void assign_test(rp<Expression> x) { test_ = std::move(x); }
|
||||
void assign_when_true(rp<Expression> x);
|
||||
void assign_when_false(rp<Expression> x);
|
||||
|
||||
private:
|
||||
IfExprAccess(TypeDescr ifexpr_type,
|
||||
rp<Expression> test,
|
||||
rp<Expression> when_true,
|
||||
rp<Expression> when_false)
|
||||
: IfExpr(ifexpr_type,
|
||||
std::move(test),
|
||||
std::move(when_true),
|
||||
std::move(when_false)) {}
|
||||
};
|
||||
#endif
|
||||
} /*namespace scm*/
|
||||
} /*namespace xo*/
|
||||
|
||||
/* end DIfElseExpr.hpp */
|
||||
|
|
@ -0,0 +1,66 @@
|
|||
/** @file IExpression_DIfElseExpr.hpp
|
||||
*
|
||||
* Generated automagically from ingredients:
|
||||
* 1. code generator:
|
||||
* [/Users/roland/proj/xo-umbrella2/xo-facet/codegen/genfacet]
|
||||
* arguments:
|
||||
* --input [idl/IExpression_DIfElseExpr.json5]
|
||||
* 2. jinja2 template for abstract facet .hpp file:
|
||||
* [iface_facet_repr.hpp.j2]
|
||||
* 3. idl for facet methods
|
||||
* [idl/IExpression_DIfElseExpr.json5]
|
||||
**/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "Expression.hpp"
|
||||
#include "Expression.hpp"
|
||||
#include "DIfElseExpr.hpp"
|
||||
|
||||
namespace xo { namespace scm { class IExpression_DIfElseExpr; } }
|
||||
|
||||
namespace xo {
|
||||
namespace facet {
|
||||
template <>
|
||||
struct FacetImplementation<xo::scm::AExpression,
|
||||
xo::scm::DIfElseExpr>
|
||||
{
|
||||
using ImplType = xo::scm::IExpression_Xfer
|
||||
<xo::scm::DIfElseExpr,
|
||||
xo::scm::IExpression_DIfElseExpr>;
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
namespace xo {
|
||||
namespace scm {
|
||||
/** @class IExpression_DIfElseExpr
|
||||
**/
|
||||
class IExpression_DIfElseExpr {
|
||||
public:
|
||||
/** @defgroup scm-expression-difelseexpr-type-traits **/
|
||||
///@{
|
||||
using TypeDescr = xo::scm::AExpression::TypeDescr;
|
||||
using Copaque = xo::scm::AExpression::Copaque;
|
||||
using Opaque = xo::scm::AExpression::Opaque;
|
||||
///@}
|
||||
/** @defgroup scm-expression-difelseexpr-methods **/
|
||||
///@{
|
||||
// const methods
|
||||
/** expression type (constant | apply | ..) **/
|
||||
static exprtype extype(const DIfElseExpr & self) noexcept;
|
||||
/** placeholder for type giving possible values for this expression **/
|
||||
static TypeRef typeref(const DIfElseExpr & self) noexcept;
|
||||
/** type giving possible values for this expression. Maybe null before typecheck **/
|
||||
static TypeDescr valuetype(const DIfElseExpr & self) noexcept;
|
||||
|
||||
// non-const methods
|
||||
/** assing to valuetype member. Useful when scaffolding expressions **/
|
||||
static void assign_valuetype(DIfElseExpr & self, TypeDescr td) noexcept;
|
||||
///@}
|
||||
};
|
||||
|
||||
} /*namespace scm*/
|
||||
} /*namespace xo*/
|
||||
|
||||
/* end */
|
||||
|
|
@ -0,0 +1,62 @@
|
|||
/** @file IPrintable_DIfElseExpr.hpp
|
||||
*
|
||||
* Generated automagically from ingredients:
|
||||
* 1. code generator:
|
||||
* [/Users/roland/proj/xo-umbrella2/xo-facet/codegen/genfacet]
|
||||
* arguments:
|
||||
* --input [idl/IPrintable_DIfElseExpr.json5]
|
||||
* 2. jinja2 template for abstract facet .hpp file:
|
||||
* [iface_facet_repr.hpp.j2]
|
||||
* 3. idl for facet methods
|
||||
* [idl/IPrintable_DIfElseExpr.json5]
|
||||
**/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "Printable.hpp"
|
||||
#include <xo/printable2/Printable.hpp>
|
||||
#include <xo/printable2/detail/IPrintable_Xfer.hpp>
|
||||
#include "DIfElseExpr.hpp"
|
||||
|
||||
namespace xo { namespace scm { class IPrintable_DIfElseExpr; } }
|
||||
|
||||
namespace xo {
|
||||
namespace facet {
|
||||
template <>
|
||||
struct FacetImplementation<xo::print::APrintable,
|
||||
xo::scm::DIfElseExpr>
|
||||
{
|
||||
using ImplType = xo::print::IPrintable_Xfer
|
||||
<xo::scm::DIfElseExpr,
|
||||
xo::scm::IPrintable_DIfElseExpr>;
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
namespace xo {
|
||||
namespace scm {
|
||||
/** @class IPrintable_DIfElseExpr
|
||||
**/
|
||||
class IPrintable_DIfElseExpr {
|
||||
public:
|
||||
/** @defgroup scm-printable-difelseexpr-type-traits **/
|
||||
///@{
|
||||
using ppindentinfo = xo::print::APrintable::ppindentinfo;
|
||||
using Copaque = xo::print::APrintable::Copaque;
|
||||
using Opaque = xo::print::APrintable::Opaque;
|
||||
///@}
|
||||
/** @defgroup scm-printable-difelseexpr-methods **/
|
||||
///@{
|
||||
// const methods
|
||||
/** Pretty-printing support for this object.
|
||||
See [xo-indentlog/xo/indentlog/pretty.hpp] **/
|
||||
static bool pretty(const DIfElseExpr & self, const ppindentinfo & ppii);
|
||||
|
||||
// non-const methods
|
||||
///@}
|
||||
};
|
||||
|
||||
} /*namespace scm*/
|
||||
} /*namespace xo*/
|
||||
|
||||
/* end */
|
||||
|
|
@ -38,9 +38,9 @@ namespace xo {
|
|||
#endif
|
||||
/** variable reference **/
|
||||
variable,
|
||||
#ifdef NOT_YET
|
||||
/** if-then-else **/
|
||||
ifexpr,
|
||||
#ifdef NOT_YET
|
||||
/** sequence **/
|
||||
sequence,
|
||||
/** type conversion **/
|
||||
|
|
|
|||
|
|
@ -8,6 +8,7 @@ set(SELF_SRCS
|
|||
DVariable.cpp
|
||||
DDefineExpr.cpp
|
||||
DApplyExpr.cpp
|
||||
DIfElseExpr.cpp
|
||||
|
||||
TypeRef.cpp
|
||||
|
||||
|
|
@ -25,6 +26,9 @@ set(SELF_SRCS
|
|||
IExpression_DApplyExpr.cpp
|
||||
IPrintable_DApplyExpr.cpp
|
||||
|
||||
IExpression_DIfElseExpr.cpp
|
||||
IPrintable_DIfElseExpr.cpp
|
||||
|
||||
DLocalSymtab.cpp
|
||||
DGlobalSymtab.cpp
|
||||
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
/** @file DDefineExpr.cpp
|
||||
*
|
||||
*
|
||||
* @author Roland Conybeare, Jan 2026
|
||||
**/
|
||||
|
||||
|
|
|
|||
184
xo-expression2/src/expression2/DIfElseExpr.cpp
Normal file
184
xo-expression2/src/expression2/DIfElseExpr.cpp
Normal file
|
|
@ -0,0 +1,184 @@
|
|||
/** @file DIfElseExpr.cpp
|
||||
*
|
||||
* @author Roland Conybeare, Jan 2026
|
||||
**/
|
||||
|
||||
#include "DIfElseExpr.hpp"
|
||||
#include "detail/IExpression_DIfElseExpr.hpp"
|
||||
#include <xo/printable2/Printable.hpp>
|
||||
#include <xo/facet/FacetRegistry.hpp>
|
||||
#include <xo/reflectutil/typeseq.hpp>
|
||||
|
||||
namespace xo {
|
||||
using xo::print::APrintable;
|
||||
using xo::reflect::typeseq;
|
||||
using xo::facet::FacetRegistry;
|
||||
|
||||
namespace scm {
|
||||
DIfElseExpr::DIfElseExpr(TypeRef ifexpr_tref,
|
||||
obj<AExpression> test_expr,
|
||||
obj<AExpression> when_true,
|
||||
obj<AExpression> when_false)
|
||||
: typeref_{ifexpr_tref},
|
||||
test_{test_expr},
|
||||
when_true_{when_true},
|
||||
when_false_{when_false}
|
||||
{}
|
||||
|
||||
obj<AExpression,DIfElseExpr>
|
||||
DIfElseExpr::make(obj<AAllocator> mm,
|
||||
obj<AExpression> test,
|
||||
obj<AExpression> when_true,
|
||||
obj<AExpression> when_false)
|
||||
{
|
||||
return obj<AExpression,DIfElseExpr>
|
||||
(_make(mm,
|
||||
test, when_true, when_false));
|
||||
}
|
||||
|
||||
DIfElseExpr *
|
||||
DIfElseExpr::_make(obj<AAllocator> mm,
|
||||
obj<AExpression> test,
|
||||
obj<AExpression> when_true,
|
||||
obj<AExpression> when_false)
|
||||
{
|
||||
void * mem = mm.alloc(typeseq::id<DIfElseExpr>(),
|
||||
sizeof(DIfElseExpr));
|
||||
|
||||
// just crete typevar here, then rely on type checking
|
||||
// later
|
||||
|
||||
auto prefix = TypeRef::prefix_type::from_chars("if");
|
||||
TypeRef tref = TypeRef::dwim(prefix, nullptr);
|
||||
|
||||
return new (mem) DIfElseExpr(tref,
|
||||
test,
|
||||
when_true,
|
||||
when_false);
|
||||
}
|
||||
|
||||
void
|
||||
DIfElseExpr::assign_valuetype(TypeDescr td) noexcept
|
||||
{
|
||||
typeref_.resolve(td);
|
||||
}
|
||||
|
||||
bool
|
||||
DIfElseExpr::pretty(const ppindentinfo & ppii) const
|
||||
{
|
||||
auto test
|
||||
= FacetRegistry::instance().try_variant<APrintable,
|
||||
AExpression>(test_);
|
||||
auto when_true
|
||||
= FacetRegistry::instance().try_variant<APrintable,
|
||||
AExpression>(when_true_);
|
||||
auto when_false
|
||||
= FacetRegistry::instance().try_variant<APrintable,
|
||||
AExpression>(when_false_);
|
||||
|
||||
|
||||
return ppii.pps()->pretty_struct
|
||||
(ppii,
|
||||
"DIfElseExpr",
|
||||
refrtag("typeref", typeref_),
|
||||
refrtag("test", test),
|
||||
refrtag("when_true", when_true),
|
||||
refrtag("when_false", when_false));
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------
|
||||
|
||||
#ifdef NOPE
|
||||
auto IfExpr::check_consistent_valuetype(const rp<Expression> & when_true,
|
||||
const rp<Expression> & when_false) -> TypeDescr
|
||||
{
|
||||
if (when_true->valuetype() != when_false->valuetype())
|
||||
return nullptr;
|
||||
|
||||
return when_true->valuetype();
|
||||
}
|
||||
|
||||
void IfExpr::establish_valuetype()
|
||||
{
|
||||
if (this->when_true_.get() && this->when_false_.get())
|
||||
this->assign_valuetype(check_consistent_valuetype(this->when_true_, this->when_false_));
|
||||
}
|
||||
|
||||
rp<IfExpr>
|
||||
IfExpr::make(const rp<Expression> & test,
|
||||
const rp<Expression> & when_true,
|
||||
const rp<Expression> & when_false)
|
||||
{
|
||||
/** TODO: verify test returns _boolean_ type **/
|
||||
|
||||
if (when_true->valuetype() != when_false->valuetype()) {
|
||||
throw std::runtime_error
|
||||
(tostr("IfExpr::make:"
|
||||
" types {T1,T2} found for branches of if-expr"
|
||||
" where equal types expected",
|
||||
xtag("T1", when_true->valuetype()->canonical_name()),
|
||||
xtag("T2", when_false->valuetype()->canonical_name())));
|
||||
}
|
||||
|
||||
/* arbitrary choice here */
|
||||
auto ifexpr_type = when_true->valuetype();
|
||||
|
||||
return new IfExpr(ifexpr_type,
|
||||
test,
|
||||
when_true,
|
||||
when_false);
|
||||
} /*make*/
|
||||
|
||||
void
|
||||
IfExpr::display(std::ostream & os) const {
|
||||
os << "<IfExpr"
|
||||
<< xtag("test", test_)
|
||||
<< xtag("when_true", when_true_);
|
||||
if (when_false_)
|
||||
os << xtag("when_false", when_false_);
|
||||
os << ">";
|
||||
} /*display*/
|
||||
|
||||
std::uint32_t
|
||||
IfExpr::pretty_print(const ppindentinfo & ppii) const {
|
||||
return ppii.pps()->pretty_struct(ppii, "IfExpr",
|
||||
refrtag("test", test_),
|
||||
refrtag("when_true", when_true_),
|
||||
refrtag("when_false", when_false_));
|
||||
}
|
||||
|
||||
rp<IfExprAccess>
|
||||
IfExprAccess::make(rp<Expression> test,
|
||||
rp<Expression> when_true,
|
||||
rp<Expression> when_false)
|
||||
{
|
||||
auto ifexpr_type = check_consistent_valuetype(when_true, when_false);
|
||||
|
||||
return new IfExprAccess(ifexpr_type, std::move(test), std::move(when_true), std::move(when_false));
|
||||
}
|
||||
|
||||
rp<IfExprAccess>
|
||||
IfExprAccess::make_empty()
|
||||
{
|
||||
return new IfExprAccess(nullptr /*ifexpr_valuetype*/,
|
||||
nullptr /*test*/,
|
||||
nullptr /*when_true*/,
|
||||
nullptr /*when_false*/);
|
||||
}
|
||||
|
||||
void
|
||||
IfExprAccess::assign_when_true(rp<Expression> x)
|
||||
{
|
||||
this->when_true_ = std::move(x);
|
||||
}
|
||||
|
||||
void
|
||||
IfExprAccess::assign_when_false(rp<Expression> x)
|
||||
{
|
||||
this->when_false_ = std::move(x);
|
||||
}
|
||||
#endif
|
||||
} /*namespace scm*/
|
||||
} /*namespace xo*/
|
||||
|
||||
/* end DIfElseExpr.cpp */
|
||||
45
xo-expression2/src/expression2/IExpression_DIfElseExpr.cpp
Normal file
45
xo-expression2/src/expression2/IExpression_DIfElseExpr.cpp
Normal file
|
|
@ -0,0 +1,45 @@
|
|||
/** @file IExpression_DIfElseExpr.cpp
|
||||
*
|
||||
* Generated automagically from ingredients:
|
||||
* 1. code generator:
|
||||
* [/Users/roland/proj/xo-umbrella2/xo-facet/codegen/genfacet]
|
||||
* arguments:
|
||||
* --input [idl/IExpression_DIfElseExpr.json5]
|
||||
* 2. jinja2 template for abstract facet .hpp file:
|
||||
* [iface_facet_any.hpp.j2]
|
||||
* 3. idl for facet methods
|
||||
* [idl/IExpression_DIfElseExpr.json5]
|
||||
**/
|
||||
|
||||
#include "detail/IExpression_DIfElseExpr.hpp"
|
||||
|
||||
namespace xo {
|
||||
namespace scm {
|
||||
auto
|
||||
IExpression_DIfElseExpr::extype(const DIfElseExpr & self) noexcept -> exprtype
|
||||
{
|
||||
return self.extype();
|
||||
}
|
||||
|
||||
auto
|
||||
IExpression_DIfElseExpr::typeref(const DIfElseExpr & self) noexcept -> TypeRef
|
||||
{
|
||||
return self.typeref();
|
||||
}
|
||||
|
||||
auto
|
||||
IExpression_DIfElseExpr::valuetype(const DIfElseExpr & self) noexcept -> TypeDescr
|
||||
{
|
||||
return self.valuetype();
|
||||
}
|
||||
|
||||
auto
|
||||
IExpression_DIfElseExpr::assign_valuetype(DIfElseExpr & self, TypeDescr td) noexcept -> void
|
||||
{
|
||||
self.assign_valuetype(td);
|
||||
}
|
||||
|
||||
} /*namespace scm*/
|
||||
} /*namespace xo*/
|
||||
|
||||
/* end IExpression_DIfElseExpr.cpp */
|
||||
28
xo-expression2/src/expression2/IPrintable_DIfElseExpr.cpp
Normal file
28
xo-expression2/src/expression2/IPrintable_DIfElseExpr.cpp
Normal file
|
|
@ -0,0 +1,28 @@
|
|||
/** @file IPrintable_DIfElseExpr.cpp
|
||||
*
|
||||
* Generated automagically from ingredients:
|
||||
* 1. code generator:
|
||||
* [/Users/roland/proj/xo-umbrella2/xo-facet/codegen/genfacet]
|
||||
* arguments:
|
||||
* --input [idl/IPrintable_DIfElseExpr.json5]
|
||||
* 2. jinja2 template for abstract facet .hpp file:
|
||||
* [iface_facet_any.hpp.j2]
|
||||
* 3. idl for facet methods
|
||||
* [idl/IPrintable_DIfElseExpr.json5]
|
||||
**/
|
||||
|
||||
#include "detail/IPrintable_DIfElseExpr.hpp"
|
||||
|
||||
namespace xo {
|
||||
namespace scm {
|
||||
auto
|
||||
IPrintable_DIfElseExpr::pretty(const DIfElseExpr & self, const ppindentinfo & ppii) -> bool
|
||||
{
|
||||
return self.pretty(ppii);
|
||||
}
|
||||
|
||||
|
||||
} /*namespace scm*/
|
||||
} /*namespace xo*/
|
||||
|
||||
/* end IPrintable_DIfElseExpr.cpp */
|
||||
|
|
@ -20,6 +20,9 @@
|
|||
#include <xo/expression2/detail/IExpression_DApplyExpr.hpp>
|
||||
#include <xo/expression2/detail/IPrintable_DApplyExpr.hpp>
|
||||
|
||||
#include <xo/expression2/detail/IExpression_DIfElseExpr.hpp>
|
||||
#include <xo/expression2/detail/IPrintable_DIfElseExpr.hpp>
|
||||
|
||||
#include <xo/gc/detail/AGCObject.hpp>
|
||||
#include <xo/printable2/detail/APrintable.hpp>
|
||||
#include <xo/facet/FacetRegistry.hpp>
|
||||
|
|
@ -44,7 +47,8 @@ namespace xo {
|
|||
// +- Constant
|
||||
// +- Variable
|
||||
// +- DefineExpr
|
||||
// \- ApplyExpr
|
||||
// +- ApplyExpr
|
||||
// \- IfElseExpr
|
||||
|
||||
FacetRegistry::register_impl<AExpression, DConstant>();
|
||||
FacetRegistry::register_impl<APrintable, DConstant>();
|
||||
|
|
@ -58,11 +62,15 @@ namespace xo {
|
|||
FacetRegistry::register_impl<AExpression, DApplyExpr>();
|
||||
FacetRegistry::register_impl<APrintable, DApplyExpr>();
|
||||
|
||||
FacetRegistry::register_impl<AExpression, DIfElseExpr>();
|
||||
FacetRegistry::register_impl<APrintable, DIfElseExpr>();
|
||||
|
||||
log && log(xtag("DUniqueString.tseq", typeseq::id<DUniqueString>()));
|
||||
log && log(xtag("DDefineExpr.tseq", typeseq::id<DDefineExpr>()));
|
||||
log && log(xtag("DVariable.tseq", typeseq::id<DVariable>()));
|
||||
log && log(xtag("DConstant.tseq", typeseq::id<DConstant>()));
|
||||
log && log(xtag("DApplyExpr.tseq", typeseq::id<DApplyExpr>()));
|
||||
log && log(xtag("DIfElseExpr.tseq", typeseq::id<DIfElseExpr>()));
|
||||
|
||||
log && log(xtag("AExpression.tqseq", typeseq::id<AExpression>()));
|
||||
|
||||
|
|
|
|||
|
|
@ -9,6 +9,7 @@ set(UTEST_SRCS
|
|||
DVariable.test.cpp
|
||||
DApplyExpr.test.cpp
|
||||
DDefineExpr.test.cpp
|
||||
DIfElseExpr.test.cpp
|
||||
)
|
||||
|
||||
xo_add_utest_executable(${UTEST_EXE} ${UTEST_SRCS})
|
||||
|
|
|
|||
345
xo-expression2/utest/DIfElseExpr.test.cpp
Normal file
345
xo-expression2/utest/DIfElseExpr.test.cpp
Normal file
|
|
@ -0,0 +1,345 @@
|
|||
/** @file DIfElseExpr.test.cpp
|
||||
*
|
||||
* @author Roland Conybeare, Jan 2026
|
||||
**/
|
||||
|
||||
#include "init_expression2.hpp"
|
||||
#include <xo/expression2/DIfElseExpr.hpp>
|
||||
#include <xo/expression2/detail/IExpression_DIfElseExpr.hpp>
|
||||
#include <xo/expression2/detail/IPrintable_DIfElseExpr.hpp>
|
||||
#include <xo/expression2/DConstant.hpp>
|
||||
#include <xo/expression2/detail/IExpression_DConstant.hpp>
|
||||
|
||||
#include <xo/object2/DFloat.hpp>
|
||||
#include <xo/object2/DBoolean.hpp>
|
||||
#include <xo/object2/number/IGCObject_DFloat.hpp>
|
||||
#include <xo/object2/boolean/IGCObject_DBoolean.hpp>
|
||||
|
||||
#include <xo/gc/CollectorTypeRegistry.hpp>
|
||||
#include <xo/gc/DX1Collector.hpp>
|
||||
#include <xo/gc/detail/IAllocator_DX1Collector.hpp>
|
||||
#include <xo/gc/detail/ICollector_DX1Collector.hpp>
|
||||
|
||||
#include <xo/printable2/Printable.hpp>
|
||||
#include <xo/facet/FacetRegistry.hpp>
|
||||
#include <xo/reflect/Reflect.hpp>
|
||||
|
||||
#include <xo/indentlog/scope.hpp>
|
||||
|
||||
#include <catch2/catch.hpp>
|
||||
|
||||
#include <sstream>
|
||||
|
||||
namespace ut {
|
||||
using xo::S_expression2_tag;
|
||||
using xo::scm::DIfElseExpr;
|
||||
using xo::scm::DConstant;
|
||||
using xo::scm::DFloat;
|
||||
using xo::scm::DBoolean;
|
||||
using xo::scm::AExpression;
|
||||
using xo::mm::CollectorTypeRegistry;
|
||||
using xo::mm::AAllocator;
|
||||
using xo::mm::ACollector;
|
||||
using xo::mm::AGCObject;
|
||||
using xo::mm::DX1Collector;
|
||||
using xo::mm::CollectorConfig;
|
||||
using xo::mm::ArenaConfig;
|
||||
using xo::print::APrintable;
|
||||
using xo::print::ppstate_standalone;
|
||||
using xo::print::ppconfig;
|
||||
using xo::facet::FacetRegistry;
|
||||
using xo::facet::with_facet;
|
||||
using xo::facet::obj;
|
||||
using xo::reflect::Reflect;
|
||||
using xo::InitEvidence;
|
||||
using xo::InitSubsys;
|
||||
using xo::scope;
|
||||
|
||||
static InitEvidence s_init = InitSubsys<S_expression2_tag>::require();
|
||||
|
||||
TEST_CASE("DIfElseExpr-init", "[expression2][DIfElseExpr]")
|
||||
{
|
||||
REQUIRE(s_init.evidence());
|
||||
}
|
||||
|
||||
TEST_CASE("DIfElseExpr-make", "[expression2][DIfElseExpr]")
|
||||
{
|
||||
REQUIRE(s_init.evidence());
|
||||
|
||||
CollectorConfig cfg{
|
||||
.name_ = "difelseexpr_make_test",
|
||||
.arena_config_ = ArenaConfig{
|
||||
.size_ = 8192,
|
||||
.store_header_flag_ = true},
|
||||
.object_types_z_ = 16384,
|
||||
.gc_trigger_v_{{4096, 4096}},
|
||||
.debug_flag_ = false,
|
||||
};
|
||||
|
||||
DX1Collector gc(cfg);
|
||||
auto alloc = with_facet<AAllocator>::mkobj(&gc);
|
||||
auto coll = with_facet<ACollector>::mkobj(&gc);
|
||||
|
||||
bool ok = CollectorTypeRegistry::instance().install_types(coll);
|
||||
REQUIRE(ok);
|
||||
|
||||
// Create test expression: constant true
|
||||
obj<AGCObject> bval = DBoolean::box<AGCObject>(alloc, true);
|
||||
auto test_expr = DConstant::make(alloc, bval);
|
||||
REQUIRE(test_expr.data() != nullptr);
|
||||
|
||||
// Create when_true expression: constant 1.0
|
||||
obj<AGCObject> fval1 = DFloat::box<AGCObject>(alloc, 1.0);
|
||||
auto when_true_expr = DConstant::make(alloc, fval1);
|
||||
REQUIRE(when_true_expr.data() != nullptr);
|
||||
|
||||
// Create when_false expression: constant 2.0
|
||||
obj<AGCObject> fval2 = DFloat::box<AGCObject>(alloc, 2.0);
|
||||
auto when_false_expr = DConstant::make(alloc, fval2);
|
||||
REQUIRE(when_false_expr.data() != nullptr);
|
||||
|
||||
// Create if-else expression: if true then 1.0 else 2.0
|
||||
auto ifexpr = DIfElseExpr::make(alloc, test_expr, when_true_expr, when_false_expr);
|
||||
REQUIRE(ifexpr.data() != nullptr);
|
||||
}
|
||||
|
||||
TEST_CASE("DIfElseExpr-test", "[expression2][DIfElseExpr]")
|
||||
{
|
||||
REQUIRE(s_init.evidence());
|
||||
|
||||
CollectorConfig cfg{
|
||||
.name_ = "difelseexpr_test_test",
|
||||
.arena_config_ = ArenaConfig{
|
||||
.size_ = 8192,
|
||||
.store_header_flag_ = true},
|
||||
.object_types_z_ = 16384,
|
||||
.gc_trigger_v_{{4096, 4096}},
|
||||
.debug_flag_ = false,
|
||||
};
|
||||
|
||||
DX1Collector gc(cfg);
|
||||
auto alloc = with_facet<AAllocator>::mkobj(&gc);
|
||||
auto coll = with_facet<ACollector>::mkobj(&gc);
|
||||
|
||||
bool ok = CollectorTypeRegistry::instance().install_types(coll);
|
||||
REQUIRE(ok);
|
||||
|
||||
obj<AGCObject> bval = DBoolean::box<AGCObject>(alloc, true);
|
||||
auto test_expr = DConstant::make(alloc, bval);
|
||||
|
||||
obj<AGCObject> fval1 = DFloat::box<AGCObject>(alloc, 1.0);
|
||||
auto when_true_expr = DConstant::make(alloc, fval1);
|
||||
|
||||
obj<AGCObject> fval2 = DFloat::box<AGCObject>(alloc, 2.0);
|
||||
auto when_false_expr = DConstant::make(alloc, fval2);
|
||||
|
||||
auto ifexpr = DIfElseExpr::make(alloc, test_expr, when_true_expr, when_false_expr);
|
||||
REQUIRE(ifexpr.data() != nullptr);
|
||||
|
||||
obj<AExpression> test = ifexpr.data()->test();
|
||||
REQUIRE(test.data() != nullptr);
|
||||
REQUIRE(test.extype() == xo::scm::exprtype::constant);
|
||||
}
|
||||
|
||||
TEST_CASE("DIfElseExpr-when-true", "[expression2][DIfElseExpr]")
|
||||
{
|
||||
REQUIRE(s_init.evidence());
|
||||
|
||||
CollectorConfig cfg{
|
||||
.name_ = "difelseexpr_when_true_test",
|
||||
.arena_config_ = ArenaConfig{
|
||||
.size_ = 8192,
|
||||
.store_header_flag_ = true},
|
||||
.object_types_z_ = 16384,
|
||||
.gc_trigger_v_{{4096, 4096}},
|
||||
.debug_flag_ = false,
|
||||
};
|
||||
|
||||
DX1Collector gc(cfg);
|
||||
auto alloc = with_facet<AAllocator>::mkobj(&gc);
|
||||
auto coll = with_facet<ACollector>::mkobj(&gc);
|
||||
|
||||
bool ok = CollectorTypeRegistry::instance().install_types(coll);
|
||||
REQUIRE(ok);
|
||||
|
||||
obj<AGCObject> bval = DBoolean::box<AGCObject>(alloc, true);
|
||||
auto test_expr = DConstant::make(alloc, bval);
|
||||
|
||||
obj<AGCObject> fval1 = DFloat::box<AGCObject>(alloc, 1.0);
|
||||
auto when_true_expr = DConstant::make(alloc, fval1);
|
||||
|
||||
obj<AGCObject> fval2 = DFloat::box<AGCObject>(alloc, 2.0);
|
||||
auto when_false_expr = DConstant::make(alloc, fval2);
|
||||
|
||||
auto ifexpr = DIfElseExpr::make(alloc, test_expr, when_true_expr, when_false_expr);
|
||||
REQUIRE(ifexpr.data() != nullptr);
|
||||
|
||||
obj<AExpression> wt = ifexpr.data()->when_true();
|
||||
REQUIRE(wt.data() != nullptr);
|
||||
REQUIRE(wt.extype() == xo::scm::exprtype::constant);
|
||||
}
|
||||
|
||||
TEST_CASE("DIfElseExpr-when-false", "[expression2][DIfElseExpr]")
|
||||
{
|
||||
REQUIRE(s_init.evidence());
|
||||
|
||||
CollectorConfig cfg{
|
||||
.name_ = "difelseexpr_when_false_test",
|
||||
.arena_config_ = ArenaConfig{
|
||||
.size_ = 8192,
|
||||
.store_header_flag_ = true},
|
||||
.object_types_z_ = 16384,
|
||||
.gc_trigger_v_{{4096, 4096}},
|
||||
.debug_flag_ = false,
|
||||
};
|
||||
|
||||
DX1Collector gc(cfg);
|
||||
auto alloc = with_facet<AAllocator>::mkobj(&gc);
|
||||
auto coll = with_facet<ACollector>::mkobj(&gc);
|
||||
|
||||
bool ok = CollectorTypeRegistry::instance().install_types(coll);
|
||||
REQUIRE(ok);
|
||||
|
||||
obj<AGCObject> bval = DBoolean::box<AGCObject>(alloc, false);
|
||||
auto test_expr = DConstant::make(alloc, bval);
|
||||
|
||||
obj<AGCObject> fval1 = DFloat::box<AGCObject>(alloc, 1.0);
|
||||
auto when_true_expr = DConstant::make(alloc, fval1);
|
||||
|
||||
obj<AGCObject> fval2 = DFloat::box<AGCObject>(alloc, 2.0);
|
||||
auto when_false_expr = DConstant::make(alloc, fval2);
|
||||
|
||||
auto ifexpr = DIfElseExpr::make(alloc, test_expr, when_true_expr, when_false_expr);
|
||||
REQUIRE(ifexpr.data() != nullptr);
|
||||
|
||||
obj<AExpression> wf = ifexpr.data()->when_false();
|
||||
REQUIRE(wf.data() != nullptr);
|
||||
REQUIRE(wf.extype() == xo::scm::exprtype::constant);
|
||||
}
|
||||
|
||||
TEST_CASE("DIfElseExpr-extype", "[expression2][DIfElseExpr]")
|
||||
{
|
||||
REQUIRE(s_init.evidence());
|
||||
|
||||
CollectorConfig cfg{
|
||||
.name_ = "difelseexpr_extype_test",
|
||||
.arena_config_ = ArenaConfig{
|
||||
.size_ = 8192,
|
||||
.store_header_flag_ = true},
|
||||
.object_types_z_ = 16384,
|
||||
.gc_trigger_v_{{4096, 4096}},
|
||||
.debug_flag_ = false,
|
||||
};
|
||||
|
||||
DX1Collector gc(cfg);
|
||||
auto alloc = with_facet<AAllocator>::mkobj(&gc);
|
||||
auto coll = with_facet<ACollector>::mkobj(&gc);
|
||||
|
||||
bool ok = CollectorTypeRegistry::instance().install_types(coll);
|
||||
REQUIRE(ok);
|
||||
|
||||
obj<AGCObject> bval = DBoolean::box<AGCObject>(alloc, true);
|
||||
auto test_expr = DConstant::make(alloc, bval);
|
||||
|
||||
obj<AGCObject> fval1 = DFloat::box<AGCObject>(alloc, 1.0);
|
||||
auto when_true_expr = DConstant::make(alloc, fval1);
|
||||
|
||||
obj<AGCObject> fval2 = DFloat::box<AGCObject>(alloc, 2.0);
|
||||
auto when_false_expr = DConstant::make(alloc, fval2);
|
||||
|
||||
auto ifexpr = DIfElseExpr::make(alloc, test_expr, when_true_expr, when_false_expr);
|
||||
REQUIRE(ifexpr.data() != nullptr);
|
||||
REQUIRE(ifexpr.data()->extype() == xo::scm::exprtype::ifexpr);
|
||||
}
|
||||
|
||||
TEST_CASE("DIfElseExpr-valuetype", "[expression2][DIfElseExpr]")
|
||||
{
|
||||
REQUIRE(s_init.evidence());
|
||||
|
||||
CollectorConfig cfg{
|
||||
.name_ = "difelseexpr_valuetype_test",
|
||||
.arena_config_ = ArenaConfig{
|
||||
.size_ = 8192,
|
||||
.store_header_flag_ = true},
|
||||
.object_types_z_ = 16384,
|
||||
.gc_trigger_v_{{4096, 4096}},
|
||||
.debug_flag_ = false,
|
||||
};
|
||||
|
||||
DX1Collector gc(cfg);
|
||||
auto alloc = with_facet<AAllocator>::mkobj(&gc);
|
||||
auto coll = with_facet<ACollector>::mkobj(&gc);
|
||||
|
||||
bool ok = CollectorTypeRegistry::instance().install_types(coll);
|
||||
REQUIRE(ok);
|
||||
|
||||
obj<AGCObject> bval = DBoolean::box<AGCObject>(alloc, true);
|
||||
auto test_expr = DConstant::make(alloc, bval);
|
||||
|
||||
obj<AGCObject> fval1 = DFloat::box<AGCObject>(alloc, 1.0);
|
||||
auto when_true_expr = DConstant::make(alloc, fval1);
|
||||
|
||||
obj<AGCObject> fval2 = DFloat::box<AGCObject>(alloc, 2.0);
|
||||
auto when_false_expr = DConstant::make(alloc, fval2);
|
||||
|
||||
auto ifexpr = DIfElseExpr::make(alloc, test_expr, when_true_expr, when_false_expr);
|
||||
REQUIRE(ifexpr.data() != nullptr);
|
||||
|
||||
// valuetype may be null before type resolution
|
||||
// just verify we can call it
|
||||
ifexpr.data()->valuetype();
|
||||
}
|
||||
|
||||
TEST_CASE("DIfElseExpr-pretty", "[expression2][DIfElseExpr][pp]")
|
||||
{
|
||||
scope log(XO_DEBUG(true));
|
||||
|
||||
REQUIRE(s_init.evidence());
|
||||
|
||||
CollectorConfig cfg{
|
||||
.name_ = "difelseexpr_pretty_test",
|
||||
.arena_config_ = ArenaConfig{
|
||||
.size_ = 8192,
|
||||
.store_header_flag_ = true},
|
||||
.object_types_z_ = 16384,
|
||||
.gc_trigger_v_{{4096, 4096}},
|
||||
.debug_flag_ = false,
|
||||
};
|
||||
|
||||
DX1Collector gc(cfg);
|
||||
auto alloc = with_facet<AAllocator>::mkobj(&gc);
|
||||
auto coll = with_facet<ACollector>::mkobj(&gc);
|
||||
|
||||
bool ok = CollectorTypeRegistry::instance().install_types(coll);
|
||||
REQUIRE(ok);
|
||||
|
||||
obj<AGCObject> bval = DBoolean::box<AGCObject>(alloc, true);
|
||||
auto test_expr = DConstant::make(alloc, bval);
|
||||
|
||||
obj<AGCObject> fval1 = DFloat::box<AGCObject>(alloc, 1.0);
|
||||
auto when_true_expr = DConstant::make(alloc, fval1);
|
||||
|
||||
obj<AGCObject> fval2 = DFloat::box<AGCObject>(alloc, 2.0);
|
||||
auto when_false_expr = DConstant::make(alloc, fval2);
|
||||
|
||||
auto ifexpr = DIfElseExpr::make(alloc,
|
||||
test_expr,
|
||||
when_true_expr, when_false_expr);
|
||||
REQUIRE(ifexpr.data() != nullptr);
|
||||
|
||||
std::stringstream ss;
|
||||
ppconfig ppc;
|
||||
ppstate_standalone pps(&ss, 0, &ppc);
|
||||
|
||||
obj<APrintable,DIfElseExpr> ifexpr_pr(ifexpr.data());
|
||||
pps.pretty(ifexpr_pr);
|
||||
|
||||
std::string output = ss.str();
|
||||
|
||||
log && log(output);
|
||||
|
||||
CHECK(output.find("DIfElseExpr") != std::string::npos);
|
||||
}
|
||||
}
|
||||
|
||||
/* end DIfElseExpr.test.cpp */
|
||||
|
|
@ -63,6 +63,12 @@ namespace xo {
|
|||
**/
|
||||
void _do_eval_apply_op();
|
||||
|
||||
/** evaluate an if-else expression
|
||||
* Require:
|
||||
* - expression in @ref expr_
|
||||
**/
|
||||
void _do_eval_if_else_op();
|
||||
|
||||
private:
|
||||
/*
|
||||
* Some registers are preserved by evaluation:
|
||||
|
|
|
|||
|
|
@ -54,6 +54,9 @@ namespace xo {
|
|||
case exprtype::apply:
|
||||
_do_eval_apply_op();
|
||||
break;
|
||||
case exprtype::ifexpr:
|
||||
_do_eval_if_else_op();
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -87,6 +90,13 @@ namespace xo {
|
|||
// not implemented
|
||||
assert(false);
|
||||
}
|
||||
|
||||
void
|
||||
VirtualSchematikaMachine::_do_eval_if_else_op()
|
||||
{
|
||||
// not implemented
|
||||
assert(false);
|
||||
}
|
||||
} /*namespace scm*/
|
||||
} /*namespace xo*/
|
||||
|
||||
|
|
|
|||
|
|
@ -1186,9 +1186,10 @@ namespace xo {
|
|||
|
||||
case optype::op_multiply:
|
||||
{
|
||||
auto pm_obj = with_facet<AGCObject>::mkobj(&Primitives::s_mul_gco_gco_pm);
|
||||
|
||||
auto fn_expr = DConstant::make(p_psm->expr_alloc(), pm_obj);
|
||||
auto pm_obj = (with_facet<AGCObject>::mkobj
|
||||
(&Primitives::s_mul_gco_gco_pm));
|
||||
auto fn_expr = (DConstant::make
|
||||
(p_psm->expr_alloc(), pm_obj));
|
||||
|
||||
/* note:
|
||||
* 1. don't assume we know lhs_ / rhs_ value types yet.
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue