diff options
| author | Andrew Kelley <superjoe30@gmail.com> | 2015-12-12 22:55:29 -0700 |
|---|---|---|
| committer | Andrew Kelley <superjoe30@gmail.com> | 2015-12-12 22:55:29 -0700 |
| commit | bd77bc749a1b38ef754fdd5b7e14a8228cb6f72c (patch) | |
| tree | 1cc38a744572519ef574fcd21bb9a3a6d18772d7 /src/analyze.cpp | |
| parent | 0f02e29a2b7a975407c7f3b4ed742f886e0c1add (diff) | |
| download | zig-bd77bc749a1b38ef754fdd5b7e14a8228cb6f72c.tar.gz zig-bd77bc749a1b38ef754fdd5b7e14a8228cb6f72c.zip | |
structs are working
Diffstat (limited to 'src/analyze.cpp')
| -rw-r--r-- | src/analyze.cpp | 82 |
1 files changed, 43 insertions, 39 deletions
diff --git a/src/analyze.cpp b/src/analyze.cpp index 7b21a43606..3d46dfcdfb 100644 --- a/src/analyze.cpp +++ b/src/analyze.cpp @@ -758,6 +758,47 @@ static bool is_op_allowed(TypeTableEntry *type, BinOpType op) { zig_unreachable(); } +static TypeTableEntry *analyze_cast_expr(CodeGen *g, ImportTableEntry *import, BlockContext *context, + TypeTableEntry *expected_type, AstNode *node) +{ + TypeTableEntry *wanted_type = resolve_type(g, node->data.cast_expr.type); + TypeTableEntry *actual_type = analyze_expression(g, import, context, nullptr, node->data.cast_expr.expr); + + if (wanted_type->id == TypeTableEntryIdInvalid || + actual_type->id == TypeTableEntryIdInvalid) + { + return g->builtin_types.entry_invalid; + } + + CastNode *cast_node = &node->codegen_node->data.cast_node; + + // special casing this for now, TODO think about casting and do a general solution + if (wanted_type == g->builtin_types.entry_isize && + actual_type->id == TypeTableEntryIdPointer) + { + cast_node->op = CastOpPtrToInt; + return wanted_type; + } else if (wanted_type->id == TypeTableEntryIdInt && + actual_type->id == TypeTableEntryIdInt) + { + cast_node->op = CastOpIntWidenOrShorten; + return wanted_type; + } else if (wanted_type == g->builtin_types.entry_string && + actual_type->id == TypeTableEntryIdArray && + actual_type->data.array.child_type == g->builtin_types.entry_u8) + { + cast_node->op = CastOpArrayToString; + context->cast_expr_alloca_list.append(node); + return wanted_type; + } else { + add_node_error(g, node, + buf_sprintf("invalid cast from type '%s' to '%s'", + buf_ptr(&actual_type->name), + buf_ptr(&wanted_type->name))); + return g->builtin_types.entry_invalid; + } +} + static TypeTableEntry * analyze_expression(CodeGen *g, ImportTableEntry *import, BlockContext *context, TypeTableEntry *expected_type, AstNode *node) { @@ -1100,45 +1141,8 @@ static TypeTableEntry * analyze_expression(CodeGen *g, ImportTableEntry *import, break; } case NodeTypeCastExpr: - { - TypeTableEntry *wanted_type = resolve_type(g, node->data.cast_expr.type); - TypeTableEntry *actual_type = analyze_expression(g, import, context, nullptr, - node->data.cast_expr.expr); - - if (wanted_type->id == TypeTableEntryIdInvalid || - actual_type->id == TypeTableEntryIdInvalid) - { - return_type = g->builtin_types.entry_invalid; - break; - } - - CastNode *cast_node = &node->codegen_node->data.cast_node; - - // special casing this for now, TODO think about casting and do a general solution - if (wanted_type == g->builtin_types.entry_isize && - actual_type->id == TypeTableEntryIdPointer) - { - cast_node->op = CastOpPtrToInt; - return_type = wanted_type; - } else if (wanted_type->id == TypeTableEntryIdInt && - actual_type->id == TypeTableEntryIdInt) - { - cast_node->op = CastOpIntWidenOrShorten; - return_type = wanted_type; - } else if (wanted_type == g->builtin_types.entry_string && - actual_type->id == TypeTableEntryIdArray && - actual_type->data.array.child_type == g->builtin_types.entry_u8) - { - cast_node->op = CastOpArrayToString; - return_type = wanted_type; - } else { - add_node_error(g, node, - buf_sprintf("TODO handle cast from '%s' to '%s'", - buf_ptr(&actual_type->name), buf_ptr(&wanted_type->name))); - return_type = g->builtin_types.entry_invalid; - } - break; - } + return_type = analyze_cast_expr(g, import, context, expected_type, node); + break; case NodeTypePrefixOpExpr: switch (node->data.prefix_op_expr.prefix_op) { case PrefixOpBoolNot: |
