diff options
-rw-r--r-- | parse.c | 60 | ||||
-rw-r--r-- | test.toc | 3 | ||||
-rw-r--r-- | tokenizer.c | 4 |
3 files changed, 64 insertions, 3 deletions
@@ -27,12 +27,24 @@ typedef struct { }; } Type; +typedef struct { + Identifier name; + Type type; +} Param; + +typedef struct { + Array params; + Type ret_type; + Array stmts; +} FnExpr; /* an expression such as fn(x: int) int {return 2 * x;} */ + typedef enum { EXPR_INT_LITERAL, EXPR_FLOAT_LITERAL, EXPR_IDENT, /* variable or constant */ EXPR_BINARY_OP, - EXPR_UNARY_OP + EXPR_UNARY_OP, + EXPR_FN } ExprKind; typedef enum { @@ -64,6 +76,7 @@ typedef struct Expression { struct Expression *rhs; } binary; Identifier ident; + FnExpr fn; }; } Expression; @@ -169,6 +182,35 @@ static bool type_parse(Type *type, Parser *p) { return false; } +static bool fn_expr_parse(FnExpr *f, Parser *p) { + Tokenizer *t = p->tokr; + /* only called when token is fn */ + assert(token_is_kw(t->token, KW_FN)); + t->token++; + if (!token_is_kw(t->token, KW_LPAREN)) { + tokr_err(t, "Expected '(' after 'fn'."); + return false; + } + + t->token++; + if (!token_is_kw(t->token, KW_RPAREN)) { + tokr_err(t, "Expected ')' at end of parameter list."); + return false; + } + t->token++; + if (!token_is_kw(t->token, KW_LBRACE)) { + tokr_err(t, "Expected '{' to open function body."); + return false; + } + t->token++; + if (!token_is_kw(t->token, KW_RBRACE)) { + tokr_err(t, "Expected '}' to close function body."); + return false; + } + t->token++; + return true; +} + #define NOT_AN_OP -1 static int op_precedence(Keyword op) { switch (op) { @@ -276,7 +318,18 @@ static bool expr_parse(Expression *e, Parser *p, Token *end) { } if (lowest_precedence == NOT_AN_OP) { /* function calls, array accesses, etc. */ - tokr_err(t, "Not implemented yet."); + if (token_is_kw(t->token, KW_FN)) { + /* this is a function */ + e->kind = EXPR_FN; + if (!fn_expr_parse(&e->fn, p)) + return false; + if (t->token != end) { + tokr_err(t, "Direct function calling in an expression is not supported yet."); + /* TODO */ + return false; + } + return true; + } return false; } @@ -534,6 +587,9 @@ static void expr_fprint(FILE *out, Expression *e) { expr_fprint(out, e->unary.of); fprintf(out, ")"); break; + case EXPR_FN: + fprintf(out, "function!"); + break; } } @@ -1 +1,4 @@ x :- 3 + 4 - (3 + ((-3--b-5)+6++8)---+a+-4); +main :- fn () { + +}; diff --git a/tokenizer.c b/tokenizer.c index 5dbd9f4..d905bc8 100644 --- a/tokenizer.c +++ b/tokenizer.c @@ -193,8 +193,9 @@ static void tokenization_err(Tokenizer *t, const char *fmt, ...) { } /* to be used after tokenization */ -static void tokr_err(Tokenizer *t, const char *fmt, ...) { +static void tokr_err_(const char *src_file, int src_line, Tokenizer *t, const char *fmt, ...) { LineNo line = t->token->where.line; + err_fprint("At line %d of %s:\n", src_line, src_file); /* RELEASE: Remove this */ va_list args; va_start(args, fmt); err_vprint(line, t->token->where.code, fmt, args); @@ -205,6 +206,7 @@ static void tokr_err(Tokenizer *t, const char *fmt, ...) { t->token++; } } +#define tokr_err(...) tokr_err_(__FILE__, __LINE__, __VA_ARGS__) static void tokr_put_location(Tokenizer *tokr, Token *t) { t->where.line = tokr->line; |