Skip to content

Commit

Permalink
[cpp] attempted to implement if-statement codegen. its almost certain…
Browse files Browse the repository at this point in the history
…ly wrong in cases where the branch assigns to a variable - that would violate SSA which apparantly is real bad. verifier might complain at this when i get around to using it
  • Loading branch information
harrand committed May 21, 2024
1 parent 9f61935 commit aeecb24
Show file tree
Hide file tree
Showing 3 changed files with 111 additions and 8 deletions.
104 changes: 96 additions & 8 deletions cpp/src/codegen.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -648,15 +648,18 @@ namespace code
value lhs_value = expression(d, *payload.lhs_expr);
type ty = lhs_value.ty;

volatile bool check = lhs_value.variable_name == "val" && payload.op.t == lex::type::operator_asterisk;

type rhs_ty = type::undefined();
if(payload.op.t == lex::type::operator_cast)
{
// cast has different syntax so handle it here and early return.
d.ctx.assert_that(std::holds_alternative<ast::identifier>(payload.rhs_expr->expr), error_code::codegen,"in a cast, rhs of the cast token \"{}\" must be an identifier, not an expression or anything else.", payload.op.lexeme);
std::string type_name = std::get<ast::identifier>(payload.rhs_expr->expr).iden;
rhs_ty = d.state.get_type_from_name(type_name);
if(lhs_value.is_variable)
{
lhs_value = get_variable_val(lhs_value, d);
ty = lhs_value.ty;
}
return
{
.llv = load_as(lhs_value.llv, d, ty, rhs_ty, true),
Expand Down Expand Up @@ -754,7 +757,14 @@ namespace code
ret.is_variable = false;
break;
case lex::type::operator_double_equals:
ret.llv = builder->CreateICmpEQ(lhs_value.llv, rhs_value.llv);
if(lhs_value.ty.is_floating_point_type())
{
ret.llv = builder->CreateFCmpUEQ(lhs_value.llv, rhs_value.llv);
}
else if(lhs_value.ty.is_integer_type())
{
ret.llv = builder->CreateICmpEQ(lhs_value.llv, rhs_value.llv);
}
ret.ty = type::from_primitive(primitive_type::boolean);
ret.is_variable = false;
break;
Expand Down Expand Up @@ -973,8 +983,8 @@ namespace code
auto* llvm_parent_fn = static_cast<llvm::Function*>(parent_function->userdata);

llvm::BasicBlock* if_blk = nullptr;
auto if_blk_path = d.ctx.path;
{
auto if_blk_path = d.ctx.path;
if_blk_path.push_back(0);
if_blk = block(
data{
Expand All @@ -987,9 +997,9 @@ namespace code
}, "if_true");
}
llvm::BasicBlock* else_blk = nullptr;
auto else_blk_path = d.ctx.path;
if(else_blk_node != nullptr)
{
auto else_blk_path = d.ctx.path;
else_blk_path.push_back(1);
else_blk = block(
data{
Expand All @@ -999,13 +1009,91 @@ namespace code
.path = else_blk_path
},
.state = d.state
}, "if_else", true);
}, "if_else");
}

d.ctx.warning("if-statements are not yet implemented. no corresponding code will be generated.");
auto do_if_blk = [if_blk, if_blk_node, if_blk_path, &d]()->bool
{
bool contains_unconditional_return = false;
for(std::size_t i = 0; i < if_blk_node.children.size(); i++)
{
auto child_path = if_blk_path;
child_path.push_back(i);
semal::context ctx
{
.tree = d.ctx.tree,
.path = child_path
};
codegen_thing(data{
.ctx = ctx,
.state = d.state
}, if_blk_node.children[i].payload);
contains_unconditional_return |= std::holds_alternative<ast::return_statement>(if_blk_node.children[i].payload);
// if we see a return before the last instruction, compile error.
// i.e if i < last and unconditional return, boom
ctx.assert_that(i >= (if_blk_node.children.size() - 1) || !contains_unconditional_return, error_code::codegen, "detected early-return within if block. all other code within the if-block is dead code.");
}
return contains_unconditional_return;
};

// todo: if statement logic.
auto do_else_blk = [else_blk, else_blk_node, else_blk_path, &d]()
{
bool contains_unconditional_return = false;
for(std::size_t i = 0; i < else_blk_node->children.size(); i++)
{
auto child_path = else_blk_path;
child_path.push_back(i);
semal::context ctx
{
.tree = d.ctx.tree,
.path = child_path
};
codegen_thing(data{
.ctx = ctx,
.state = d.state
}, else_blk_node->children[i].payload);
contains_unconditional_return |= std::holds_alternative<ast::return_statement>(else_blk_node->children[i].payload);
// if we see a return before the last instruction, compile error.
// i.e if i < last and unconditional return, boom
ctx.assert_that(i >= (else_blk_node->children.size() - 1) || !contains_unconditional_return, error_code::codegen, "detected early-return within else block. all other code within the else-block is dead code.");
}
return contains_unconditional_return;
};

llvm::BasicBlock* cont_blk = llvm::BasicBlock::Create(*ctx, "cont", llvm_parent_fn);
//d.ctx.warning("if-statements are not yet implemented. no corresponding code will be generated.");
if(else_blk == nullptr)
{
// if
builder->CreateCondBr(llvm_cond.llv, if_blk, cont_blk);
builder->SetInsertPoint(if_blk);
if(!do_if_blk())
{
builder->CreateBr(cont_blk);
}

builder->SetInsertPoint(cont_blk);
}
else
{
// if-else
builder->CreateCondBr(llvm_cond.llv, if_blk, else_blk);
builder->SetInsertPoint(if_blk);
if(!do_if_blk())
{
builder->CreateBr(cont_blk);
}

builder->SetInsertPoint(else_blk);
if(!do_else_blk())
{
builder->CreateBr(cont_blk);
}

builder->SetInsertPoint(cont_blk);
}

// todo: if statement logic.
return {};
}

Expand Down
6 changes: 6 additions & 0 deletions cpp/src/type.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,8 @@ bool type::is_integer_type() const
case primitive_type::u16:
[[fallthrough]];
case primitive_type::u8:
[[fallthrough]];
case primitive_type::boolean:
return true;
break;
default:
Expand All @@ -67,6 +69,8 @@ bool type::is_signed_integer_type() const
case primitive_type::u16:
[[fallthrough]];
case primitive_type::u8:
[[fallthrough]];
case primitive_type::boolean:
return false;
break;
case primitive_type::i64:
Expand Down Expand Up @@ -100,6 +104,8 @@ bool type::is_unsigned_integer_type() const
case primitive_type::u16:
[[fallthrough]];
case primitive_type::u8:
[[fallthrough]];
case primitive_type::boolean:
return true;
break;
case primitive_type::i64:
Expand Down
9 changes: 9 additions & 0 deletions samples/scratchpad.psy
Original file line number Diff line number Diff line change
Expand Up @@ -70,6 +70,15 @@ morb :: (par0 : i64) -> f64
complicated(poggers, dub(5), mydata123.member2);
complicated(--complicated(1, 2, 3), dub(5), 690);

phicond : i64 := 5;
phi1 : i64 := 0;
if phicond == 5
{
phi1 = 56;
return 5.0;
}
putchar(phi1@i8);

if poggers1 == 59
{
e : i64 := 5;
Expand Down

0 comments on commit aeecb24

Please sign in to comment.