Pass more tests
All checks were successful
All checks were successful
This commit is contained in:
parent
0d910fd58d
commit
3309329911
@ -505,13 +505,13 @@ pub const Value = struct {
|
|||||||
cast,
|
cast,
|
||||||
cast_to,
|
cast_to,
|
||||||
extend: *Value,
|
extend: *Value,
|
||||||
integer_max,
|
integer_max: *Type,
|
||||||
int_from_enum,
|
int_from_enum,
|
||||||
int_from_pointer,
|
int_from_pointer,
|
||||||
pointer_cast,
|
pointer_cast,
|
||||||
select,
|
select,
|
||||||
trap,
|
trap,
|
||||||
truncate,
|
truncate: *Value,
|
||||||
va_start,
|
va_start,
|
||||||
va_end,
|
va_end,
|
||||||
va_copy,
|
va_copy,
|
||||||
@ -755,6 +755,21 @@ pub const Module = struct {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn parse_hexadecimal(noalias module: *Module) u64 {
|
||||||
|
var value: u64 = 0;
|
||||||
|
while (true) {
|
||||||
|
const ch = module.content[module.offset];
|
||||||
|
if (!lib.is_hex_digit(ch)) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
module.offset += 1;
|
||||||
|
value = lib.parse.accumulate_hexadecimal(value, ch);
|
||||||
|
}
|
||||||
|
|
||||||
|
return value;
|
||||||
|
}
|
||||||
|
|
||||||
fn parse_decimal(noalias module: *Module) u64 {
|
fn parse_decimal(noalias module: *Module) u64 {
|
||||||
var value: u64 = 0;
|
var value: u64 = 0;
|
||||||
while (true) {
|
while (true) {
|
||||||
@ -1351,6 +1366,8 @@ pub const Module = struct {
|
|||||||
else => .decimal,
|
else => .decimal,
|
||||||
};
|
};
|
||||||
const value: u64 = switch (token_integer_kind) {
|
const value: u64 = switch (token_integer_kind) {
|
||||||
|
.binary => @trap(),
|
||||||
|
.octal => @trap(),
|
||||||
.decimal => switch (next_ch) {
|
.decimal => switch (next_ch) {
|
||||||
0...9 => module.report_error(),
|
0...9 => module.report_error(),
|
||||||
else => b: {
|
else => b: {
|
||||||
@ -1358,7 +1375,11 @@ pub const Module = struct {
|
|||||||
break :b 0;
|
break :b 0;
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
else => @trap(),
|
.hexadecimal => b: {
|
||||||
|
module.offset += 2;
|
||||||
|
const v = module.parse_hexadecimal();
|
||||||
|
break :b v;
|
||||||
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
if (module.content[module.offset] == '.') {
|
if (module.content[module.offset] == '.') {
|
||||||
@ -1721,26 +1742,53 @@ pub const Module = struct {
|
|||||||
|
|
||||||
fn rule_before_value_intrinsic(noalias module: *Module, value_builder: Value.Builder) *Value {
|
fn rule_before_value_intrinsic(noalias module: *Module, value_builder: Value.Builder) *Value {
|
||||||
const intrinsic = value_builder.token.value_intrinsic;
|
const intrinsic = value_builder.token.value_intrinsic;
|
||||||
switch (intrinsic) {
|
const value = module.values.add();
|
||||||
.extend => {
|
value.* = switch (intrinsic) {
|
||||||
|
.extend => blk: {
|
||||||
module.skip_space();
|
module.skip_space();
|
||||||
module.expect_character(left_parenthesis);
|
module.expect_character(left_parenthesis);
|
||||||
module.skip_space();
|
module.skip_space();
|
||||||
const arg_value = module.parse_value(.{});
|
const arg_value = module.parse_value(.{});
|
||||||
module.expect_character(right_parenthesis);
|
module.expect_character(right_parenthesis);
|
||||||
const value = module.values.add();
|
break :blk .{
|
||||||
value.* = .{
|
|
||||||
.bb = .{
|
.bb = .{
|
||||||
.intrinsic = .{
|
.intrinsic = .{
|
||||||
.extend = arg_value,
|
.extend = arg_value,
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
return value;
|
},
|
||||||
|
.integer_max => blk: {
|
||||||
|
module.skip_space();
|
||||||
|
module.expect_character(left_parenthesis);
|
||||||
|
module.skip_space();
|
||||||
|
const ty = module.parse_type();
|
||||||
|
module.expect_character(right_parenthesis);
|
||||||
|
break :blk .{
|
||||||
|
.bb = .{
|
||||||
|
.intrinsic = .{
|
||||||
|
.integer_max = ty,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
};
|
||||||
|
},
|
||||||
|
.truncate => blk: {
|
||||||
|
module.skip_space();
|
||||||
|
module.expect_character(left_parenthesis);
|
||||||
|
module.skip_space();
|
||||||
|
const v = module.parse_value(.{});
|
||||||
|
module.expect_character(right_parenthesis);
|
||||||
|
break :blk .{
|
||||||
|
.bb = .{
|
||||||
|
.intrinsic = .{
|
||||||
|
.truncate = v,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
};
|
||||||
},
|
},
|
||||||
else => @trap(),
|
else => @trap(),
|
||||||
}
|
};
|
||||||
@trap();
|
return value;
|
||||||
}
|
}
|
||||||
|
|
||||||
fn rule_before_integer(noalias module: *Module, value_builder: Value.Builder) *Value {
|
fn rule_before_integer(noalias module: *Module, value_builder: Value.Builder) *Value {
|
||||||
@ -2720,6 +2768,20 @@ pub const Module = struct {
|
|||||||
};
|
};
|
||||||
break :blk extension_instruction;
|
break :blk extension_instruction;
|
||||||
},
|
},
|
||||||
|
.integer_max => |max_type| blk: {
|
||||||
|
const bit_count = max_type.bb.integer.bit_count;
|
||||||
|
const max_value = if (bit_count == 64) ~@as(u64, 0) else (@as(u64, 1) << @intCast(bit_count - @intFromBool(max_type.bb.integer.signed))) - 1;
|
||||||
|
const constant_integer = max_type.resolve(module).handle.to_integer().get_constant(max_value, @intFromBool(false));
|
||||||
|
break :blk constant_integer.to_value();
|
||||||
|
},
|
||||||
|
.truncate => |value_to_truncate| blk: {
|
||||||
|
if (value_to_truncate.llvm == null) {
|
||||||
|
module.emit_value(function, value_to_truncate);
|
||||||
|
}
|
||||||
|
const llvm_value = value_to_truncate.llvm orelse unreachable;
|
||||||
|
const truncate = module.llvm.builder.create_truncate(llvm_value, value_type.llvm.handle.?);
|
||||||
|
break :blk truncate;
|
||||||
|
},
|
||||||
else => @trap(),
|
else => @trap(),
|
||||||
},
|
},
|
||||||
.dereference => |dereferenceable_value| blk: {
|
.dereference => |dereferenceable_value| blk: {
|
||||||
@ -2756,8 +2818,10 @@ pub const Module = struct {
|
|||||||
@trap();
|
@trap();
|
||||||
},
|
},
|
||||||
false => {
|
false => {
|
||||||
const type_max = (@as(u64, 1) << @intCast(integer.bit_count)) - 1;
|
const bit_count = integer.bit_count;
|
||||||
if (constant_integer.value > type_max) {
|
const max_value = if (bit_count == 64) ~@as(u64, 0) else (@as(u64, 1) << @intCast(bit_count - @intFromBool(integer.signed))) - 1;
|
||||||
|
|
||||||
|
if (constant_integer.value > max_value) {
|
||||||
module.report_error();
|
module.report_error();
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
@ -2811,6 +2875,12 @@ pub const Module = struct {
|
|||||||
module.report_error();
|
module.report_error();
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
.truncate => |value_to_truncate| {
|
||||||
|
module.analyze_value_type(function, value_to_truncate, .{});
|
||||||
|
if (expected_type.get_bit_size() >= value_to_truncate.type.?.get_bit_size()) {
|
||||||
|
module.report_error();
|
||||||
|
}
|
||||||
|
},
|
||||||
else => @trap(),
|
else => @trap(),
|
||||||
},
|
},
|
||||||
.dereference => |dereferenceable_value| {
|
.dereference => |dereferenceable_value| {
|
||||||
@ -2863,6 +2933,16 @@ pub const Module = struct {
|
|||||||
.right => variable.type,
|
.right => variable.type,
|
||||||
else => variable.storage.?.type.?,
|
else => variable.storage.?.type.?,
|
||||||
},
|
},
|
||||||
|
.intrinsic => |intrinsic| switch (intrinsic) {
|
||||||
|
// TODO: typecheck
|
||||||
|
.integer_max => |integer_max_type| blk: {
|
||||||
|
if (integer_max_type.bb != .integer) {
|
||||||
|
module.report_error();
|
||||||
|
}
|
||||||
|
break :blk integer_max_type;
|
||||||
|
},
|
||||||
|
else => @trap(),
|
||||||
|
},
|
||||||
else => @trap(),
|
else => @trap(),
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -189,5 +189,7 @@ const names = &[_][]const u8{
|
|||||||
"extend",
|
"extend",
|
||||||
"stack_negation",
|
"stack_negation",
|
||||||
"basic_pointer",
|
"basic_pointer",
|
||||||
|
"integer_max",
|
||||||
|
"integer_hex",
|
||||||
// "pointer",
|
// "pointer",
|
||||||
};
|
};
|
||||||
|
Loading…
x
Reference in New Issue
Block a user