aboutsummaryrefslogtreecommitdiff
path: root/src/codegen.cpp
diff options
context:
space:
mode:
authorAndrew Kelley <superjoe30@gmail.com>2016-01-24 01:34:48 -0700
committerAndrew Kelley <superjoe30@gmail.com>2016-01-24 01:34:57 -0700
commit5c18826240fe983a30a9de6e04d3848643db7cf6 (patch)
treed427af30c78ff59d768bf75cd194e008757ab7bf /src/codegen.cpp
parent37aae530098f10565ea3408891c901e086b8d5b8 (diff)
downloadzig-5c18826240fe983a30a9de6e04d3848643db7cf6.tar.gz
zig-5c18826240fe983a30a9de6e04d3848643db7cf6.zip
introduce the error keyword and type
See #23
Diffstat (limited to 'src/codegen.cpp')
-rw-r--r--src/codegen.cpp46
1 files changed, 39 insertions, 7 deletions
diff --git a/src/codegen.cpp b/src/codegen.cpp
index 786127cd42..be96fe1b9f 100644
--- a/src/codegen.cpp
+++ b/src/codegen.cpp
@@ -306,7 +306,7 @@ static LLVMValueRef gen_cast_expr(CodeGen *g, AstNode *node) {
case CastOpNoop:
return expr_val;
case CastOpErrToInt:
- assert(actual_type->id == TypeTableEntryIdError);
+ assert(actual_type->id == TypeTableEntryIdErrorUnion);
if (actual_type->data.error.child_type->size_in_bits == 0) {
return gen_widen_or_shorten(g, node, g->err_tag_type, wanted_type, expr_val);
} else {
@@ -330,12 +330,19 @@ static LLVMValueRef gen_cast_expr(CodeGen *g, AstNode *node) {
return cast_expr->tmp_ptr;
}
case CastOpErrorWrap:
- assert(wanted_type->id == TypeTableEntryIdError);
+ assert(wanted_type->id == TypeTableEntryIdErrorUnion);
if (wanted_type->data.error.child_type->size_in_bits == 0) {
return LLVMConstNull(g->err_tag_type->type_ref);
} else {
zig_panic("TODO");
}
+ case CastOpPureErrorWrap:
+ assert(wanted_type->id == TypeTableEntryIdErrorUnion);
+ if (wanted_type->data.error.child_type->size_in_bits == 0) {
+ return expr_val;
+ } else {
+ zig_panic("TODO");
+ }
case CastOpPtrToInt:
add_debug_source_node(g, node);
return LLVMBuildPtrToInt(g->builder, expr_val, wanted_type->type_ref, "");
@@ -1292,7 +1299,7 @@ static LLVMValueRef gen_if_bool_expr_raw(CodeGen *g, AstNode *source_node, LLVMV
return nullptr;
}
- assert(!use_expr_value || then_type->id == TypeTableEntryIdError);
+ assert(!use_expr_value || then_type->id == TypeTableEntryIdErrorUnion);
LLVMBasicBlockRef then_block = LLVMAppendBasicBlock(g->cur_fn->fn_value, "Then");
LLVMBasicBlockRef endif_block = LLVMAppendBasicBlock(g->cur_fn->fn_value, "EndIf");
@@ -2011,7 +2018,6 @@ static LLVMValueRef gen_expr(CodeGen *g, AstNode *node) {
return gen_container_init_expr(g, node);
case NodeTypeSwitchExpr:
return gen_switch_expr(g, node);
- case NodeTypeErrorLiteral:
case NodeTypeNumberLiteral:
case NodeTypeBoolLiteral:
case NodeTypeStringLiteral:
@@ -2033,6 +2039,7 @@ static LLVMValueRef gen_expr(CodeGen *g, AstNode *node) {
case NodeTypeStructField:
case NodeTypeStructValueField:
case NodeTypeArrayType:
+ case NodeTypeErrorType:
case NodeTypeSwitchProng:
case NodeTypeSwitchRange:
case NodeTypeErrorValueDecl:
@@ -2063,6 +2070,9 @@ static LLVMValueRef gen_const_val(CodeGen *g, TypeTableEntry *type_entry, ConstE
if (type_entry->id == TypeTableEntryIdInt) {
return LLVMConstInt(type_entry->type_ref, bignum_to_twos_complement(&const_val->data.x_bignum), false);
+ } else if (type_entry->id == TypeTableEntryIdPureError) {
+ assert(const_val->data.x_err.err);
+ return LLVMConstInt(g->builtin_types.entry_pure_error->type_ref, const_val->data.x_err.err->value, false);
} else if (type_entry->id == TypeTableEntryIdFloat) {
if (const_val->data.x_bignum.kind == BigNumKindFloat) {
return LLVMConstReal(type_entry->type_ref, const_val->data.x_bignum.data.x_float);
@@ -2148,12 +2158,26 @@ static LLVMValueRef gen_const_val(CodeGen *g, TypeTableEntry *type_entry, ConstE
} else {
return global_value;
}
- } else if (type_entry->id == TypeTableEntryIdError) {
- if (type_entry->data.error.child_type->size_in_bits == 0) {
+ } else if (type_entry->id == TypeTableEntryIdErrorUnion) {
+ TypeTableEntry *child_type = type_entry->data.error.child_type;
+ if (child_type->size_in_bits == 0) {
uint64_t value = const_val->data.x_err.err ? const_val->data.x_err.err->value : 0;
return LLVMConstInt(g->err_tag_type->type_ref, value, false);
} else {
- zig_panic("TODO");
+ LLVMValueRef err_tag_value;
+ LLVMValueRef err_payload_value;
+ if (const_val->data.x_err.err) {
+ err_tag_value = LLVMConstInt(g->err_tag_type->type_ref, const_val->data.x_err.err->value, false);
+ err_payload_value = LLVMConstNull(child_type->type_ref);
+ } else {
+ err_tag_value = LLVMConstNull(g->err_tag_type->type_ref);
+ err_payload_value = gen_const_val(g, child_type, const_val->data.x_err.payload);
+ }
+ LLVMValueRef fields[] = {
+ err_tag_value,
+ err_payload_value,
+ };
+ return LLVMConstStruct(fields, 2, false);
}
} else {
zig_unreachable();
@@ -2557,6 +2581,14 @@ static void define_builtin_types(CodeGen *g) {
g->builtin_types.entry_type = entry;
g->primitive_type_table.put(&entry->name, entry);
}
+ {
+ // partially complete the error type. we complete it later after we know
+ // error_value_count.
+ TypeTableEntry *entry = new_type_table_entry(TypeTableEntryIdPureError);
+ buf_init_from_str(&entry->name, "error");
+ g->builtin_types.entry_pure_error = entry;
+ g->primitive_type_table.put(&entry->name, entry);
+ }
g->builtin_types.entry_u8 = get_int_type(g, false, 8);
g->builtin_types.entry_u16 = get_int_type(g, false, 16);