mirror of
https://github.com/Ed94/Odin.git
synced 2026-06-28 00:01:48 -07:00
for in string16; Support string16 across core
This commit is contained in:
@@ -7179,7 +7179,11 @@ gb_internal bool check_builtin_procedure(CheckerContext *c, Operand *operand, As
|
||||
return false;
|
||||
}
|
||||
operand->mode = Addressing_Value;
|
||||
operand->type = alloc_type_multi_pointer(t_u16);
|
||||
if (type_hint != nullptr && is_type_cstring16(type_hint)) {
|
||||
operand->type = type_hint;
|
||||
} else {
|
||||
operand->type = alloc_type_multi_pointer(t_u16);
|
||||
}
|
||||
operand->value = {};
|
||||
break;
|
||||
}
|
||||
|
||||
+1
-1
@@ -3426,7 +3426,7 @@ gb_internal bool check_is_castable_to(CheckerContext *c, Operand *operand, Type
|
||||
if (are_types_identical(src, t_cstring16) && is_type_u16_multi_ptr(dst)) {
|
||||
return !is_constant;
|
||||
}
|
||||
// cstring -> rawptr
|
||||
// cstring16 -> rawptr
|
||||
if (are_types_identical(src, t_cstring16) && is_type_rawptr(dst)) {
|
||||
return !is_constant;
|
||||
}
|
||||
|
||||
+23
-3
@@ -974,7 +974,14 @@ gb_internal void check_unroll_range_stmt(CheckerContext *ctx, Ast *node, u32 mod
|
||||
Type *t = base_type(operand.type);
|
||||
switch (t->kind) {
|
||||
case Type_Basic:
|
||||
if (is_type_string(t) && t->Basic.kind != Basic_cstring) {
|
||||
if (is_type_string16(t) && t->Basic.kind != Basic_cstring) {
|
||||
val0 = t_rune;
|
||||
val1 = t_int;
|
||||
inline_for_depth = exact_value_i64(operand.value.value_string.len);
|
||||
if (unroll_count > 0) {
|
||||
error(node, "#unroll(%lld) does not support strings", cast(long long)unroll_count);
|
||||
}
|
||||
} else if (is_type_string(t) && t->Basic.kind != Basic_cstring) {
|
||||
val0 = t_rune;
|
||||
val1 = t_int;
|
||||
inline_for_depth = exact_value_i64(operand.value.value_string.len);
|
||||
@@ -1236,7 +1243,11 @@ gb_internal void check_switch_stmt(CheckerContext *ctx, Ast *node, u32 mod_flags
|
||||
|
||||
add_to_seen_map(ctx, &seen, upper_op, x, lhs, rhs);
|
||||
|
||||
if (is_type_string(x.type)) {
|
||||
if (is_type_string16(x.type)) {
|
||||
// NOTE(bill): Force dependency for strings here
|
||||
add_package_dependency(ctx, "runtime", "string16_le");
|
||||
add_package_dependency(ctx, "runtime", "string16_lt");
|
||||
} else if (is_type_string(x.type)) {
|
||||
// NOTE(bill): Force dependency for strings here
|
||||
add_package_dependency(ctx, "runtime", "string_le");
|
||||
add_package_dependency(ctx, "runtime", "string_lt");
|
||||
@@ -1770,7 +1781,16 @@ gb_internal void check_range_stmt(CheckerContext *ctx, Ast *node, u32 mod_flags)
|
||||
|
||||
switch (t->kind) {
|
||||
case Type_Basic:
|
||||
if (t->Basic.kind == Basic_string || t->Basic.kind == Basic_UntypedString) {
|
||||
if (t->Basic.kind == Basic_string16) {
|
||||
is_possibly_addressable = false;
|
||||
array_add(&vals, t_rune);
|
||||
array_add(&vals, t_int);
|
||||
if (is_reverse) {
|
||||
add_package_dependency(ctx, "runtime", "string16_decode_last_rune");
|
||||
} else {
|
||||
add_package_dependency(ctx, "runtime", "string16_decode_rune");
|
||||
}
|
||||
} else if (t->Basic.kind == Basic_string || t->Basic.kind == Basic_UntypedString) {
|
||||
is_possibly_addressable = false;
|
||||
array_add(&vals, t_rune);
|
||||
array_add(&vals, t_int);
|
||||
|
||||
+120
-1
@@ -622,6 +622,121 @@ gb_internal void lb_build_range_string(lbProcedure *p, lbValue expr, Type *val_t
|
||||
if (done_) *done_ = done;
|
||||
}
|
||||
|
||||
gb_internal void lb_build_range_string16(lbProcedure *p, lbValue expr, Type *val_type,
|
||||
lbValue *val_, lbValue *idx_, lbBlock **loop_, lbBlock **done_,
|
||||
bool is_reverse) {
|
||||
|
||||
lbModule *m = p->module;
|
||||
lbValue count = lb_const_int(m, t_int, 0);
|
||||
Type *expr_type = base_type(expr.type);
|
||||
switch (expr_type->kind) {
|
||||
case Type_Basic:
|
||||
count = lb_string_len(p, expr);
|
||||
break;
|
||||
default:
|
||||
GB_PANIC("Cannot do range_string of %s", type_to_string(expr_type));
|
||||
break;
|
||||
}
|
||||
|
||||
lbValue val = {};
|
||||
lbValue idx = {};
|
||||
lbBlock *loop = nullptr;
|
||||
lbBlock *done = nullptr;
|
||||
lbBlock *body = nullptr;
|
||||
|
||||
loop = lb_create_block(p, "for.string16.loop");
|
||||
body = lb_create_block(p, "for.string16.body");
|
||||
done = lb_create_block(p, "for.string16.done");
|
||||
|
||||
lbAddr offset_ = lb_add_local_generated(p, t_int, false);
|
||||
lbValue offset = {};
|
||||
lbValue cond = {};
|
||||
|
||||
if (!is_reverse) {
|
||||
/*
|
||||
for c, offset in str {
|
||||
...
|
||||
}
|
||||
|
||||
offset := 0
|
||||
for offset < len(str) {
|
||||
c, _w := string16_decode_rune(str[offset:])
|
||||
...
|
||||
offset += _w
|
||||
}
|
||||
*/
|
||||
lb_addr_store(p, offset_, lb_const_int(m, t_int, 0));
|
||||
|
||||
lb_emit_jump(p, loop);
|
||||
lb_start_block(p, loop);
|
||||
|
||||
|
||||
offset = lb_addr_load(p, offset_);
|
||||
cond = lb_emit_comp(p, Token_Lt, offset, count);
|
||||
} else {
|
||||
// NOTE(bill): REVERSED LOGIC
|
||||
/*
|
||||
#reverse for c, offset in str {
|
||||
...
|
||||
}
|
||||
|
||||
offset := len(str)
|
||||
for offset > 0 {
|
||||
c, _w := string16_decode_last_rune(str[:offset])
|
||||
offset -= _w
|
||||
...
|
||||
}
|
||||
*/
|
||||
lb_addr_store(p, offset_, count);
|
||||
|
||||
lb_emit_jump(p, loop);
|
||||
lb_start_block(p, loop);
|
||||
|
||||
offset = lb_addr_load(p, offset_);
|
||||
cond = lb_emit_comp(p, Token_Gt, offset, lb_const_int(m, t_int, 0));
|
||||
}
|
||||
lb_emit_if(p, cond, body, done);
|
||||
lb_start_block(p, body);
|
||||
|
||||
|
||||
lbValue rune_and_len = {};
|
||||
if (!is_reverse) {
|
||||
lbValue str_elem = lb_emit_ptr_offset(p, lb_string_elem(p, expr), offset);
|
||||
lbValue str_len = lb_emit_arith(p, Token_Sub, count, offset, t_int);
|
||||
auto args = array_make<lbValue>(permanent_allocator(), 1);
|
||||
args[0] = lb_emit_string16(p, str_elem, str_len);
|
||||
|
||||
rune_and_len = lb_emit_runtime_call(p, "string16_decode_rune", args);
|
||||
lbValue len = lb_emit_struct_ev(p, rune_and_len, 1);
|
||||
lb_addr_store(p, offset_, lb_emit_arith(p, Token_Add, offset, len, t_int));
|
||||
|
||||
idx = offset;
|
||||
} else {
|
||||
// NOTE(bill): REVERSED LOGIC
|
||||
lbValue str_elem = lb_string_elem(p, expr);
|
||||
lbValue str_len = offset;
|
||||
auto args = array_make<lbValue>(permanent_allocator(), 1);
|
||||
args[0] = lb_emit_string16(p, str_elem, str_len);
|
||||
|
||||
rune_and_len = lb_emit_runtime_call(p, "string16_decode_last_rune", args);
|
||||
lbValue len = lb_emit_struct_ev(p, rune_and_len, 1);
|
||||
lb_addr_store(p, offset_, lb_emit_arith(p, Token_Sub, offset, len, t_int));
|
||||
|
||||
idx = lb_addr_load(p, offset_);
|
||||
}
|
||||
|
||||
|
||||
if (val_type != nullptr) {
|
||||
val = lb_emit_struct_ev(p, rune_and_len, 0);
|
||||
}
|
||||
|
||||
if (val_) *val_ = val;
|
||||
if (idx_) *idx_ = idx;
|
||||
if (loop_) *loop_ = loop;
|
||||
if (done_) *done_ = done;
|
||||
}
|
||||
|
||||
|
||||
|
||||
gb_internal Ast *lb_strip_and_prefix(Ast *ident) {
|
||||
if (ident != nullptr) {
|
||||
@@ -1138,7 +1253,11 @@ gb_internal void lb_build_range_stmt(lbProcedure *p, AstRangeStmt *rs, Scope *sc
|
||||
}
|
||||
Type *t = base_type(string.type);
|
||||
GB_ASSERT(!is_type_cstring(t));
|
||||
lb_build_range_string(p, string, val0_type, &val, &key, &loop, &done, rs->reverse);
|
||||
if (is_type_string16(t)) {
|
||||
lb_build_range_string16(p, string, val0_type, &val, &key, &loop, &done, rs->reverse);
|
||||
} else {
|
||||
lb_build_range_string(p, string, val0_type, &val, &key, &loop, &done, rs->reverse);
|
||||
}
|
||||
break;
|
||||
}
|
||||
case Type_Tuple:
|
||||
|
||||
@@ -191,6 +191,23 @@ gb_internal lbValue lb_emit_clamp(lbProcedure *p, Type *t, lbValue x, lbValue mi
|
||||
return z;
|
||||
}
|
||||
|
||||
gb_internal lbValue lb_emit_string16(lbProcedure *p, lbValue str_elem, lbValue str_len) {
|
||||
if (false && lb_is_const(str_elem) && lb_is_const(str_len)) {
|
||||
LLVMValueRef values[2] = {
|
||||
str_elem.value,
|
||||
str_len.value,
|
||||
};
|
||||
lbValue res = {};
|
||||
res.type = t_string16;
|
||||
res.value = llvm_const_named_struct(p->module, t_string16, values, gb_count_of(values));
|
||||
return res;
|
||||
} else {
|
||||
lbAddr res = lb_add_local_generated(p, t_string16, false);
|
||||
lb_emit_store(p, lb_emit_struct_ep(p, res.addr, 0), str_elem);
|
||||
lb_emit_store(p, lb_emit_struct_ep(p, res.addr, 1), str_len);
|
||||
return lb_addr_load(p, res);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
gb_internal lbValue lb_emit_string(lbProcedure *p, lbValue str_elem, lbValue str_len) {
|
||||
|
||||
Reference in New Issue
Block a user