for i: 0 .. length do s[i] = value;
}
-alloc_slice :: proc (sl: ^[] $T, count: i32) {
- sl.data = calloc(sizeof T * count);
+alloc_slice :: proc (sl: ^[] $T, count: i32, allocator := context.allocator) {
+ sl.data = raw_alloc(allocator, sizeof T * count);
sl.count = count;
}
-make_slice :: proc ($T: type_expr, count: i32) -> [] T {
+make_slice :: proc ($T: type_expr, count: i32, allocator := context.allocator) -> [] T {
return <[] T>.{
- data = calloc(sizeof T * count),
+ data = raw_alloc(allocator, sizeof T * count),
count = count
};
}
\ No newline at end of file
// of these types in terms of other types. Let's look at some of those types.
// A pointer in Onyx is written as ^<type>. This is read as 'a pointer to a <type>'.
- // I will not type to explain what a pointer is here, but it is something to note
- // that pointers in Onyx are only 4-bytes instead of 8-bytes, since Onyx's compile
- // target is WASM32.
+ // I will not try to explain what a pointer is here, but something to note is that
+ // pointers in Onyx are 8-bytes in size, but only have their lower 4-bytes used,
+ // since Onyx's compile target is WASM32. This way, when WASM64 is standardized,
+ // pointer will not cause any issues when moving over code to 64-bit.
//
// Here foo is an i32. The unary prefix ^ operator takes the address of a value.
// The type of foo_ptr is ^i32, or a pointer to an i32. Another example of a pointer
AstNumLit* make_int_literal(bh_allocator a, i64 value);
AstNumLit* make_float_literal(bh_allocator a, f64 value);
+AstRangeLiteral* make_range_literal(bh_allocator a, AstTyped* low, AstTyped* high);
AstBinaryOp* make_binary_op(bh_allocator a, BinaryOp operation, AstTyped* left, AstTyped* right);
AstArgument* make_argument(bh_allocator a, AstTyped* value);
AstFieldAccess* make_field_access(bh_allocator a, AstTyped* node, char* field);
return num;
}
+AstRangeLiteral* make_range_literal(bh_allocator a, AstTyped* low, AstTyped* high) {
+ AstRangeLiteral* rl = onyx_ast_node_new(a, sizeof(AstRangeLiteral), Ast_Kind_Range_Literal);
+ rl->type = builtin_range_type_type;
+ rl->low = low;
+ rl->high = high;
+ return rl;
+}
+
AstBinaryOp* make_binary_op(bh_allocator a, BinaryOp operation, AstTyped* left, AstTyped* right) {
AstBinaryOp* binop_node = onyx_ast_node_new(a, sizeof(AstBinaryOp), Ast_Kind_Binary_Op);
binop_node->left = left;
CheckStatus check_for(AstFor* fornode) {
CHECK(expression, &fornode->iter);
- fornode->loop_type = For_Loop_Invalid;
+ resolve_expression_type(fornode->iter);
Type* iter_type = fornode->iter->type;
- b32 can_iterate = 0;
- if (types_are_compatible(iter_type, builtin_range_type_type)) {
+ fornode->loop_type = For_Loop_Invalid;
+ if (types_are_compatible(iter_type, &basic_types[Basic_Kind_I32])) {
if (fornode->by_pointer) {
onyx_report_error(fornode->var->token->pos, "Cannot iterate by pointer over a range.");
return Check_Error;
}
- can_iterate = 1;
+ AstNumLit* low_0 = make_int_literal(context.ast_alloc, 0);
+ AstRangeLiteral* rl = make_range_literal(context.ast_alloc, (AstTyped *) low_0, fornode->iter);
+ CHECK(range_literal, &rl);
+ fornode->iter = (AstTyped *) rl;
+
+ fornode->var->type = builtin_range_type_type->Struct.memarr[0]->type;
+ fornode->var->flags |= Ast_Flag_Cannot_Take_Addr;
+ fornode->loop_type = For_Loop_Range;
+ }
+ else if (types_are_compatible(iter_type, builtin_range_type_type)) {
+ if (fornode->by_pointer) {
+ onyx_report_error(fornode->var->token->pos, "Cannot iterate by pointer over a range.");
+ return Check_Error;
+ }
// NOTE: Blindly copy the first range member's type which will
// be the low value. - brendanfh 2020/09/04
}
else if (iter_type->kind == Type_Kind_Array) {
- can_iterate = 1;
-
if (fornode->by_pointer) fornode->var->type = type_make_pointer(context.ast_alloc, iter_type->Array.elem);
else fornode->var->type = iter_type->Array.elem;
fornode->loop_type = For_Loop_Array;
}
else if (iter_type->kind == Type_Kind_Slice) {
- can_iterate = 1;
-
if (fornode->by_pointer) fornode->var->type = iter_type->Slice.ptr_to_data;
else fornode->var->type = iter_type->Slice.ptr_to_data->Pointer.elem;
return Check_Error;
}
- can_iterate = 1;
-
fornode->var->type = iter_type->VarArgs.ptr_to_data->Pointer.elem;
// NOTE: Slices are VarArgs are being treated the same here.
fornode->loop_type = For_Loop_Slice;
}
else if (iter_type->kind == Type_Kind_DynArray) {
- can_iterate = 1;
-
if (fornode->by_pointer) fornode->var->type = iter_type->DynArray.ptr_to_data;
else fornode->var->type = iter_type->DynArray.ptr_to_data->Pointer.elem;
if (fornode->by_pointer)
fornode->var->flags |= Ast_Flag_Cannot_Take_Addr;
- if (!can_iterate) {
+ if (fornode->loop_type == For_Loop_Invalid) {
onyx_report_error(fornode->iter->token->pos,
"Cannot iterate over a '%s'.",
type_get_name(iter_type));