Skip to content

Commit

Permalink
Support for Enums
Browse files Browse the repository at this point in the history
  • Loading branch information
Kracken256 committed Jun 22, 2024
1 parent b197da9 commit b242f5c
Show file tree
Hide file tree
Showing 24 changed files with 142 additions and 261 deletions.
1 change: 1 addition & 0 deletions libquixcc/internal/IR/IRModule.h
Original file line number Diff line number Diff line change
Expand Up @@ -63,6 +63,7 @@ namespace ir {
struct PState {
size_t ind;
bool modinfo = true;
int last_node_type = -1;

PState() { ind = 0; }
};
Expand Down
6 changes: 3 additions & 3 deletions libquixcc/internal/IR/Q/Control.h
Original file line number Diff line number Diff line change
Expand Up @@ -82,15 +82,15 @@ class For : public Value {
boost::uuids::uuid hash_impl() const override;
bool verify_impl() const override;

For(Expr *init, Expr *cond, Expr *step, Value *body)
For(Value *init, Expr *cond, Expr *step, Value *body)
: init(init), cond(cond), step(step), body(body) {
ntype = (int)NodeType::For;
}

public:
static For *create(Expr *init, Expr *cond, Expr *step, Value *body);
static For *create(Value *init, Expr *cond, Expr *step, Value *body);

Expr *init;
Value *init;
Expr *cond;
Expr *step;
Value *body;
Expand Down
6 changes: 0 additions & 6 deletions libquixcc/internal/mutate/Routine.h
Original file line number Diff line number Diff line change
Expand Up @@ -53,14 +53,8 @@ void ResolveNamedConstructs(quixcc_job_t *job,
const std::shared_ptr<libquixcc::Ptree> ptree);
void MethodToFunc(quixcc_job_t *job,
const std::shared_ptr<libquixcc::Ptree> ptree);
inline void ObjectConstruction(quixcc_job_t *job,
const std::shared_ptr<libquixcc::Ptree> ptree) {}
inline void ObjectDestruction(quixcc_job_t *job,
const std::shared_ptr<libquixcc::Ptree> ptree) {}
void SubsystemCollapse(quixcc_job_t *job,
const std::shared_ptr<libquixcc::Ptree> ptree);
void ImplicitReturn(quixcc_job_t *job,
const std::shared_ptr<libquixcc::Ptree> ptree);
} // namespace mutate

typedef std::function<void(quixcc_job_t *job,
Expand Down
4 changes: 2 additions & 2 deletions libquixcc/internal/parsetree/nodes/ControlFlow.h
Original file line number Diff line number Diff line change
Expand Up @@ -126,15 +126,15 @@ class WhileStmtNode : public StmtNode {

class ForStmtNode : public StmtNode {
public:
ForStmtNode(const std::shared_ptr<ExprNode> &init,
ForStmtNode(const std::shared_ptr<StmtNode> &init,
const std::shared_ptr<ExprNode> &cond,
const std::shared_ptr<ExprNode> &step,
const std::shared_ptr<StmtNode> &body)
: m_init(init), m_cond(cond), m_step(step), m_stmt(body) {
ntype = NodeType::ForStmtNode;
}

std::shared_ptr<ExprNode> m_init;
std::shared_ptr<StmtNode> m_init;
std::shared_ptr<ExprNode> m_cond;
std::shared_ptr<ExprNode> m_step;
std::shared_ptr<StmtNode> m_stmt;
Expand Down
5 changes: 2 additions & 3 deletions libquixcc/internal/parsetree/nodes/EnumNode.h
Original file line number Diff line number Diff line change
Expand Up @@ -83,16 +83,15 @@ class EnumFieldNode : public ParseNode {
class EnumDefNode : public DefNode {
public:
EnumDefNode() { ntype = NodeType::EnumDefNode; }
EnumDefNode(EnumTypeNode *type, bool scoped,
EnumDefNode(EnumTypeNode *type,
const std::vector<std::shared_ptr<EnumFieldNode>> &fields = {})
: m_type(type), m_fields(fields), m_scoped(scoped) {
: m_type(type), m_fields(fields) {
ntype = NodeType::EnumDefNode;
}
virtual TypeNode *get_type() const { return m_type; }

EnumTypeNode *m_type;
std::vector<std::shared_ptr<EnumFieldNode>> m_fields;
bool m_scoped = false;
};
} // namespace libquixcc

Expand Down
2 changes: 1 addition & 1 deletion libquixcc/src/IR/Q/cache/create.cc
Original file line number Diff line number Diff line change
Expand Up @@ -126,7 +126,7 @@ IfElse *IfElse::create(Expr *cond, Value *then, Value *els) {

While *While::create(Expr *cond, Value *body) { MAKE_GC(While, cond, body); }

For *For::create(Expr *init, Expr *cond, Expr *step, Value *body) {
For *For::create(Value *init, Expr *cond, Expr *step, Value *body) {
MAKE_GC(For, init, cond, step, body);
}

Expand Down
6 changes: 5 additions & 1 deletion libquixcc/src/IR/Q/print/Function.cc
Original file line number Diff line number Diff line change
Expand Up @@ -100,8 +100,12 @@ bool libquixcc::ir::q::RootNode::print_impl(
std::ostream &os, libquixcc::ir::PState &state) const {
for (auto it = children.begin(); it != children.end(); it++) {
if (!(*it)->print(os, state)) return false;

os << ";\n";

if (state.last_node_type != (*it)->ntype)
os << "\n";

state.last_node_type = (*it)->ntype;
}

return true;
Expand Down
52 changes: 46 additions & 6 deletions libquixcc/src/IR/Q/reducer/PTree2QIR.cc
Original file line number Diff line number Diff line change
Expand Up @@ -86,6 +86,7 @@ struct QState {
ExportLangType lang;
std::stack<const FunctionDefNode *> function;
std::map<std::string, const DefNode *> typedefs;
std::unordered_map<std::string, Expr *> enum_values;

QState() {
inside_segment = false;
Expand Down Expand Up @@ -360,8 +361,7 @@ static QResult conv(const StaticCastExprNode *n, QState &state) {
return ir::q::SCast::create(to, expr);
if (from->is_unsigned() && to->is_unsigned())
return ir::q::UCast::create(to, expr);
if (from->is_float() && to->is_float())
return ir::q::SCast::create(to, expr);
if (from->is_float() && to->is_float()) return ir::q::SCast::create(to, expr);

LOG(FATAL) << "error converting from static_cast to primitive casts"
<< std::endl;
Expand Down Expand Up @@ -1050,9 +1050,14 @@ static QResult conv(const IdentifierNode *n, QState &state) {
return Ident::create(n->m_name, state.local_idents.top()[n->m_name]);
}

if (!state.global_idents.contains(n->m_name))
if (state.enum_values.contains(n->m_name)) {
return state.enum_values[n->m_name];
}

if (!state.global_idents.contains(n->m_name)) {
throw std::runtime_error("QIR translation: IdentifierNode not found: " +
n->m_name);
}

return Ident::create(n->m_name, state.global_idents[n->m_name]);
}
Expand Down Expand Up @@ -2116,12 +2121,37 @@ static QResult conv(const UnionFieldNode *n, QState &state) {

static QResult conv(const EnumDefNode *n, QState &state) {
/// TODO: cleanup

if (n->m_fields.empty()) {
return nullptr;
}

Expr *last = nullptr;

for (auto &field : n->m_fields) {
if (field->m_value) {
last = conv(field->m_value.get(), state)[0]->as<Expr>();
} else {
if (!last) {
last = Number::create("0");
} else {
last = Add::create(last, Number::create("1"));
}
}

state.enum_values[Symbol::join(n->m_type->m_name, field->m_name)] = last;
}

return nullptr;
}

static QResult conv(const EnumFieldNode *n, QState &state) {
/// TODO: cleanup
return nullptr;
if (!n->m_value) {
return nullptr;
}

return conv(n->m_value.get(), state);
}

static QResult conv(const FunctionDefNode *n, QState &state) {
Expand All @@ -2137,6 +2167,16 @@ static QResult conv(const FunctionDefNode *n, QState &state) {
auto dseg = glob->value->as<Segment>();

auto body = conv(n->m_body.get(), state)[0]->as<Block>();

if (body->stmts.empty() || !body->stmts.back()->is<Ret>()) {
if (dseg->return_type->is<Void>()) {
body->stmts.push_back(Ret::create(nullptr));
} else {
LOG(ERROR) << "QIR conv: function does not return" << std::endl;
return nullptr;
}
}

state.inside_segment = old;

state.function.pop();
Expand Down Expand Up @@ -2464,14 +2504,14 @@ static QResult conv(const ForStmtNode *n, QState &state) {
* - One-for-one lowering of the for loop node.
**/

Expr *init = nullptr;
Value *init = nullptr;
Expr *cond = nullptr;
Expr *step = nullptr;
Block *stmt = nullptr;

/* If the init, cond, step, or stmt fields are null, ignore them */
if (n->m_init)
init = conv(n->m_init.get(), state)[0]->as<Expr>();
init = conv(n->m_init.get(), state)[0]->as<Value>();
else
init = Number::create("0");

Expand Down
4 changes: 2 additions & 2 deletions libquixcc/src/IR/delta/reducer/Q2Delta.cc
Original file line number Diff line number Diff line change
Expand Up @@ -486,12 +486,12 @@ static auto conv(const ir::q::While *n, DState &state) -> DResult {
}

static auto conv(const ir::q::For *n, DState &state) -> DResult {
const Expr *init = nullptr;
const Value *init = nullptr;
const Expr *cond = nullptr;
const Expr *step = nullptr;
const Value *body = nullptr;

if (n->init) init = conv(n->init, state)[0]->as<Expr>();
if (n->init) init = conv(n->init, state)[0]->as<Value>();
if (n->cond) cond = conv(n->cond, state)[0]->as<Expr>();
if (n->step) step = conv(n->step, state)[0]->as<Expr>();
if (n->body) body = conv(n->body, state)[0];
Expand Down
77 changes: 0 additions & 77 deletions libquixcc/src/mutate/ExtrapolateEnumFields.cc

This file was deleted.

71 changes: 0 additions & 71 deletions libquixcc/src/mutate/ImplicitReturn.cc

This file was deleted.

Loading

0 comments on commit b242f5c

Please sign in to comment.