aboutsummaryrefslogtreecommitdiff
path: root/src/analyze.cpp
diff options
context:
space:
mode:
authorAndrew Kelley <superjoe30@gmail.com>2016-01-08 23:41:40 -0700
committerAndrew Kelley <superjoe30@gmail.com>2016-01-08 23:41:40 -0700
commitb7dd88ad68aab5b6bc8321431d1a53b343b2dd37 (patch)
tree78a9cd198eb94529a5841eb68c6bf57f9be21607 /src/analyze.cpp
parent14b9cbd43c21ad2ba75b38ef5fc681c044e7662e (diff)
downloadzig-b7dd88ad68aab5b6bc8321431d1a53b343b2dd37.tar.gz
zig-b7dd88ad68aab5b6bc8321431d1a53b343b2dd37.zip
suport checked arithmetic operations via intrinsics
closes #32
Diffstat (limited to 'src/analyze.cpp')
-rw-r--r--src/analyze.cpp42
1 files changed, 40 insertions, 2 deletions
diff --git a/src/analyze.cpp b/src/analyze.cpp
index 18afb9eb05..3f4462be71 100644
--- a/src/analyze.cpp
+++ b/src/analyze.cpp
@@ -2064,6 +2064,41 @@ static TypeTableEntry *analyze_compiler_fn_type(CodeGen *g, ImportTableEntry *im
}
}
+static TypeTableEntry *analyze_builtin_fn_call_expr(CodeGen *g, ImportTableEntry *import, BlockContext *context,
+ TypeTableEntry *expected_type, AstNode *node)
+{
+ AstNode *fn_ref_expr = node->data.fn_call_expr.fn_ref_expr;
+ Buf *name = &fn_ref_expr->data.symbol;
+
+ auto entry = g->builtin_fn_table.maybe_get(name);
+
+ if (entry) {
+ BuiltinFnEntry *builtin_fn = entry->value;
+ int actual_param_count = node->data.fn_call_expr.params.length;
+
+ assert(node->codegen_node);
+ node->codegen_node->data.fn_call_node.builtin_fn = builtin_fn;
+
+ if (builtin_fn->param_count != actual_param_count) {
+ add_node_error(g, node,
+ buf_sprintf("expected %d arguments, got %d",
+ builtin_fn->param_count, actual_param_count));
+ }
+
+ for (int i = 0; i < actual_param_count; i += 1) {
+ AstNode *child = node->data.fn_call_expr.params.at(i);
+ TypeTableEntry *expected_param_type = builtin_fn->param_types[i];
+ analyze_expression(g, import, context, expected_param_type, child);
+ }
+
+ return builtin_fn->return_type;
+ } else {
+ add_node_error(g, node,
+ buf_sprintf("invalid builtin function: '%s'", buf_ptr(name)));
+ return g->builtin_types.entry_invalid;
+ }
+}
+
static TypeTableEntry *analyze_fn_call_expr(CodeGen *g, ImportTableEntry *import, BlockContext *context,
TypeTableEntry *expected_type, AstNode *node)
{
@@ -2091,6 +2126,9 @@ static TypeTableEntry *analyze_fn_call_expr(CodeGen *g, ImportTableEntry *import
return g->builtin_types.entry_invalid;
}
} else if (fn_ref_expr->type == NodeTypeSymbol) {
+ if (node->data.fn_call_expr.is_builtin) {
+ return analyze_builtin_fn_call_expr(g, import, context, expected_type, node);
+ }
name = &fn_ref_expr->data.symbol;
} else {
add_node_error(g, node,
@@ -2126,12 +2164,12 @@ static TypeTableEntry *analyze_fn_call_expr(CodeGen *g, ImportTableEntry *import
if (fn_proto->is_var_args) {
if (actual_param_count < expected_param_count) {
add_node_error(g, node,
- buf_sprintf("wrong number of arguments. Expected at least %d, got %d.",
+ buf_sprintf("expected at least %d arguments, got %d",
expected_param_count, actual_param_count));
}
} else if (expected_param_count != actual_param_count) {
add_node_error(g, node,
- buf_sprintf("wrong number of arguments. Expected %d, got %d.",
+ buf_sprintf("expected %d arguments, got %d",
expected_param_count, actual_param_count));
}