Implement pointer support in IR via load/store instructions
This commit is contained in:
parent
0c11b09548
commit
dd3eb5d14b
4 changed files with 87 additions and 15 deletions
|
|
@ -7,7 +7,6 @@ foreign func free(ptr: unit*)
|
|||
let array = alloc(400ul) as i32 mut*
|
||||
*array = 10
|
||||
*(array + 1) = 20
|
||||
let q = array + 10
|
||||
let n = q - array
|
||||
array[5] = 50
|
||||
let test = array[10]
|
||||
array[15] = 1500
|
||||
free(array as unit*)
|
||||
|
|
|
|||
|
|
@ -25,6 +25,17 @@ namespace pslang::ir
|
|||
node_ref source;
|
||||
};
|
||||
|
||||
struct load
|
||||
{
|
||||
node_ref ptr;
|
||||
};
|
||||
|
||||
struct store
|
||||
{
|
||||
node_ref ptr;
|
||||
node_ref value;
|
||||
};
|
||||
|
||||
struct unary_operation
|
||||
{
|
||||
ast::unary_operation_type type;
|
||||
|
|
@ -49,7 +60,7 @@ namespace pslang::ir
|
|||
std::size_t index;
|
||||
};
|
||||
|
||||
struct address
|
||||
struct instruction_address
|
||||
{
|
||||
node_ref target;
|
||||
};
|
||||
|
|
@ -100,11 +111,13 @@ namespace pslang::ir
|
|||
nop,
|
||||
literal,
|
||||
copy,
|
||||
load,
|
||||
store,
|
||||
unary_operation,
|
||||
binary_operation,
|
||||
cast_operation,
|
||||
argument,
|
||||
address,
|
||||
instruction_address,
|
||||
extern_symbol,
|
||||
assignment,
|
||||
jump,
|
||||
|
|
|
|||
|
|
@ -75,7 +75,7 @@ namespace pslang::ir
|
|||
}
|
||||
else if (node.function_node)
|
||||
{
|
||||
mcontext.nodes.emplace_back(address{}, node.inferred_type);
|
||||
mcontext.nodes.emplace_back(instruction_address{}, node.inferred_type);
|
||||
lcontext.resolve_address.emplace_back(last(), node.function_node);
|
||||
return last();
|
||||
}
|
||||
|
|
@ -91,6 +91,13 @@ namespace pslang::ir
|
|||
node_ref apply(ast::unary_operation const & node)
|
||||
{
|
||||
auto arg1 = apply(*node.arg1);
|
||||
|
||||
if (node.type == ast::unary_operation_type::dereference)
|
||||
{
|
||||
mcontext.nodes.emplace_back(load{arg1}, node.inferred_type);
|
||||
return last();
|
||||
}
|
||||
|
||||
mcontext.nodes.emplace_back(unary_operation{node.type, arg1}, node.inferred_type);
|
||||
return last();
|
||||
}
|
||||
|
|
@ -162,6 +169,20 @@ namespace pslang::ir
|
|||
}
|
||||
}
|
||||
|
||||
node_ref apply(ast::array_access const & node)
|
||||
{
|
||||
auto array = apply(*node.array);
|
||||
auto index = apply(*node.index);
|
||||
auto array_type = ast::get_type(*node.array);
|
||||
if (std::get_if<types::pointer_type>(array_type.get()))
|
||||
{
|
||||
mcontext.nodes.emplace_back(binary_operation{ast::binary_operation_type::addition, array, index}, array_type);
|
||||
mcontext.nodes.emplace_back(load{last()}, node.inferred_type);
|
||||
return last();
|
||||
}
|
||||
throw std::runtime_error("Unknown array access left-hand side");
|
||||
}
|
||||
|
||||
// TODO: array, array_access, field_access
|
||||
|
||||
// Statements
|
||||
|
|
@ -174,11 +195,40 @@ namespace pslang::ir
|
|||
node_ref apply(ast::assignment const & node)
|
||||
{
|
||||
auto rhs = apply(*node.rhs);
|
||||
|
||||
if (std::holds_alternative<ast::identifier>(*node.lhs))
|
||||
{
|
||||
auto lhs = apply(*node.lhs);
|
||||
mcontext.nodes.emplace_back(assignment{lhs, rhs}, ast::get_type(*node.rhs));
|
||||
return last();
|
||||
}
|
||||
|
||||
if (auto array_access = std::get_if<ast::array_access>(node.lhs.get()))
|
||||
{
|
||||
auto array_type = get_type(*array_access->array);
|
||||
if (std::get_if<types::pointer_type>(array_type.get()))
|
||||
{
|
||||
auto base_ptr = apply(*array_access->array);
|
||||
auto index = apply(*array_access->index);
|
||||
mcontext.nodes.emplace_back(binary_operation{ast::binary_operation_type::addition, base_ptr, index}, array_type);
|
||||
mcontext.nodes.emplace_back(store{last(), rhs}, ast::get_type(*node.rhs));
|
||||
return last();
|
||||
}
|
||||
}
|
||||
|
||||
if (auto unary_operation = std::get_if<ast::unary_operation>(node.lhs.get()))
|
||||
{
|
||||
if (unary_operation->type == ast::unary_operation_type::dereference)
|
||||
{
|
||||
auto lhs = apply(*unary_operation->arg1);
|
||||
mcontext.nodes.emplace_back(store{lhs, rhs}, ast::get_type(*node.rhs));
|
||||
return last();
|
||||
}
|
||||
}
|
||||
|
||||
throw std::runtime_error("Unknown assignment left-hand side");
|
||||
}
|
||||
|
||||
node_ref apply(ast::variable_declaration const & node)
|
||||
{
|
||||
auto before = last();
|
||||
|
|
@ -380,7 +430,7 @@ namespace pslang::ir
|
|||
mcontext.nodes.erase(extra_nop);
|
||||
|
||||
for (auto const & resolve : lcontext.resolve_address)
|
||||
std::get<address>(resolve.address->instruction).target = lcontext.functions.at(resolve.target);
|
||||
std::get<instruction_address>(resolve.address->instruction).target = lcontext.functions.at(resolve.target);
|
||||
|
||||
for (auto const & resolve : lcontext.resolve_call)
|
||||
std::get<call>(resolve.call->instruction).target = lcontext.functions.at(resolve.target);
|
||||
|
|
|
|||
|
|
@ -23,10 +23,10 @@ namespace pslang::ir
|
|||
out << "not";
|
||||
break;
|
||||
case ast::unary_operation_type::address_of:
|
||||
out << "address";
|
||||
out << "addr";
|
||||
break;
|
||||
case ast::unary_operation_type::mutable_address_of:
|
||||
out << "address";
|
||||
out << "addr";
|
||||
break;
|
||||
case ast::unary_operation_type::dereference:
|
||||
out << "deref";
|
||||
|
|
@ -204,6 +204,16 @@ namespace pslang::ir
|
|||
out << "copy $" << get_index(instruction.source);
|
||||
}
|
||||
|
||||
void operator()(load const & instruction)
|
||||
{
|
||||
out << "load $" << get_index(instruction.ptr);
|
||||
}
|
||||
|
||||
void operator()(store const & instruction)
|
||||
{
|
||||
out << "store $" << get_index(instruction.ptr) << " $" << get_index(instruction.value);
|
||||
}
|
||||
|
||||
void operator()(unary_operation const & instruction)
|
||||
{
|
||||
print(out, instruction.type);
|
||||
|
|
@ -226,9 +236,9 @@ namespace pslang::ir
|
|||
out << "arg #" << instruction.index;
|
||||
}
|
||||
|
||||
void operator()(address const & instruction)
|
||||
void operator()(instruction_address const & instruction)
|
||||
{
|
||||
out << "addr $" << get_index(instruction.target);
|
||||
out << "iaddr $" << get_index(instruction.target);
|
||||
}
|
||||
|
||||
void operator()(extern_symbol const & instruction)
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue