From 37198812016cf53ca2b3fb832d8d09d528f81098 Mon Sep 17 00:00:00 2001 From: Camil Staps Date: Thu, 6 Oct 2016 17:23:17 +0200 Subject: List notation shortcut (resolves #5) --- doc/grammar.tex | 5 ++++- examples/list-test.fusp | 4 ++-- interpreter/parse.c | 58 +++++++++++++++++++++++++++++++++++-------------- 3 files changed, 48 insertions(+), 19 deletions(-) diff --git a/doc/grammar.tex b/doc/grammar.tex index 00e24b8..111cfc8 100644 --- a/doc/grammar.tex +++ b/doc/grammar.tex @@ -24,8 +24,11 @@ \alt \alt - ::= `[' `:' `]' + ::= `[' `:' `]' + \alt `[' `]' \alt `[]' + + ::= `,' | ::= `(' `,' `)' diff --git a/examples/list-test.fusp b/examples/list-test.fusp index d90a252..f4b5755 100644 --- a/examples/list-test.fusp +++ b/examples/list-test.fusp @@ -1,4 +1,4 @@ import list; -main = flatten [[1:[2:[3:[]]]]:[[4:[5:[6:[]]]]:[]]]; -main = append [1:[2:[3:[]]]] [4:[5:[6:[]]]]; +main = append [1,2,3] [4,5,6]; +main = flatten [[1,2,3],[4,5,6]]; diff --git a/interpreter/parse.c b/interpreter/parse.c index e0953d1..bdfd968 100644 --- a/interpreter/parse.c +++ b/interpreter/parse.c @@ -156,7 +156,6 @@ token_list* parse_expression_no_app(expression* expr, token_list* list) { free_expression(expr); } } else if (list->elem.kind == TOKEN_OPEN_SQ) { - expression *expr1, *expr2; token_list* _list; expr->kind = EXPR_LIST; @@ -165,24 +164,51 @@ token_list* parse_expression_no_app(expression* expr, token_list* list) { return list->rest->rest; } - expr1 = my_calloc(1, sizeof(expression)); - expr2 = my_calloc(1, sizeof(expression)); + expr->var1 = my_calloc(1, sizeof(expression)); + expr->var2 = my_calloc(1, sizeof(expression)); - _list = parse_expression(expr1, list->rest); - if (!_list || _list->elem.kind != TOKEN_COLON) { - free_expression(expr1); - my_free(expr1); - my_free(expr2); - } else { - _list = parse_expression(expr2, _list->rest); + _list = parse_expression(expr->var1, list->rest); + if (!_list || + (_list->elem.kind != TOKEN_COLON && + _list->elem.kind != TOKEN_COMMA && + _list->elem.kind != TOKEN_CLOSE_SQ)) { + free_expression(expr); + } else if (_list->elem.kind == TOKEN_CLOSE_SQ) { + ((expression *) expr->var2)->kind = EXPR_LIST; + ((expression *) expr->var2)->var1 = NULL; + ((expression *) expr->var2)->var2 = NULL; + return _list->rest; + } else if (_list->elem.kind == TOKEN_COMMA) { + expression* _expr = expr; + while (_list && _list->elem.kind == TOKEN_COMMA) { + _expr = _expr->var2; + _expr->kind = EXPR_LIST; + _expr->var1 = my_calloc(1, sizeof(expression)); + _expr->var2 = my_calloc(1, sizeof(expression)); + _list = parse_expression(_expr->var1, _list->rest); + } + if (!_list || + (_list->elem.kind != TOKEN_CLOSE_SQ && + _list->elem.kind != TOKEN_COLON)) { + free_expression(expr); + } else if (_list->elem.kind == TOKEN_COLON) { + _list = parse_expression(((expression*) expr->var2)->var2, _list->rest); + if (!_list || _list->elem.kind != TOKEN_CLOSE_SQ) { + free_expression(expr); + } else { + return _list->rest; + } + } else if (_list->elem.kind == TOKEN_CLOSE_SQ) { + ((expression*) _expr->var2)->kind = EXPR_LIST; + ((expression*) _expr->var2)->var1 = NULL; + ((expression*) _expr->var2)->var2 = NULL; + return _list->rest; + } + } else if (_list->elem.kind == TOKEN_COLON) { + _list = parse_expression(expr->var2, _list->rest); if (!_list || _list->elem.kind != TOKEN_CLOSE_SQ) { - free_expression(expr1); - free_expression(expr2); - my_free(expr1); - my_free(expr2); + free_expression(expr); } else { - expr->var1 = expr1; - expr->var2 = expr2; return _list->rest; } } -- cgit v1.2.3