Hello world array
This commit is contained in:
parent
9000a9abd7
commit
06f9fe3597
@ -869,6 +869,27 @@ const Parser = struct{
|
|||||||
const unary: Unary = switch (src[parser.i]) {
|
const unary: Unary = switch (src[parser.i]) {
|
||||||
'A'...'Z', 'a'...'z', '_' => Unary.none,
|
'A'...'Z', 'a'...'z', '_' => Unary.none,
|
||||||
'0'...'9' => Unary.none,
|
'0'...'9' => Unary.none,
|
||||||
|
'\'' => {
|
||||||
|
// Character literal
|
||||||
|
parser.i += 1;
|
||||||
|
const is_escape = src[parser.i] == '\\';
|
||||||
|
parser.i += @intFromBool(is_escape);
|
||||||
|
const potential_ch = src[parser.i];
|
||||||
|
parser.i += 1;
|
||||||
|
parser.expect_character(src, '\'');
|
||||||
|
const ch = switch (is_escape) {
|
||||||
|
true => switch (potential_ch) {
|
||||||
|
'n' => '\n',
|
||||||
|
else => unreachable,
|
||||||
|
},
|
||||||
|
false => potential_ch,
|
||||||
|
};
|
||||||
|
const character_literal = create_constant_int(thread, .{
|
||||||
|
.n = ch,
|
||||||
|
.type = &thread.integers[8 - 1].type,
|
||||||
|
});
|
||||||
|
return &character_literal.value;
|
||||||
|
},
|
||||||
'-' => block: {
|
'-' => block: {
|
||||||
parser.i += 1;
|
parser.i += 1;
|
||||||
break :block .negation;
|
break :block .negation;
|
||||||
@ -1232,6 +1253,7 @@ const Parser = struct{
|
|||||||
const ty = if (initial_type) |source_ty| if (maybe_type) |destination_ty| blk: {
|
const ty = if (initial_type) |source_ty| if (maybe_type) |destination_ty| blk: {
|
||||||
switch (typecheck(destination_ty, source_ty)) {
|
switch (typecheck(destination_ty, source_ty)) {
|
||||||
.success => {},
|
.success => {},
|
||||||
|
else => unreachable,
|
||||||
}
|
}
|
||||||
break :blk source_ty;
|
break :blk source_ty;
|
||||||
} else source_ty
|
} else source_ty
|
||||||
@ -1435,8 +1457,21 @@ const Parser = struct{
|
|||||||
|
|
||||||
switch (argument_abi.kind) {
|
switch (argument_abi.kind) {
|
||||||
.direct => {
|
.direct => {
|
||||||
assert(argument_value_type == argument_type);
|
const v = switch (typecheck(argument_type, argument_value_type)) {
|
||||||
_ = abi_argument_values.append(argument_value);
|
.success => argument_value,
|
||||||
|
.implicit_pointer_cast => b: {
|
||||||
|
const cast = emit_cast(analyzer, thread, .{
|
||||||
|
.value = argument_value,
|
||||||
|
.type = argument_type,
|
||||||
|
.id = .implicit_pointer_cast,
|
||||||
|
.scope = analyzer.current_scope,
|
||||||
|
.line = 0,
|
||||||
|
.column = 0,
|
||||||
|
});
|
||||||
|
break :b &cast.instruction.value;
|
||||||
|
},
|
||||||
|
};
|
||||||
|
_ = abi_argument_values.append(v);
|
||||||
},
|
},
|
||||||
.direct_coerce => |coerced_type| {
|
.direct_coerce => |coerced_type| {
|
||||||
const coerced_value = emit_direct_coerce(analyzer, thread, .{
|
const coerced_value = emit_direct_coerce(analyzer, thread, .{
|
||||||
@ -1724,6 +1759,7 @@ const Parser = struct{
|
|||||||
if (maybe_type) |ty| {
|
if (maybe_type) |ty| {
|
||||||
switch (typecheck(ty, pointer_load_type)) {
|
switch (typecheck(ty, pointer_load_type)) {
|
||||||
.success => {},
|
.success => {},
|
||||||
|
else => unreachable,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1854,6 +1890,7 @@ const Parser = struct{
|
|||||||
if (expected_type) |expected| {
|
if (expected_type) |expected| {
|
||||||
switch (typecheck(expected, result_type)) {
|
switch (typecheck(expected, result_type)) {
|
||||||
.success => {},
|
.success => {},
|
||||||
|
else => unreachable,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1910,6 +1947,19 @@ const Parser = struct{
|
|||||||
assert(result != value);
|
assert(result != value);
|
||||||
return result;
|
return result;
|
||||||
},
|
},
|
||||||
|
.array => {
|
||||||
|
const array_field_access_id = parser.parse_raw_identifier(src);
|
||||||
|
if (byte_equal(array_field_access_id, "length")) {
|
||||||
|
const array_type = ty.get_payload(.array);
|
||||||
|
const constant = create_constant_int(thread, .{
|
||||||
|
.n = array_type.descriptor.element_count,
|
||||||
|
.type = if (expected_type) |exp| exp else unreachable,
|
||||||
|
});
|
||||||
|
return &constant.value;
|
||||||
|
} else {
|
||||||
|
fail_term("Array access must only be 'length', got", array_field_access_id);
|
||||||
|
}
|
||||||
|
},
|
||||||
else => |t| @panic(@tagName(t)),
|
else => |t| @panic(@tagName(t)),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -3428,6 +3478,7 @@ const Cast = struct{
|
|||||||
int_from_bitfield,
|
int_from_bitfield,
|
||||||
int_from_pointer,
|
int_from_pointer,
|
||||||
truncate,
|
truncate,
|
||||||
|
implicit_pointer_cast,
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -5375,7 +5426,9 @@ fn worker_thread(thread_index: u32, cpu_count: *u32) void {
|
|||||||
const cast = instruction.get_payload(.cast);
|
const cast = instruction.get_payload(.cast);
|
||||||
const cast_value = llvm_get_value(thread, cast.value);
|
const cast_value = llvm_get_value(thread, cast.value);
|
||||||
const v = switch (cast.id) {
|
const v = switch (cast.id) {
|
||||||
.int_from_bitfield => cast_value,
|
.int_from_bitfield,
|
||||||
|
.implicit_pointer_cast,
|
||||||
|
=> cast_value,
|
||||||
.truncate, .int_from_pointer => |cast_id| b: {
|
.truncate, .int_from_pointer => |cast_id| b: {
|
||||||
const cast_type = llvm_get_type(thread, cast.type);
|
const cast_type = llvm_get_type(thread, cast.type);
|
||||||
const cast_i = builder.createCast(switch (cast_id) {
|
const cast_i = builder.createCast(switch (cast_id) {
|
||||||
@ -9158,12 +9211,35 @@ fn try_resolve_file(thread: *Thread, file: *File) void {
|
|||||||
|
|
||||||
const TypecheckResult = enum{
|
const TypecheckResult = enum{
|
||||||
success,
|
success,
|
||||||
|
implicit_pointer_cast,
|
||||||
};
|
};
|
||||||
|
|
||||||
fn typecheck(expected: *Type, have: *Type) TypecheckResult {
|
fn typecheck(expected: *Type, have: *Type) TypecheckResult {
|
||||||
if (expected == have) {
|
if (expected == have) {
|
||||||
return TypecheckResult.success;
|
return TypecheckResult.success;
|
||||||
} else {
|
} else {
|
||||||
|
switch (expected.sema.id) {
|
||||||
|
.typed_pointer => {
|
||||||
|
const expected_pointer = expected.get_payload(.typed_pointer);
|
||||||
|
switch (have.sema.id) {
|
||||||
|
.typed_pointer => {
|
||||||
|
const have_pointer = have.get_payload(.typed_pointer);
|
||||||
|
switch (have_pointer.descriptor.pointee.sema.id) {
|
||||||
|
.array => {
|
||||||
|
const have_pointed_array_type = have_pointer.descriptor.pointee.get_payload(.array);
|
||||||
|
if (have_pointed_array_type.descriptor.element_type == expected_pointer.descriptor.pointee) {
|
||||||
|
return .implicit_pointer_cast;
|
||||||
|
}
|
||||||
|
},
|
||||||
|
else => |t| @panic(@tagName(t)),
|
||||||
|
}
|
||||||
|
},
|
||||||
|
else => |t| @panic(@tagName(t)),
|
||||||
|
}
|
||||||
|
},
|
||||||
|
else => |t| @panic(@tagName(t)),
|
||||||
|
}
|
||||||
|
|
||||||
fail();
|
fail();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
6
retest/standalone/hello_world_array/main.nat
Normal file
6
retest/standalone/hello_world_array/main.nat
Normal file
@ -0,0 +1,6 @@
|
|||||||
|
fn [cc(.c)] write[extern](file_descriptor: s32, byte_pointer: *u8, byte_count: u64) s64;
|
||||||
|
fn [cc(.c)] main[export]() s32 {
|
||||||
|
>arr: [4]u8 = ['H', 'i', '!', '\n'];
|
||||||
|
write(1, arr&, arr.length);
|
||||||
|
return 0;
|
||||||
|
}
|
Loading…
x
Reference in New Issue
Block a user