Fix compilation to IR, in particular initializing a variable with a copy of another variable

This commit is contained in:
Nikita Lisitsa 2026-03-19 15:05:08 +03:00
parent 29c936c19c
commit 7d5795d9bf
4 changed files with 31 additions and 11 deletions

View file

@ -1,7 +1,8 @@
func test(x: f32) -> f32:
foreign func sin(x: f32) -> f32
let pi = 3.1415926535
return sin(pi * x)
func print(c: u8):
foreign func putchar(c: i32) -> i32
putchar(c as i32)
let myfunc = test
let x = myfunc(7.5)
mut a = 10ub
let b = a
a = 11ub
print(b)

View file

@ -20,6 +20,11 @@ namespace pslang::ir
ast::literal value;
};
struct copy
{
node_ref source;
};
struct unary_operation
{
ast::unary_operation_type type;
@ -94,6 +99,7 @@ namespace pslang::ir
using instruction = std::variant<
nop,
literal,
copy,
unary_operation,
binary_operation,
cast_operation,

View file

@ -225,8 +225,7 @@ namespace pslang::ir
node_ref apply(ast::expression_ptr const & node)
{
apply(*node);
return last();
return apply(*node);
}
node_ref apply(ast::assignment const & node)
@ -239,9 +238,18 @@ namespace pslang::ir
node_ref apply(ast::variable_declaration const & node)
{
apply(*node.initializer);
lcontext.scopes.back().variables[node.name] = last();
return last();
auto before = last();
auto result = apply(*node.initializer);
if (result == before)
{
// Evaluating variable initializer didn't produce any nodes
// It must have been just a reference to another variable or smth like that
// Introduce a copy node to prevent accidental variable coalescing
mcontext.nodes.emplace_back(copy{result});
result = last();
}
lcontext.scopes.back().variables[node.name] = result;
return result;
}
node_ref apply(ast::if_chain const & node)

View file

@ -190,6 +190,11 @@ namespace pslang::ir
std::visit(print_literal_visitor{out}, instruction.value);
}
void operator()(copy const & instruction)
{
out << "copy $" << get_index(instruction.source);
}
void operator()(unary_operation const & instruction)
{
print(out, instruction.type);