}
array_to_slice :: proc (arr: ^[..] $T) -> [] T {
- return arr.data[0 : arr.count];
+ return arr.data[0 .. arr.count];
}
/*
array_map :: proc (arr: ^[..] $T, f: proc (T) -> T) {
for i: 0, arr.count do arr.data[i] = f(arr.data[i]);
-}
\ No newline at end of file
+}
fd_seek(file.fd, prev_loc, Whence.Set, ^dummy);
- return data[0 : size];
+ return data[0 .. size];
}
file_get_contents :: proc #overloaded {
return file_get_contents(tmp_file);
}
-}
\ No newline at end of file
+}
for i: 0, str.count {
if str[i] == delim {
- strarr[curr_str] = str.data[begin : i];
+ strarr[curr_str] = str.data[begin .. i];
begin = i + 1;
curr_str += 1;
}
}
- strarr[curr_str] = str.data[begin : str.count];
+ strarr[curr_str] = str.data[begin .. str.count];
- return strarr[0 : delim_count + 1];
+ return strarr[0 .. delim_count + 1];
}
string_substr :: proc (str: string, sub: string) -> string {
while j := 0; j < sub.count && str[i + j] == sub[j] {
j += 1;
- if j == sub.count do return str.data[i : i + j];
+ if j == sub.count do return str.data[i .. i + j];
}
}
- return str.data[0:0];
+ return str.data[0 .. 0];
}
string_contains :: proc (str: string, c: u8) -> bool {
c -= 1;
n /= base;
-
+
} else {
*c = #char "0";
len += 1;
stdio_init();
- main.main(argv[0 : argc]);
+ main.main(argv[0 .. argc]);
print_buffer_flush();
}
- I think all the infrastructure is there for this
[ ] data structure based iteration
+ - Currently, I do not plan on having custom iterators. This may very well change in the near future.
+ - For now, a for loop will be reimagined to look like:
+ for val: iterable ...
+
+ - 'iterable' will be something of a type that the compiler knows how to iterate over:
+ * range
+ * array
+ * slice
+ * dynamic array
[ ] baked parameters
- Compile time known parameters
typedef struct AstAddressOf AstAddressOf;
typedef struct AstDereference AstDereference;
typedef struct AstArrayAccess AstArrayAccess;
-typedef struct AstSlice AstSlice;
typedef struct AstFieldAccess AstFieldAccess;
typedef struct AstSizeOf AstSizeOf;
typedef struct AstAlignOf AstAlignOf;
struct AstAddressOf { AstTyped_base; AstTyped *expr; };
struct AstDereference { AstTyped_base; AstTyped *expr; };
struct AstArrayAccess { AstTyped_base; AstTyped *addr; AstTyped *expr; u64 elem_size; };
-struct AstSlice { AstTyped_base; AstTyped *addr; AstTyped *lo, *hi; u64 elem_size; };
struct AstFieldAccess { AstTyped_base; AstTyped *expr; u32 offset; u32 idx; };
struct AstSizeOf { AstTyped_base; AstType *so_type; u64 size; };
struct AstAlignOf { AstTyped_base; AstType *ao_type; u64 alignment; };
array_sort(^s.a, cmp_dec);
array_sort(^s.b, cmp_asc);
- print_array(^s.a);
+ print_array(s.a.data[21 .. 27]);
print_array(^s.b);
print("After adding...\n");
CHECK(address_of, AstAddressOf* aof);
CHECK(dereference, AstDereference* deref);
CHECK(array_access, AstArrayAccess* expr);
-CHECK(slice, AstSlice* sl);
+CHECK(slice, AstArrayAccess* sl);
CHECK(field_access, AstFieldAccess** pfield);
CHECK(range_literal, AstBinaryOp** range);
CHECK(size_of, AstSizeOf* so);
return 0;
}
-b32 check_slice(AstSlice* sl) {
+b32 check_slice(AstArrayAccess* sl) {
if (check_expression(&sl->addr)) return 1;
- if (check_expression(&sl->lo)) return 1;
- if (check_expression(&sl->hi)) return 1;
+ if (check_expression(&sl->expr)) return 1;
if (!type_is_pointer(sl->addr->type)) {
onyx_report_error(sl->token->pos, "Expected pointer or array type for left of slice creation.");
return 1;
}
- if (sl->lo->type->kind != Type_Kind_Basic
- || (sl->lo->type->Basic.kind != Basic_Kind_I32 && sl->lo->type->Basic.kind != Basic_Kind_U32)) {
- onyx_report_error(sl->lo->token->pos, "Expected type u32 or i32 for lower index.");
- return 1;
- }
-
- if (sl->hi->type->kind != Type_Kind_Basic
- || (sl->hi->type->Basic.kind != Basic_Kind_I32 && sl->hi->type->Basic.kind != Basic_Kind_U32)) {
- onyx_report_error(sl->hi->token->pos, "Expected type u32 or i32 for upper index.");
- return 1;
- }
-
Type *of = NULL;
if (sl->addr->type->kind == Type_Kind_Pointer)
of = sl->addr->type->Pointer.elem;
case Ast_Kind_Address_Of: retval = check_address_of((AstAddressOf *) expr); break;
case Ast_Kind_Dereference: retval = check_dereference((AstDereference *) expr); break;
case Ast_Kind_Array_Access: retval = check_array_access((AstArrayAccess *) expr); break;
- case Ast_Kind_Slice: retval = check_slice((AstSlice *) expr); break;
+ case Ast_Kind_Slice: retval = check_slice((AstArrayAccess *) expr); break;
case Ast_Kind_Field_Access: retval = check_field_access((AstFieldAccess **) pexpr); break;
case Ast_Kind_Size_Of: retval = check_size_of((AstSizeOf *) expr); break;
case Ast_Kind_Align_Of: retval = check_align_of((AstAlignOf *) expr); break;
case Ast_Kind_Address_Of: return sizeof(AstAddressOf);
case Ast_Kind_Dereference: return sizeof(AstDereference);
case Ast_Kind_Array_Access: return sizeof(AstArrayAccess);
- case Ast_Kind_Slice: return sizeof(AstSlice);
+ case Ast_Kind_Slice: return sizeof(AstArrayAccess);
case Ast_Kind_Field_Access: return sizeof(AstFieldAccess);
case Ast_Kind_Pipe: return sizeof(AstBinaryOp);
case Ast_Kind_Range: return sizeof(AstBinaryOp);
switch ((u16) node->kind) {
case Ast_Kind_Binary_Op:
+ case Ast_Kind_Range:
((AstBinaryOp *) nn)->left = (AstTyped *) ast_clone(a, ((AstBinaryOp *) node)->left);
((AstBinaryOp *) nn)->right = (AstTyped *) ast_clone(a, ((AstBinaryOp *) node)->right);
break;
((AstDereference *) nn)->expr = (AstTyped *) ast_clone(a, ((AstDereference *) node)->expr);
break;
+ case Ast_Kind_Slice:
case Ast_Kind_Array_Access:
((AstArrayAccess *) nn)->addr = (AstTyped *) ast_clone(a, ((AstArrayAccess *) node)->addr);
((AstArrayAccess *) nn)->expr = (AstTyped *) ast_clone(a, ((AstArrayAccess *) node)->expr);
break;
- case Ast_Kind_Slice:
- ((AstSlice *) nn)->lo = (AstTyped *) ast_clone(a, ((AstSlice *) node)->lo);
- ((AstSlice *) nn)->hi = (AstTyped *) ast_clone(a, ((AstSlice *) node)->hi);
- ((AstSlice *) nn)->addr = (AstTyped *) ast_clone(a, ((AstSlice *) node)->addr);
- break;
-
case Ast_Kind_Field_Access:
((AstFieldAccess *) nn)->expr = (AstTyped *) ast_clone(a, ((AstFieldAccess *) node)->expr);
break;
switch ((u16) parser->curr->type) {
case '[': {
OnyxToken *open_bracket = expect_token(parser, '[');
- AstTyped *lo = parse_expression(parser);
+ AstTyped *expr = parse_expression(parser);
- if (parser->curr->type == ':') {
- consume_token(parser);
-
- AstSlice *sl_node = make_node(AstSlice, Ast_Kind_Slice);
- sl_node->token = open_bracket;
- sl_node->addr = retval;
- sl_node->lo = lo;
- sl_node->hi = parse_expression(parser);
-
- retval = (AstTyped *) sl_node;
- expect_token(parser, ']');
- goto factor_parsed;
+ AstKind kind = Ast_Kind_Array_Access;
+ if (expr->kind == Ast_Kind_Range)
+ kind = Ast_Kind_Slice;
- } else {
- AstArrayAccess* aa_node = make_node(AstArrayAccess, Ast_Kind_Array_Access);
- aa_node->token = open_bracket;
- aa_node->addr = retval;
- aa_node->expr = lo;
-
- retval = (AstTyped *) aa_node;
- expect_token(parser, ']');
- }
+ AstArrayAccess *aa_node = make_node(AstArrayAccess, kind);
+ aa_node->token = open_bracket;
+ aa_node->addr = retval;
+ aa_node->expr = expr;
+ retval = (AstTyped *) aa_node;
+ expect_token(parser, ']');
break;
}
(*expr)->type_node = symres_type(builtin_string_type);
break;
+ case Ast_Kind_Slice:
case Ast_Kind_Array_Access:
symres_expression(&((AstArrayAccess *)(*expr))->addr);
symres_expression(&((AstArrayAccess *)(*expr))->expr);
break;
- case Ast_Kind_Slice:
- symres_expression(&((AstSlice *)(*expr))->addr);
- symres_expression(&((AstSlice *)(*expr))->lo);
- symres_expression(&((AstSlice *)(*expr))->hi);
- break;
-
case Ast_Kind_Struct_Literal:
symres_struct_literal((AstStructLiteral *)(*expr));
break;
if (smem.idx == 1)
WID(WI_I32_CONST, ((AstStrLit *) field->expr)->length);
-
+
break;
}
}
case Ast_Kind_Slice: {
- AstSlice* sl = (AstSlice *) expr;
+ AstArrayAccess* sl = (AstArrayAccess *) expr;
+
+ AstTyped *lo, *hi;
+
+ // NOTE: Since all ranges are converted to struct literals,
+ // we need to extract the expressions from the struct literal
+ // data. Doing it in this verbose way for robustness sake.
+ AstStructLiteral *range_literal = (AstStructLiteral *) sl->expr;
+ StructMember smem;
+ type_lookup_member(range_literal->type, "low", &smem);
+ lo = range_literal->values[smem.idx];
+ type_lookup_member(range_literal->type, "high", &smem);
+ hi = range_literal->values[smem.idx];
u64 tmp_local = local_raw_allocate(mod->local_alloc, WASM_TYPE_INT32);
- emit_expression(mod, &code, sl->lo);
+ emit_expression(mod, &code, lo);
WIL(WI_LOCAL_TEE, tmp_local);
if (sl->elem_size != 1) {
WID(WI_I32_CONST, sl->elem_size);
}
emit_expression(mod, &code, sl->addr);
WI(WI_I32_ADD);
- emit_expression(mod, &code, sl->hi);
+ emit_expression(mod, &code, hi);
WIL(WI_LOCAL_GET, tmp_local);
WI(WI_I32_SUB);
break;
case WI_JUMP_TABLE: {
- BranchTable* bt = (BranchTable *) instr->data.p;
+ BranchTable* bt = (BranchTable *) instr->data.p;
leb = uint_to_uleb128((u64) bt->count, &leb_len);
bh_buffer_append(buff, leb, leb_len);