aboutsummaryrefslogtreecommitdiff
path: root/src/checker
diff options
context:
space:
mode:
authorGinger Bill <bill@gingerbill.org>2016-10-07 09:41:38 +0100
committerGinger Bill <bill@gingerbill.org>2016-10-07 09:41:38 +0100
commitc5d20d2eef6c25b23c2aa69cdc1dbc7ce7d6753a (patch)
tree23c6a0a5badbf67634a000df4d856f384fc51176 /src/checker
parentf40482aa29f687b4630744457844bad7f45ec614 (diff)
Demaybe operator ?
Diffstat (limited to 'src/checker')
-rw-r--r--src/checker/checker.cpp19
-rw-r--r--src/checker/expr.cpp62
2 files changed, 49 insertions, 32 deletions
diff --git a/src/checker/checker.cpp b/src/checker/checker.cpp
index 19a4807d8..9e1295b9a 100644
--- a/src/checker/checker.cpp
+++ b/src/checker/checker.cpp
@@ -168,8 +168,6 @@ enum BuiltinProcId {
BuiltinProc_enum_to_string,
- BuiltinProc_maybe_value,
-
BuiltinProc_Count,
};
struct BuiltinProc {
@@ -213,9 +211,6 @@ gb_global BuiltinProc builtin_procs[BuiltinProc_Count] = {
{STR_LIT("abs"), 1, false, Expr_Expr},
{STR_LIT("enum_to_string"), 1, false, Expr_Expr},
-
- {STR_LIT("maybe_value"), 1, false, Expr_Expr},
-
};
struct CheckerContext {
@@ -874,8 +869,6 @@ Map<Entity *> generate_minimum_dependency_map(CheckerInfo *info, Entity *start)
Map<Entity *> map = {}; // Key: Entity *
map_init(&map, gb_heap_allocator());
- add_dependency_to_map(&map, info, start);
-
gb_for_array(i, info->entities.entries) {
auto *entry = &info->entities.entries[i];
Entity *e = cast(Entity *)cast(uintptr)entry->key.key;
@@ -885,6 +878,8 @@ Map<Entity *> generate_minimum_dependency_map(CheckerInfo *info, Entity *start)
}
}
+ add_dependency_to_map(&map, info, start);
+
return map;
}
@@ -1200,6 +1195,16 @@ void check_parsed_files(Checker *c) {
add_curr_ast_file(c, d->scope->file);
if (d->scope == e->scope) {
+ if (kind != Entity_Procedure && e->token.string == "main") {
+ if (e->scope->is_init) {
+ error(e->token, "`main` is reserved as the entry point procedure in the initial scope");
+ continue;
+ }
+ } else if (e->scope->is_global && e->token.string == "main") {
+ error(e->token, "`main` is reserved as the entry point procedure in the initial scope");
+ continue;
+ }
+
Scope *prev_scope = c->context.scope;
c->context.scope = d->scope;
check_entity_decl(c, e, d, NULL);
diff --git a/src/checker/expr.cpp b/src/checker/expr.cpp
index 527b2d92d..26b8399d5 100644
--- a/src/checker/expr.cpp
+++ b/src/checker/expr.cpp
@@ -3028,31 +3028,6 @@ b32 check_builtin_procedure(Checker *c, Operand *operand, AstNode *call, i32 id)
operand->mode = Addressing_Value;
operand->type = t_string;
} break;
-
- case BuiltinProc_maybe_value: {
- Type *type = operand->type;
- if (!is_type_maybe(type)) {
- gbString type_str = type_to_string(operand->type);
- defer (gb_string_free(type_str));
- error(ast_node_token(call),
- "Expected a maybe to `maybe_value`, got `%s`",
- type_str);
- return false;
- }
-
- operand->mode = Addressing_Value;
-
- Entity **variables = gb_alloc_array(c->allocator, Entity *, 2);
- Type *elem = base_type(type)->Maybe.elem;
- Token t = make_token_ident(make_string(""));
- variables[0] = make_entity_param(c->allocator, NULL, t, elem, false);
- variables[1] = make_entity_param(c->allocator, NULL, t, t_bool, false);
-
- Type *tuple = make_type_tuple(c->allocator);
- tuple->Tuple.variables = variables;
- tuple->Tuple.variable_count = 2;
- operand->type = tuple;
- } break;
}
return true;
@@ -3270,6 +3245,10 @@ ExprKind check__expr_base(Checker *c, Operand *o, AstNode *node, Type *type_hint
o->type = t_invalid;
switch (node->kind) {
+ default:
+ goto error;
+ break;
+
case_ast_node(be, BadExpr, node)
goto error;
case_end;
@@ -3731,6 +3710,34 @@ ExprKind check__expr_base(Checker *c, Operand *o, AstNode *node, Type *type_hint
}
case_end;
+ case_ast_node(de, DemaybeExpr, node);
+ check_expr_or_type(c, o, de->expr);
+ if (o->mode == Addressing_Invalid) {
+ goto error;
+ } else {
+ Type *t = base_type(o->type);
+ if (t->kind == Type_Maybe) {
+ Entity **variables = gb_alloc_array(c->allocator, Entity *, 2);
+ Type *elem = t->Maybe.elem;
+ Token tok = make_token_ident(make_string(""));
+ variables[0] = make_entity_param(c->allocator, NULL, tok, elem, false);
+ variables[1] = make_entity_param(c->allocator, NULL, tok, t_bool, false);
+
+ Type *tuple = make_type_tuple(c->allocator);
+ tuple->Tuple.variables = variables;
+ tuple->Tuple.variable_count = 2;
+
+ o->type = tuple;
+ o->mode = Addressing_Variable;
+ } else {
+ gbString str = expr_to_string(o->expr);
+ error(ast_node_token(o->expr), "Cannot demaybe `%s`", str);
+ gb_string_free(str);
+ goto error;
+ }
+ }
+ case_end;
+
case AstNode_ProcType:
case AstNode_PointerType:
case AstNode_MaybeType:
@@ -3910,6 +3917,11 @@ gbString write_expr_to_string(gbString str, AstNode *node) {
str = gb_string_appendc(str, "^");
case_end;
+ case_ast_node(de, DemaybeExpr, node);
+ str = write_expr_to_string(str, de->expr);
+ str = gb_string_appendc(str, "?");
+ case_end;
+
case_ast_node(be, BinaryExpr, node);
str = write_expr_to_string(str, be->left);
str = gb_string_appendc(str, " ");