This commit is contained in:
David Gonzalez Martin 2025-06-06 21:32:57 -06:00
parent 09c92d666c
commit 7d4511abae
2 changed files with 151 additions and 2 deletions

View File

@ -1487,6 +1487,8 @@ ValueId = enum
function, function,
constant_integer, constant_integer,
global, global,
unary,
binary,
} }
ValueConstantInteger = struct ValueConstantInteger = struct
@ -1510,10 +1512,37 @@ ValueFunction = struct
attributes: FunctionAttributes, attributes: FunctionAttributes,
} }
UnaryId = enum
{
minus,
plus,
ampersand,
exclamation,
tilde,
enum_name,
extend,
truncate,
pointer_cast,
int_from_enum,
int_from_pointer,
va_end,
bitwise_not,
dereference,
pointer_from_int,
enum_from_int,
}
ValueUnary = struct
{
value: &Value,
id: UnaryId,
}
ValueContent = union ValueContent = union
{ {
constant_integer: ValueConstantInteger, constant_integer: ValueConstantInteger,
function: ValueFunction, function: ValueFunction,
unary: ValueUnary,
} }
ValueKind = enum ValueKind = enum
@ -2819,7 +2848,7 @@ tokenize = fn (module: &Module) Token
>start_character = module.content[start_index]; >start_character = module.content[start_index];
>token: Token = undefined; >token: Token = zero;
switch (start_character) switch (start_character)
{ {
@ -2940,7 +2969,45 @@ tokenize = fn (module: &Module) Token
'!', '!',
=> =>
{ {
#trap(); >next_ch = module.content[start_index + 1];
>id: TokenId = undefined;
if (next_ch == '=')
{
switch (start_character)
{
'+' => { id = .assign_plus; },
'-' => { id = .assign_dash; },
'*' => { id = .assign_asterisk; },
'/' => { id = .assign_forward_slash; },
'%' => { id = .assign_percentage; },
'&' => { id = .assign_ampersand; },
'|' => { id = .assign_bar; },
'^' => { id = .assign_caret; },
'!' => { id = .compare_not_equal; },
else => { unreachable; }
}
}
else
{
switch (start_character)
{
'+' => { id = .plus; },
'-' => { id = .dash; },
'*' => { id = .asterisk; },
'/' => { id = .forward_slash; },
'%' => { id = .percentage; },
'&' => { id = .ampersand; },
'|' => { id = .bar; },
'^' => { id = .caret; },
'!' => { id = .exclamation; },
else => { unreachable; }
}
}
token.id = id;
module.offset += #extend(next_ch == '=') + 1;
}, },
else => else =>
{ {
@ -2984,6 +3051,8 @@ ValueBuilder = struct
allow_assignment_operators: u1, allow_assignment_operators: u1,
} }
parse_precedence = fn (module: &Module, scope: &Scope, builder: ValueBuilder) &Value;
parse_left = fn (module: &Module, scope: &Scope, builder: ValueBuilder) &Value parse_left = fn (module: &Module, scope: &Scope, builder: ValueBuilder) &Value
{ {
>token = builder.token; >token = builder.token;
@ -3007,6 +3076,72 @@ parse_left = fn (module: &Module, scope: &Scope, builder: ValueBuilder) &Value
zero, zero,
}; };
}, },
.dash, .ampersand, .exclamation, .tilde =>
{
assert(!builder.left);
>id: UnaryId = undefined;
switch (token.id)
{
.dash => { id = .minus; },
.ampersand => { id = .ampersand; },
.exclamation => { id = .exclamation; },
.tilde => { id = .bitwise_not; },
else => { unreachable; },
}
>unary_builder = builder;
unary_builder.precedence = .prefix;
unary_builder.token = zero;
unary_builder.kind = #select(token.id == .ampersand, .left, builder.kind);
>unary_value = parse_precedence(module, scope, builder);
result = new_value(module);
result.& = {
.content = {
.unary = {
.value = unary_value,
.id = id,
},
},
.id = .unary,
.kind = .right,
zero,
};
},
.identifier =>
{
#trap();
},
.value_intrinsic =>
{
#trap();
},
.left_bracket =>
{
#trap();
},
.dot =>
{
#trap();
},
.left_parenthesis =>
{
#trap();
},
.string_literal =>
{
#trap();
},
.left_brace =>
{
#trap();
},
.value_keyword =>
{
#trap();
},
else => else =>
{ {
report_error(); report_error();
@ -5738,6 +5873,18 @@ compile_file = fn (arena: &Arena, compile_options: CompileFile) []u8
names: [_][]u8 = [ names: [_][]u8 = [
"minimal", "minimal",
"comments",
"constant_add",
"constant_and",
"constant_div",
"constant_mul",
"constant_rem",
"constant_or",
"constant_sub",
"constant_xor",
"constant_shift_left",
"constant_shift_right",
]; ];
[export] main = fn [cc(c)] (argument_count: u32, argv: &&u8, envp: &&u8) s32 [export] main = fn [cc(c)] (argument_count: u32, argv: &&u8, envp: &&u8) s32

View File

@ -5983,6 +5983,7 @@ fn LLVMValueRef emit_field_access(Module* module, Value* value, LLVMValueRef lef
auto load = create_load(module, { auto load = create_load(module, {
.type = field_access.type, .type = field_access.type,
.pointer = gep, .pointer = gep,
.kind = type_kind,
}); });
return load; return load;
} break; } break;
@ -7704,6 +7705,7 @@ fn void emit_value(Module* module, Value* value, TypeKind type_kind, bool expect
auto condition = value->select.condition; auto condition = value->select.condition;
auto true_value = value->select.true_value; auto true_value = value->select.true_value;
auto false_value = value->select.false_value; auto false_value = value->select.false_value;
emit_value(module, condition, TypeKind::abi, must_be_constant); emit_value(module, condition, TypeKind::abi, must_be_constant);
LLVMValueRef llvm_condition = condition->llvm; LLVMValueRef llvm_condition = condition->llvm;
auto condition_type = condition->type; auto condition_type = condition->type;