diff options
| author | Ginger Bill <bill@gingerbill.org> | 2016-10-08 10:01:29 +0100 |
|---|---|---|
| committer | Ginger Bill <bill@gingerbill.org> | 2016-10-08 10:01:29 +0100 |
| commit | a5c6340316245f4f63e74d307f9d7c8be09360c6 (patch) | |
| tree | 43d2c68064a5ca31428e22f978a2f0283e2f3589 /src/checker/expr.cpp | |
| parent | c5d20d2eef6c25b23c2aa69cdc1dbc7ce7d6753a (diff) | |
"Maybe-fy" operator
Diffstat (limited to 'src/checker/expr.cpp')
| -rw-r--r-- | src/checker/expr.cpp | 30 |
1 files changed, 28 insertions, 2 deletions
diff --git a/src/checker/expr.cpp b/src/checker/expr.cpp index 26b8399d5..23d877bd9 100644 --- a/src/checker/expr.cpp +++ b/src/checker/expr.cpp @@ -1044,6 +1044,9 @@ Type *check_type(Checker *c, AstNode *e, Type *named_type, CycleChecker *cycle_c if (ue->op.kind == Token_Pointer) { type = make_type_pointer(c->allocator, check_type(c, ue->expr)); goto end; + } else if (ue->op.kind == Token_Maybe) { + type = make_type_maybe(c->allocator, check_type(c, ue->expr)); + goto end; } case_end; @@ -1365,7 +1368,8 @@ b32 check_is_expr_vector_index(Checker *c, AstNode *expr) { } void check_unary_expr(Checker *c, Operand *o, Token op, AstNode *node) { - if (op.kind == Token_Pointer) { // Pointer address + switch (op.kind) { + case Token_Pointer: { // Pointer address if (o->mode != Addressing_Variable || check_is_expr_vector_index(c, o->expr)) { ast_node(ue, UnaryExpr, node); @@ -1380,6 +1384,27 @@ void check_unary_expr(Checker *c, Operand *o, Token op, AstNode *node) { return; } + case Token_Maybe: { // Make maybe + Type *t = default_type(o->type); + b32 is_value = + o->mode == Addressing_Variable || + o->mode == Addressing_Value || + o->mode == Addressing_Constant; + + if (!is_value || is_type_untyped(t)) { + ast_node(ue, UnaryExpr, node); + gbString str = expr_to_string(ue->expr); + defer (gb_string_free(str)); + error(op, "Cannot convert `%s` to a maybe", str); + o->mode = Addressing_Invalid; + return; + } + o->mode = Addressing_Value; + o->type = make_type_maybe(c->allocator, t); + return; + } + } + if (!check_unary_op(c, o, op)) { o->mode = Addressing_Invalid; return; @@ -1399,8 +1424,9 @@ void check_unary_expr(Checker *c, Operand *o, Token op, AstNode *node) { i32 precision = 0; - if (is_type_unsigned(type)) + if (is_type_unsigned(type)) { precision = cast(i32)(8 * type_size_of(c->sizes, c->allocator, type)); + } o->value = exact_unary_operator_value(op, o->value, precision); if (is_type_typed(type)) { |