diff options
| author | gingerBill <bill@gingerbill.org> | 2022-03-24 12:00:27 +0000 |
|---|---|---|
| committer | gingerBill <bill@gingerbill.org> | 2022-03-24 12:00:27 +0000 |
| commit | 13cb894b309faa2dc66b77f1aa4e89fdffba9512 (patch) | |
| tree | 82feaba0980ccd546229640426d115e9fa37c00e | |
| parent | 3f935bea2505b3ee7e169a29b7aed50c0e5614b7 (diff) | |
Update `core:odin` for `union #shared_nil`
| -rw-r--r-- | core/odin/ast/ast.odin | 10 | ||||
| -rw-r--r-- | core/odin/parser/parser.odin | 32 | ||||
| -rw-r--r-- | core/odin/printer/visit.odin | 7 |
3 files changed, 41 insertions, 8 deletions
diff --git a/core/odin/ast/ast.odin b/core/odin/ast/ast.odin index 740299539..f4aa67446 100644 --- a/core/odin/ast/ast.odin +++ b/core/odin/ast/ast.odin @@ -708,13 +708,19 @@ Struct_Type :: struct { name_count: int, } +Union_Type_Kind :: enum u8 { + Normal, + maybe, + no_nil, + shared_nil, +} + Union_Type :: struct { using node: Expr, tok_pos: tokenizer.Pos, poly_params: ^Field_List, align: ^Expr, - is_maybe: bool, - is_no_nil: bool, + kind: Union_Type_Kind, where_token: tokenizer.Token, where_clauses: []^Expr, variants: []^Expr, diff --git a/core/odin/parser/parser.odin b/core/odin/parser/parser.odin index 1546dce2d..4be14f2cf 100644 --- a/core/odin/parser/parser.odin +++ b/core/odin/parser/parser.odin @@ -2630,8 +2630,9 @@ parse_operand :: proc(p: ^Parser, lhs: bool) -> ^ast.Expr { tok := expect_token(p, .Union) poly_params: ^ast.Field_List align: ^ast.Expr - is_maybe: bool - is_no_nil: bool + is_maybe: bool + is_no_nil: bool + is_shared_nil: bool if allow_token(p, .Open_Paren) { param_count: int @@ -2663,12 +2664,34 @@ parse_operand :: proc(p: ^Parser, lhs: bool) -> ^ast.Expr { error(p, tag.pos, "duplicate union tag '#%s'", tag.text) } is_no_nil = true + case "shared_nil": + if is_shared_nil { + error(p, tag.pos, "duplicate union tag '#%s'", tag.text) + } + is_shared_nil = true case: error(p, tag.pos, "invalid union tag '#%s", tag.text) } } p.expr_level = prev_level + if is_no_nil && is_maybe { + error(p, p.curr_tok.pos, "#maybe and #no_nil cannot be applied together"); + } + if is_no_nil && is_shared_nil { + error(p, p.curr_tok.pos, "#shared_nil and #no_nil cannot be applied together"); + } + if is_shared_nil && is_maybe { + error(p, p.curr_tok.pos, "#maybe and #shared_nil cannot be applied together"); + } + + union_kind := ast.Union_Type_Kind.Normal + switch { + case is_maybe: union_kind = .maybe + case is_no_nil: union_kind = .no_nil + case is_shared_nil: union_kind = .shared_nil + } + where_token: tokenizer.Token where_clauses: []^ast.Expr @@ -2699,14 +2722,15 @@ parse_operand :: proc(p: ^Parser, lhs: bool) -> ^ast.Expr { close := expect_closing_brace_of_field_list(p) + + ut := ast.new(ast.Union_Type, tok.pos, end_pos(close)) ut.poly_params = poly_params ut.variants = variants[:] ut.align = align ut.where_token = where_token ut.where_clauses = where_clauses - ut.is_maybe = is_maybe - ut.is_no_nil = is_no_nil + ut.kind = union_kind return ut diff --git a/core/odin/printer/visit.odin b/core/odin/printer/visit.odin index 9eba29987..70140f180 100644 --- a/core/odin/printer/visit.odin +++ b/core/odin/printer/visit.odin @@ -1046,8 +1046,11 @@ visit_expr :: proc(p: ^Printer, expr: ^ast.Expr, options := List_Options{}) { push_poly_params(p, v.poly_params)
- if v.is_maybe {
- push_ident_token(p, "#maybe", 1)
+ switch v.kind {
+ case .Normal:
+ case .maybe: push_ident_token(p, "#maybe", 1)
+ case .no_nil: push_ident_token(p, "#no_nil", 1)
+ case .shared_nil: push_ident_token(p, "#shared_nil", 1)
}
push_where_clauses(p, v.where_clauses)
|