diff --git a/lib/std/core/string.c3 b/lib/std/core/string.c3 index a29e45130..60b0d7fb1 100644 --- a/lib/std/core/string.c3 +++ b/lib/std/core/string.c3 @@ -200,7 +200,7 @@ fn void String.destroy(String* str) *str = (String)null; } -fn bool String.less_than(String* str, String other_string) +fn bool String.less(String* str, String other_string) { StringData* str1 = str.data(); StringData* str2 = other_string.data(); @@ -255,6 +255,23 @@ fn void String.append_char(String* str, char c) data.chars[data.len++] = c; } +macro void String.@append(String &str, value) +{ + $switch ($typeof(value)): + $case char: + str.append_char(value); + $case String: + str.append_string(value); + $case char[]: + str.append(value); + $case char32: + str.append_char32(value); + $default: + $assert("Unsupported type for appending"); + $endswitch; +} + + private fn StringData* String.data(String* str) @inline { return (StringData*)*str; diff --git a/src/compiler/parse_global.c b/src/compiler/parse_global.c index 5e7ea9508..ee789181a 100644 --- a/src/compiler/parse_global.c +++ b/src/compiler/parse_global.c @@ -138,7 +138,7 @@ static inline Decl *parse_ct_if_top_level(ParseContext *c) if (!parse_top_level_block(c, &ct_else->ct_else_decl, TOKEN_CT_ENDIF, TOKEN_CT_ENDIF, TOKEN_CT_ENDIF)) return poisoned_decl; } CONSUME_OR_RET(TOKEN_CT_ENDIF, poisoned_decl); - CONSUME_OR_RET(TOKEN_EOS, poisoned_decl); + CONSUME_EOS_OR_RET(poisoned_decl); return ct; } @@ -194,7 +194,7 @@ static inline Decl *parse_ct_switch_top_level(ParseContext *c) ASSIGN_DECL_OR_RET(Decl * result, parse_ct_case(c), poisoned_decl); vec_add(ct->ct_switch_decl.cases, result); } - CONSUME_OR_RET(TOKEN_EOS, poisoned_decl); + CONSUME_EOS_OR_RET(poisoned_decl); return ct; } @@ -1325,7 +1325,7 @@ bool parse_struct_body(ParseContext *c, Decl *parent) return false; } } - CONSUME_OR_RET(TOKEN_EOS, false); + CONSUME_EOS_OR_RET(false); } advance_and_verify(c, TOKEN_RBRACE); return true; @@ -1398,7 +1398,7 @@ static inline bool parse_bitstruct_body(ParseContext *c, Decl *decl) { member_decl->var.end = NULL; } - CONSUME_OR_RET(TOKEN_EOS, false); + CONSUME_EOS_OR_RET(false); vec_add(decl->bitstruct.members, member_decl); } diff --git a/src/compiler/parse_stmt.c b/src/compiler/parse_stmt.c index 87512b5a6..f0b6a39c5 100644 --- a/src/compiler/parse_stmt.c +++ b/src/compiler/parse_stmt.c @@ -17,7 +17,7 @@ static inline Ast *parse_declaration_stmt(ParseContext *c) { Ast *decl_stmt = new_ast(AST_DECLARE_STMT, c->span); ASSIGN_DECL_OR_RET(decl_stmt->declare_stmt, parse_decl(c), poisoned_ast); - CONSUME_OR_RET(TOKEN_EOS, poisoned_ast); + CONSUME_EOS_OR_RET(poisoned_ast); return decl_stmt; } @@ -60,7 +60,7 @@ static inline Ast* parse_asm_stmt(ParseContext *c) ast->asm_stmt.is_volatile = true; CONSUME_OR_RET(TOKEN_RPAREN, poisoned_ast); RANGE_EXTEND_PREV(ast); - CONSUME_OR_RET(TOKEN_EOS, poisoned_ast); + CONSUME_EOS_OR_RET(poisoned_ast); return ast; } @@ -92,7 +92,7 @@ static inline Ast* parse_do_stmt(ParseContext *c) CONSUME_OR_RET(TOKEN_LPAREN, poisoned_ast); ASSIGN_EXPRID_OR_RET(do_ast->for_stmt.cond, parse_expr(c), poisoned_ast); CONSUME_OR_RET(TOKEN_RPAREN, poisoned_ast); - CONSUME_OR_RET(TOKEN_EOS, poisoned_ast); + CONSUME_EOS_OR_RET(poisoned_ast); } return do_ast; } @@ -232,7 +232,11 @@ static inline Ast *parse_case_stmt(ParseContext *c, TokenType case_type, TokenTy { ASSIGN_EXPR_OR_RET(ast->case_stmt.to_expr, parse_expr(c), poisoned_ast); } - TRY_CONSUME(TOKEN_COLON, "Missing ':' after case"); + if (!try_consume(c, TOKEN_COLON)) + { + sema_error_at(c->prev_span, "Missing ':' after case"); + return poisoned_ast; + } RANGE_EXTEND_PREV(ast); ASSIGN_AST_OR_RET(ast->case_stmt.body, parse_case_stmts(c, case_type, default_type), poisoned_ast); return ast; @@ -342,15 +346,14 @@ static inline Ast* parse_for_stmt(ParseContext *c) { ast->for_stmt.init = 0; } - - CONSUME_OR_RET(TOKEN_EOS, poisoned_ast); + CONSUME_EOS_OR_RET(poisoned_ast); if (!tok_is(c, TOKEN_EOS)) { ASSIGN_EXPRID_OR_RET(ast->for_stmt.cond, parse_cond(c), poisoned_ast); } - CONSUME_OR_RET(TOKEN_EOS, poisoned_ast); + CONSUME_EOS_OR_RET(poisoned_ast); if (!tok_is(c, TOKEN_RPAREN)) { @@ -495,7 +498,7 @@ static inline Ast *parse_expr_stmt(ParseContext *c) { if (!tok_is(c, TOKEN_EOS)) { - sema_error_at_after(c->prev_span, "Expected ';'"); + sema_error_at_after(c->prev_span, "Expected ';' after the expression."); return poisoned_ast; } advance(c); @@ -533,7 +536,7 @@ static inline Ast *parse_decl_or_expr_stmt(ParseContext *c) return poisoned_ast; } } - CONSUME_OR_RET(TOKEN_EOS, poisoned_ast); + CONSUME_EOS_OR_RET(poisoned_ast); return ast; } @@ -702,11 +705,11 @@ static inline Ast* parse_ct_for_stmt(ParseContext *c) { ASSIGN_EXPRID_OR_RET(ast->for_stmt.init, parse_ct_expression_list(c, true), poisoned_ast); } - CONSUME_OR_RET(TOKEN_EOS, poisoned_ast); + CONSUME_EOS_OR_RET(poisoned_ast); // Cond is required. ASSIGN_EXPRID_OR_RET(ast->for_stmt.cond, parse_expr(c), poisoned_ast); - CONSUME_OR_RET(TOKEN_EOS, poisoned_ast); + CONSUME_EOS_OR_RET(poisoned_ast); if (!tok_is(c, TOKEN_RPAREN)) {