mutable decl syntax change

This commit is contained in:
2026-08-05 21:19:41 +02:00
parent 88b94197c9
commit 081a3fd5df
74 changed files with 870 additions and 733 deletions
+45 -8
View File
@@ -1868,15 +1868,35 @@ parse_statement :: proc(parser: ^Parser) -> ast.Stmt_Id {
had_type = true
}
operator := current(parser)
if operator.kind == .Colon_Colon || operator.kind == .Equal {
if had_type && operator.kind == .Equal {
diagnostic := source.add(
parser.diagnostics,
operator.span,
"mutable declarations use ':=' instead of '='",
)
for current(parser).kind != .Newline &&
current(parser).kind != .Right_Brace &&
current(parser).kind != .Eof {
advance(parser)
}
id := ast.stmt_id(len(parser.module.statements))
append(&parser.module.statements, ast.Stmt{
kind=.Invalid,
span=span_from(name.span, operator.span),
expr=ast.INVALID_EXPR,
diagnostic=diagnostic,
})
return id
}
is_sink := name.kind == .Underscore && operator.kind == .Equal
if operator.kind == .Colon_Colon || operator.kind == .Colon_Equal || is_sink {
advance(parser)
skip_newlines(parser)
kind := ast.Stmt_Kind.Assignment
immutable := false
if operator.kind == .Colon_Colon || had_type {
kind = .Declaration
immutable = operator.kind == .Colon_Colon
kind := ast.Stmt_Kind.Declaration
if is_sink {
kind = .Assignment
}
immutable := operator.kind == .Colon_Colon
// A labeled value block (`x :: blk: { … yield :blk v }`): the label lets a
// `yield :blk` exit the block past a nested `if`. Block-init body + label.
if current(parser).kind == .Identifier && peek(parser).kind == .Colon {
@@ -1954,6 +1974,11 @@ parse_statement :: proc(parser: ^Parser) -> ast.Stmt_Id {
}
expr := parse_expression(parser)
assignment_name := symbol.INVALID
target_expr := parser.module.exprs[expr]
if target_expr.kind == .Name && !symbol.is_valid(target_expr.qualifier) {
assignment_name = target_expr.name
}
if _, ok := allow(parser, .Equal); ok {
skip_newlines(parser)
// A labeled value block assigned to a complex target (`a[i] = blk: { … }`).
@@ -1964,6 +1989,7 @@ parse_statement :: proc(parser: ^Parser) -> ast.Stmt_Id {
append(&parser.module.statements, ast.Stmt{
kind=.Assignment,
span=span_from(parser.module.exprs[expr].span, previous(parser).span),
name=assignment_name,
target=expr,
label=label,
expr=ast.INVALID_EXPR,
@@ -1980,6 +2006,7 @@ parse_statement :: proc(parser: ^Parser) -> ast.Stmt_Id {
append(&parser.module.statements, ast.Stmt{
kind=.Assignment,
span=span_from(parser.module.exprs[expr].span, brace.span),
name=assignment_name,
target=expr,
expr=ast.INVALID_EXPR,
body=body,
@@ -1995,6 +2022,7 @@ parse_statement :: proc(parser: ^Parser) -> ast.Stmt_Id {
append(&parser.module.statements, ast.Stmt{
kind=.Assignment,
span=span_from(parser.module.exprs[expr].span, previous(parser).span),
name=assignment_name,
target=expr,
value_control_flow=true,
expr=ast.INVALID_EXPR,
@@ -2008,6 +2036,7 @@ parse_statement :: proc(parser: ^Parser) -> ast.Stmt_Id {
append(&parser.module.statements, ast.Stmt{
kind=.Assignment,
span=span_from(parser.module.exprs[expr].span, parser.module.exprs[value].span),
name=assignment_name,
target=expr,
expr=value,
diagnostic=source.INVALID_DIAGNOSTIC,
@@ -3312,8 +3341,16 @@ parse_top_level :: proc(parser: ^Parser) {
type_syntax = parse_type(parser)
}
operator := current(parser)
if operator.kind != .Colon_Colon && operator.kind != .Equal {
source.add(parser.diagnostics, operator.span, "expected '::' or '=' after top-level name")
if operator.kind == .Equal {
source.add(parser.diagnostics, operator.span, "mutable declarations use ':=' instead of '='")
for current(parser).kind != .Newline && current(parser).kind != .Eof {
advance(parser)
}
_ = finish_statement(parser)
return
}
if operator.kind != .Colon_Colon && operator.kind != .Colon_Equal {
source.add(parser.diagnostics, operator.span, "expected '::' or ':=' after top-level name")
_ = finish_statement(parser)
return
}