Support string literals for fixed arrays of runes; Add %q support for arrays/slices of bytes

This commit is contained in:
gingerBill
2020-11-20 16:24:23 +00:00
parent 6416a6f39c
commit 63e4a2341f
6 changed files with 96 additions and 29 deletions
+2 -2
View File
@@ -1599,7 +1599,7 @@ fmt_value :: proc(fi: ^Info, v: any, verb: rune) {
}
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);
fmt_string(fi, s, verb);
} else {
@@ -1664,7 +1664,7 @@ fmt_value :: proc(fi: ^Info, v: any, verb: rune) {
case runtime.Type_Info_Slice:
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);
fmt_string(fi, s, verb);
} else if verb == 'p' {
+10 -3
View File
@@ -2955,10 +2955,17 @@ void convert_to_typed(CheckerContext *c, Operand *operand, Type *target_type) {
if (check_is_assignable_to(c, operand, elem)) {
operand->mode = Addressing_Value;
} else {
if (operand->value.kind == ExactValue_String && is_type_u8_array(t)) {
if (operand->value.kind == ExactValue_String) {
String s = operand->value.value_string;
if (s.len == t->Array.count) {
break;
if (is_type_u8_array(t)) {
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;
+5 -3
View File
@@ -7801,9 +7801,11 @@ irValue *ir_build_expr_internal(irProcedure *proc, Ast *expr) {
if (tv.value.kind != ExactValue_Invalid) {
// NOTE(bill): Edge case
if (is_type_u8_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 &&
if (is_type_u8_array(tv.type) && tv.value.kind == ExactValue_String) {
return ir_add_module_constant(proc->module, tv.type, tv.value);
} 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)) {
Type *elem = core_array_type(tv.type);
ExactValue value = convert_exact_value_for_type(tv.value, elem);
+22
View File
@@ -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))) {
i64 count = type->Array.count;
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, '[');
for (i64 i = 0; i < count; i++) {
+26
View File
@@ -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))) {
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,
cast(char const *)value.value_string.text,
cast(unsigned)value.value_string.len,
+31 -21
View File
@@ -1214,27 +1214,6 @@ bool is_type_slice(Type *t) {
t = base_type(t);
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) {
t = base_type(t);
return t->kind == Type_Proc;
@@ -1278,6 +1257,37 @@ bool is_type_relative_slice(Type *t) {
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) {
for (;;) {