diff options
-rw-r--r-- | main.c | 2 | ||||
-rw-r--r-- | parse.c | 16 | ||||
-rw-r--r-- | std/io.toc | 6 | ||||
-rw-r--r-- | test.toc | 11 |
4 files changed, 15 insertions, 20 deletions
@@ -8,8 +8,6 @@ /* TODO: -allow omission of trailing ; in foo ::= fn() {...} or foo ::= nms {...} or foo ::= struct { ... } -- just end expressions when you get to a closing brace unless there's an elif, etc. break continue switch @@ -341,7 +341,6 @@ static Token *expr_find_end(Parser *p, ExprEndFlags flags) { int brace_level = 0; int square_level = 0; Token *token = t->token; - bool could_be_vbs = false; /* could this be a void block statement (whose semicolons can be omitted)? e.g. {x := 5;} */ while (1) { bool all_levels_0 = paren_level == 0 && brace_level == 0 && square_level == 0; if (token->kind == TOKEN_KW) { @@ -370,12 +369,10 @@ static Token *expr_find_end(Parser *p, ExprEndFlags flags) { if ((flags & EXPR_CAN_END_WITH_LBRACE) && square_level == 0 && paren_level == 0) return token; ++brace_level; - could_be_vbs = true; break; case KW_RBRACE: --brace_level; - if (paren_level == 0 && brace_level == 0 && square_level == 0 - && could_be_vbs && !token_is_kw(token + 1, KW_RPAREN)) { + if (paren_level == 0 && brace_level == 0 && square_level == 0) { /* if there's an else/elif, the expr must continue */ if (!(token_is_kw(token + 1, KW_ELSE) || token_is_kw(token + 1, KW_ELIF))) return token + 1; /* token afer } is end */ @@ -386,7 +383,6 @@ static Token *expr_find_end(Parser *p, ExprEndFlags flags) { case KW_SEMICOLON: if (brace_level == 0) return token; - could_be_vbs = true; break; case KW_DOTDOT: if (all_levels_0 && (flags & EXPR_CAN_END_WITH_DOTDOT)) @@ -401,10 +397,6 @@ static Token *expr_find_end(Parser *p, ExprEndFlags flags) { return token; default: break; } - if (token->kw != KW_RBRACE && token->kw != KW_SEMICOLON && token->kw != KW_LBRACE) - could_be_vbs = false; - } else { - could_be_vbs = false; } if (token->kind == TOKEN_EOF) { if (brace_level > 0) { @@ -2352,7 +2344,7 @@ static Status parse_decl(Parser *p, Declaration *d, DeclEndKind ends_with, U16 f goto ret_false; } Token *end = expr_find_end(p, expr_flags); - if (!end || !ends_decl(end, ends_with)) { + if (!end) { if (end) t->token = end; tokr_err(t, "Expected %s at end of declaration.", end_str); goto ret_false; @@ -2361,7 +2353,9 @@ static Status parse_decl(Parser *p, Declaration *d, DeclEndKind ends_with, U16 f t->token = end; /* move to ; */ goto ret_false; } - if (ends_decl(t->token, ends_with)) { + if (ends_with == DECL_END_SEMICOLON && end > t->tokens && token_is_kw(end - 1, KW_RBRACE)) { + /* allow semicolon to be ommitted, e.g. f ::= fn() {} */ + } else if (ends_decl(t->token, ends_with)) { ++t->token; } else { tokr_err(t, "Expected %s at end of declaration.", end_str); @@ -1,7 +1,7 @@ putchar ::= #foreign("putchar", "libc.so.6") fn(#C int) #C int; toc_putchar ::= fn(x: char) { putchar(x as #C int); -}; +} puts ::= fn(x: []char) { @@ -9,7 +9,7 @@ puts ::= fn(x: []char) { toc_putchar(c); } toc_putchar('\n'); -}; +} puti ::= fn(x: int) { if x < 0 { @@ -32,4 +32,4 @@ puti ::= fn(x: int) { } } toc_putchar('\n'); -}; +} @@ -1,3 +1,4 @@ + printf ::= #foreign("printf","libc.so.6") fn(#C &"const char", #C ..) #C int; @@ -19,7 +20,7 @@ tprintf_valid ::= fn(fmt :: []char, nargs: int) bool { } } count == nargs -}; +} tprintf ::= fn(fmt :: []char, args: ..) { @@ -28,8 +29,10 @@ tprintf ::= fn(fmt :: []char, args: ..) { } f := fmt; printf(&f[0], args); -}; +} main ::= fn() { - tprintf("%d %d%%\n", 3, 4); -}; + tprintf("%d %d%%\n\0", 3, 4); +} + +main();
\ No newline at end of file |