From 685460f382e2e7039bd6ddf5c336abdb803a0372 Mon Sep 17 00:00:00 2001 From: Leo Tenenbaum Date: Fri, 27 Sep 2019 19:08:16 -0400 Subject: started named arguments --- abbrevs.txt | 3 +++ identifiers.c | 2 +- main.c | 2 +- parse.c | 31 ++++++++++++++++++++++++------- test.toc | 3 +++ types.c | 15 ++++++++------- 6 files changed, 40 insertions(+), 16 deletions(-) diff --git a/abbrevs.txt b/abbrevs.txt index 8efb3e3..56a73b7 100644 --- a/abbrevs.txt +++ b/abbrevs.txt @@ -1,3 +1,4 @@ +arg - argument decl - declaration deref - dereference direct - directive @@ -8,8 +9,10 @@ ident - identifier kw - keyword num - number op - operator +param - parameter ptr - pointer ret - return stmt - statement str - string tokr - tokenizer +val - value diff --git a/identifiers.c b/identifiers.c index 6b19d18..6eafc41 100644 --- a/identifiers.c +++ b/identifiers.c @@ -56,7 +56,7 @@ static int isident(int c) { static Identifier ident_new(Identifiers *ids, Identifier parent, unsigned char index_in_parent) { IdentTree *tree = block_arr_add(&ids->trees); memset(tree, 0, sizeof *tree); /* use zero value of IdentTree */ -#if NONZERO_NULL_PTRS +#ifdef NONZERO_NULL_PTRS tree->parent = NULL; for (size_t i = 0; i < TREE_NCHILDREN; i++) tree->children[i] = NULL; diff --git a/main.c b/main.c index eecc4de..7375c89 100644 --- a/main.c +++ b/main.c @@ -1,7 +1,7 @@ /* TODO: -optional params named args +optional params evaluator (simplify compile time constant expressions) re-do cgen */ diff --git a/parse.c b/parse.c index 8d6230c..f7407fd 100644 --- a/parse.c +++ b/parse.c @@ -103,12 +103,13 @@ typedef enum { typedef struct { Directive which; - Array args; /* of Expression */ + Array args; /* of Argument */ } DirectExpr; + typedef struct { struct Expression *fn; - Array args; /* of Expression */ + Array args; /* of Argument */ } CallExpr; typedef struct { @@ -166,6 +167,11 @@ typedef struct Expression { }; } Expression; +typedef struct { + Identifier name; /* NULL = no name */ + Expression val; +} Argument; + #define DECL_FLAG_ANNOTATES_TYPE 0x01 #define DECL_FLAG_CONST 0x02 #define DECL_FLAG_HAS_EXPR 0x04 @@ -745,7 +751,7 @@ static bool parse_args(Parser *p, Array *args) { Tokenizer *t = p->tokr; Token *start = t->token; assert(token_is_kw(start, KW_LPAREN)); - arr_create(args, sizeof(Expression)); + arr_create(args, sizeof(Argument)); t->token++; /* move past ( */ if (!token_is_kw(t->token, KW_RPAREN)) { /* non-empty arg list */ @@ -755,8 +761,15 @@ static bool parse_args(Parser *p, Array *args) { info_print(start->where, "This is where the argument list starts."); return false; } - Expression *arg = arr_add(args); - if (!parse_expr(p, arg, expr_find_end(p, EXPR_CAN_END_WITH_COMMA, NULL))) { + Argument *arg = arr_add(args); + /* named arguments */ + if (t->token->kind == TOKEN_IDENT && token_is_kw(t->token + 1, KW_EQ)) { + arg->name = t->token->ident; + t->token += 2; + } else { + arg->name = NULL; + } + if (!parse_expr(p, &arg->val, expr_find_end(p, EXPR_CAN_END_WITH_COMMA, NULL))) { return false; } if (token_is_kw(t->token, KW_RPAREN)) @@ -1534,9 +1547,13 @@ static void fprint_fn_expr(FILE *out, FnExpr *f) { static void fprint_args(FILE *out, Array *args) { fprintf(out, "("); - arr_foreach(args, Expression, arg) { + arr_foreach(args, Argument, arg) { if (arg != args->data) fprintf(out, ", "); - fprint_expr(out, arg); + if (arg->name) { + fprint_ident(out, arg->name); + fprintf(out, " = "); + } + fprint_expr(out, &arg->val); } fprintf(out, ")"); } diff --git a/test.toc b/test.toc index 9ecb5f9..4646541 100644 --- a/test.toc +++ b/test.toc @@ -3,5 +3,8 @@ main @= fn() { test @= fn(x : i64, y : i32, z,w: i64) ret1 : i64, ret2 : i64 { ret1 = x; }; + a,b : i64; + // a, b = test(3,7,2,3); + a, b = test(x = 3, y = 7, z = 30, w = 20); }; diff --git a/types.c b/types.c index 9fcd5f1..896a480 100644 --- a/types.c +++ b/types.c @@ -482,8 +482,8 @@ static bool types_expr(Typer *tr, Expression *e) { } else { if (!types_expr(tr, f)) return false; } - arr_foreach(&c->args, Expression, arg) { - if (!types_expr(tr, arg)) + arr_foreach(&c->args, Argument, arg) { + if (!types_expr(tr, &arg->val)) return false; } if (f->type.kind != TYPE_FN) { @@ -493,7 +493,7 @@ static bool types_expr(Typer *tr, Expression *e) { } Type *ret_type = (Type *)f->type.fn.types.data; Type *param_types = ret_type + 1; - Expression *args = c->args.data; + Argument *args = c->args.data; size_t nparams = f->type.fn.types.len - 1; if (nparams != c->args.len) { err_print(e->where, "Expected %lu arguments to function, but got %lu.", (unsigned long)nparams, (unsigned long)c->args.len); @@ -501,13 +501,14 @@ static bool types_expr(Typer *tr, Expression *e) { } bool ret = true; for (size_t p = 0; p < nparams; p++) { + Expression *val = &args[p].val; Type *expected = ¶m_types[p]; - Type *got = &args[p].type; + Type *got = &val->type; if (!type_eq(expected, got)) { ret = false; char *estr = type_to_str(expected); char *gstr = type_to_str(got); - err_print(args[p].where, "Expected type %s as %lu%s argument to function, but got %s.", estr, 1+(unsigned long)p, ordinals(1+p), gstr); + err_print(val->where, "Expected type %s as %lu%s argument to function, but got %s.", estr, 1+(unsigned long)p, ordinals(1+p), gstr); } } if (!ret) return false; @@ -526,8 +527,8 @@ static bool types_expr(Typer *tr, Expression *e) { } break; case EXPR_DIRECT: t->kind = TYPE_UNKNOWN; - arr_foreach(&e->direct.args, Expression, arg) { - if (!types_expr(tr, arg)) + arr_foreach(&e->direct.args, Argument, arg) { + if (!types_expr(tr, &arg->val)) return false; } switch (e->direct.which) { -- cgit v1.2.3