diff options
| author | Ginger Bill <bill@gingerbill.org> | 2016-09-07 19:23:00 +0100 |
|---|---|---|
| committer | Ginger Bill <bill@gingerbill.org> | 2016-09-07 19:23:00 +0100 |
| commit | 7ba13a18a33d8f852eb41b58da662ddb4649d04f (patch) | |
| tree | 89663aff3ad0c5e5f62a3432d269dcee050a71ed /src | |
| parent | 2c4193a24226b084797af61e29c8355835c179a8 (diff) | |
Basic variadic `print` procedure
Diffstat (limited to 'src')
| -rw-r--r-- | src/checker/expr.cpp | 13 | ||||
| -rw-r--r-- | src/checker/type.cpp | 2 | ||||
| -rw-r--r-- | src/codegen/codegen.cpp | 4 | ||||
| -rw-r--r-- | src/codegen/print_llvm.cpp | 2 | ||||
| -rw-r--r-- | src/codegen/ssa.cpp | 6 | ||||
| -rw-r--r-- | src/parser.cpp | 23 |
6 files changed, 36 insertions, 14 deletions
diff --git a/src/checker/expr.cpp b/src/checker/expr.cpp index e55efd56d..b5fb1249f 100644 --- a/src/checker/expr.cpp +++ b/src/checker/expr.cpp @@ -2714,6 +2714,8 @@ void check_call_arguments(Checker *c, Operand *operand, Type *proc_type, AstNode GB_ASSERT(call->kind == AstNode_CallExpr); GB_ASSERT(proc_type->kind == Type_Proc); ast_node(ce, CallExpr, call); + + isize error_code = 0; isize param_index = 0; isize param_count = 0; @@ -2723,6 +2725,15 @@ void check_call_arguments(Checker *c, Operand *operand, Type *proc_type, AstNode param_count = proc_type->Proc.params->Tuple.variable_count; } + if (ce->ellipsis.pos.line != 0) { + if (!variadic) { + error(&c->error_collector, ce->ellipsis, + "Cannot use `..` in call to a non-variadic procedure: `%.*s`", + LIT(ce->proc->Ident.string)); + return; + } + } + if (ce->arg_list_count == 0) { if (variadic && param_count-1 == 0) return; @@ -2730,6 +2741,8 @@ void check_call_arguments(Checker *c, Operand *operand, Type *proc_type, AstNode return; } + + if (ce->arg_list_count > param_count && !variadic) { error_code = +1; } else { diff --git a/src/checker/type.cpp b/src/checker/type.cpp index 2ef56111c..8db89a38c 100644 --- a/src/checker/type.cpp +++ b/src/checker/type.cpp @@ -722,7 +722,7 @@ Selection lookup_field(Type *type_, String field_name, b32 is_type, Selection se if (type->kind == Type_Basic) { if (type->Basic.kind == Basic_any) { String type_info_str = make_string("type_info"); - String data_str = make_string("data_str"); + String data_str = make_string("data"); if (entity_any_type_info == NULL) { Token token = {Token_Identifier}; token.string = type_info_str; diff --git a/src/codegen/codegen.cpp b/src/codegen/codegen.cpp index 5d8df5060..13a362ce5 100644 --- a/src/codegen/codegen.cpp +++ b/src/codegen/codegen.cpp @@ -238,7 +238,7 @@ void ssa_gen_tree(ssaGen *s) { case Basic_uint: { tag = ssa_add_local_generated(proc, t_type_info_integer); b32 is_unsigned = (basic_types[t->Basic.kind].flags & BasicFlag_Unsigned) != 0; - ssaValue *bits = ssa_make_value_constant(a, t_int, make_exact_value_integer(8*type_size_of(m->sizes, a, t))); + ssaValue *bits = ssa_make_value_constant(a, t_int, make_exact_value_integer(type_size_of(m->sizes, a, t))); ssaValue *is_signed = ssa_make_value_constant(a, t_bool, make_exact_value_bool(!is_unsigned)); ssa_emit_store(proc, ssa_emit_struct_gep(proc, tag, v_zero32, t_int_ptr), bits); ssa_emit_store(proc, ssa_emit_struct_gep(proc, tag, v_one32, t_bool_ptr), is_signed); @@ -247,7 +247,7 @@ void ssa_gen_tree(ssaGen *s) { case Basic_f32: case Basic_f64: { tag = ssa_add_local_generated(proc, t_type_info_float); - ssaValue *bits = ssa_make_value_constant(a, t_int, make_exact_value_integer(8*type_size_of(m->sizes, a, t))); + ssaValue *bits = ssa_make_value_constant(a, t_int, make_exact_value_integer(type_size_of(m->sizes, a, t))); ssa_emit_store(proc, ssa_emit_struct_gep(proc, tag, v_zero32, t_int_ptr), bits); } break; diff --git a/src/codegen/print_llvm.cpp b/src/codegen/print_llvm.cpp index ea30d910c..cc349588c 100644 --- a/src/codegen/print_llvm.cpp +++ b/src/codegen/print_llvm.cpp @@ -146,7 +146,7 @@ void ssa_print_type(ssaFileBuffer *f, BaseTypeSizes s, Type *t) { case Basic_u16: ssa_fprintf(f, "i16"); break; case Basic_u32: ssa_fprintf(f, "i32"); break; case Basic_u64: ssa_fprintf(f, "i64"); break; - case Basic_u128: ssa_fprintf(f, "u128"); break; + case Basic_u128: ssa_fprintf(f, "i128"); break; case Basic_f32: ssa_fprintf(f, "float"); break; case Basic_f64: ssa_fprintf(f, "double"); break; case Basic_rawptr: ssa_fprintf(f, "%%..rawptr"); break; diff --git a/src/codegen/ssa.cpp b/src/codegen/ssa.cpp index a5fe3c566..fc55600ab 100644 --- a/src/codegen/ssa.cpp +++ b/src/codegen/ssa.cpp @@ -2085,12 +2085,12 @@ ssaValue *ssa_build_single_expr(ssaProcedure *proc, AstNode *expr, TypeAndValue // append :: proc(s: ^[]Type, item: Type) -> bool AstNode *sptr_node = ce->arg_list; AstNode *item_node = ce->arg_list->next; - ssaValue *slice_ptr = ssa_build_addr(proc, sptr_node).addr; + ssaValue *slice_ptr = ssa_build_expr(proc, sptr_node); ssaValue *slice = ssa_emit_load(proc, slice_ptr); ssaValue *elem = ssa_slice_elem(proc, slice); - ssaValue *len = ssa_slice_len(proc, slice); - ssaValue *cap = ssa_slice_cap(proc, slice); + ssaValue *len = ssa_slice_len(proc, slice); + ssaValue *cap = ssa_slice_cap(proc, slice); Type *elem_type = type_deref(ssa_type(elem)); diff --git a/src/parser.cpp b/src/parser.cpp index ec95e2926..3dd92d096 100644 --- a/src/parser.cpp +++ b/src/parser.cpp @@ -106,6 +106,7 @@ AST_NODE_KIND(_ExprBegin, "", struct{}) \ AstNode *proc, *arg_list; \ isize arg_list_count; \ Token open, close; \ + Token ellipsis; \ CallExprKind kind; \ }) \ AST_NODE_KIND(SliceExpr, "slice expression", struct { \ @@ -511,13 +512,14 @@ gb_inline AstNode *make_paren_expr(AstFile *f, AstNode *expr, Token open, Token return result; } -gb_inline AstNode *make_call_expr(AstFile *f, AstNode *proc, AstNode *arg_list, isize arg_list_count, Token open, Token close) { +gb_inline AstNode *make_call_expr(AstFile *f, AstNode *proc, AstNode *arg_list, isize arg_list_count, Token open, Token close, Token ellipsis) { AstNode *result = make_node(f, AstNode_CallExpr); result->CallExpr.proc = proc; result->CallExpr.arg_list = arg_list; result->CallExpr.arg_list_count = arg_list_count; - result->CallExpr.open = open; - result->CallExpr.close = close; + result->CallExpr.open = open; + result->CallExpr.close = close; + result->CallExpr.ellipsis = ellipsis; return result; } @@ -1296,15 +1298,22 @@ AstNode *parse_call_expr(AstFile *f, AstNode *operand) { AstNode *arg_list_curr = NULL; isize arg_list_count = 0; Token open_paren, close_paren; + Token ellipsis = {}; f->expr_level++; open_paren = expect_token(f, Token_OpenParen); while (f->cursor[0].kind != Token_CloseParen && - f->cursor[0].kind != Token_EOF) { + f->cursor[0].kind != Token_EOF && + ellipsis.pos.line == 0) { if (f->cursor[0].kind == Token_Comma) ast_file_err(f, f->cursor[0], "Expected an expression not a ,"); + if (f->cursor[0].kind == Token_Ellipsis) { + ellipsis = f->cursor[0]; + next_token(f); + } + DLIST_APPEND(arg_list, arg_list_curr, parse_expr(f, false)); arg_list_count++; @@ -1319,7 +1328,7 @@ AstNode *parse_call_expr(AstFile *f, AstNode *operand) { f->expr_level--; close_paren = expect_token(f, Token_CloseParen); - return make_call_expr(f, operand, arg_list, arg_list_count, open_paren, close_paren); + return make_call_expr(f, operand, arg_list, arg_list_count, open_paren, close_paren, ellipsis); } AstNode *parse_atom_expr(AstFile *f, b32 lhs) { @@ -1335,7 +1344,7 @@ AstNode *parse_atom_expr(AstFile *f, b32 lhs) { // TODO(bill): Handle this } AstNode *proc = parse_identifier(f); - operand = make_call_expr(f, proc, operand, 1, ast_node_token(operand), op); + operand = make_call_expr(f, proc, operand, 1, ast_node_token(operand), op, empty_token); } break; case Token_OpenParen: { @@ -1473,7 +1482,7 @@ AstNode *parse_binary_expr(AstFile *f, b32 lhs, i32 prec_in) { AstNode *proc = parse_identifier(f); AstNode *right = parse_binary_expr(f, false, prec+1); expression->next = right; - expression = make_call_expr(f, proc, expression, 2, op, ast_node_token(right)); + expression = make_call_expr(f, proc, expression, 2, op, ast_node_token(right), empty_token); continue; } break; |