mirror of
https://github.com/Ed94/Odin.git
synced 2026-08-05 15:18:49 +00:00
Support string literals for fixed arrays of runes; Add %q support for arrays/slices of bytes
This commit is contained in:
+2
-2
@@ -1599,7 +1599,7 @@ fmt_value :: proc(fi: ^Info, v: any, verb: rune) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
case runtime.Type_Info_Array:
|
case runtime.Type_Info_Array:
|
||||||
if verb == 's' && reflect.is_byte(info.elem) {
|
if (verb == 's' || verb == 'q') && reflect.is_byte(info.elem) {
|
||||||
s := strings.string_from_ptr((^byte)(v.data), info.count);
|
s := strings.string_from_ptr((^byte)(v.data), info.count);
|
||||||
fmt_string(fi, s, verb);
|
fmt_string(fi, s, verb);
|
||||||
} else {
|
} else {
|
||||||
@@ -1664,7 +1664,7 @@ fmt_value :: proc(fi: ^Info, v: any, verb: rune) {
|
|||||||
|
|
||||||
case runtime.Type_Info_Slice:
|
case runtime.Type_Info_Slice:
|
||||||
slice := cast(^mem.Raw_Slice)v.data;
|
slice := cast(^mem.Raw_Slice)v.data;
|
||||||
if verb == 's' && reflect.is_byte(info.elem) {
|
if (verb == 's' || verb == 'q') && reflect.is_byte(info.elem) {
|
||||||
s := strings.string_from_ptr((^byte)(slice.data), slice.len);
|
s := strings.string_from_ptr((^byte)(slice.data), slice.len);
|
||||||
fmt_string(fi, s, verb);
|
fmt_string(fi, s, verb);
|
||||||
} else if verb == 'p' {
|
} else if verb == 'p' {
|
||||||
|
|||||||
+10
-3
@@ -2955,10 +2955,17 @@ void convert_to_typed(CheckerContext *c, Operand *operand, Type *target_type) {
|
|||||||
if (check_is_assignable_to(c, operand, elem)) {
|
if (check_is_assignable_to(c, operand, elem)) {
|
||||||
operand->mode = Addressing_Value;
|
operand->mode = Addressing_Value;
|
||||||
} else {
|
} else {
|
||||||
if (operand->value.kind == ExactValue_String && is_type_u8_array(t)) {
|
if (operand->value.kind == ExactValue_String) {
|
||||||
String s = operand->value.value_string;
|
String s = operand->value.value_string;
|
||||||
if (s.len == t->Array.count) {
|
if (is_type_u8_array(t)) {
|
||||||
break;
|
if (s.len == t->Array.count) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
} else if (is_type_rune_array(t)) {
|
||||||
|
isize rune_count = s.len;
|
||||||
|
if (rune_count == t->Array.count) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
operand->mode = Addressing_Invalid;
|
operand->mode = Addressing_Invalid;
|
||||||
|
|||||||
+5
-3
@@ -7801,9 +7801,11 @@ irValue *ir_build_expr_internal(irProcedure *proc, Ast *expr) {
|
|||||||
|
|
||||||
if (tv.value.kind != ExactValue_Invalid) {
|
if (tv.value.kind != ExactValue_Invalid) {
|
||||||
// NOTE(bill): Edge case
|
// NOTE(bill): Edge case
|
||||||
if (is_type_u8_array(tv.type) && tv.value.kind == ExactValue_String) {
|
if (is_type_u8_array(tv.type) && tv.value.kind == ExactValue_String) {
|
||||||
return ir_add_module_constant(proc->module, tv.type, tv.value);
|
return ir_add_module_constant(proc->module, tv.type, tv.value);
|
||||||
} else if (tv.value.kind != ExactValue_Compound &&
|
} else if (is_type_rune_array(tv.type) && tv.value.kind == ExactValue_String) {
|
||||||
|
return ir_add_module_constant(proc->module, tv.type, tv.value);
|
||||||
|
} else if (tv.value.kind != ExactValue_Compound &&
|
||||||
is_type_array(tv.type)) {
|
is_type_array(tv.type)) {
|
||||||
Type *elem = core_array_type(tv.type);
|
Type *elem = core_array_type(tv.type);
|
||||||
ExactValue value = convert_exact_value_for_type(tv.value, elem);
|
ExactValue value = convert_exact_value_for_type(tv.value, elem);
|
||||||
|
|||||||
@@ -734,6 +734,28 @@ void ir_print_exact_value(irFileBuffer *f, irModule *m, ExactValue value, Type *
|
|||||||
if (is_type_array(type) && value.kind == ExactValue_String && !is_type_u8(core_array_type(type))) {
|
if (is_type_array(type) && value.kind == ExactValue_String && !is_type_u8(core_array_type(type))) {
|
||||||
i64 count = type->Array.count;
|
i64 count = type->Array.count;
|
||||||
Type *elem = type->Array.elem;
|
Type *elem = type->Array.elem;
|
||||||
|
|
||||||
|
if (is_type_rune_array(type)) {
|
||||||
|
Rune rune;
|
||||||
|
isize offset = 0;
|
||||||
|
isize width = 1;
|
||||||
|
String s = value.value_string;
|
||||||
|
ir_write_byte(f, '[');
|
||||||
|
for (i64 i = 0; i < count && offset < s.len; i++) {
|
||||||
|
width = gb_utf8_decode(s.text+offset, s.len-offset, &rune);
|
||||||
|
if (i > 0) ir_write_str_lit(f, ", ");
|
||||||
|
ir_print_type(f, m, elem);
|
||||||
|
ir_write_byte(f, ' ');
|
||||||
|
ir_print_exact_value(f, m, exact_value_i64(rune), elem);
|
||||||
|
offset += width;
|
||||||
|
}
|
||||||
|
GB_ASSERT(offset == s.len);
|
||||||
|
|
||||||
|
ir_write_byte(f, ']');
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
ir_write_byte(f, '[');
|
ir_write_byte(f, '[');
|
||||||
|
|
||||||
for (i64 i = 0; i < count; i++) {
|
for (i64 i = 0; i < count; i++) {
|
||||||
|
|||||||
@@ -5123,6 +5123,32 @@ lbValue lb_const_value(lbModule *m, Type *type, ExactValue value, bool allow_loc
|
|||||||
|
|
||||||
}
|
}
|
||||||
} else if (is_type_array(type) && value.kind == ExactValue_String && !is_type_u8(core_array_type(type))) {
|
} else if (is_type_array(type) && value.kind == ExactValue_String && !is_type_u8(core_array_type(type))) {
|
||||||
|
if (is_type_rune_array(type) && value.kind == ExactValue_String) {
|
||||||
|
i64 count = type->Array.count;
|
||||||
|
Type *elem = type->Array.elem;
|
||||||
|
LLVMTypeRef et = lb_type(m, elem);
|
||||||
|
|
||||||
|
Rune rune;
|
||||||
|
isize offset = 0;
|
||||||
|
isize width = 1;
|
||||||
|
String s = value.value_string;
|
||||||
|
|
||||||
|
LLVMValueRef *elems = gb_alloc_array(permanent_allocator(), LLVMValueRef, count);
|
||||||
|
|
||||||
|
for (i64 i = 0; i < count && offset < s.len; i++) {
|
||||||
|
width = gb_utf8_decode(s.text+offset, s.len-offset, &rune);
|
||||||
|
offset += width;
|
||||||
|
|
||||||
|
elems[i] = LLVMConstInt(et, rune, true);
|
||||||
|
|
||||||
|
}
|
||||||
|
GB_ASSERT(offset == s.len);
|
||||||
|
|
||||||
|
res.value = LLVMConstArray(et, elems, cast(unsigned)count);
|
||||||
|
return res;
|
||||||
|
}
|
||||||
|
GB_PANIC("HERE!\n");
|
||||||
|
|
||||||
LLVMValueRef data = LLVMConstStringInContext(ctx,
|
LLVMValueRef data = LLVMConstStringInContext(ctx,
|
||||||
cast(char const *)value.value_string.text,
|
cast(char const *)value.value_string.text,
|
||||||
cast(unsigned)value.value_string.len,
|
cast(unsigned)value.value_string.len,
|
||||||
|
|||||||
+31
-21
@@ -1214,27 +1214,6 @@ bool is_type_slice(Type *t) {
|
|||||||
t = base_type(t);
|
t = base_type(t);
|
||||||
return t->kind == Type_Slice;
|
return t->kind == Type_Slice;
|
||||||
}
|
}
|
||||||
bool is_type_u8_slice(Type *t) {
|
|
||||||
t = base_type(t);
|
|
||||||
if (t->kind == Type_Slice) {
|
|
||||||
return is_type_u8(t->Slice.elem);
|
|
||||||
}
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
bool is_type_u8_array(Type *t) {
|
|
||||||
t = base_type(t);
|
|
||||||
if (t->kind == Type_Array) {
|
|
||||||
return is_type_u8(t->Array.elem);
|
|
||||||
}
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
bool is_type_u8_ptr(Type *t) {
|
|
||||||
t = base_type(t);
|
|
||||||
if (t->kind == Type_Pointer) {
|
|
||||||
return is_type_u8(t->Slice.elem);
|
|
||||||
}
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
bool is_type_proc(Type *t) {
|
bool is_type_proc(Type *t) {
|
||||||
t = base_type(t);
|
t = base_type(t);
|
||||||
return t->kind == Type_Proc;
|
return t->kind == Type_Proc;
|
||||||
@@ -1278,6 +1257,37 @@ bool is_type_relative_slice(Type *t) {
|
|||||||
return t->kind == Type_RelativeSlice;
|
return t->kind == Type_RelativeSlice;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool is_type_u8_slice(Type *t) {
|
||||||
|
t = base_type(t);
|
||||||
|
if (t->kind == Type_Slice) {
|
||||||
|
return is_type_u8(t->Slice.elem);
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
bool is_type_u8_array(Type *t) {
|
||||||
|
t = base_type(t);
|
||||||
|
if (t->kind == Type_Array) {
|
||||||
|
return is_type_u8(t->Array.elem);
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
bool is_type_u8_ptr(Type *t) {
|
||||||
|
t = base_type(t);
|
||||||
|
if (t->kind == Type_Pointer) {
|
||||||
|
return is_type_u8(t->Slice.elem);
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
bool is_type_rune_array(Type *t) {
|
||||||
|
t = base_type(t);
|
||||||
|
if (t->kind == Type_Array) {
|
||||||
|
return is_type_rune(t->Array.elem);
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
Type *core_array_type(Type *t) {
|
Type *core_array_type(Type *t) {
|
||||||
for (;;) {
|
for (;;) {
|
||||||
|
|||||||
Reference in New Issue
Block a user