From 8bf32ac697ea21ff3b37e5b31fe0fc10e700c9a4 Mon Sep 17 00:00:00 2001 From: gingerBill Date: Mon, 22 May 2023 12:53:29 +0100 Subject: Minor change to handling of propagation of errors with `---` as a value --- src/parser.cpp | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) (limited to 'src/parser.cpp') diff --git a/src/parser.cpp b/src/parser.cpp index 698ba99ab..bb492fca9 100644 --- a/src/parser.cpp +++ b/src/parser.cpp @@ -115,7 +115,7 @@ gb_internal Ast *clone_ast(Ast *node, AstFile *f) { n->Ident.entity = nullptr; break; case Ast_Implicit: break; - case Ast_Undef: break; + case Ast_Uninit: break; case Ast_BasicLit: break; case Ast_BasicDirective: break; @@ -646,9 +646,9 @@ gb_internal Ast *ast_implicit(AstFile *f, Token token) { result->Implicit = token; return result; } -gb_internal Ast *ast_undef(AstFile *f, Token token) { - Ast *result = alloc_ast_node(f, Ast_Undef); - result->Undef = token; +gb_internal Ast *ast_uninit(AstFile *f, Token token) { + Ast *result = alloc_ast_node(f, Ast_Uninit); + result->Uninit = token; return result; } @@ -2092,8 +2092,8 @@ gb_internal Ast *parse_operand(AstFile *f, bool lhs) { case Token_Ident: return parse_ident(f); - case Token_Undef: - return ast_undef(f, expect_token(f, Token_Undef)); + case Token_Uninit: + return ast_uninit(f, expect_token(f, Token_Uninit)); case Token_context: return ast_implicit(f, expect_token(f, Token_context)); @@ -2292,7 +2292,7 @@ gb_internal Ast *parse_operand(AstFile *f, bool lhs) { skip_possible_newline_for_literal(f); - if (allow_token(f, Token_Undef)) { + if (allow_token(f, Token_Uninit)) { if (where_token.kind != Token_Invalid) { syntax_error(where_token, "'where' clauses are not allowed on procedure literals without a defined body (replaced with ---)"); } -- cgit v1.2.3 From d2f62730bc26fd18355de3c86d2d825a221aa288 Mon Sep 17 00:00:00 2001 From: gingerBill Date: Mon, 29 May 2023 14:55:27 +0100 Subject: Fix #2560 --- src/parser.cpp | 14 ++++++++++++-- 1 file changed, 12 insertions(+), 2 deletions(-) (limited to 'src/parser.cpp') diff --git a/src/parser.cpp b/src/parser.cpp index bb492fca9..1b48dce87 100644 --- a/src/parser.cpp +++ b/src/parser.cpp @@ -3744,8 +3744,18 @@ gb_internal bool allow_field_separator(AstFile *f) { if (allow_token(f, Token_Comma)) { return true; } - if (ALLOW_NEWLINE && token.kind == Token_Semicolon) { - if (!token_is_newline(token)) { + if (token.kind == Token_Semicolon) { + bool ok = false; + if (ALLOW_NEWLINE && token_is_newline(token)) { + TokenKind next = peek_token(f).kind; + switch (next) { + case Token_CloseBrace: + case Token_CloseParen: + ok = true; + break; + } + } + if (!ok) { String p = token_to_string(token); syntax_error(token_end_of_line(f, f->prev_token), "Expected a comma, got a %.*s", LIT(p)); } -- cgit v1.2.3 From 97490c6445cb3ba85f470e64e6ed6d24394c421a Mon Sep 17 00:00:00 2001 From: gingerBill Date: Mon, 29 May 2023 23:17:06 +0100 Subject: Basic support for `#reverse for in` on normal arrays --- src/check_stmt.cpp | 21 ++++++++++++++++ src/llvm_backend_stmt.cpp | 64 ++++++++++++++++++++++++++++++++++------------- src/parser.cpp | 11 ++++++++ src/parser.hpp | 1 + 4 files changed, 79 insertions(+), 18 deletions(-) (limited to 'src/parser.cpp') diff --git a/src/check_stmt.cpp b/src/check_stmt.cpp index 6c69ad59f..c64de40c7 100644 --- a/src/check_stmt.cpp +++ b/src/check_stmt.cpp @@ -1461,6 +1461,7 @@ gb_internal void check_range_stmt(CheckerContext *ctx, Ast *node, u32 mod_flags) bool is_map = false; bool use_by_reference_for_value = false; bool is_soa = false; + bool is_reverse = rs->reverse; Ast *expr = unparen_expr(rs->expr); @@ -1476,6 +1477,10 @@ gb_internal void check_range_stmt(CheckerContext *ctx, Ast *node, u32 mod_flags) } array_add(&vals, x.type); array_add(&vals, t_int); + + if (is_reverse) { + error(node, "#reverse for is not yet supported with ranges"); + } } else { Operand operand = {Addressing_Invalid}; check_expr_base(ctx, &operand, expr, nullptr); @@ -1488,6 +1493,9 @@ gb_internal void check_range_stmt(CheckerContext *ctx, Ast *node, u32 mod_flags) gb_string_free(t); goto skip_expr_range_stmt; } else { + if (is_reverse) { + error(node, "#reverse for is not supported for enum types"); + } array_add(&vals, operand.type); array_add(&vals, t_int); add_type_info_type(ctx, operand.type); @@ -1503,6 +1511,9 @@ gb_internal void check_range_stmt(CheckerContext *ctx, Ast *node, u32 mod_flags) array_add(&vals, t_int); add_package_dependency(ctx, "runtime", "string_decode_rune"); } + if (is_reverse) { + error(node, "#reverse for is not supported for string types"); + } break; case Type_EnumeratedArray: @@ -1534,6 +1545,9 @@ gb_internal void check_range_stmt(CheckerContext *ctx, Ast *node, u32 mod_flags) is_map = true; array_add(&vals, t->Map.key); array_add(&vals, t->Map.value); + if (is_reverse) { + error(node, "#reverse for is not supported for map types"); + } break; case Type_Tuple: @@ -1570,6 +1584,9 @@ gb_internal void check_range_stmt(CheckerContext *ctx, Ast *node, u32 mod_flags) break; } + if (is_reverse) { + error(node, "#reverse for is not supported for multiple return valued parameters"); + } } break; @@ -1579,6 +1596,10 @@ gb_internal void check_range_stmt(CheckerContext *ctx, Ast *node, u32 mod_flags) if (is_ptr) use_by_reference_for_value = true; array_add(&vals, t->Struct.soa_elem); array_add(&vals, t_int); + + if (is_reverse) { + error(node, "#reverse for is not yet supported for #soa types"); + } } break; } diff --git a/src/llvm_backend_stmt.cpp b/src/llvm_backend_stmt.cpp index 125913ac5..60468c7f0 100644 --- a/src/llvm_backend_stmt.cpp +++ b/src/llvm_backend_stmt.cpp @@ -249,7 +249,8 @@ gb_internal void lb_build_when_stmt(lbProcedure *p, AstWhenStmt *ws) { gb_internal void lb_build_range_indexed(lbProcedure *p, lbValue expr, Type *val_type, lbValue count_ptr, - lbValue *val_, lbValue *idx_, lbBlock **loop_, lbBlock **done_) { + lbValue *val_, lbValue *idx_, lbBlock **loop_, lbBlock **done_, + bool is_reverse) { lbModule *m = p->module; lbValue count = {}; @@ -267,23 +268,50 @@ gb_internal void lb_build_range_indexed(lbProcedure *p, lbValue expr, Type *val_ lbBlock *body = nullptr; - lbAddr index = lb_add_local_generated(p, t_int, false); - lb_addr_store(p, index, lb_const_int(m, t_int, cast(u64)-1)); + lbAddr index = {}; + lbValue incr = {}; + lbValue cond = {}; - loop = lb_create_block(p, "for.index.loop"); - lb_emit_jump(p, loop); - lb_start_block(p, loop); + index = lb_add_local_generated(p, t_int, false); - lbValue incr = lb_emit_arith(p, Token_Add, lb_addr_load(p, index), lb_const_int(m, t_int, 1), t_int); - lb_addr_store(p, index, incr); + if (!is_reverse) { + lb_addr_store(p, index, lb_const_int(m, t_int, cast(u64)-1)); - body = lb_create_block(p, "for.index.body"); - done = lb_create_block(p, "for.index.done"); - if (count.value == nullptr) { - GB_ASSERT(count_ptr.value != nullptr); - count = lb_emit_load(p, count_ptr); + loop = lb_create_block(p, "for.index.loop"); + lb_emit_jump(p, loop); + lb_start_block(p, loop); + + incr = lb_emit_arith(p, Token_Add, lb_addr_load(p, index), lb_const_int(m, t_int, 1), t_int); + lb_addr_store(p, index, incr); + + body = lb_create_block(p, "for.index.body"); + done = lb_create_block(p, "for.index.done"); + if (count.value == nullptr) { + GB_ASSERT(count_ptr.value != nullptr); + count = lb_emit_load(p, count_ptr); + } + cond = lb_emit_comp(p, Token_Lt, incr, count); + } else { + // NOTE(bill): REVERSED LOGIC + if (count.value == nullptr) { + GB_ASSERT(count_ptr.value != nullptr); + count = lb_emit_load(p, count_ptr); + } + count = lb_emit_conv(p, count, t_int); + lb_addr_store(p, index, count); + + loop = lb_create_block(p, "for.index.loop"); + lb_emit_jump(p, loop); + lb_start_block(p, loop); + + incr = lb_emit_arith(p, Token_Sub, lb_addr_load(p, index), lb_const_int(m, t_int, 1), t_int); + lb_addr_store(p, index, incr); + + body = lb_create_block(p, "for.index.body"); + done = lb_create_block(p, "for.index.done"); + cond = lb_emit_comp(p, Token_GtEq, incr, lb_const_int(m, t_int, 0)); } - lbValue cond = lb_emit_comp(p, Token_Lt, incr, count); + lb_emit_if(p, cond, body, done); lb_start_block(p, body); @@ -820,7 +848,7 @@ gb_internal void lb_build_range_stmt(lbProcedure *p, AstRangeStmt *rs, Scope *sc } lbAddr count_ptr = lb_add_local_generated(p, t_int, false); lb_addr_store(p, count_ptr, lb_const_int(p->module, t_int, et->Array.count)); - lb_build_range_indexed(p, array, val0_type, count_ptr.addr, &val, &key, &loop, &done); + lb_build_range_indexed(p, array, val0_type, count_ptr.addr, &val, &key, &loop, &done, rs->reverse); break; } case Type_EnumeratedArray: { @@ -830,7 +858,7 @@ gb_internal void lb_build_range_stmt(lbProcedure *p, AstRangeStmt *rs, Scope *sc } lbAddr count_ptr = lb_add_local_generated(p, t_int, false); lb_addr_store(p, count_ptr, lb_const_int(p->module, t_int, et->EnumeratedArray.count)); - lb_build_range_indexed(p, array, val0_type, count_ptr.addr, &val, &key, &loop, &done); + lb_build_range_indexed(p, array, val0_type, count_ptr.addr, &val, &key, &loop, &done, rs->reverse); break; } case Type_DynamicArray: { @@ -840,7 +868,7 @@ gb_internal void lb_build_range_stmt(lbProcedure *p, AstRangeStmt *rs, Scope *sc array = lb_emit_load(p, array); } count_ptr = lb_emit_struct_ep(p, array, 1); - lb_build_range_indexed(p, array, val0_type, count_ptr, &val, &key, &loop, &done); + lb_build_range_indexed(p, array, val0_type, count_ptr, &val, &key, &loop, &done, rs->reverse); break; } case Type_Slice: { @@ -853,7 +881,7 @@ gb_internal void lb_build_range_stmt(lbProcedure *p, AstRangeStmt *rs, Scope *sc count_ptr = lb_add_local_generated(p, t_int, false).addr; lb_emit_store(p, count_ptr, lb_slice_len(p, slice)); } - lb_build_range_indexed(p, slice, val0_type, count_ptr, &val, &key, &loop, &done); + lb_build_range_indexed(p, slice, val0_type, count_ptr, &val, &key, &loop, &done, rs->reverse); break; } case Type_Basic: { diff --git a/src/parser.cpp b/src/parser.cpp index 1b48dce87..afdb1078d 100644 --- a/src/parser.cpp +++ b/src/parser.cpp @@ -4759,6 +4759,17 @@ gb_internal Ast *parse_stmt(AstFile *f) { return stmt; } else if (tag == "unroll") { return parse_unrolled_for_loop(f, name); + } else if (tag == "reverse") { + Ast *for_stmt = parse_for_stmt(f); + if (for_stmt->kind == Ast_RangeStmt) { + if (for_stmt->RangeStmt.reverse) { + syntax_error(token, "#reverse already applied to a 'for in' statement"); + } + for_stmt->RangeStmt.reverse = true; + } else { + syntax_error(token, "#reverse can only be applied to a 'for in' statement"); + } + return for_stmt; } else if (tag == "include") { syntax_error(token, "#include is not a valid import declaration kind. Did you mean 'import'?"); s = ast_bad_stmt(f, token, f->curr_token); diff --git a/src/parser.hpp b/src/parser.hpp index d4883f287..6ba4ef6d6 100644 --- a/src/parser.hpp +++ b/src/parser.hpp @@ -529,6 +529,7 @@ AST_KIND(_ComplexStmtBegin, "", bool) \ Token in_token; \ Ast *expr; \ Ast *body; \ + bool reverse; \ }) \ AST_KIND(UnrollRangeStmt, "#unroll range statement", struct { \ Scope *scope; \ -- cgit v1.2.3 From 5376d32772186c5d676eb3718c67ac32fd662f7c Mon Sep 17 00:00:00 2001 From: gingerBill Date: Tue, 30 May 2023 23:06:04 +0100 Subject: Parse leading comment above attribute for value declarations --- src/parser.cpp | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) (limited to 'src/parser.cpp') diff --git a/src/parser.cpp b/src/parser.cpp index afdb1078d..c19e3f859 100644 --- a/src/parser.cpp +++ b/src/parser.cpp @@ -4519,7 +4519,7 @@ gb_internal Ast *parse_foreign_decl(AstFile *f) { return ast_bad_decl(f, token, f->curr_token); } -gb_internal Ast *parse_attribute(AstFile *f, Token token, TokenKind open_kind, TokenKind close_kind) { +gb_internal Ast *parse_attribute(AstFile *f, Token token, TokenKind open_kind, TokenKind close_kind, CommentGroup *docs) { Array elems = {}; Token open = {}; Token close = {}; @@ -4560,6 +4560,9 @@ gb_internal Ast *parse_attribute(AstFile *f, Token token, TokenKind open_kind, T Ast *decl = parse_stmt(f); if (decl->kind == Ast_ValueDecl) { + if (decl->ValueDecl.docs == nullptr && docs != nullptr) { + decl->ValueDecl.docs = docs; + } array_add(&decl->ValueDecl.attributes, attribute); } else if (decl->kind == Ast_ForeignBlockDecl) { array_add(&decl->ForeignBlockDecl.attributes, attribute); @@ -4708,8 +4711,9 @@ gb_internal Ast *parse_stmt(AstFile *f) { } break; case Token_At: { + CommentGroup *docs = f->lead_comment; Token token = expect_token(f, Token_At); - return parse_attribute(f, token, Token_OpenParen, Token_CloseParen); + return parse_attribute(f, token, Token_OpenParen, Token_CloseParen, docs); } case Token_Hash: { -- cgit v1.2.3