aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorgingerBill <bill@gingerbill.org>2020-11-20 16:24:23 +0000
committergingerBill <bill@gingerbill.org>2020-11-20 16:24:23 +0000
commit63e4a2341f1409eec1f2e58036cd01b24b66b8f0 (patch)
tree93801df8d25cb3c09c77d293fa4a53a513bb4383 /src
parent6416a6f39cce4c65c80e29bb4ff4b93a3e463947 (diff)
Support string literals for fixed arrays of runes; Add %q support for arrays/slices of bytes
Diffstat (limited to 'src')
-rw-r--r--src/check_expr.cpp13
-rw-r--r--src/ir.cpp8
-rw-r--r--src/ir_print.cpp22
-rw-r--r--src/llvm_backend.cpp26
-rw-r--r--src/types.cpp52
5 files changed, 94 insertions, 27 deletions
diff --git a/src/check_expr.cpp b/src/check_expr.cpp
index f258253f5..c67ad22b8 100644
--- a/src/check_expr.cpp
+++ b/src/check_expr.cpp
@@ -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;
diff --git a/src/ir.cpp b/src/ir.cpp
index e8378bb97..24fe15afb 100644
--- a/src/ir.cpp
+++ b/src/ir.cpp
@@ -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);
diff --git a/src/ir_print.cpp b/src/ir_print.cpp
index 3ca9954ef..a6bfc75d3 100644
--- a/src/ir_print.cpp
+++ b/src/ir_print.cpp
@@ -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++) {
diff --git a/src/llvm_backend.cpp b/src/llvm_backend.cpp
index d47c45401..62a0013bc 100644
--- a/src/llvm_backend.cpp
+++ b/src/llvm_backend.cpp
@@ -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,
diff --git a/src/types.cpp b/src/types.cpp
index 8c39b9979..b381ba9c9 100644
--- a/src/types.cpp
+++ b/src/types.cpp
@@ -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 (;;) {