xo-expression: + ConvertExpr

This commit is contained in:
Roland Conybeare 2024-08-06 03:20:38 -04:00
commit 0708bc7569
3 changed files with 163 additions and 0 deletions

View file

@ -0,0 +1,109 @@
/* file ConvertExpr.hpp
*
* author: Roland Conybeare, Aug 2024
*/
#pragma once
#include "Expression.hpp"
namespace xo {
namespace ast {
/** @class Convertexpr
* @brief Convenience for automatic type conversion
*
* This is equivalent to calling a built-in primitive
* that performs the conversion.
*
* We rely on this for convenience, for example to parse
* code like
*
* def foo : i16 = 0
**/
class ConvertExpr : public Expression {
public:
static rp<ConvertExpr> make(TypeDescr dest_type,
rp<Expression> arg);
static ref::brw<ConvertExpr> from(ref::brw<Expression> x) {
return ref::brw<ConvertExpr>::from(x);
}
const rp<Expression> & arg() const { return arg_; }
// ----- Expression -----
virtual std::set<std::string> get_free_variables() const override;
virtual std::size_t visit_preorder(VisitFn visitor_fn) override {
std::size_t n = 1;
visitor_fn(this);
n += arg_->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->arg_->visit_layer(visitor_fn);
return n;
}
virtual rp<Expression> xform_layer(TransformFn xform_fn) override {
this->arg_ = this->arg_->xform_layer(xform_fn);
return xform_fn(this);
}
virtual void attach_envs(ref::brw<Environment> p) override {
arg_->attach_envs(p);
}
virtual void display(std::ostream & os) const override;
protected:
ConvertExpr(TypeDescr dest_type,
rp<Expression> arg)
: Expression(exprtype::convert, dest_type),
arg_{std::move(arg)}
{}
protected:
/** source expression. Convert
* @c arg_->valuetype() to @c dest_type_
**/
rp<Expression> arg_;
};
/** @class ConvertExprAccess
* @brief ConvertExpr with writeable members.
*
* Convenient when scaffolding a parser,
* e.g. see xo-parser
**/
class ConvertExprAccess : public ConvertExpr {
public:
static rp<ConvertExprAccess> make(TypeDescr dest_type,
rp<Expression> arg);
static rp<ConvertExprAccess> make_empty();
void assign_arg(rp<Expression> arg) { this->arg_ = std::move(arg); }
private:
ConvertExprAccess(TypeDescr dest_type,
rp<Expression> arg)
: ConvertExpr(dest_type,
std::move(arg))
{}
};
} /*namespace ast*/
} /*namespace xo*/
/* end ConvertExpr.hpp */

View file

@ -9,6 +9,7 @@ set(SELF_SRCS
Variable.cpp
IfExpr.cpp
LocalEnv.cpp
ConvertExpr.cpp
)
xo_add_shared_library4(${SELF_LIB} ${PROJECT_NAME}Targets ${PROJECT_VERSION} 1 ${SELF_SRCS})

View file

@ -0,0 +1,53 @@
/* file ConvertExpr.cpp
*
* author: Roland Conybeare
*/
#include "ConvertExpr.hpp"
namespace xo {
namespace ast {
rp<ConvertExpr>
ConvertExpr::make(TypeDescr dest_type,
rp<Expression> arg)
{
return new ConvertExpr(dest_type,
std::move(arg));
}
std::set<std::string>
ConvertExpr::get_free_variables() const {
if (this->arg_)
return this->arg_->get_free_variables();
else
return std::set<std::string>();
}
void
ConvertExpr::display(std::ostream & os) const {
os << "<Convert"
<< xtag("dest_type", this->valuetype()->short_name())
<< xtag("arg", arg_)
<< ">";
}
// ----- ConvertExprAccess -----
rp<ConvertExprAccess>
ConvertExprAccess::make(TypeDescr dest_type,
rp<Expression> arg)
{
return new ConvertExprAccess(dest_type,
std::move(arg));
}
rp<ConvertExprAccess>
ConvertExprAccess::make_empty() {
return new ConvertExprAccess(nullptr /*dest_type*/,
nullptr /*arg*/);
}
} /*namespace ast*/
} /*namespace xo*/
/* end ConvertExpr.cpp */