aboutsummaryrefslogtreecommitdiff
path: root/src/ir_print.cpp
diff options
context:
space:
mode:
authorgingerBill <bill@gingerbill.org>2019-12-27 12:51:02 +0000
committergingerBill <bill@gingerbill.org>2019-12-27 12:51:02 +0000
commit10f0961184a5f486bad2050d1bb42320b833a370 (patch)
treed60b7baf8fca53d410a196591d2be26070bf8737 /src/ir_print.cpp
parenteea403d0abea5db849a7e383c76d53d5c181b5e6 (diff)
Enumerated arrays `[Enum_Type]Elem_Type`
Diffstat (limited to 'src/ir_print.cpp')
-rw-r--r--src/ir_print.cpp102
1 files changed, 102 insertions, 0 deletions
diff --git a/src/ir_print.cpp b/src/ir_print.cpp
index 35116fb69..f6eacf146 100644
--- a/src/ir_print.cpp
+++ b/src/ir_print.cpp
@@ -457,6 +457,14 @@ void ir_print_type(irFileBuffer *f, irModule *m, Type *t, bool in_struct) {
ir_print_type(f, m, t->Array.elem);
ir_write_byte(f, ']');
return;
+ case Type_EnumeratedArray:
+ ir_write_byte(f, '[');
+ ir_write_i64(f, t->EnumeratedArray.count);
+ ir_write_str_lit(f, " x ");
+ ir_print_type(f, m, t->EnumeratedArray.elem);
+ ir_write_byte(f, ']');
+ return;
+
case Type_Slice:
ir_write_byte(f, '{');
ir_print_type(f, m, t->Slice.elem); ir_write_str_lit(f, "*, ");
@@ -974,6 +982,100 @@ void ir_print_exact_value(irFileBuffer *f, irModule *m, ExactValue value, Type *
ir_write_byte(f, ']');
}
+ } else if (is_type_enumerated_array(type)) {
+ ast_node(cl, CompoundLit, value.value_compound);
+
+ Type *index_type = type->EnumeratedArray.elem;
+ Type *elem_type = type->Array.elem;
+ isize elem_count = cl->elems.count;
+ if (elem_count == 0) {
+ ir_write_str_lit(f, "zeroinitializer");
+ break;
+ }
+ if (cl->elems[0]->kind == Ast_FieldValue) {
+ // TODO(bill): This is O(N*M) and will be quite slow; it should probably be sorted before hand
+ ir_write_byte(f, '[');
+
+ i64 total_lo = exact_value_to_i64(type->EnumeratedArray.min_value);
+ i64 total_hi = exact_value_to_i64(type->EnumeratedArray.max_value);
+
+ for (i64 i = total_lo; i <= total_hi; i++) {
+ if (i > total_lo) ir_write_str_lit(f, ", ");
+
+ bool found = false;
+
+ for (isize j = 0; j < elem_count; j++) {
+ Ast *elem = cl->elems[j];
+ ast_node(fv, FieldValue, elem);
+ if (is_ast_range(fv->field)) {
+ ast_node(ie, BinaryExpr, fv->field);
+ TypeAndValue lo_tav = ie->left->tav;
+ TypeAndValue hi_tav = ie->right->tav;
+ GB_ASSERT(lo_tav.mode == Addressing_Constant);
+ GB_ASSERT(hi_tav.mode == Addressing_Constant);
+
+ TokenKind op = ie->op.kind;
+ i64 lo = exact_value_to_i64(lo_tav.value);
+ i64 hi = exact_value_to_i64(hi_tav.value);
+ if (op == Token_Ellipsis) {
+ hi += 1;
+ }
+ if (lo == i) {
+ TypeAndValue tav = fv->value->tav;
+ if (tav.mode != Addressing_Constant) {
+ break;
+ }
+ for (i64 k = lo; k < hi; k++) {
+ if (k > lo) ir_write_str_lit(f, ", ");
+
+ ir_print_compound_element(f, m, tav.value, elem_type);
+ }
+
+ found = true;
+ i += (hi-lo-1);
+ break;
+ }
+ } else {
+ TypeAndValue index_tav = fv->field->tav;
+ GB_ASSERT(index_tav.mode == Addressing_Constant);
+ i64 index = exact_value_to_i64(index_tav.value);
+ if (index == i) {
+ TypeAndValue tav = fv->value->tav;
+ if (tav.mode != Addressing_Constant) {
+ break;
+ }
+ ir_print_compound_element(f, m, tav.value, elem_type);
+ found = true;
+ break;
+ }
+ }
+ }
+
+ if (!found) {
+ ir_print_type(f, m, elem_type);
+ ir_write_byte(f, ' ');
+ ir_write_str_lit(f, "zeroinitializer");
+ }
+ }
+ ir_write_byte(f, ']');
+ } else {
+ GB_ASSERT_MSG(elem_count == type->EnumeratedArray.count, "%td != %td", elem_count, type->EnumeratedArray.count);
+
+ ir_write_byte(f, '[');
+
+ for (isize i = 0; i < elem_count; i++) {
+ if (i > 0) ir_write_str_lit(f, ", ");
+ TypeAndValue tav = cl->elems[i]->tav;
+ GB_ASSERT(tav.mode != Addressing_Invalid);
+ ir_print_compound_element(f, m, tav.value, elem_type);
+ }
+ for (isize i = elem_count; i < type->EnumeratedArray.count; i++) {
+ if (i >= elem_count) ir_write_str_lit(f, ", ");
+ ir_print_compound_element(f, m, empty_exact_value, elem_type);
+ }
+
+ ir_write_byte(f, ']');
+ }
} else if (is_type_simd_vector(type)) {
ast_node(cl, CompoundLit, value.value_compound);