Fix decimal.odin assignment bug

This commit is contained in:
Ginger Bill
2017-09-20 22:59:46 +01:00
parent 14d0cbf6d7
commit 3bfaac0844
4 changed files with 117 additions and 114 deletions
+2 -1
View File
@@ -68,9 +68,10 @@ assign :: proc(a: ^Decimal, i: u64) {
} }
a.count = 0; a.count = 0;
for n -= 1; n >= 0; n -= 1 { for n >= 0 {
a.digits[a.count] = buf[n]; a.digits[a.count] = buf[n];
a.count += 1; a.count += 1;
n -= 1;
} }
a.decimal_point = a.count; a.decimal_point = a.count;
trim(a); trim(a);
+1 -2
View File
@@ -300,7 +300,7 @@ format_digits :: proc(buf: []u8, shortest: bool, neg: bool, digs: DecimalSlice,
// integer, padded with zeros when needed // integer, padded with zeros when needed
if digs.decimal_point > 0 { if digs.decimal_point > 0 {
m := min(digs.count, digs.decimal_point); m := min(digs.count, digs.decimal_point);
append(&buf, ...digs.digits[..m]); append(&buf, ...digs.digits[0..m]);
for ; m < digs.decimal_point; m += 1 { for ; m < digs.decimal_point; m += 1 {
append(&buf, '0'); append(&buf, '0');
} }
@@ -320,7 +320,6 @@ format_digits :: proc(buf: []u8, shortest: bool, neg: bool, digs: DecimalSlice,
append(&buf, c); append(&buf, c);
} }
} }
return buf; return buf;
case 'e', 'E': case 'e', 'E':
+4 -1
View File
@@ -3324,7 +3324,6 @@ bool check_representable_as_constant(Checker *c, ExactValue in_value, Type *type
} }
if (out_value) *out_value = v; if (out_value) *out_value = v;
switch (type->Basic.kind) { switch (type->Basic.kind) {
// case Basic_f16: // case Basic_f16:
case Basic_f32: case Basic_f32:
@@ -3333,6 +3332,8 @@ bool check_representable_as_constant(Checker *c, ExactValue in_value, Type *type
case Basic_UntypedFloat: case Basic_UntypedFloat:
return true; return true;
default: GB_PANIC("Compiler error: Unknown float type!"); break;
} }
} else if (is_type_complex(type)) { } else if (is_type_complex(type)) {
ExactValue v = exact_value_to_complex(in_value); ExactValue v = exact_value_to_complex(in_value);
@@ -3353,6 +3354,8 @@ bool check_representable_as_constant(Checker *c, ExactValue in_value, Type *type
} break; } break;
case Basic_UntypedComplex: case Basic_UntypedComplex:
return true; return true;
default: GB_PANIC("Compiler error: Unknown complex type!"); break;
} }
return false; return false;
+97 -97
View File
@@ -327,6 +327,90 @@ void entity_graph_node_swap(EntityGraphNode **data, isize i, isize j) {
struct ImportGraphNode;
typedef PtrSet<ImportGraphNode *> ImportGraphNodeSet;
void import_graph_node_set_destroy(ImportGraphNodeSet *s) {
if (s->hashes.data != nullptr) {
ptr_set_destroy(s);
}
}
void import_graph_node_set_add(ImportGraphNodeSet *s, ImportGraphNode *n) {
if (s->hashes.data == nullptr) {
ptr_set_init(s, heap_allocator());
}
ptr_set_add(s, n);
}
bool import_graph_node_set_exists(ImportGraphNodeSet *s, ImportGraphNode *n) {
return ptr_set_exists(s, n);
}
void import_graph_node_set_remove(ImportGraphNodeSet *s, ImportGraphNode *n) {
ptr_set_remove(s, n);
}
struct ImportGraphNode {
Scope * scope;
String path;
isize file_id;
ImportGraphNodeSet pred;
ImportGraphNodeSet succ;
isize index; // Index in array/queue
isize dep_count;
};
ImportGraphNode *import_graph_node_create(gbAllocator a, Scope *scope) {
ImportGraphNode *n = gb_alloc_item(a, ImportGraphNode);
n->scope = scope;
n->path = scope->file->tokenizer.fullpath;
n->file_id = scope->file->id;
return n;
}
void import_graph_node_destroy(ImportGraphNode *n, gbAllocator a) {
import_graph_node_set_destroy(&n->pred);
import_graph_node_set_destroy(&n->succ);
gb_free(a, n);
}
int import_graph_node_cmp(ImportGraphNode **data, isize i, isize j) {
ImportGraphNode *x = data[i];
ImportGraphNode *y = data[j];
GB_ASSERT(x != y);
GB_ASSERT(x->scope != y->scope);
bool xg = x->scope->is_global;
bool yg = y->scope->is_global;
if (xg != yg) return xg ? -1 : +1;
if (x->dep_count < y->dep_count) return -1;
if (x->dep_count > y->dep_count) return +1;
return 0;
}
void import_graph_node_swap(ImportGraphNode **data, isize i, isize j) {
ImportGraphNode *x = data[i];
ImportGraphNode *y = data[j];
data[i] = y;
data[j] = x;
x->index = j;
y->index = i;
}
GB_COMPARE_PROC(ast_node_cmp) {
AstNode *x = *cast(AstNode **)a;
AstNode *y = *cast(AstNode **)b;
Token i = ast_node_token(x);
Token j = ast_node_token(y);
return token_pos_cmp(i.pos, j.pos);
}
struct CheckerContext { struct CheckerContext {
Scope * file_scope; Scope * file_scope;
Scope * scope; Scope * scope;
@@ -378,6 +462,7 @@ struct Checker {
// NOTE(bill): Procedures to check // NOTE(bill): Procedures to check
Map<ProcedureInfo> procs; // Key: DeclInfo * Map<ProcedureInfo> procs; // Key: DeclInfo *
Map<Scope *> file_scopes; // Key: String (fullpath) Map<Scope *> file_scopes; // Key: String (fullpath)
Array<ImportGraphNode *> file_order;
Pool pool; Pool pool;
gbAllocator allocator; gbAllocator allocator;
@@ -899,6 +984,8 @@ void init_checker(Checker *c, Parser *parser) {
map_init(&c->file_scopes, heap_allocator()); map_init(&c->file_scopes, heap_allocator());
ptr_set_init(&c->checked_files, heap_allocator()); ptr_set_init(&c->checked_files, heap_allocator());
array_init(&c->file_order, heap_allocator(), c->parser->files.count);
} }
void destroy_checker(Checker *c) { void destroy_checker(Checker *c) {
@@ -912,6 +999,7 @@ void destroy_checker(Checker *c) {
map_destroy(&c->file_scopes); map_destroy(&c->file_scopes);
ptr_set_destroy(&c->checked_files); ptr_set_destroy(&c->checked_files);
array_free(&c->file_order);
} }
@@ -2185,88 +2273,6 @@ String path_to_entity_name(String name, String fullpath) {
struct ImportGraphNode;
typedef PtrSet<ImportGraphNode *> ImportGraphNodeSet;
void import_graph_node_set_destroy(ImportGraphNodeSet *s) {
if (s->hashes.data != nullptr) {
ptr_set_destroy(s);
}
}
void import_graph_node_set_add(ImportGraphNodeSet *s, ImportGraphNode *n) {
if (s->hashes.data == nullptr) {
ptr_set_init(s, heap_allocator());
}
ptr_set_add(s, n);
}
bool import_graph_node_set_exists(ImportGraphNodeSet *s, ImportGraphNode *n) {
return ptr_set_exists(s, n);
}
void import_graph_node_set_remove(ImportGraphNodeSet *s, ImportGraphNode *n) {
ptr_set_remove(s, n);
}
struct ImportGraphNode {
Scope * scope;
String path;
isize file_id;
ImportGraphNodeSet pred;
ImportGraphNodeSet succ;
isize index; // Index in array/queue
isize dep_count;
};
ImportGraphNode *import_graph_node_create(gbAllocator a, Scope *scope) {
ImportGraphNode *n = gb_alloc_item(a, ImportGraphNode);
n->scope = scope;
n->path = scope->file->tokenizer.fullpath;
n->file_id = scope->file->id;
return n;
}
void import_graph_node_destroy(ImportGraphNode *n, gbAllocator a) {
import_graph_node_set_destroy(&n->pred);
import_graph_node_set_destroy(&n->succ);
gb_free(a, n);
}
int import_graph_node_cmp(ImportGraphNode **data, isize i, isize j) {
ImportGraphNode *x = data[i];
ImportGraphNode *y = data[j];
GB_ASSERT(x != y);
GB_ASSERT(x->scope != y->scope);
bool xg = x->scope->is_global;
bool yg = y->scope->is_global;
if (xg != yg) return xg ? -1 : +1;
if (x->dep_count < y->dep_count) return -1;
if (x->dep_count > y->dep_count) return +1;
return 0;
}
void import_graph_node_swap(ImportGraphNode **data, isize i, isize j) {
ImportGraphNode *x = data[i];
ImportGraphNode *y = data[j];
data[i] = y;
data[j] = x;
x->index = j;
y->index = i;
}
GB_COMPARE_PROC(ast_node_cmp) {
AstNode *x = *cast(AstNode **)a;
AstNode *y = *cast(AstNode **)b;
Token i = ast_node_token(x);
Token j = ast_node_token(y);
return token_pos_cmp(i.pos, j.pos);
}
void add_import_dependency_node(Checker *c, AstNode *decl, Map<ImportGraphNode *> *M) { void add_import_dependency_node(Checker *c, AstNode *decl, Map<ImportGraphNode *> *M) {
Scope *parent_file_scope = decl->file->scope; Scope *parent_file_scope = decl->file->scope;
@@ -2818,10 +2824,6 @@ void check_import_entities(Checker *c) {
ptr_set_init(&emitted, heap_allocator()); ptr_set_init(&emitted, heap_allocator());
defer (ptr_set_destroy(&emitted)); defer (ptr_set_destroy(&emitted));
Array<ImportGraphNode *> file_order = {};
array_init(&file_order, heap_allocator());
defer (array_free(&file_order));
while (pq.queue.count > 0) { while (pq.queue.count > 0) {
ImportGraphNode *n = priority_queue_pop(&pq); ImportGraphNode *n = priority_queue_pop(&pq);
@@ -2844,12 +2846,10 @@ void check_import_entities(Checker *c) {
Token token = mt(s); Token token = mt(s);
error(token, "Cyclic importation of `%.*s`", LIT(token.string)); error(token, "Cyclic importation of `%.*s`", LIT(token.string));
for (isize i = path.count-1; i >= 0; i--) { for (isize i = path.count-1; i >= 0; i--) {
token = mt(s); gb_printf_err("\t`%.*s` refers to", LIT(token.string));
error(token, "\t`%.*s` refers to", LIT(token.string));
s = path[i]; s = path[i];
} }
token = mt(s); gb_printf_err("\t`%.*s`", LIT(token.string));
error(token, "\t`%.*s`", LIT(token.string));
} }
} }
@@ -2869,7 +2869,7 @@ void check_import_entities(Checker *c) {
} }
ptr_set_add(&emitted, s); ptr_set_add(&emitted, s);
array_add(&file_order, n); array_add(&c->file_order, n);
} }
for_array(file_index, c->parser->files) { for_array(file_index, c->parser->files) {
@@ -2880,16 +2880,16 @@ void check_import_entities(Checker *c) {
} }
} }
// for_array(file_index, file_order) { // for_array(file_index, c->file_order) {
// ImportGraphNode *node = file_order[file_index]; // ImportGraphNode *node = c->file_order[file_index];
// AstFile *f = node->scope->file; // AstFile *f = node->scope->file;
// gb_printf_err("--- %.*s\n", LIT(f->fullpath)); // gb_printf_err("--- %.*s\n", LIT(f->fullpath));
// } // }
for (;;) { for (;;) {
bool new_files = false; bool new_files = false;
for_array(file_index, file_order) { for_array(file_index, c->file_order) {
ImportGraphNode *node = file_order[file_index]; ImportGraphNode *node = c->file_order[file_index];
AstFile *f = node->scope->file; AstFile *f = node->scope->file;
if (!ptr_set_exists(&c->checked_files, f)) { if (!ptr_set_exists(&c->checked_files, f)) {
@@ -2905,8 +2905,8 @@ void check_import_entities(Checker *c) {
if (new_files) break; if (new_files) break;
} }
for (isize file_index = 0; file_index < file_order.count; file_index += 1) { for (isize file_index = 0; file_index < c->file_order.count; file_index += 1) {
ImportGraphNode *node = file_order[file_index]; ImportGraphNode *node = c->file_order[file_index];
AstFile *f = node->scope->file; AstFile *f = node->scope->file;
if (!ptr_set_exists(&c->checked_files, f)) { if (!ptr_set_exists(&c->checked_files, f)) {