aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorAndrew Kelley <superjoe30@gmail.com>2016-01-28 16:55:54 -0700
committerAndrew Kelley <superjoe30@gmail.com>2016-01-28 16:55:54 -0700
commit974d69ea3d0db71b97af00e325fdfb421c0906c2 (patch)
tree05c145b633277b78735765d8f9c15f78d504b2ed /src
parentbb4f7835286f047fc596715101ee0318c8e7f924 (diff)
downloadzig-974d69ea3d0db71b97af00e325fdfb421c0906c2.tar.gz
zig-974d69ea3d0db71b97af00e325fdfb421c0906c2.zip
ability to call member functions directly
see #14
Diffstat (limited to 'src')
-rw-r--r--src/analyze.cpp22
-rw-r--r--src/codegen.cpp25
2 files changed, 34 insertions, 13 deletions
diff --git a/src/analyze.cpp b/src/analyze.cpp
index cd743710e2..5f3c83f3e1 100644
--- a/src/analyze.cpp
+++ b/src/analyze.cpp
@@ -3694,17 +3694,17 @@ static TypeTableEntry *analyze_fn_call_expr(CodeGen *g, ImportTableEntry *import
} else if (struct_type->id == TypeTableEntryIdInvalid) {
return struct_type;
} else if (struct_type->id == TypeTableEntryIdMetaType) {
- TypeTableEntry *enum_type = resolve_type(g, first_param_expr);
+ TypeTableEntry *child_type = resolve_type(g, first_param_expr);
- if (enum_type->id == TypeTableEntryIdInvalid) {
+ if (child_type->id == TypeTableEntryIdInvalid) {
return g->builtin_types.entry_invalid;
- } else if (enum_type->id == TypeTableEntryIdEnum) {
+ } else if (child_type->id == TypeTableEntryIdEnum) {
Buf *field_name = &fn_ref_expr->data.field_access_expr.field_name;
int param_count = node->data.fn_call_expr.params.length;
if (param_count > 1) {
add_node_error(g, first_executing_node(node->data.fn_call_expr.params.at(1)),
buf_sprintf("enum values accept only one parameter"));
- return enum_type;
+ return child_type;
} else {
AstNode *value_node;
if (param_count == 1) {
@@ -3714,7 +3714,19 @@ static TypeTableEntry *analyze_fn_call_expr(CodeGen *g, ImportTableEntry *import
}
return analyze_enum_value_expr(g, import, context, fn_ref_expr, value_node,
- enum_type, field_name);
+ child_type, field_name);
+ }
+ } else if (child_type->id == TypeTableEntryIdStruct) {
+ Buf *field_name = &fn_ref_expr->data.field_access_expr.field_name;
+ auto entry = child_type->data.structure.fn_table.maybe_get(field_name);
+ if (entry) {
+ return analyze_fn_call_raw(g, import, context, expected_type, node,
+ entry->value, nullptr);
+ } else {
+ add_node_error(g, node,
+ buf_sprintf("struct '%s' has no function called '%s'",
+ buf_ptr(&child_type->name), buf_ptr(field_name)));
+ return g->builtin_types.entry_invalid;
}
} else {
add_node_error(g, first_param_expr, buf_sprintf("member reference base type not struct or enum"));
diff --git a/src/codegen.cpp b/src/codegen.cpp
index 6f4ba6c58f..97b03d14db 100644
--- a/src/codegen.cpp
+++ b/src/codegen.cpp
@@ -496,16 +496,25 @@ static LLVMValueRef gen_fn_call_expr(CodeGen *g, AstNode *node) {
assert(struct_type->data.pointer.child_type->id == TypeTableEntryIdStruct);
fn_table_entry = node->data.fn_call_expr.fn_entry;
} else if (struct_type->id == TypeTableEntryIdMetaType) {
- TypeTableEntry *enum_type = get_type_for_type_node(first_param_expr);
- int param_count = node->data.fn_call_expr.params.length;
- AstNode *arg1_node;
- if (param_count == 1) {
- arg1_node = node->data.fn_call_expr.params.at(0);
+ TypeTableEntry *child_type = get_type_for_type_node(first_param_expr);
+
+ if (child_type->id == TypeTableEntryIdEnum) {
+ int param_count = node->data.fn_call_expr.params.length;
+ AstNode *arg1_node;
+ if (param_count == 1) {
+ arg1_node = node->data.fn_call_expr.params.at(0);
+ } else {
+ assert(param_count == 0);
+ arg1_node = nullptr;
+ }
+ return gen_enum_value_expr(g, fn_ref_expr, child_type, arg1_node);
+ } else if (child_type->id == TypeTableEntryIdStruct) {
+ struct_type = nullptr;
+ first_param_expr = nullptr;
+ fn_table_entry = node->data.fn_call_expr.fn_entry;
} else {
- assert(param_count == 0);
- arg1_node = nullptr;
+ zig_unreachable();
}
- return gen_enum_value_expr(g, fn_ref_expr, enum_type, arg1_node);
} else {
zig_unreachable();
}