This may break a lot of things. Still need to do extensive testing.
"type": "cppdbg",
"request": "launch",
"program": "${workspaceFolder}/onyx",
- "args": ["-verbose", "progs/vararg_test.onyx"],
+ "args": ["-verbose", "tests/i32map.onyx"],
"stopAtEntry": true,
- "cwd": "~/dev/onyx",
+ "cwd": "~/dev/c/onyx",
"environment": [],
"externalConsole": false,
"MIMode": "gdb",
get_size :: proc (file: File) -> u64 {
fs: FileStat;
- if fd_filestat_get(file.fd, ^fs) != Errno.Success do return 0l;
+ if fd_filestat_get(file.fd, ^fs) != Errno.Success do return 0;
return fs.size;
}
fd_tell(file.fd, ^prev_loc);
dummy: i64;
- fd_seek(file.fd, 0l, Whence.Set, ^dummy);
+ fd_seek(file.fd, 0, Whence.Set, ^dummy);
dummy2: u32;
buf := IOVec.{ data, size };
- fd_pread(file.fd, IOVecArray.{ ^buf, 1 }, 0l, ^dummy2);
+ fd_pread(file.fd, IOVecArray.{ ^buf, 1 }, 0, ^dummy2);
fd_seek(file.fd, prev_loc, Whence.Set, ^dummy);
package core.random
-#private_file seed := 8675309
+#private_file seed : i32 = 8675309
#private_file RANDOM_MULTIPLIER :: 1664525
#private_file RANDOM_INCREMENT :: 1013904223
set_seed :: proc (s: u32) do seed = s;
int :: proc (s := ^seed) -> u32 {
- *s = *s * RANDOM_MULTIPLIER + RANDOM_INCREMENT;
+ *s = *s * RANDOM_MULTIPLIER + RANDOM_INCREMENT;
return *s;
}
if s.data[s.count - 1] == #char "\n" do print_buffer_flush();
}
-print_cstring :: proc (s: cstring) do str.builder_append(^print_buffer, s);
-print_i64 :: proc (n: i64, base := 10l) do str.builder_append(^print_buffer, n, base);
-print_i32 :: proc (n: i32, base := 10) do str.builder_append(^print_buffer, cast(i64) n, cast(u64) base);
-print_f64 :: proc (n: f64) do str.builder_append(^print_buffer, n);
-print_f32 :: proc (n: f32) do str.builder_append(^print_buffer, cast(f64) n);
-print_bool :: proc (b: bool) do str.builder_append(^print_buffer, b);
-print_ptr :: proc (p: ^void) do str.builder_append(^print_buffer, cast(i64) p, 16l);
+print_cstring :: proc (s: cstring) do str.builder_append(^print_buffer, s);
+print_i64 :: proc (n: i64, base: u64 = 10) do str.builder_append(^print_buffer, n, base);
+print_i32 :: proc (n: i32, base: u32 = 10) do str.builder_append(^print_buffer, cast(i64) n, cast(u64) base);
+print_f64 :: proc (n: f64) do str.builder_append(^print_buffer, n);
+print_f32 :: proc (n: f32) do str.builder_append(^print_buffer, cast(f64) n);
+print_bool :: proc (b: bool) do str.builder_append(^print_buffer, b);
+print_ptr :: proc (p: ^void) do str.builder_append(^print_buffer, cast(i64) p, cast(u64) 16);
print_range :: proc (r: range, sep := " ") {
for i: r {
if !vararg_get(va, ^n) do return;
ibuf : [128] u8;
- istr := str.i64_to_string(~~n, 10l, Buffer.{ ~~ibuf, 128 });
+ istr := str.i64_to_string(~~n, 10, Buffer.{ ~~ibuf, 128 });
for a: istr {
buffer[len] = a;
if !vararg_get(va, ^n) do return;
ibuf : [128] u8;
- istr := str.i64_to_string(n, 10l, Buffer.{ ~~ibuf, 128 });
+ istr := str.i64_to_string(n, 10, Buffer.{ ~~ibuf, 128 });
for a: istr {
buffer[len] = a;
if !vararg_get(va, ^n) do return;
ibuf : [128] u8;
- istr := str.i64_to_string(~~n, 16l, Buffer.{ ~~ibuf, 128 });
+ istr := str.i64_to_string(~~n, 16, Buffer.{ ~~ibuf, 128 });
for a: istr {
buffer[len] = a;
n := cast(u64) n_;
is_neg := false;
- if n_ < 0l && base == 10l {
+ if n_ < 0 && base == 10 {
is_neg = true;
n = cast(u64) -n_;
}
s :: "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz+/";
- while n > 0l {
+ while n > 0 {
m :: n % base;
*c = s[cast(u32) m];
c -= 1;
}
- if base == 16l {
+ if base == 16 {
*c = #char "x";
len += 1;
c -= 1;
c -= 1;
}
- if base == 2l {
+ if base == 2 {
*c = #char "b";
len += 1;
c -= 1;
b := Buffer.{ cast(^void) buf.data, buf.count };
len := 0;
- s1 := i64_to_string(v / 10000l, 10l, b);
+ s1 := i64_to_string(v / 10000, 10, b);
for i: 0 .. s1.count do buf.data[i] = s1.data[i];
buf.data[s1.count] = #char ".";
len = s1.count + 1;
if v < ~~0 do v = -v;
- s2 := i64_to_string(v % 10000l, 10l, b);
+ s2 := i64_to_string(v % 10000, 10, b);
for i: 0 .. s2.count do buf.data[s1.count + 1 + i] = s2.data[i];
len += s2.count;
return string.{ buf.data, len };
}
-builder_add_i64 :: proc (use sb: ^StringBuilder, n: i64, base := 10l) -> ^StringBuilder {
+builder_add_i64 :: proc (use sb: ^StringBuilder, n: i64, base: u64 = 10) -> ^StringBuilder {
buf : [256] u8;
s := i64_to_string(n, base, Buffer.{ cast(^void) buf, 256 });
return builder_add_string(sb, s);
extern AstBasicType basic_type_f64;
extern AstBasicType basic_type_rawptr;
+extern AstBasicType basic_type_int_unsized;
+extern AstBasicType basic_type_float_unsized;
+
extern AstNode builtin_package_node;
extern AstNumLit builtin_heap_start;
extern AstGlobal builtin_stack_top;
AstTyped* ast_reduce(bh_allocator a, AstTyped* node);
AstNode* ast_clone(bh_allocator a, void* n);
void promote_numlit_to_larger(AstNumLit* num);
+b32 convert_numlit_to_type(AstNumLit* num, Type* type);
+b32 type_check_or_auto_cast(AstTyped* node, Type* type);
+Type* resolve_expression_type(AstTyped* node);
typedef enum PolyProcLookupMethod {
PPLM_By_Call,
Basic_Kind_Bool,
+ Basic_Kind_Int_Unsized,
Basic_Kind_I8,
Basic_Kind_U8,
Basic_Kind_I16,
Basic_Kind_I64,
Basic_Kind_U64,
+ Basic_Kind_Float_Unsized,
Basic_Kind_F32,
Basic_Kind_F64,
multi_max(4, 2, 76, 3, 1203, 2, 4) |> print();
print("\n");
- multi_max(4l, 2l, 76l, 3l, 1203l, 2l, 4l) |> print();
+ multi_max(cast(u64) 4, cast(u64) 2, cast(u64) 76, cast(u64) 3, cast(u64) 1203, cast(u64) 2, cast(u64) 4) |> print();
print("\n");
weird_sum(4, 1) |> print();
for i: 0 .. 100 {
array_push(^s.a, (5 * i) % 21);
- array_push(^s.b, 3l * cast(i64) i);
+ array_push(^s.b, 3 * cast(i64) i);
array_push(^s.c, V2.{ i, i * i });
}
print("\n");
print("Does the array contain 2637? ");
- print(array_contains(^barr, 2637l));
+ print(array_contains(^barr, 2637));
print("\n");
readline :: proc (buf: ^u8, bufsize: u32) -> u32 {
iov := IOVec.{ buf, bufsize };
nread : Size;
- fd_pread(0, IOVecArray.{ ^iov, 1 }, 0l, ^nread);
+ fd_pread(0, IOVecArray.{ ^iov, 1 }, 0, ^nread);
return nread;
}
print("\n");
print("\td_namlen: ");
- print_i64(cast(u64) dirent.d_namlen, 16l);
+ print_i64(cast(u64) dirent.d_namlen, 16);
print("\n");
print("\td_type: ");
- print_i64(cast(u64) dirent.d_type, 16l);
+ print_i64(cast(u64) dirent.d_type, 16);
print("\n");
bufused -= sizeof DirEnt + dirent.d_namlen;
timer_end :: proc (start_time: Timestamp) -> Timestamp {
curr_time: Timestamp;
clock_time_get(ClockID.Realtime, cast(Timestamp) 1, ^curr_time);
- return (curr_time - start_time) / 1000000l;
+ return (curr_time - start_time) / 1000000;
}
is_prime :: proc (n := 0) -> bool {
defer {
^sb |> string_builder_clear()
|> sba("\nTime taken: ")
- |> sba(cast(u64) timer_end(timer), 10l)
+ |> sba(cast(u64) timer_end(timer), 10)
|> sba("ms\n")
|> string_builder_to_string()
|> print();
defer cfree(cont.data);
print(cont);
- sum := 0l;
+ sum: u64 = 0;
for i: 0 .. 20000 do if is_prime(i) do sum += cast(u64) i;
print("Sum of primes less than 20000 is: ");
print_i64(sum);
case #default {
print("Unexpected token: ");
- print_i64(cast(u64) tokens[i][0], 16l);
+ print_i64(cast(u64) tokens[i][0], 16);
print("\n");
// This breaks out of the for loop
print_i64(cast(u64) fib(20));
print("\n");
- print(add(20l, 5l));
- print(add(20l, 5l));
- print(add(20l, 5l));
- print(add(20l, 5l));
+ print(add(cast(u64) 20, cast(u64) 5));
+ print(add(cast(u64) 20, cast(u64) 5));
+ print(add(cast(u64) 20, cast(u64) 5));
+ print(add(cast(u64) 20, cast(u64) 5));
print("\n");
print(cast(u64) add(20.0f, 5.0f));
print("\n");
print(cast(u64) get_slice_length(^slice));
print("\n");
- print(multi_poly(5.4f, 10l));
+ print(multi_poly(5.4f, 10));
print("\n");
dynarr : [..] Vec3;
print(dynarr.count, 10);
}
-foobar :: proc (a: i32, b := 1, c := 5l) {
+foobar :: proc (a: i32, b := 1, c: i64 = 5) {
print_i64(cast(u64) a);
print("\n");
- print_i64(cast(u64) b, 16l);
+ print_i64(cast(u64) b, 16);
print("\n");
print_i64(c);
print("\n");
AstBasicType basic_type_f64 = { Ast_Kind_Basic_Type, 0, NULL, "f64" , &basic_types[Basic_Kind_F64] };
AstBasicType basic_type_rawptr = { Ast_Kind_Basic_Type, 0, NULL, "rawptr", &basic_types[Basic_Kind_Rawptr] };
+// NOTE: Types used for numeric literals
+AstBasicType basic_type_int_unsized = { Ast_Kind_Basic_Type, 0, NULL, "unsized_int", &basic_types[Basic_Kind_Int_Unsized] };
+AstBasicType basic_type_float_unsized = { Ast_Kind_Basic_Type, 0, NULL, "unsized_float", &basic_types[Basic_Kind_Float_Unsized] };
+
static OnyxToken simd_token = { Token_Type_Symbol, 0, "", { 0 } };
AstBasicType basic_type_i8x16 = { Ast_Kind_Basic_Type, 0, &simd_token, "i8x16", &basic_types[Basic_Kind_I8X16] };
AstBasicType basic_type_i16x8 = { Ast_Kind_Basic_Type, 0, &simd_token, "i16x8", &basic_types[Basic_Kind_I16X8] };
static inline void fill_in_type(AstTyped* node) {
if (node->type_node && node->type_node->kind == Ast_Kind_Array_Type) {
- if (((AstArrayType *) node->type_node)->count_expr) check_expression(&((AstArrayType *) node->type_node)->count_expr);
+ if (((AstArrayType *) node->type_node)->count_expr) {
+ check_expression(&((AstArrayType *) node->type_node)->count_expr);
+ resolve_expression_type(((AstArrayType *) node->type_node)->count_expr);
+ }
}
if (node->type == NULL)
node->type = type_build_from_ast(semstate.allocator, node->type_node);
}
-/*
-// NOTE: Returns 1 if the conversion was successful.
-static b32 convert_numlit_to_type(AstNumLit* num, Type* type) {
- fill_in_type((AstTyped *) num);
- assert(num->type);
-
- if (types_are_compatible(num->type, type)) return 1;
-
- if (!type_is_numeric(type)) return 0;
-
- if (num->type->Basic.flags & Basic_Flag_Integer) {
-
- //
- // Integer literal auto cast rules:
- // - Up in size always works
- // - Down in size only works if value is in range of smaller type.
- // - Cast to float only works if value is less than the maximum precise value for float size.
- //
-
- if (type->Basic.flags & Basic_Flag_Integer) {
- if (num->type->Basic.size < type->Basic.size) {
- num->value.l = (i64) num->value.i;
- num->type = type;
- return 1;
- }
- }
-
- if (type->Basic.flags & Basic_Flag_Float) {
-
- }
-
- }
- else if (num->type->Basic.flags & Basic_Flag_Float) {
- // NOTE: Floats don't cast to integers implicitly.
- if ((type->Basic.flags & Basic_Flag_Float) == 0) return 0;
-
- if (num->type->Basic.kind == Basic_Kind_F32 && type->Basic.kind == Basic_Kind_F64) num->value.d = (f64) num->value.f;
- else return 0;
-
- num->type = type;
-
- return 1;
- }
-
- return 0;
-} */
-
-// NOTE: Returns 0 if it was not possible to make the types compatible.
-static b32 type_check_or_auto_cast(AstTyped* node, Type* type) {
- assert(type != NULL);
- assert(node != NULL);
-
- if (types_are_compatible(node->type, type)) return 1;
- if (node_is_auto_cast((AstNode *) node)) {
- // If the node is an auto cast, we convert it to a cast node which will reports errors if
- // the cast is illegal in the code generation.
- ((AstUnaryOp *) node)->type = type;
- ((AstUnaryOp *) node)->operation = Unary_Op_Cast;
- return 1;
- }
- else if (node->kind == Ast_Kind_NumLit) {
- // if (convert_numlit_to_type((AstNumLit *) node, type)) return 1;
- }
-
- return 0;
-}
-
b32 check_return(AstReturn* retnode) {
if (retnode->expr) {
if (check_expression(&retnode->expr)) return 1;
return 1;
}
+ resolve_expression_type(sc->value);
promote_numlit_to_larger((AstNumLit *) sc->value);
u64 value = ((AstNumLit *) sc->value)->value.l;
call->va_kind = VA_Kind_Untyped;
if (arg_pos >= bh_arr_length(arg_arr)) goto type_checking_done;
+
+ resolve_expression_type(arg_arr[arg_pos]->value);
arg_arr[arg_pos]->va_kind = VA_Kind_Untyped;
break;
}
// NOTE: This is the 'type inference' system. Very stupid, but very easy.
// If a left operand has an unknown type, fill it in with the type of
// the right hand side.
- if (binop->left->type == NULL) binop->left->type = binop->right->type;
+ if (binop->left->type == NULL) binop->left->type = resolve_expression_type(binop->right);
} else {
// NOTE: +=, -=, ...
if (ltype->kind == Type_Kind_Pointer) ltype = &basic_types[Basic_Kind_Rawptr];
if (rtype->kind == Type_Kind_Pointer) rtype = &basic_types[Basic_Kind_Rawptr];
+
if (!types_are_compatible(ltype, rtype)) {
b32 left_ac = node_is_auto_cast((AstNode *) binop->left);
b32 right_ac = node_is_auto_cast((AstNode *) binop->right);
onyx_report_error(binop->token->pos, "Cannot have auto cast on both sides of binary operator.");
return 1;
}
- else if (left_ac && type_check_or_auto_cast(binop->left, rtype));
- else if (right_ac && type_check_or_auto_cast(binop->right, ltype));
+ else if (type_check_or_auto_cast(binop->left, rtype));
+ else if (type_check_or_auto_cast(binop->right, ltype));
else {
onyx_report_error(binop->token->pos,
"Cannot compare '%s' to '%s'.",
if (check_expression(&binop->left)) return 1;
if (check_expression(&binop->right)) return 1;
+ // resolve_expression_type(binop->left);
+ // resolve_expression_type(binop->right);
if ((binop->left->flags & Ast_Flag_Comptime) && (binop->right->flags & Ast_Flag_Comptime)) {
binop->flags |= Ast_Flag_Comptime;
return check_binaryop_bool(pbinop);
if (binop->left->type == NULL) {
- onyx_report_error(binop->token->pos,
+ onyx_report_error(binop->left->token->pos,
"Unable to resolve type for symbol '%b'.",
binop->left->token->text, binop->left->token->length);
return 1;
}
if (binop->right->type == NULL) {
- onyx_report_error(binop->token->pos,
+ onyx_report_error(binop->right->token->pos,
"Unable to resolve type for symbol '%b'.",
binop->right->token->text, binop->right->token->length);
return 1;
}
if (lptr) {
+ resolve_expression_type(binop->right);
if (!type_is_integer(binop->right->type)) {
onyx_report_error(binop->right->token->pos, "Expected integer type.");
return 1;
AstUnaryOp* unaryop = *punop;
if (check_expression(&unaryop->expr)) return 1;
+ resolve_expression_type(unaryop->expr);
if (unaryop->operation != Unary_Op_Cast) {
unaryop->type = unaryop->expr->type;
return 0;
}
+ resolve_expression_type(aa->expr);
if (aa->expr->type->kind != Type_Kind_Basic
|| (aa->expr->type->Basic.kind != Basic_Kind_I32 && aa->expr->type->Basic.kind != Basic_Kind_U32)) {
onyx_report_error(aa->token->pos, "Expected type u32 or i32 for index.");
if (memres->initial_value != NULL) {
fill_in_type(memres->initial_value);
+ resolve_expression_type(memres->initial_value);
check_expression(&memres->initial_value);
if ((memres->initial_value->flags & Ast_Flag_Comptime) == 0) {
return 1;
}
- Type* memres_type = memres->type;
+ if (memres->type != NULL) {
+ Type* memres_type = memres->type;
+ if (!type_check_or_auto_cast(memres->initial_value, memres_type)) {
+ onyx_report_error(memres->token->pos,
+ "Cannot assign value of type '%s' to a '%s'.",
+ type_get_name(memres_type),
+ type_get_name(memres->initial_value->type));
+ return 1;
+ }
- if (!type_check_or_auto_cast(memres->initial_value, memres_type)) {
- onyx_report_error(memres->token->pos,
- "Cannot assign value of type '%s' to a '%s'.",
- type_get_name(memres_type),
- type_get_name(memres->initial_value->type));
- return 1;
+ } else {
+ memres->type = memres->initial_value->type;
+ bh_printf("Memres type: %s\n", type_get_name(memres->type));
}
}
case Entity_Type_Expression:
if (check_expression(&ent->expr)) return;
+ resolve_expression_type(ent->expr);
break;
case Entity_Type_Type_Alias:
}
ent->state = Entity_State_Code_Gen;
-}
\ No newline at end of file
+}
int_node->flags |= Ast_Flag_Comptime;
int_node->value.l = 0ll;
- AstType* type = (AstType *) &basic_type_i32;
token_toggle_end(int_node->token);
char* first_invalid = NULL;
i64 value = strtoll(int_node->token->text, &first_invalid, 0);
- if (bh_abs(value) > ((u64) 1 << 32) || *first_invalid == 'l') {
- type = (AstType *) &basic_type_i64;
- }
int_node->value.l = value;
- int_node->type_node = type;
+ int_node->type_node = (AstType *) &basic_type_int_unsized;
token_toggle_end(int_node->token);
return int_node;
float_node->flags |= Ast_Flag_Comptime;
float_node->value.d = 0.0;
- AstType* type = (AstType *) &basic_type_f64;
+ AstType* type = (AstType *) &basic_type_float_unsized;
token_toggle_end(float_node->token);
if (float_node->token->text[float_node->token->length - 1] == 'f') {
type = (AstType *) &basic_type_f32;
float_node->value.f = strtof(float_node->token->text, NULL);
} else {
- type = (AstType *) &basic_type_f64;
float_node->value.d = strtod(float_node->token->text, NULL);
}
pnode->token = symbol;
pnode->package = newpackage;
- symbol_introduce(package->scope, symbol, pnode);
+ symbol_introduce(package->scope, symbol, (AstNode *) pnode);
}
package = newpackage;
#include "onyxsempass.h"
#include "onyxparser.h"
#include "onyxutils.h"
-
+#include "onyxastnodes.h"
static void scope_enter(Scope* new_scope);
param->local->type = type_build_from_ast(semstate.node_allocator, param->local->type_node);
if (param->default_value != NULL) {
- if (!types_are_compatible(param->local->type, param->default_value->type)) {
+ if (!type_check_or_auto_cast(param->default_value, param->local->type)) {
onyx_report_error(param->local->token->pos,
"Expected default value of type '%s', was of type '%s'.",
type_get_name(param->local->type),
}
} else if (param->default_value != NULL) {
- param->local->type = param->default_value->type;
+ param->local->type = resolve_expression_type(param->default_value);
} else if (param->vararg_kind == VA_Kind_Untyped) {
// HACK
if ((*value)->value != NULL) {
// HACK
- if ((*value)->value->type_node == (AstType *) &basic_type_i32) {
+ resolve_expression_type((AstTyped *) (*value)->value);
+ if (type_is_small_integer((*value)->value->type)) {
next_assign_value = (*value)->value->value.i;
- } else if ((*value)->value->type_node == (AstType *) &basic_type_i64) {
+ } else if (type_is_integer((*value)->value->type)) {
next_assign_value = (*value)->value->value.l;
} else {
onyx_report_error((*value)->token->pos, "expected numeric integer literal for enum initialization");
static void symres_memres(AstMemRes** memres) {
(*memres)->type_node = symres_type((*memres)->type_node);
+
if ((*memres)->initial_value != NULL) {
symres_expression(&(*memres)->initial_value);
- if ((*memres)->type_node == NULL)
- (*memres)->type_node = (*memres)->initial_value->type_node;
-
- } else {
- if ((*memres)->type_node == NULL) return;
+ // if ((*memres)->type_node == NULL)
+ // (*memres)->type_node = (*memres)->initial_value->type_node;
}
}
ent->state = Entity_State_Check_Types;
if (ent->package) scope_leave();
-}
\ No newline at end of file
+}
{ Type_Kind_Basic, 0, { Basic_Kind_Bool, Basic_Flag_Boolean, 1, 1, "bool" } },
+ { Type_Kind_Basic, 0, { Basic_Kind_Int_Unsized, Basic_Flag_Integer, 0, 0, "unsized int" } },
{ Type_Kind_Basic, 0, { Basic_Kind_I8, Basic_Flag_Integer, 1, 1, "i8" } },
{ Type_Kind_Basic, 0, { Basic_Kind_U8, Basic_Flag_Integer | Basic_Flag_Unsigned, 1, 1, "u8" } },
{ Type_Kind_Basic, 0, { Basic_Kind_I16, Basic_Flag_Integer, 2, 2, "i16" } },
{ Type_Kind_Basic, 0, { Basic_Kind_I64, Basic_Flag_Integer, 8, 8, "i64" } },
{ Type_Kind_Basic, 0, { Basic_Kind_U64, Basic_Flag_Integer | Basic_Flag_Unsigned, 8, 8, "u64" } },
+ { Type_Kind_Basic, 0, { Basic_Kind_Float_Unsized, Basic_Flag_Float, 0, 0, "unsized float" } },
{ Type_Kind_Basic, 0, { Basic_Kind_F32, Basic_Flag_Float, 4, 4, "f32" } },
{ Type_Kind_Basic, 0, { Basic_Kind_F64, Basic_Flag_Float, 8, 4, "f64" } },
u32 count = 0;
if (a_node->count_expr) {
- a_node->count_expr->type = type_build_from_ast(alloc, a_node->count_expr->type_node);
+ if (a_node->count_expr->type == NULL)
+ a_node->count_expr->type = type_build_from_ast(alloc, a_node->count_expr->type_node);
if (node_is_auto_cast((AstNode *) a_node->count_expr)) {
a_node->count_expr = ((AstUnaryOp *) a_node)->expr;
case Ast_Kind_Poly_Call_Type: {
AstPolyCallType* pc_type = (AstPolyCallType *) type_node;
- // @Cleanup: make this a proper error message. -brendanfh 2020/09/14
- assert(pc_type->callee && pc_type->callee->kind == Ast_Kind_Poly_Struct_Type);
+ if (!(pc_type->callee && pc_type->callee->kind == Ast_Kind_Poly_Struct_Type)) {
+ onyx_report_error(pc_type->token->pos, "Cannot instantiate a concrete type off of a non-polymorphic type.");
+ return NULL;
+ }
AstPolyStructType* ps_type = (AstPolyStructType *) pc_type->callee;
if (type->kind == Type_Kind_Enum) return 1;
if (type->kind != Type_Kind_Basic) return 0;
- return type->Basic.kind >= Basic_Kind_I8 && type->Basic.kind <= Basic_Kind_F64;
+ return type->Basic.kind >= Basic_Kind_Int_Unsized && type->Basic.kind <= Basic_Kind_F64;
}
b32 type_is_compound(Type* type) {
// NOTE: Int32, Int16, Int8
i64 val = (i64) num->value.i;
num->value.l = val;
+ num->type = &basic_types[Basic_Kind_I64];
} else if (num->type->Basic.size <= 4) {
// NOTE: Float32
f64 val = (f64) num->value.f;
num->value.d = val;
+ num->type = &basic_types[Basic_Kind_F64];
}
}
}
fori (i, 0, param->idx) arg = (AstArgument *) arg->next;
- actual_type = arg->value->type;
+ actual_type = resolve_expression_type(arg->value);
}
else if (pp_lookup == PPLM_By_Function_Type) {
return concrete_struct;
}
+
+// NOTE: Returns 1 if the conversion was successful.
+b32 convert_numlit_to_type(AstNumLit* num, Type* type) {
+ if (num->type == NULL)
+ num->type = type_build_from_ast(semstate.allocator, num->type_node);
+ assert(num->type);
+
+ if (types_are_compatible(num->type, type)) return 1;
+ if (!type_is_numeric(type)) return 0;
+
+ if (num->type->Basic.kind == Basic_Kind_Int_Unsized) {
+
+ //
+ // Integer literal auto cast rules:
+ // - Up in size always works
+ // - Down in size only works if value is in range of smaller type.
+ // - Cast to float only works if value is less than the maximum precise value for float size.
+ //
+
+ if (type->Basic.flags & Basic_Flag_Integer) {
+ if (type->Basic.flags & Basic_Flag_Unsigned) {
+ u64 value = (u64) num->value.l;
+ if (type->Basic.size == 8) {
+ num->type = type;
+ return 1;
+ }
+ if (value <= ((u64) 1 << (type->Basic.size * 8)) - 1) {
+ num->type = type;
+ return 1;
+ }
+
+ } else {
+ i64 value = (i64) num->value.l;
+ switch (type->Basic.size) {
+ case 1: if (-128 <= value && value <= 127) {
+ num->value.i = (i8) value;
+ num->type = type;
+ return 1;
+ }
+ case 2: if (-32768 <= value && value <= 32767) {
+ num->value.i = (i16) value;
+ num->type = type;
+ return 1;
+ }
+ case 4: if (-247483648 <= value && value <= 2147483647) {
+ num->value.i = (i32) value;
+ num->type = type;
+ return 1;
+ }
+ case 8: { num->type = type;
+ return 1;
+ }
+ }
+ }
+ }
+
+ else if (type->Basic.flags & Basic_Flag_Float) {
+ if (type->Basic.size == 4) {
+ // TODO(Brendan): Check these boundary conditions
+ if (bh_abs(num->value.l) >= (1 << 23)) {
+ onyx_report_error(num->token->pos, "Integer '%l' does not fit in 32-bit float exactly.", num->value.l);
+ return 0;
+ }
+
+ num->type = type;
+ num->value.f = (f32) num->value.l;
+ return 1;
+ }
+ if (type->Basic.size == 8) {
+ // TODO(Brendan): Check these boundary conditions
+ if (bh_abs(num->value.l) >= (1ull << 52)) {
+ onyx_report_error(num->token->pos, "Integer '%l' does not fit in 32-bit float exactly.", num->value.l);
+ return 0;
+ }
+
+ num->type = type;
+ num->value.d = (f64) num->value.l;
+ return 1;
+ }
+ }
+ }
+ else if (num->type->Basic.kind == Basic_Kind_Float_Unsized) {
+ // NOTE: Floats don't cast to integers implicitly.
+ if ((type->Basic.flags & Basic_Flag_Float) == 0) return 0;
+
+ if (type->Basic.kind == Basic_Kind_F32) {
+ num->value.f = (f32) num->value.d;
+ }
+
+ num->type = type;
+ return 1;
+ }
+ else if (num->type->Basic.kind == Basic_Kind_F32) {
+ // NOTE: Floats don't cast to integers implicitly.
+ if ((type->Basic.flags & Basic_Flag_Float) == 0) return 0;
+
+ if (type->Basic.kind == Basic_Kind_F64) {
+ num->value.d = (f64) num->value.f;
+ num->type = type;
+ return 1;
+ }
+ }
+
+ return 0;
+}
+
+// NOTE: Returns 0 if it was not possible to make the types compatible.
+b32 type_check_or_auto_cast(AstTyped* node, Type* type) {
+ assert(type != NULL);
+ assert(node != NULL);
+
+ if (types_are_compatible(node->type, type)) return 1;
+ if (node_is_auto_cast((AstNode *) node)) {
+ // If the node is an auto cast, we convert it to a cast node which will reports errors if
+ // the cast is illegal in the code generation.
+ ((AstUnaryOp *) node)->type = type;
+ ((AstUnaryOp *) node)->operation = Unary_Op_Cast;
+ return 1;
+ }
+ else if (node->kind == Ast_Kind_NumLit) {
+ if (convert_numlit_to_type((AstNumLit *) node, type)) return 1;
+ }
+
+ return 0;
+}
+
+Type* resolve_expression_type(AstTyped* node) {
+ if (node->type == NULL)
+ node->type = type_build_from_ast(semstate.allocator, node->type_node);
+
+ if (node->kind == Ast_Kind_NumLit) {
+ if (node->type->Basic.kind == Basic_Kind_Int_Unsized) {
+ convert_numlit_to_type((AstNumLit *) node, &basic_types[Basic_Kind_I32]);
+ }
+ else if (node->type->Basic.kind == Basic_Kind_Float_Unsized) {
+ convert_numlit_to_type((AstNumLit *) node, &basic_types[Basic_Kind_F32]);
+ }
+ }
+
+ return node->type;
+}
+
u32 vararg_count = 0;
u32 vararg_offset = -1;
- u64 stack_top_store_local;;
+ u64 stack_top_store_local;
bh_arr_each(AstArgument *, parg, call->arg_arr) {
AstArgument* arg = *parg;
Array details:
Size: 0
Capacity: 4
- Data ptr: 0x10A28
+ Data ptr: 0x10A38
Size of elements: 4
Alignment of elements: 4
Array details:
Size: 0
Capacity: 4
- Data ptr: 0x10A48
+ Data ptr: 0x10A58
Size of elements: 8
Alignment of elements: 8
0 5 10 15 20 4 9 14 19 3 8 13 18 2 7 12 17 1 6 11 16 0 5 10 15 20 4 9 14 19 3 8 13 18 2 7 12 17 1 6 11 16 0 5 10 15 20 4 9 14 19 3 8 13 18 2 7 12 17 1 6 11 16 0 5 10 15 20 4 9 14 19 3 8 13 18 2 7 12 17 1 6 11 16 0 5 10 15 20 4 9 14 19 3 8 13 18 2 7 12
A has 22? false
Vec3(0, 0, 0) Vec3(1, 1, 1) Vec3(2, 4, 8) Vec3(3, 9, 27) Vec3(4, 16, 64) Vec3(5, 25, 125) Vec3(6, 36, 216) Vec3(7, 49, 343) Vec3(8, 64, 512) Vec3(9, 81, 729) Vec3(10, 100, 1000) Vec3(11, 121, 1331) Vec3(12, 144, 1728) Vec3(13, 169, 2197) Vec3(14, 196, 2744) Vec3(15, 225, 3375) Vec3(16, 256, 4096) Vec3(17, 289, 4913) Vec3(18, 324, 5832) Vec3(19, 361, 6859) Vec3(20, 400, 8000) Vec3(21, 441, 9261) Vec3(22, 484, 10648) Vec3(23, 529, 12167) Vec3(24, 576, 13824) Vec3(25, 625, 15625) Vec3(26, 676, 17576) Vec3(27, 729, 19683) Vec3(28, 784, 21952) Vec3(29, 841, 24389) Vec3(30, 900, 27000) Vec3(31, 961, 29791) Vec3(32, 1024, 32768) Vec3(33, 1089, 35937) Vec3(34, 1156, 39304) Vec3(35, 1225, 42875) Vec3(36, 1296, 46656) Vec3(37, 1369, 50653) Vec3(38, 1444, 54872) Vec3(39, 1521, 59319) Vec3(40, 1600, 64000) Vec3(41, 1681, 68921) Vec3(42, 1764, 74088) Vec3(43, 1849, 79507) Vec3(44, 1936, 85184) Vec3(45, 2025, 91125) Vec3(46, 2116, 97336) Vec3(47, 2209, 103823) Vec3(48, 2304, 110592) Vec3(49, 2401, 117649) Vec3(50, 2500, 125000) Vec3(51, 2601, 132651) Vec3(52, 2704, 140608) Vec3(53, 2809, 148877) Vec3(54, 2916, 157464) Vec3(55, 3025, 166375) Vec3(56, 3136, 175616) Vec3(57, 3249, 185193) Vec3(58, 3364, 195112) Vec3(59, 3481, 205379) Vec3(60, 3600, 216000) Vec3(61, 3721, 226981) Vec3(62, 3844, 238328) Vec3(63, 3969, 250047) Vec3(64, 4096, 262144) Vec3(65, 4225, 274625) Vec3(66, 4356, 287496) Vec3(67, 4489, 300763) Vec3(68, 4624, 314432) Vec3(69, 4761, 328509) Vec3(70, 4900, 343000) Vec3(71, 5041, 357911) Vec3(72, 5184, 373248) Vec3(73, 5329, 389017) Vec3(74, 5476, 405224) Vec3(75, 5625, 421875) Vec3(76, 5776, 438976) Vec3(77, 5929, 456533) Vec3(78, 6084, 474552) Vec3(79, 6241, 493039) Vec3(80, 6400, 512000) Vec3(81, 6561, 531441) Vec3(82, 6724, 551368) Vec3(83, 6889, 571787) Vec3(84, 7056, 592704) Vec3(85, 7225, 614125) Vec3(86, 7396, 636056) Vec3(87, 7569, 658503) Vec3(88, 7744, 681472) Vec3(89, 7921, 704969) Vec3(90, 8100, 729000) Vec3(91, 8281, 753571) Vec3(92, 8464, 778688) Vec3(93, 8649, 804357) Vec3(94, 8836, 830584) Vec3(95, 9025, 857375) Vec3(96, 9216, 884736) Vec3(97, 9409, 912673) Vec3(98, 9604, 941192) Vec3(99, 9801, 970299)
-0x11CD8 0x11CE4 0x11CF0 0x11CFC 0x11D08 0x11D14 0x11D20 0x11D2C 0x11D38 0x11D44 0x11D50 0x11D5C 0x11D68 0x11D74 0x11D80 0x11D8C 0x11D98 0x11DA4 0x11DB0 0x11DBC 0x11DC8 0x11DD4 0x11DE0 0x11DEC 0x11DF8 0x11E04 0x11E10 0x11E1C 0x11E28 0x11E34 0x11E40 0x11E4C 0x11E58 0x11E64 0x11E70 0x11E7C 0x11E88 0x11E94 0x11EA0 0x11EAC 0x11EB8 0x11EC4 0x11ED0 0x11EDC 0x11EE8 0x11EF4 0x11F00 0x11F0C 0x11F18 0x11F24 0x11F30 0x11F3C 0x11F48 0x11F54 0x11F60 0x11F6C 0x11F78 0x11F84 0x11F90 0x11F9C 0x11FA8 0x11FB4 0x11FC0 0x11FCC 0x11FD8 0x11FE4 0x11FF0 0x11FFC 0x12008 0x12014 0x12020 0x1202C 0x12038 0x12044 0x12050 0x1205C 0x12068 0x12074 0x12080 0x1208C 0x12098 0x120A4 0x120B0 0x120BC 0x120C8 0x120D4 0x120E0 0x120EC 0x120F8 0x12104 0x12110 0x1211C 0x12128 0x12134 0x12140 0x1214C 0x12158 0x12164 0x12170 0x1217C
-1838 1842 1846 1850 1854 1858 1862 1866 1870 1874 1878 1882
+0x11CE8 0x11CF4 0x11D00 0x11D0C 0x11D18 0x11D24 0x11D30 0x11D3C 0x11D48 0x11D54 0x11D60 0x11D6C 0x11D78 0x11D84 0x11D90 0x11D9C 0x11DA8 0x11DB4 0x11DC0 0x11DCC 0x11DD8 0x11DE4 0x11DF0 0x11DFC 0x11E08 0x11E14 0x11E20 0x11E2C 0x11E38 0x11E44 0x11E50 0x11E5C 0x11E68 0x11E74 0x11E80 0x11E8C 0x11E98 0x11EA4 0x11EB0 0x11EBC 0x11EC8 0x11ED4 0x11EE0 0x11EEC 0x11EF8 0x11F04 0x11F10 0x11F1C 0x11F28 0x11F34 0x11F40 0x11F4C 0x11F58 0x11F64 0x11F70 0x11F7C 0x11F88 0x11F94 0x11FA0 0x11FAC 0x11FB8 0x11FC4 0x11FD0 0x11FDC 0x11FE8 0x11FF4 0x12000 0x1200C 0x12018 0x12024 0x12030 0x1203C 0x12048 0x12054 0x12060 0x1206C 0x12078 0x12084 0x12090 0x1209C 0x120A8 0x120B4 0x120C0 0x120CC 0x120D8 0x120E4 0x120F0 0x120FC 0x12108 0x12114 0x12120 0x1212C 0x12138 0x12144 0x12150 0x1215C 0x12168 0x12174 0x12180 0x1218C
+1854 1858 1862 1866 1870 1874 1878 1882 1886 1890 1894 1898
20 20 20 20 20 19 19 19 19 19 18 18 18 18 18 17 17 17 17 16 16 16 16 15 15 15 15 15 14 14 14 14 14 13 13 13 13 13 12 12 12 12 12 11 11 11 11 10 10 10 10 10 9 9 9 9 9 8 8 8 8 8 7 7 7 7 7 6 6 6 6 5 5 5 5 5 4 4 4 4 4 3 3 3 3 3 2 2 2 2 2 1 1 1 1 0 0 0 0 0
297 294 291 288 285 282 279 276 273 270 267 264 261 258 255 252 249 246 243 240 237 234 231 228 225 222 219 216 213 210 207 204 201 198 195 192 189 186 183 180 177 174 171 168 165 162 159 156 153 150 147 144 141 138 135 132 129 126 123 120 117 114 111 108 105 102 99 96 93 90 87 84 81 78 75 72 69 66 63 60 57 54 51 48 45 42 39 36 33 30 27 24 21 18 15 12 9 6 3 0
After adding...
Array details:
Size: 100
Capacity: 128
- Data ptr: 0x116B8
+ Data ptr: 0x116C8
Size of elements: 4
Alignment of elements: 4
Array details:
Size: 100
Capacity: 128
- Data ptr: 0x118C8
+ Data ptr: 0x118D8
Size of elements: 8
Alignment of elements: 8
Has ^a[20]? true
Has null? false
-Value at ^a[50]: 0x11A58 == 0x11A58
+Value at ^a[50]: 0x11A68 == 0x11A68
Deleteing ^a[20]
Has ^a[20]? false
Clearing SOA...
vararg_test("Here are some numbers:\n", 1, 2, 3, 4, 5);
print("\n\n");
- multi_max(4, 2, 76, 3, 1203, 2, 4) |> println();
- multi_max(4l, 2l, 76l, 3l, 1203l, 2l, 4l) |> println();
+ multi_max(4, 2, 76, 3, 1203, 2, 4) |> println();
+ multi_max(4, 2, 76, 3, 1203, 2, 4) |> println();
weird_sum(4, 1) |> println();
for i: 0 .. 100 {
array.push(^s.a, (5 * i) % 21);
- array.push(^s.b, 3l * cast(i64) i);
+ array.push(^s.b, 3 * cast(i64) i);
array.push(^s.c, Vec3.{ i, i * i, i * i * i });
}