This commit is contained in:
David Gonzalez Martin 2025-06-08 09:07:52 -06:00
parent 04ca049e6c
commit 3a44191196
2 changed files with 164 additions and 8 deletions

View File

@ -1417,6 +1417,10 @@ get_byte_size = fn (type: &Type) u64
assert(byte_count == 1 or byte_count == 2 or byte_count == 4 or byte_count == 8 or byte_count == 16);
return byte_count;
},
.pointer =>
{
return 8;
},
else =>
{
#trap();
@ -1449,6 +1453,7 @@ get_byte_alignment = fn (type: &Type) u32
assert(aligned_byte_count == 1 or aligned_byte_count == 2 or aligned_byte_count == 4 or aligned_byte_count == 8 or aligned_byte_count == 16);
return aligned_byte_count;
},
.pointer => { return 8; },
else =>
{
#trap();
@ -2321,8 +2326,19 @@ Statement = struct
scope_to_block = fn (scope: &Scope) &Block
{
assert(scope.kind == .local);
>result: &Block = #field_parent_pointer(scope, "scope");
return result;
return #field_parent_pointer(scope, "scope");
}
scope_to_function = fn (scope: &Scope) &ValueFunction
{
assert(scope.kind == .function);
return #field_parent_pointer(scope, "scope");
}
scope_to_module = fn (scope: &Scope) &Module
{
assert(scope.kind == .global);
return #field_parent_pointer(scope, "scope");
}
new_local = fn (module: &Module, scope: &Scope) &Local
@ -3233,7 +3249,38 @@ tokenize = fn (module: &Module) Token
},
'.' =>
{
#trap();
>id: TokenId = undefined;
>next_ch = module.content[start_index + 1];
switch (next_ch)
{
else => { id = .dot; },
'&' => { id = .pointer_dereference; },
'.' =>
{
switch (module.content[start_index + 2])
{
'.' => { id = .triple_dot; },
else => { id = .double_dot; },
}
},
}
>add: u64 = undefined;
switch (id)
{
.dot => { add = 1; },
.double_dot, .pointer_dereference => { add = 2; },
.triple_dot => { add = 3; },
else => { unreachable; },
}
module.offset += add;
token = {
.id = id,
zero,
};
},
'"' =>
{
@ -3437,11 +3484,41 @@ reference_identifier = fn (module: &Module, current_scope: &Scope, identifier: [
{
.global =>
{
#trap();
assert(module == scope_to_module(scope));
>global = module.first_global;
while (global != zero)
{
if (string_equal(identifier, global.variable.name))
{
variable = &global.variable;
break;
}
global = global.next;
}
>macro_declaration = module.first_macro_declaration;
while (macro_declaration != zero)
{
#trap();
}
},
.function =>
{
#trap();
assert(scope.parent != zero);
>function = scope_to_function(scope);
for (&argument: function.arguments)
{
if (string_equal(identifier, argument.variable.name))
{
variable = &argument.variable;
break;
}
}
},
.local =>
{
@ -3887,7 +3964,18 @@ parse_right = fn (module: &Module, scope: &Scope, builder: ValueBuilder) &Value
},
.pointer_dereference =>
{
#trap();
result = new_value(module);
result.& = {
.content = {
.unary = {
.value = left,
.id = .dereference,
},
},
.id = .unary,
.kind = .right,
zero,
};
},
.left_parenthesis =>
{
@ -5488,7 +5576,17 @@ analyze_type = fn (module: &Module, value: &Value, expected_type: &Type, analysi
},
.dereference =>
{
#trap();
analyze_type(module, unary_value, zero, { .must_be_constant = analysis.must_be_constant, zero });
if (value.kind == .left)
{
report_error();
}
>pointer_type = unary_value.type;
assert(pointer_type.id == .pointer);
>dereference_type = pointer_type.content.pointer.element_type;
typecheck(module, expected_type, dereference_type);
value_type = dereference_type;
},
.int_from_enum =>
{
@ -5533,6 +5631,24 @@ analyze_type = fn (module: &Module, value: &Value, expected_type: &Type, analysi
typecheck(module, expected_type, value_type);
},
// TODO: this is the default case
.ampersand
=>
{
>is_boolean = unary_is_boolean(unary_id);
if (is_boolean)
{
analyze_type(module, unary_value, zero, { .must_be_constant = analysis.must_be_constant, zero });
value_type = uint1(module);
}
else
{
analyze_type(module, unary_value, expected_type, { .must_be_constant = analysis.must_be_constant, zero });
value_type = unary_value.type;
}
typecheck(module, expected_type, value_type);
},
else =>
{
// TODO
@ -5826,6 +5942,35 @@ emit_value = fn (module: &Module, value: &Value, type_kind: TypeKind, expect_con
llvm_value = LLVMBuildTrunc(module.llvm.builder, llvm_unary_value, destination_type, "");
},
.ampersand =>
{
assert(resolved_value_type == resolved_unary_type);
llvm_value = llvm_unary_value;
},
.dereference =>
{
switch (value.kind)
{
.right =>
{
>pointer_type = unary_value.type;
assert(pointer_type.id == .pointer);
>child_type = resolve_alias(module, pointer_type.content.pointer.element_type);
assert(child_type == resolved_value_type);
>load = create_load(module, {
.type = child_type,
.pointer = unary_value.llvm,
.kind = type_kind,
zero,
});
llvm_value = load;
},
.left =>
{
#trap();
}
}
},
else => { #trap(); },
}
},
@ -7184,6 +7329,15 @@ names: [_][]u8 = [
"extend",
"integer_max",
"integer_hex",
"basic_pointer",
"basic_call",
"basic_branch",
"basic_array",
"basic_enum",
"basic_slice",
"basic_string",
"basic_varargs",
"basic_while",
];
[export] main = fn [cc(c)] (argument_count: u32, argv: &&u8, envp: &&u8) s32

View File

@ -8621,8 +8621,10 @@ fn void analyze_statement(Module* module, Scope* scope, Statement* statement, u3
LLVMValueRef indices[] = {
body_index_load,
};
auto gep_type = aggregate_type->structure.fields[0].type->pointer.element_type;
resolve_type_in_place(module, gep_type);
auto gep = create_gep(module, {
.type = aggregate_type->structure.fields[0].type->pointer.element_type->llvm.memory,
.type = gep_type->llvm.memory,
.pointer = extract_pointer,
.indices = array_to_slice(indices),
});