summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--abbrevs.txt3
-rw-r--r--identifiers.c2
-rw-r--r--main.c2
-rw-r--r--parse.c31
-rw-r--r--test.toc3
-rw-r--r--types.c15
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 = &param_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) {