aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorDanielGavin <danielgavin5@hotmail.com>2020-12-18 14:19:03 +0100
committerGitHub <noreply@github.com>2020-12-18 14:19:03 +0100
commitbd6ead32f8d05a9662c7fa6fde867b71da0e79c9 (patch)
treee610f06a230cca9d89bf075ec55e520dae83ad8e /src
parent934809397f1f5f567c0ec668de72d2ac28e85f74 (diff)
parent3558848da818dc330d139ff5d756bb9b9498b1d4 (diff)
Merge pull request #1 from odin-lang/master
update from master
Diffstat (limited to 'src')
-rw-r--r--src/check_decl.cpp22
-rw-r--r--src/check_expr.cpp8
-rw-r--r--src/check_stmt.cpp14
-rw-r--r--src/ir.cpp12
-rw-r--r--src/ir_print.cpp5
-rw-r--r--src/parser.cpp17
-rw-r--r--src/types.cpp3
7 files changed, 44 insertions, 37 deletions
diff --git a/src/check_decl.cpp b/src/check_decl.cpp
index 5234955fb..9f8f460ba 100644
--- a/src/check_decl.cpp
+++ b/src/check_decl.cpp
@@ -168,18 +168,6 @@ void check_init_constant(CheckerContext *ctx, Entity *e, Operand *operand) {
return;
}
-#if 0
- if (!is_type_constant_type(operand->type)) {
- gbString type_str = type_to_string(operand->type);
- error(operand->expr, "Invalid constant type: '%s'", type_str);
- gb_string_free(type_str);
- if (e->type == nullptr) {
- e->type = t_invalid;
- }
- return;
- }
-#endif
-
if (e->type == nullptr) { // NOTE(bill): type inference
e->type = operand->type;
}
@@ -388,15 +376,7 @@ void check_const_decl(CheckerContext *ctx, Entity *e, Ast *type_expr, Ast *init,
e->flags |= EntityFlag_Visited;
if (type_expr) {
- Type *t = check_type(ctx, type_expr);
- if (!is_type_constant_type(t) && !is_type_proc(t)) {
- gbString str = type_to_string(t);
- error(type_expr, "Invalid constant type '%s'", str);
- gb_string_free(str);
- e->type = t_invalid;
- return;
- }
- e->type = t;
+ e->type = check_type(ctx, type_expr);
}
Operand operand = {};
diff --git a/src/check_expr.cpp b/src/check_expr.cpp
index 15380e55c..63b275c99 100644
--- a/src/check_expr.cpp
+++ b/src/check_expr.cpp
@@ -7910,7 +7910,9 @@ void check_expr_with_type_hint(CheckerContext *c, Operand *o, Ast *e, Type *t) {
err_str = "used as a value";
break;
case Addressing_Type:
- err_str = "is not an expression but a type";
+ if (t == nullptr || !is_type_typeid(t)) {
+ err_str = "is not an expression but a type";
+ }
break;
case Addressing_Builtin:
err_str = "must be called";
@@ -8760,8 +8762,10 @@ ExprKind check_expr_base_internal(CheckerContext *c, Operand *o, Ast *node, Type
i64 lo = exact_value_to_i64(x.value);
i64 hi = exact_value_to_i64(y.value);
i64 max_index = hi;
- if (op.kind == Token_RangeHalf) {
+ if (op.kind == Token_RangeHalf) { // ..< (exclusive)
hi -= 1;
+ } else { // .. (inclusive)
+ max_index += 1;
}
bool new_range = range_cache_add_range(&rc, lo, hi);
diff --git a/src/check_stmt.cpp b/src/check_stmt.cpp
index 8a41dd12b..117872848 100644
--- a/src/check_stmt.cpp
+++ b/src/check_stmt.cpp
@@ -1803,9 +1803,19 @@ void check_stmt_internal(CheckerContext *ctx, Ast *node, u32 flags) {
if (val0 == nullptr) {
gbString s = expr_to_string(operand.expr);
gbString t = type_to_string(operand.type);
+ defer (gb_string_free(s));
+ defer (gb_string_free(t));
+
error(operand.expr, "Cannot iterate over '%s' of type '%s'", s, t);
- gb_string_free(t);
- gb_string_free(s);
+
+ if (rs->val0 != nullptr && rs->val1 == nullptr) {
+ if (is_type_map(operand.type) || is_type_bit_set(operand.type)) {
+ gbString v = expr_to_string(rs->val0);
+ defer (gb_string_free(v));
+ error_line("\tSuggestion: place parentheses around the expression\n");
+ error_line("\t for (%s in %s) {\n", v, s);
+ }
+ }
}
}
diff --git a/src/ir.cpp b/src/ir.cpp
index f69b25494..90cce3699 100644
--- a/src/ir.cpp
+++ b/src/ir.cpp
@@ -1638,6 +1638,7 @@ irValue *ir_check_compound_lit_constant(irModule *m, Ast *expr) {
if (expr == nullptr) {
return nullptr;
}
+
if (expr->kind == Ast_CompoundLit) {
ast_node(cl, CompoundLit, expr);
for_array(i, cl->elems) {
@@ -1661,6 +1662,7 @@ irValue *ir_check_compound_lit_constant(irModule *m, Ast *expr) {
}
}
+
return nullptr;
}
@@ -6743,7 +6745,10 @@ irValue *ir_type_info(irProcedure *proc, Type *type) {
return ir_emit_array_ep(proc, ir_global_type_info_data, ir_const_i32(id));
}
-irValue *ir_typeid(irModule *m, Type *type) {
+u64 ir_typeid_as_integer(irModule *m, Type *type) {
+ if (type == nullptr) {
+ return 0;
+ }
type = default_type(type);
u64 id = cast(u64)ir_type_info_index(m->info, type);
@@ -6808,8 +6813,11 @@ irValue *ir_typeid(irModule *m, Type *type) {
data |= (reserved &~ (1ull<<1)) << 63ull; // kind
}
+ return id;
+}
- return ir_value_constant(t_typeid, exact_value_u64(data));
+irValue *ir_typeid(irModule *m, Type *type) {
+ return ir_value_constant(t_typeid, exact_value_u64(ir_typeid_as_integer(m, type)));
}
diff --git a/src/ir_print.cpp b/src/ir_print.cpp
index a58ddbe0f..594cc57c2 100644
--- a/src/ir_print.cpp
+++ b/src/ir_print.cpp
@@ -787,6 +787,11 @@ void ir_print_exact_value(irFileBuffer *f, irModule *m, ExactValue value, Type *
}
switch (value.kind) {
+ case ExactValue_Typeid:
+ GB_ASSERT(is_type_typeid(type));
+ ir_write_u64(f, ir_typeid_as_integer(m, value.value_typeid));
+ break;
+
case ExactValue_Bool:
if (value.value_bool) {
ir_write_string(f, are_types_identical(type, t_llvm_bool) ? str_lit("true") : str_lit("1"));
diff --git a/src/parser.cpp b/src/parser.cpp
index 46af47c2d..59d02090e 100644
--- a/src/parser.cpp
+++ b/src/parser.cpp
@@ -1284,8 +1284,7 @@ bool skip_possible_newline(AstFile *f) {
if ((f->tokenizer.flags & TokenizerFlag_InsertSemicolon) == 0) {
return false;
}
- Token *prev = &f->curr_token;
- if (prev->kind == Token_Semicolon && prev->string == "\n") {
+ if (token_is_newline(f->curr_token)) {
advance_token(f);
return true;
}
@@ -1296,10 +1295,10 @@ bool skip_possible_newline_for_literal(AstFile *f) {
if ((f->tokenizer.flags & TokenizerFlag_InsertSemicolon) == 0) {
return false;
}
- TokenPos curr_pos = f->curr_token.pos;
- if (token_is_newline(f->curr_token)) {
+ Token curr = f->curr_token;
+ if (token_is_newline(curr)) {
Token next = peek_token(f);
- if (curr_pos.line+1 >= next.pos.line) {
+ if (curr.pos.line+1 >= next.pos.line) {
switch (next.kind) {
case Token_OpenBrace:
case Token_else:
@@ -3182,6 +3181,7 @@ Ast *parse_simple_stmt(AstFile *f, u32 flags) {
Ast *parse_block_stmt(AstFile *f, b32 is_when) {
+ skip_possible_newline_for_literal(f);
if (!is_when && f->curr_proc == nullptr) {
syntax_error(f->curr_token, "You cannot use a block statement in the file scope");
return ast_bad_stmt(f, f->curr_token, f->curr_token);
@@ -3796,9 +3796,9 @@ Ast *parse_if_stmt(AstFile *f) {
}
} else {
body = parse_block_stmt(f, false);
- skip_possible_newline_for_literal(f);
}
+ skip_possible_newline_for_literal(f);
if (allow_token(f, Token_else)) {
switch (f->curr_token.kind) {
case Token_if:
@@ -3852,9 +3852,9 @@ Ast *parse_when_stmt(AstFile *f) {
}
} else {
body = parse_block_stmt(f, true);
- skip_possible_newline_for_literal(f);
}
+ skip_possible_newline_for_literal(f);
if (allow_token(f, Token_else)) {
switch (f->curr_token.kind) {
case Token_when:
@@ -3958,7 +3958,6 @@ Ast *parse_for_stmt(AstFile *f) {
}
} else {
body = parse_block_stmt(f, false);
- skip_possible_newline_for_literal(f);
}
return ast_range_stmt(f, token, nullptr, nullptr, in_token, rhs, body);
}
@@ -3994,7 +3993,6 @@ Ast *parse_for_stmt(AstFile *f) {
}
} else {
body = parse_block_stmt(f, false);
- skip_possible_newline_for_literal(f);
}
if (is_range) {
@@ -4346,7 +4344,6 @@ Ast *parse_stmt(AstFile *f) {
}
} else {
body = parse_block_stmt(f, false);
- skip_possible_newline_for_literal(f);
}
if (bad_stmt) {
return ast_bad_stmt(f, inline_token, f->curr_token);
diff --git a/src/types.cpp b/src/types.cpp
index df87cb645..d79a3337a 100644
--- a/src/types.cpp
+++ b/src/types.cpp
@@ -1720,6 +1720,9 @@ TypeTuple *get_record_polymorphic_params(Type *t) {
bool is_type_polymorphic(Type *t, bool or_specialized=false) {
+ if (t == nullptr) {
+ return false;
+ }
if (t->flags & TypeFlag_InProcessOfCheckingPolymorphic) {
return false;
}