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: func print(c: u8):
foreign func sin(x: f32) -> f32 foreign func putchar(c: i32) -> i32
let pi = 3.1415926535 putchar(c as i32)
return sin(pi * x)
let myfunc = test mut a = 10ub
let x = myfunc(7.5) let b = a
a = 11ub
print(b)

View file

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

View file

@ -225,8 +225,7 @@ namespace pslang::ir
node_ref apply(ast::expression_ptr const & node) node_ref apply(ast::expression_ptr const & node)
{ {
apply(*node); return apply(*node);
return last();
} }
node_ref apply(ast::assignment const & node) node_ref apply(ast::assignment const & node)
@ -239,9 +238,18 @@ namespace pslang::ir
node_ref apply(ast::variable_declaration const & node) node_ref apply(ast::variable_declaration const & node)
{ {
apply(*node.initializer); auto before = last();
lcontext.scopes.back().variables[node.name] = last(); auto result = apply(*node.initializer);
return last(); 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) 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); 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) void operator()(unary_operation const & instruction)
{ {
print(out, instruction.type); print(out, instruction.type);