commit
f6bb34a354
2
TODOLIST
2
TODOLIST
@ -1,5 +1,3 @@
|
|||||||
assert
|
|
||||||
orelse
|
|
||||||
size
|
size
|
||||||
trailing zeroes
|
trailing zeroes
|
||||||
leading zeroes
|
leading zeroes
|
||||||
|
@ -176,7 +176,7 @@ const Parser = struct{
|
|||||||
fn skip_space(parser: *Parser, file: []const u8) void {
|
fn skip_space(parser: *Parser, file: []const u8) void {
|
||||||
const original_i = parser.i;
|
const original_i = parser.i;
|
||||||
|
|
||||||
if (!is_space(file[original_i])) return;
|
if (original_i == file.len or !is_space(file[original_i])) return;
|
||||||
|
|
||||||
while (parser.i < file.len) : (parser.i += 1) {
|
while (parser.i < file.len) : (parser.i += 1) {
|
||||||
const ch = file[parser.i];
|
const ch = file[parser.i];
|
||||||
@ -859,6 +859,8 @@ const Parser = struct{
|
|||||||
compare_unsigned_less_equal,
|
compare_unsigned_less_equal,
|
||||||
compare_signed_less,
|
compare_signed_less,
|
||||||
compare_signed_less_equal,
|
compare_signed_less_equal,
|
||||||
|
|
||||||
|
@"orelse",
|
||||||
};
|
};
|
||||||
|
|
||||||
fn parse_constant_expression(parser: *Parser, thread: *Thread, file: *File, maybe_type: ?*Type) *Value {
|
fn parse_constant_expression(parser: *Parser, thread: *Thread, file: *File, maybe_type: ?*Type) *Value {
|
||||||
@ -971,10 +973,61 @@ const Parser = struct{
|
|||||||
previous_value = &i.instruction.value;
|
previous_value = &i.instruction.value;
|
||||||
},
|
},
|
||||||
.assign, .add_assign, .sub_assign, .mul_assign, .udiv_assign, .sdiv_assign, .and_assign, .or_assign, .xor_assign, .shift_left_assign, .logical_shift_right_assign, .arithmetic_shift_right_assign => unreachable,
|
.assign, .add_assign, .sub_assign, .mul_assign, .udiv_assign, .sdiv_assign, .and_assign, .or_assign, .xor_assign, .shift_left_assign, .logical_shift_right_assign, .arithmetic_shift_right_assign => unreachable,
|
||||||
|
.@"orelse" => {
|
||||||
|
const orelse_type = ty orelse unreachable;
|
||||||
|
const condition = emit_condition(analyzer, thread, previous_value);
|
||||||
|
const true_block = create_basic_block(thread);
|
||||||
|
const false_block = create_basic_block(thread);
|
||||||
|
const phi_block = create_basic_block(thread);
|
||||||
|
_ = emit_branch(analyzer, thread, condition, true_block, false_block);
|
||||||
|
const phi = thread.phis.append(.{
|
||||||
|
.instruction = .{
|
||||||
|
.id = .phi,
|
||||||
|
.value = .{
|
||||||
|
.sema = .{
|
||||||
|
.id = .instruction,
|
||||||
|
.thread = thread.get_index(),
|
||||||
|
.resolved = true,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
.type = orelse_type,
|
||||||
|
});
|
||||||
|
_ = phi.nodes.append(.{
|
||||||
|
.value = previous_value,
|
||||||
|
.basic_block = true_block,
|
||||||
|
});
|
||||||
|
_ = phi.nodes.append(.{
|
||||||
|
.value = current_value,
|
||||||
|
.basic_block = false_block,
|
||||||
|
});
|
||||||
|
analyzer.current_basic_block = true_block;
|
||||||
|
_ = emit_jump(analyzer, thread, phi_block);
|
||||||
|
analyzer.current_basic_block = false_block;
|
||||||
|
_ = emit_jump(analyzer, thread, phi_block);
|
||||||
|
|
||||||
|
analyzer.current_basic_block = phi_block;
|
||||||
|
_ = analyzer.current_basic_block.instructions.append(&phi.instruction);
|
||||||
|
|
||||||
|
previous_value = &phi.instruction.value;
|
||||||
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
switch (src[parser.i]) {
|
const original_index = parser.i;
|
||||||
|
const original = src[original_index];
|
||||||
|
switch (original) {
|
||||||
')', ';', ',' => return previous_value,
|
')', ';', ',' => return previous_value,
|
||||||
|
'o' => {
|
||||||
|
const identifier = parser.parse_raw_identifier(src);
|
||||||
|
if (byte_equal(identifier, "orelse")) {
|
||||||
|
current_operation = .@"orelse";
|
||||||
|
} else {
|
||||||
|
parser.i = original;
|
||||||
|
exit(1);
|
||||||
|
}
|
||||||
|
|
||||||
|
parser.skip_space(src);
|
||||||
|
},
|
||||||
'=' => {
|
'=' => {
|
||||||
current_operation = .assign;
|
current_operation = .assign;
|
||||||
parser.i += 1;
|
parser.i += 1;
|
||||||
@ -1206,49 +1259,7 @@ const Parser = struct{
|
|||||||
|
|
||||||
parser.skip_space(src);
|
parser.skip_space(src);
|
||||||
|
|
||||||
const condition_type = condition.get_type();
|
return emit_condition(analyzer, thread, condition);
|
||||||
const compare = switch (condition_type.sema.id) {
|
|
||||||
.integer => int: {
|
|
||||||
const integer_ty = condition_type.get_payload(.integer);
|
|
||||||
if (integer_ty.bit_count == 1) {
|
|
||||||
break :int condition;
|
|
||||||
} else {
|
|
||||||
const zero = thread.constant_ints.append(.{
|
|
||||||
.value = .{
|
|
||||||
.sema = .{
|
|
||||||
.thread = thread.get_index(),
|
|
||||||
.resolved = true,
|
|
||||||
.id = .constant_int,
|
|
||||||
},
|
|
||||||
},
|
|
||||||
.n = 0,
|
|
||||||
.type = condition_type,
|
|
||||||
});
|
|
||||||
|
|
||||||
const compare = thread.integer_compares.append(.{
|
|
||||||
.instruction = .{
|
|
||||||
.value = .{
|
|
||||||
.sema = .{
|
|
||||||
.thread = thread.get_index(),
|
|
||||||
.resolved = true,
|
|
||||||
.id = .instruction,
|
|
||||||
},
|
|
||||||
},
|
|
||||||
.id = .integer_compare,
|
|
||||||
},
|
|
||||||
.left = condition,
|
|
||||||
.right = &zero.value,
|
|
||||||
.id = .not_zero,
|
|
||||||
});
|
|
||||||
_ = analyzer.current_basic_block.instructions.append(&compare.instruction);
|
|
||||||
|
|
||||||
break :int &compare.instruction.value;
|
|
||||||
}
|
|
||||||
},
|
|
||||||
else => |t| @panic(@tagName(t)),
|
|
||||||
};
|
|
||||||
|
|
||||||
return compare;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fn parse_if_expression(parser: *Parser, analyzer: *Analyzer, thread: *Thread, file: *File) IfResult {
|
fn parse_if_expression(parser: *Parser, analyzer: *Analyzer, thread: *Thread, file: *File) IfResult {
|
||||||
@ -1535,11 +1546,12 @@ const Type = struct {
|
|||||||
};
|
};
|
||||||
|
|
||||||
const Keyword = enum{
|
const Keyword = enum{
|
||||||
|
@"break",
|
||||||
@"else",
|
@"else",
|
||||||
@"for",
|
@"for",
|
||||||
@"if",
|
@"if",
|
||||||
@"loop",
|
@"loop",
|
||||||
@"break",
|
@"orelse",
|
||||||
};
|
};
|
||||||
|
|
||||||
const Intrinsic = enum{
|
const Intrinsic = enum{
|
||||||
@ -4661,6 +4673,52 @@ fn emit_branch(analyzer: *Analyzer, thread: *Thread, condition: *Value, taken: *
|
|||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn emit_condition(analyzer: *Analyzer, thread: *Thread, condition: *Value) *Value {
|
||||||
|
const condition_type = condition.get_type();
|
||||||
|
const compare = switch (condition_type.sema.id) {
|
||||||
|
.integer => int: {
|
||||||
|
const integer_ty = condition_type.get_payload(.integer);
|
||||||
|
if (integer_ty.bit_count == 1) {
|
||||||
|
break :int condition;
|
||||||
|
} else {
|
||||||
|
const zero = thread.constant_ints.append(.{
|
||||||
|
.value = .{
|
||||||
|
.sema = .{
|
||||||
|
.thread = thread.get_index(),
|
||||||
|
.resolved = true,
|
||||||
|
.id = .constant_int,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
.n = 0,
|
||||||
|
.type = condition_type,
|
||||||
|
});
|
||||||
|
|
||||||
|
const compare = thread.integer_compares.append(.{
|
||||||
|
.instruction = .{
|
||||||
|
.value = .{
|
||||||
|
.sema = .{
|
||||||
|
.thread = thread.get_index(),
|
||||||
|
.resolved = true,
|
||||||
|
.id = .instruction,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
.id = .integer_compare,
|
||||||
|
},
|
||||||
|
.left = condition,
|
||||||
|
.right = &zero.value,
|
||||||
|
.id = .not_zero,
|
||||||
|
});
|
||||||
|
_ = analyzer.current_basic_block.instructions.append(&compare.instruction);
|
||||||
|
|
||||||
|
break :int &compare.instruction.value;
|
||||||
|
}
|
||||||
|
},
|
||||||
|
else => |t| @panic(@tagName(t)),
|
||||||
|
};
|
||||||
|
|
||||||
|
return compare;
|
||||||
|
}
|
||||||
|
|
||||||
pub const LLVM = struct {
|
pub const LLVM = struct {
|
||||||
const bindings = @import("backend/llvm_bindings.zig");
|
const bindings = @import("backend/llvm_bindings.zig");
|
||||||
pub const x86_64 = struct {
|
pub const x86_64 = struct {
|
||||||
@ -5853,3 +5911,5 @@ pub fn panic(message: []const u8, stack_trace: ?*std.builtin.StackTrace, return_
|
|||||||
},
|
},
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
9
retest/standalone/orelse/main.nat
Normal file
9
retest/standalone/orelse/main.nat
Normal file
@ -0,0 +1,9 @@
|
|||||||
|
fn[cc(.c)] main[export]() s32 {
|
||||||
|
>a: s32 = 5;
|
||||||
|
>b: s32 = a orelse 4;
|
||||||
|
#assert(b == a);
|
||||||
|
>c: s32 = 0;
|
||||||
|
>d: s32 = c orelse a;
|
||||||
|
#assert(d == a);
|
||||||
|
return 0;
|
||||||
|
}
|
Loading…
x
Reference in New Issue
Block a user