Merge pull request #9 from birth-software/comp

Implement comparisons
This commit is contained in:
David 2024-07-06 19:36:27 +02:00 committed by GitHub
commit e871db4670
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
2 changed files with 248 additions and 83 deletions

View File

@ -997,7 +997,7 @@ struct Arena
u64 commited; u64 commited;
u64 commit_position; u64 commit_position;
u64 granularity; u64 granularity;
u8 reserved[4 * 8]; u8 reserved[4 * 8] = {};
global auto constexpr minimum_granularity = KB(4); global auto constexpr minimum_granularity = KB(4);
global auto constexpr middle_granularity = MB(2); global auto constexpr middle_granularity = MB(2);
@ -1472,15 +1472,13 @@ struct NodeType
struct struct
{ {
u64 constant; u64 constant;
u8 bit_count;
u8 is_constant; u8 is_constant;
} integer; } integer;
struct struct
{ {
Slice<NodeType> types; Slice<NodeType> types;
} multi; } multi;
}; } payload = {};
u8 is_simple() u8 is_simple()
{ {
@ -1506,6 +1504,8 @@ struct NodeType
switch (id) switch (id)
{ {
case NodeType::Id::INTEGER:
return (payload.integer.is_constant == other.payload.integer.is_constant) & (payload.integer.constant == other.payload.integer.constant);
default: default:
trap(); trap();
} }
@ -1518,7 +1518,7 @@ struct NodeType
case Id::VOID: case Id::VOID:
trap(); trap();
case Id::INTEGER: case Id::INTEGER:
return integer.is_constant; return payload.integer.is_constant;
case Id::CONTROL: case Id::CONTROL:
case Id::MULTIVALUE: case Id::MULTIVALUE:
case Id::BOTTOM: case Id::BOTTOM:
@ -1572,7 +1572,7 @@ struct NodeType
} }
assert(is_constant() & other.is_constant()); assert(is_constant() & other.is_constant());
if (integer.constant == other.integer.constant) if (payload.integer.constant == other.payload.integer.constant)
{ {
trap(); trap();
} }
@ -1589,37 +1589,43 @@ struct NodeType
u8 is_bot() u8 is_bot()
{ {
assert(id == Id::INTEGER); assert(id == Id::INTEGER);
return !integer.is_constant & (integer.constant == 1); return !payload.integer.is_constant & (payload.integer.constant == 1);
} }
u8 is_top() u8 is_top()
{ {
assert(id == Id::INTEGER); assert(id == Id::INTEGER);
return !integer.is_constant & (integer.constant == 0); return !payload.integer.is_constant & (payload.integer.constant == 0);
} }
}; };
may_be_unused global auto constexpr integer_top = NodeType{ may_be_unused global auto constexpr integer_top = NodeType{
.id = NodeType::Id::TOP, .id = NodeType::Id::TOP,
.integer = { .payload = {
.constant = 0, .integer = {
.is_constant = 0, .constant = 0,
.is_constant = 0,
},
}, },
}; };
may_be_unused global auto constexpr integer_bot = NodeType{ may_be_unused global auto constexpr integer_bot = NodeType{
.id = NodeType::Id::TOP, .id = NodeType::Id::TOP,
.integer = { .payload = {
.constant = 1, .integer = {
.is_constant = 0, .constant = 1,
.is_constant = 0,
},
}, },
}; };
may_be_unused global auto constexpr integer_zero = NodeType{ may_be_unused global auto constexpr integer_zero = NodeType{
.id = NodeType::Id::TOP, .id = NodeType::Id::TOP,
.integer = { .payload = {
.constant = 0, .integer = {
.is_constant = 1, .constant = 0,
.is_constant = 1,
},
}, },
}; };
@ -1630,7 +1636,7 @@ struct SemaType
SemaTypeId id : type_id_bit_count; SemaTypeId id : type_id_bit_count;
u32 resolved: 1; u32 resolved: 1;
u32 flags: type_flags_bit_count; u32 flags: type_flags_bit_count;
u32 reserved; u32 reserved = 0;
String name; String name;
u8 get_bit_count() u8 get_bit_count()
@ -1656,9 +1662,12 @@ struct SemaType
case SemaTypeId::INTEGER: case SemaTypeId::INTEGER:
return NodeType{ return NodeType{
.id = NodeType::Id::INTEGER, .id = NodeType::Id::INTEGER,
.integer = { .payload = {
.bit_count = get_bit_count(), .integer = {
.is_constant = 0, .constant = 0,
// .bit_count = get_bit_count(),
.is_constant = 0,
},
}, },
}; };
case SemaTypeId::ARRAY: case SemaTypeId::ARRAY:
@ -1726,8 +1735,8 @@ struct Function;
struct Thread struct Thread
{ {
Arena* arena; Arena* arena;
PinnedArray<Function> functions; PinnedArray<Function> functions = {};
u32 node_count; u32 node_count = 0;
}; };
struct Unit struct Unit
@ -1776,8 +1785,8 @@ typedef struct AbiInfoAttributes AbiInfoAttributes;
struct AbiInfo struct AbiInfo
{ {
AbiInfoPayload payload; AbiInfoPayload payload;
u16 indices[2]; u16 indices[2] = {};
AbiInfoAttributes attributes; AbiInfoAttributes attributes = {};
AbiInfoKind kind; AbiInfoKind kind;
}; };
@ -1811,7 +1820,6 @@ struct ConstantIntData
{ {
u64 value; u64 value;
Node* input; Node* input;
u32 gvn;
u8 bit_count; u8 bit_count;
}; };
@ -1827,8 +1835,15 @@ struct Node
PROJECTION, PROJECTION,
RETURN, RETURN,
CONSTANT_INT, CONSTANT_INT,
INT_ADD, INTEGER_ADD,
INT_SUB, INTEGER_SUB,
INTEGER_COMPARE_EQUAL,
INTEGER_COMPARE_NOT_EQUAL,
INTEGER_COMPARE_LESS,
INTEGER_COMPARE_LESS_EQUAL,
INTEGER_COMPARE_GREATER,
INTEGER_COMPARE_GREATER_EQUAL,
SCOPE, SCOPE,
SYMBOL_FUNCTION, SYMBOL_FUNCTION,
CALL, CALL,
@ -1858,9 +1873,9 @@ struct Node
Type args; Type args;
} root; } root;
Symbol* symbol; Symbol* symbol;
}; } payload;
u8 padding[40]; u8 padding[40] = {};
forceinline Slice<Node*> get_inputs() forceinline Slice<Node*> get_inputs()
{ {
@ -1896,6 +1911,7 @@ struct Node
.outputs = {}, .outputs = {},
.gvn = gvn, .gvn = gvn,
.id = data.id, .id = data.id,
.payload = {},
}; };
node->inputs.append(data.inputs); node->inputs.append(data.inputs);
@ -1970,14 +1986,21 @@ struct Node
case Id::PROJECTION: case Id::PROJECTION:
case Id::CONSTANT_INT: case Id::CONSTANT_INT:
break; break;
case Id::INT_ADD: case Id::INTEGER_ADD:
case Id::INT_SUB: case Id::INTEGER_SUB:
trap(); trap();
case Id::SCOPE: case Id::SCOPE:
trap(); trap();
case Id::SYMBOL_FUNCTION: case Id::SYMBOL_FUNCTION:
case Id::CALL: case Id::CALL:
trap(); trap();
case Id::INTEGER_COMPARE_EQUAL:
case Id::INTEGER_COMPARE_NOT_EQUAL:
case Id::INTEGER_COMPARE_LESS:
case Id::INTEGER_COMPARE_LESS_EQUAL:
case Id::INTEGER_COMPARE_GREATER:
case Id::INTEGER_COMPARE_GREATER_EQUAL:
trap();
} }
return is_good_id | is_projection() | cfg_is_control_projection(); return is_good_id | is_projection() | cfg_is_control_projection();
@ -2022,7 +2045,7 @@ struct Node
{ {
switch (id) switch (id)
{ {
case Id::INT_SUB: case Id::INTEGER_SUB:
if (inputs[1] == inputs[2]) if (inputs[1] == inputs[2])
{ {
trap(); trap();
@ -2035,7 +2058,7 @@ struct Node
case Id::PROJECTION: case Id::PROJECTION:
case Id::RETURN: case Id::RETURN:
case Id::CONSTANT_INT: case Id::CONSTANT_INT:
case Id::INT_ADD: case Id::INTEGER_ADD:
return 0; return 0;
case Id::SCOPE: case Id::SCOPE:
trap(); trap();
@ -2043,6 +2066,13 @@ struct Node
case Id::SYMBOL_FUNCTION: case Id::SYMBOL_FUNCTION:
case Id::CALL: case Id::CALL:
return 0; return 0;
case Id::INTEGER_COMPARE_EQUAL:
case Id::INTEGER_COMPARE_NOT_EQUAL:
case Id::INTEGER_COMPARE_LESS:
case Id::INTEGER_COMPARE_LESS_EQUAL:
case Id::INTEGER_COMPARE_GREATER:
case Id::INTEGER_COMPARE_GREATER_EQUAL:
trap();
} }
} }
@ -2140,9 +2170,15 @@ struct Node
switch (id) switch (id)
{ {
case Node::Id::ROOT: case Node::Id::ROOT:
return root.args; return payload.root.args;
case Node::Id::INT_ADD: case Node::Id::INTEGER_ADD:
case Node::Id::INT_SUB: case Node::Id::INTEGER_SUB:
case Node::Id::INTEGER_COMPARE_EQUAL:
case Node::Id::INTEGER_COMPARE_NOT_EQUAL:
case Node::Id::INTEGER_COMPARE_LESS:
case Node::Id::INTEGER_COMPARE_LESS_EQUAL:
case Node::Id::INTEGER_COMPARE_GREATER:
case Node::Id::INTEGER_COMPARE_GREATER_EQUAL:
{ {
auto left_type = inputs[1]->type; auto left_type = inputs[1]->type;
auto right_type = inputs[2]->type; auto right_type = inputs[2]->type;
@ -2161,20 +2197,40 @@ struct Node
case Id::SYMBOL_FUNCTION: case Id::SYMBOL_FUNCTION:
case Id::CALL: case Id::CALL:
trap(); trap();
case Id::INT_ADD: case Id::INTEGER_ADD:
result = left_type.integer.constant + right_type.integer.constant; result = left_type.payload.integer.constant + right_type.payload.integer.constant;
break; break;
case Id::INT_SUB: case Id::INTEGER_SUB:
result = left_type.integer.constant - right_type.integer.constant; result = left_type.payload.integer.constant - right_type.payload.integer.constant;
break;
case Id::INTEGER_COMPARE_EQUAL:
result = left_type.payload.integer.constant == right_type.payload.integer.constant;
break;
case Id::INTEGER_COMPARE_NOT_EQUAL:
result = left_type.payload.integer.constant != right_type.payload.integer.constant;
break;
case Id::INTEGER_COMPARE_LESS:
result = left_type.payload.integer.constant < right_type.payload.integer.constant;
break;
case Id::INTEGER_COMPARE_LESS_EQUAL:
result = left_type.payload.integer.constant <= right_type.payload.integer.constant;
break;
case Id::INTEGER_COMPARE_GREATER:
result = left_type.payload.integer.constant > right_type.payload.integer.constant;
break;
case Id::INTEGER_COMPARE_GREATER_EQUAL:
result = left_type.payload.integer.constant >= right_type.payload.integer.constant;
break; break;
} }
return Node::Type{ return Node::Type{
.id = Node::Type::Id::INTEGER, .id = Node::Type::Id::INTEGER,
.integer = { .payload = {
.constant = result, .integer = {
.bit_count = left_type.integer.bit_count, .constant = result,
.is_constant = 1, // .bit_count = left_type.payload.integer.bit_count,
.is_constant = 1,
},
}, },
}; };
} }
@ -2195,7 +2251,7 @@ struct Node
auto* control_node = inputs[0]; auto* control_node = inputs[0];
if (control_node->type.id == NodeType::Id::MULTIVALUE) if (control_node->type.id == NodeType::Id::MULTIVALUE)
{ {
auto type = control_node->type.multi.types[this->projection.index]; auto type = control_node->type.payload.multi.types[this->payload.projection.index];
return type; return type;
} }
else else
@ -2217,9 +2273,11 @@ struct Node
types.append_one(inputs[1]->type); types.append_one(inputs[1]->type);
return Type{ return Type{
.id = Node::Type::Id::MULTIVALUE, .id = Node::Type::Id::MULTIVALUE,
.payload = {
.multi = { .multi = {
.types = types.slice(), .types = types.slice(),
}, },
},
}; };
} }
default: default:
@ -2235,8 +2293,8 @@ struct Node
.inputs = { .pointer = &function->root_node, .length = 1 }, .inputs = { .pointer = &function->root_node, .length = 1 },
.id = Node::Id::PROJECTION, .id = Node::Id::PROJECTION,
}); });
projection->projection.index = index; projection->payload.projection.index = index;
projection->projection.name = label; projection->payload.projection.name = label;
return projection; return projection;
} }
@ -2267,11 +2325,12 @@ static_assert(page_size % sizeof(Node) == 0);
.type = .type =
{ {
.id = Node::Type::Id::INTEGER, .id = Node::Type::Id::INTEGER,
.integer = .payload = {
{ .integer = {
.constant = data.value, .constant = data.value,
.bit_count = data.bit_count, // .bit_count = data.bit_count,
.is_constant = 1, .is_constant = 1,
},
}, },
}, },
.inputs = { .pointer = &data.input, .length = 1 }, .inputs = { .pointer = &data.input, .length = 1 },
@ -2491,6 +2550,7 @@ fn void unit_initialize(Unit* unit)
// .node_arena = Arena::init(Arena::default_size, Arena::minimum_granularity, KB(64)), // .node_arena = Arena::init(Arena::default_size, Arena::minimum_granularity, KB(64)),
// .type_arena = type_arena, // .type_arena = type_arena,
.builtin_types = builtin_types, .builtin_types = builtin_types,
.generate_debug_information = 1,
}; };
builtin_types[void_type_index] = { builtin_types[void_type_index] = {
@ -2498,6 +2558,7 @@ fn void unit_initialize(Unit* unit)
.alignment = 1, .alignment = 1,
.id = SemaTypeId::VOID, .id = SemaTypeId::VOID,
.resolved = 1, .resolved = 1,
.flags = 0,
.name = strlit("void"), .name = strlit("void"),
}; };
builtin_types[noreturn_type_index] = { builtin_types[noreturn_type_index] = {
@ -2505,6 +2566,7 @@ fn void unit_initialize(Unit* unit)
.alignment = 1, .alignment = 1,
.id = SemaTypeId::NORETURN, .id = SemaTypeId::NORETURN,
.resolved = 1, .resolved = 1,
.flags = 0,
.name = strlit("noreturn"), .name = strlit("noreturn"),
}; };
builtin_types[opaque_pointer_type_index] = { builtin_types[opaque_pointer_type_index] = {
@ -2512,6 +2574,7 @@ fn void unit_initialize(Unit* unit)
.alignment = 8, .alignment = 8,
.id = SemaTypeId::POINTER, .id = SemaTypeId::POINTER,
.resolved = 1, .resolved = 1,
.flags = 0,
.name = strlit("*any"), .name = strlit("*any"),
}; };
// TODO: float types // TODO: float types
@ -2747,7 +2810,7 @@ struct File
String path; String path;
String source_code; String source_code;
FileStatus status; FileStatus status;
Hashmap<String, Node> symbols; Hashmap<String, Node> symbols = {};
}; };
fn File* add_file(Arena* arena, String file_path) fn File* add_file(Arena* arena, String file_path)
@ -2755,6 +2818,8 @@ fn File* add_file(Arena* arena, String file_path)
auto* file = arena->allocate_one<File>(); auto* file = arena->allocate_one<File>();
*file = { *file = {
.path = file_path, .path = file_path,
.source_code = {},
.status = FILE_STATUS_ADDED,
}; };
return file; return file;
} }
@ -3077,7 +3142,7 @@ fn Node* scope_update_extended(Node* scope, String name, Node* node, s32 nesting
} }
// TODO: avoid recursion // TODO: avoid recursion
auto& map = scope->scope.stack[nesting_level]; auto& map = scope->payload.scope.stack[nesting_level];
if (auto index = map.get(name)) if (auto index = map.get(name))
{ {
auto* old = scope->get_inputs()[*index]; auto* old = scope->get_inputs()[*index];
@ -3103,7 +3168,7 @@ fn Node* scope_update_extended(Node* scope, String name, Node* node, s32 nesting
fn Node* scope_lookup(Analyzer* analyzer, String name) fn Node* scope_lookup(Analyzer* analyzer, String name)
{ {
if (auto* node = scope_update_extended(analyzer->scope, name, nullptr, analyzer->scope->scope.stack.length - 1)) if (auto* node = scope_update_extended(analyzer->scope, name, nullptr, analyzer->scope->payload.scope.stack.length - 1))
{ {
return node; return node;
} }
@ -3238,6 +3303,7 @@ fn Node* scope_lookup(Analyzer* analyzer, String name)
argument_nodes.append_one(node); argument_nodes.append_one(node);
Node* call_node = Node::add(thread, { Node* call_node = Node::add(thread, {
.type = {},
.inputs = argument_nodes.slice(), .inputs = argument_nodes.slice(),
.id = Node::Id::CALL, .id = Node::Id::CALL,
})->peephole(thread, function); })->peephole(thread, function);
@ -3258,10 +3324,17 @@ fn Node* scope_lookup(Analyzer* analyzer, String name)
enum class CurrentOperation enum class CurrentOperation
{ {
NONE, NONE,
ADD, ASSIGN,
ADD_ASSIGN, INTEGER_ADD,
SUB, INTEGER_ADD_ASSIGN,
SUB_ASSIGN, INTEGER_SUB,
INTEGER_SUB_ASSIGN,
INTEGER_COMPARE_EQUAL,
INTEGER_COMPARE_NOT_EQUAL,
INTEGER_COMPARE_LESS,
INTEGER_COMPARE_LESS_EQUAL,
INTEGER_COMPARE_GREATER,
INTEGER_COMPARE_GREATER_EQUAL,
}; };
u64 iterations = 0; u64 iterations = 0;
@ -3295,22 +3368,31 @@ fn Node* scope_lookup(Analyzer* analyzer, String name)
case CurrentOperation::NONE: case CurrentOperation::NONE:
previous_node = current_node; previous_node = current_node;
break; break;
case CurrentOperation::ADD: case CurrentOperation::INTEGER_ADD:
case CurrentOperation::SUB: case CurrentOperation::INTEGER_SUB:
{ {
Node::Id id; Node::Id id;
switch (current_operation) switch (current_operation)
{ {
case CurrentOperation::NONE: case CurrentOperation::NONE:
trap(); trap();
case CurrentOperation::ADD: case CurrentOperation::INTEGER_ADD:
id = Node::Id::INT_ADD; id = Node::Id::INTEGER_ADD;
break; break;
case CurrentOperation::SUB: case CurrentOperation::INTEGER_SUB:
id = Node::Id::INT_SUB; id = Node::Id::INTEGER_SUB;
break; break;
case CurrentOperation::ADD_ASSIGN: case CurrentOperation::INTEGER_ADD_ASSIGN:
case CurrentOperation::SUB_ASSIGN: case CurrentOperation::INTEGER_SUB_ASSIGN:
trap();
case CurrentOperation::INTEGER_COMPARE_EQUAL:
trap();
case CurrentOperation::ASSIGN:
case CurrentOperation::INTEGER_COMPARE_NOT_EQUAL:
case CurrentOperation::INTEGER_COMPARE_LESS:
case CurrentOperation::INTEGER_COMPARE_LESS_EQUAL:
case CurrentOperation::INTEGER_COMPARE_GREATER:
case CurrentOperation::INTEGER_COMPARE_GREATER_EQUAL:
trap(); trap();
} }
@ -3328,9 +3410,57 @@ fn Node* scope_lookup(Analyzer* analyzer, String name)
previous_node = binary; previous_node = binary;
} break; } break;
default: case CurrentOperation::INTEGER_COMPARE_EQUAL:
trap(); case CurrentOperation::INTEGER_COMPARE_NOT_EQUAL:
} case CurrentOperation::INTEGER_COMPARE_LESS:
case CurrentOperation::INTEGER_COMPARE_LESS_EQUAL:
case CurrentOperation::INTEGER_COMPARE_GREATER:
case CurrentOperation::INTEGER_COMPARE_GREATER_EQUAL:
{
Node::Id id;
switch (current_operation)
{
case CurrentOperation::INTEGER_COMPARE_EQUAL:
id = Node::Id::INTEGER_COMPARE_EQUAL;
break;
case CurrentOperation::INTEGER_COMPARE_NOT_EQUAL:
id = Node::Id::INTEGER_COMPARE_NOT_EQUAL;
break;
case CurrentOperation::INTEGER_COMPARE_LESS:
id = Node::Id::INTEGER_COMPARE_LESS;
break;
case CurrentOperation::INTEGER_COMPARE_LESS_EQUAL:
id = Node::Id::INTEGER_COMPARE_LESS_EQUAL;
break;
case CurrentOperation::INTEGER_COMPARE_GREATER:
id = Node::Id::INTEGER_COMPARE_GREATER;
break;
case CurrentOperation::INTEGER_COMPARE_GREATER_EQUAL:
id = Node::Id::INTEGER_COMPARE_GREATER_EQUAL;
break;
default:
trap();
}
Node* inputs[] = {
0,
previous_node,
current_node,
};
auto* binary = Node::add(thread, {
.type = current_node->type,
.inputs = { .pointer = inputs, .length = array_length(inputs), },
.id = id,
});
previous_node = binary;
} break;
case CurrentOperation::ASSIGN:
case CurrentOperation::INTEGER_ADD_ASSIGN:
case CurrentOperation::INTEGER_SUB_ASSIGN:
trap();
}
previous_node = previous_node->peephole(thread, analyzer->function); previous_node = previous_node->peephole(thread, analyzer->function);
@ -3345,13 +3475,13 @@ fn Node* scope_lookup(Analyzer* analyzer, String name)
case bracket_close: case bracket_close:
return previous_node; return previous_node;
case '+': case '+':
current_operation = CurrentOperation::ADD; current_operation = CurrentOperation::INTEGER_ADD;
parser->i += 1; parser->i += 1;
switch (src[parser->i]) switch (src[parser->i])
{ {
case '=': case '=':
current_operation = CurrentOperation::ADD_ASSIGN; current_operation = CurrentOperation::INTEGER_ADD_ASSIGN;
parser->i += 1; parser->i += 1;
break; break;
default: default:
@ -3359,13 +3489,27 @@ fn Node* scope_lookup(Analyzer* analyzer, String name)
} }
break; break;
case '-': case '-':
current_operation = CurrentOperation::SUB; current_operation = CurrentOperation::INTEGER_SUB;
parser->i += 1; parser->i += 1;
switch (src[parser->i]) switch (src[parser->i])
{ {
case '=': case '=':
current_operation = CurrentOperation::SUB_ASSIGN; current_operation = CurrentOperation::INTEGER_SUB_ASSIGN;
parser->i += 1;
break;
default:
break;
}
break;
case '=':
current_operation = CurrentOperation::ASSIGN;
parser->i += 1;
switch (src[parser->i])
{
case '=':
current_operation = CurrentOperation::INTEGER_COMPARE_EQUAL;
parser->i += 1; parser->i += 1;
break; break;
default: default:
@ -3389,17 +3533,17 @@ fn Node* scope_lookup(Analyzer* analyzer, String name)
fn void push_scope(Analyzer* analyzer) fn void push_scope(Analyzer* analyzer)
{ {
analyzer->scope->scope.stack.append_one({}); analyzer->scope->payload.scope.stack.append_one({});
} }
fn void pop_scope(Analyzer* analyzer) fn void pop_scope(Analyzer* analyzer)
{ {
analyzer->scope->scope.stack.pop(); analyzer->scope->payload.scope.stack.pop();
} }
fn Node* define_variable(Analyzer* analyzer, String name, Node* node) fn Node* define_variable(Analyzer* analyzer, String name, Node* node)
{ {
auto* stack = &analyzer->scope->scope.stack; auto* stack = &analyzer->scope->payload.scope.stack;
assert(stack->length); assert(stack->length);
auto* last = &stack->pointer[stack->length - 1]; auto* last = &stack->pointer[stack->length - 1];
@ -3461,7 +3605,7 @@ fn Node* analyze_local_block(Analyzer* analyzer, Parser* parser, Unit* unit, Thr
if (!statement_node) if (!statement_node)
{ {
auto& list = analyzer->scope->scope.stack; auto& list = analyzer->scope->payload.scope.stack;
u32 i = list.length; u32 i = list.length;
u8 found = 0; u8 found = 0;
while (i > 0) while (i > 0)
@ -3812,7 +3956,9 @@ fn void analyze_function(Parser* parser, Thread* thread, Unit* unit, File* file)
.outputs = {}, .outputs = {},
.gvn = function_gvn, .gvn = function_gvn,
.id = Node::Id::SYMBOL_FUNCTION, .id = Node::Id::SYMBOL_FUNCTION,
.symbol = &function->symbol, .payload = {
.symbol = &function->symbol,
},
}); });
parser->skip_space(src); parser->skip_space(src);
@ -4150,12 +4296,20 @@ fn void analyze_function(Parser* parser, Thread* thread, Unit* unit, File* file)
root_arg_types.append(abi_argument_types.slice()); root_arg_types.append(abi_argument_types.slice());
Node::Type root_type = { .id = Node::Type::Id::MULTIVALUE, .multi = { .types = root_arg_types.slice(), }, }; Node::Type root_type = {
.id = Node::Type::Id::MULTIVALUE,
.payload = {
.multi = {
.types = root_arg_types.slice(),
},
},
};
function->root_node = Node::add(thread, { function->root_node = Node::add(thread, {
.type = root_type, .type = root_type,
.inputs = {},
.id = Node::Id::ROOT, .id = Node::Id::ROOT,
}); });
function->root_node->root.args = root_type; function->root_node->payload.root.args = root_type;
function->root_node->peephole(thread, function); function->root_node->peephole(thread, function);
auto* scope_node = Node::add(thread, { auto* scope_node = Node::add(thread, {
@ -4163,7 +4317,7 @@ fn void analyze_function(Parser* parser, Thread* thread, Unit* unit, File* file)
.inputs = { .pointer = &function->root_node, .length = 1 }, .inputs = { .pointer = &function->root_node, .length = 1 },
.id = Node::Id::SCOPE, .id = Node::Id::SCOPE,
}); });
scope_node->scope.stack = {}; scope_node->payload.scope.stack = {};
Analyzer analyzer = { Analyzer analyzer = {
.function = function, .function = function,
.scope = scope_node, .scope = scope_node,
@ -4363,6 +4517,7 @@ String test_file_paths[] = {
strlit("tests/constant_prop/main.nat"), strlit("tests/constant_prop/main.nat"),
strlit("tests/simple_variable_declaration/main.nat"), strlit("tests/simple_variable_declaration/main.nat"),
strlit("tests/function_call_args/main.nat"), strlit("tests/function_call_args/main.nat"),
strlit("tests/comparison/main.nat"),
}; };
#ifdef __linux__ #ifdef __linux__

10
tests/comparison/main.nat Normal file
View File

@ -0,0 +1,10 @@
fn foo(arg: s32) s32
{
return arg == 0;
}
fn[cc(.c)] main [export] () s32
{
>arg: s32 = 0;
return foo(arg);
}