Merge branch 'master' into parsing-package-fixes

This commit is contained in:
RilleP
2024-04-10 19:10:33 +02:00
committed by GitHub
541 changed files with 46020 additions and 30525 deletions
+31 -6
View File
@@ -597,6 +597,7 @@ Field_Flag :: enum {
Any_Int,
Subtype,
By_Ptr,
No_Broadcast,
Results,
Tags,
@@ -616,6 +617,7 @@ field_flag_strings := [Field_Flag]string{
.Any_Int = "#any_int",
.Subtype = "#subtype",
.By_Ptr = "#by_ptr",
.No_Broadcast = "#no_broadcast",
.Results = "results",
.Tags = "field tag",
@@ -624,12 +626,13 @@ field_flag_strings := [Field_Flag]string{
}
field_hash_flag_strings := []struct{key: string, flag: Field_Flag}{
{"no_alias", .No_Alias},
{"c_vararg", .C_Vararg},
{"const", .Const},
{"any_int", .Any_Int},
{"subtype", .Subtype},
{"by_ptr", .By_Ptr},
{"no_alias", .No_Alias},
{"c_vararg", .C_Vararg},
{"const", .Const},
{"any_int", .Any_Int},
{"subtype", .Subtype},
{"by_ptr", .By_Ptr},
{"no_broadcast", .No_Broadcast},
}
@@ -650,6 +653,7 @@ Field_Flags_Signature :: Field_Flags{
.Const,
.Any_Int,
.By_Ptr,
.No_Broadcast,
.Default_Parameters,
}
@@ -768,6 +772,7 @@ Struct_Type :: struct {
tok_pos: tokenizer.Pos,
poly_params: ^Field_List,
align: ^Expr,
field_align: ^Expr,
where_token: tokenizer.Token,
where_clauses: []^Expr,
is_packed: bool,
@@ -837,6 +842,23 @@ Matrix_Type :: struct {
elem: ^Expr,
}
Bit_Field_Type :: struct {
using node: Expr,
tok_pos: tokenizer.Pos,
backing_type: ^Expr,
open: tokenizer.Pos,
fields: []^Bit_Field_Field,
close: tokenizer.Pos,
}
Bit_Field_Field :: struct {
using node: Node,
docs: ^Comment_Group,
name: ^Expr,
type: ^Expr,
bit_size: ^Expr,
comments: ^Comment_Group,
}
Any_Node :: union {
^Package,
@@ -893,6 +915,7 @@ Any_Node :: union {
^Map_Type,
^Relative_Type,
^Matrix_Type,
^Bit_Field_Type,
^Bad_Stmt,
^Empty_Stmt,
@@ -923,6 +946,7 @@ Any_Node :: union {
^Attribute,
^Field,
^Field_List,
^Bit_Field_Field,
}
@@ -977,6 +1001,7 @@ Any_Expr :: union {
^Map_Type,
^Relative_Type,
^Matrix_Type,
^Bit_Field_Type,
}
+9 -1
View File
@@ -1,6 +1,6 @@
package odin_ast
import "core:intrinsics"
import "base:intrinsics"
import "core:mem"
import "core:fmt"
import "core:reflect"
@@ -314,6 +314,7 @@ clone_node :: proc(node: ^Node) -> ^Node {
case ^Struct_Type:
r.poly_params = auto_cast clone(r.poly_params)
r.align = clone(r.align)
r.field_align = clone(r.field_align)
r.fields = auto_cast clone(r.fields)
case ^Union_Type:
r.poly_params = auto_cast clone(r.poly_params)
@@ -335,6 +336,13 @@ clone_node :: proc(node: ^Node) -> ^Node {
case ^Relative_Type:
r.tag = clone(r.tag)
r.type = clone(r.type)
case ^Bit_Field_Type:
r.backing_type = clone(r.backing_type)
r.fields = auto_cast clone(r.fields)
case ^Bit_Field_Field:
r.name = clone(r.name)
r.type = clone(r.type)
r.bit_size = clone(r.bit_size)
case:
fmt.panicf("Unhandled node kind: %v", r)
}
+9 -1
View File
@@ -414,7 +414,15 @@ walk :: proc(v: ^Visitor, node: ^Node) {
walk(v, n.row_count)
walk(v, n.column_count)
walk(v, n.elem)
case ^Bit_Field_Type:
walk(v, n.backing_type)
for f in n.fields {
walk(v, f)
}
case ^Bit_Field_Field:
walk(v, n.name)
walk(v, n.type)
walk(v, n.bit_size)
case:
fmt.panicf("ast.walk: unexpected node type %T", n)
}
+16 -10
View File
@@ -10,8 +10,8 @@ Array :: struct($T: typeid) {
String :: distinct Array(byte)
Version_Type_Major :: 0
Version_Type_Minor :: 2
Version_Type_Patch :: 4
Version_Type_Minor :: 3
Version_Type_Patch :: 1
Version_Type :: struct {
major, minor, patch: u8,
@@ -102,13 +102,17 @@ Entity_Flag :: enum u32le {
Foreign = 0,
Export = 1,
Param_Using = 2, // using
Param_Const = 3, // #const
Param_Auto_Cast = 4, // auto_cast
Param_Ellipsis = 5, // Variadic parameter
Param_CVararg = 6, // #c_vararg
Param_No_Alias = 7, // #no_alias
Param_Any_Int = 8, // #any_int
Param_Using = 2, // using
Param_Const = 3, // #const
Param_Auto_Cast = 4, // auto_cast
Param_Ellipsis = 5, // Variadic parameter
Param_CVararg = 6, // #c_vararg
Param_No_Alias = 7, // #no_alias
Param_Any_Int = 8, // #any_int
Param_By_Ptr = 9, // #by_ptr
Param_No_Broadcast = 10, // #no_broadcast
Bit_Field_Field = 19,
Type_Alias = 20,
@@ -137,6 +141,7 @@ Entity :: struct {
// May be used by (Struct fields and procedure fields):
// .Variable
// .Constant
// This is equal to the negative of the "bit size" it this is a `bit_field`s field
field_group_index: i32le,
// May used by:
@@ -187,6 +192,7 @@ Type_Kind :: enum u32le {
Multi_Pointer = 22,
Matrix = 23,
Soa_Pointer = 24,
Bit_Field = 25,
}
Type_Elems_Cap :: 4
@@ -243,10 +249,10 @@ Type :: struct {
// .Bit_Set - <=2 types: 0=element type, 1=underlying type (Underlying_Type flag will be set)
// .Simd_Vector - 1 type: 0=element
// .Relative_Pointer - 2 types: 0=pointer type, 1=base integer
// .Relative_Slice - 2 types: 0=slice type, 1=base integer
// .Multi_Pointer - 1 type: 0=element
// .Matrix - 1 type: 0=element
// .Soa_Pointer - 1 type: 0=element
// .Bit_Field - 1 type: 0=backing type
types: Array(Type_Index),
// Used by:
+72 -3
View File
@@ -440,6 +440,24 @@ expect_closing_token_of_field_list :: proc(p: ^Parser, closing_kind: tokenizer.T
return expect_closing
}
expect_closing_parentheses_of_field_list :: proc(p: ^Parser) -> tokenizer.Token {
token := p.curr_tok
if allow_token(p, .Close_Paren) {
return token
}
if allow_token(p, .Semicolon) && !tokenizer.is_newline(token) {
str := tokenizer.token_to_string(token)
error(p, end_of_line_pos(p, p.prev_tok), "expected a comma, got %s", str)
}
for p.curr_tok.kind != .Close_Paren && p.curr_tok.kind != .EOF && !is_non_inserted_semicolon(p.curr_tok) {
advance_token(p)
}
return expect_token(p, .Close_Paren)
}
is_non_inserted_semicolon :: proc(tok: tokenizer.Token) -> bool {
return tok.kind == .Semicolon && tok.text != "\n"
}
@@ -517,7 +535,7 @@ is_semicolon_optional_for_node :: proc(p: ^Parser, node: ^ast.Node) -> bool {
return is_semicolon_optional_for_node(p, n.type)
case ^ast.Pointer_Type:
return is_semicolon_optional_for_node(p, n.elem)
case ^ast.Struct_Type, ^ast.Union_Type, ^ast.Enum_Type:
case ^ast.Struct_Type, ^ast.Union_Type, ^ast.Enum_Type, ^ast.Bit_Set_Type, ^ast.Bit_Field_Type:
// Require semicolon within a procedure body
return p.curr_proc == nil
case ^ast.Proc_Lit:
@@ -2100,7 +2118,7 @@ parse_proc_type :: proc(p: ^Parser, tok: tokenizer.Token) -> ^ast.Proc_Type {
expect_token(p, .Open_Paren)
params, _ := parse_field_list(p, .Close_Paren, ast.Field_Flags_Signature_Params)
expect_token(p, .Close_Paren)
expect_closing_parentheses_of_field_list(p)
results, diverging := parse_results(p)
is_generic := false
@@ -2534,6 +2552,7 @@ parse_operand :: proc(p: ^Parser, lhs: bool) -> ^ast.Expr {
poly_params: ^ast.Field_List
align: ^ast.Expr
field_align: ^ast.Expr
is_packed: bool
is_raw_union: bool
is_no_copy: bool
@@ -2565,6 +2584,11 @@ parse_operand :: proc(p: ^Parser, lhs: bool) -> ^ast.Expr {
error(p, tag.pos, "duplicate struct tag '#%s'", tag.text)
}
align = parse_expr(p, true)
case "field_align":
if field_align != nil {
error(p, tag.pos, "duplicate struct tag '#%s'", tag.text)
}
field_align = parse_expr(p, true)
case "raw_union":
if is_raw_union {
error(p, tag.pos, "duplicate struct tag '#%s'", tag.text)
@@ -2607,6 +2631,7 @@ parse_operand :: proc(p: ^Parser, lhs: bool) -> ^ast.Expr {
st := ast.new(ast.Struct_Type, tok.pos, end_pos(close))
st.poly_params = poly_params
st.align = align
st.field_align = field_align
st.is_packed = is_packed
st.is_raw_union = is_raw_union
st.is_no_copy = is_no_copy
@@ -2770,6 +2795,48 @@ parse_operand :: proc(p: ^Parser, lhs: bool) -> ^ast.Expr {
mt.column_count = column_count
mt.elem = elem
return mt
case .Bit_Field:
tok := expect_token(p, .Bit_Field)
backing_type := parse_type_or_ident(p)
if backing_type == nil {
token := advance_token(p)
error(p, token.pos, "Expected a backing type for a 'bit_field'")
}
skip_possible_newline_for_literal(p)
open := expect_token_after(p, .Open_Brace, "bit_field")
fields: [dynamic]^ast.Bit_Field_Field
for p.curr_tok.kind != .Close_Brace && p.curr_tok.kind != .EOF {
name := parse_ident(p)
expect_token(p, .Colon)
type := parse_type(p)
expect_token(p, .Or)
bit_size := parse_expr(p, true)
field := ast.new(ast.Bit_Field_Field, name.pos, bit_size)
field.name = name
field.type = type
field.bit_size = bit_size
append(&fields, field)
allow_token(p, .Comma) or_break
}
close := expect_closing_brace_of_field_list(p)
bf := ast.new(ast.Bit_Field_Type, tok.pos, close.pos)
bf.tok_pos = tok.pos
bf.backing_type = backing_type
bf.open = open.pos
bf.fields = fields[:]
bf.close = close.pos
return bf
case .Asm:
tok := expect_token(p, .Asm)
@@ -2877,7 +2944,8 @@ is_literal_type :: proc(expr: ^ast.Expr) -> bool {
^ast.Map_Type,
^ast.Bit_Set_Type,
^ast.Matrix_Type,
^ast.Call_Expr:
^ast.Call_Expr,
^ast.Bit_Field_Type:
return true
}
return false
@@ -2927,6 +2995,7 @@ parse_literal_value :: proc(p: ^Parser, type: ^ast.Expr) -> ^ast.Comp_Lit {
}
p.expr_level -= 1
skip_possible_newline(p)
close := expect_closing_brace_of_field_list(p);
pos := type.pos if type != nil else open.pos
+3 -3
View File
@@ -643,7 +643,7 @@ align_switch_stmt :: proc(p: ^Printer, index: int) {
format_tokens := make([dynamic]TokenAndLength, 0, brace_token.parameter_count, context.temp_allocator)
//find all the switch cases that are one lined
for line, line_index in p.lines[brace_line + 1:] {
for line in p.lines[brace_line + 1:] {
case_found := false
colon_found := false
@@ -716,7 +716,7 @@ align_enum :: proc(p: ^Printer, index: int) {
format_tokens := make([dynamic]TokenAndLength, 0, brace_token.parameter_count, context.temp_allocator)
for line, line_index in p.lines[brace_line + 1:] {
for line in p.lines[brace_line + 1:] {
length := 0
for format_token, i in line.format_tokens {
@@ -880,7 +880,7 @@ align_comments :: proc(p: ^Printer) {
length := 0
for format_token, i in line.format_tokens {
for format_token in line.format_tokens {
if format_token.kind == .Comment {
current_info.length = max(current_info.length, length)
current_info.end = line_index
+53 -3
View File
@@ -445,7 +445,7 @@ visit_decl :: proc(p: ^Printer, decl: ^ast.Decl, called_in_stmt := false) {
for value in v.values {
#partial switch a in value.derived {
case ^ast.Union_Type, ^ast.Enum_Type, ^ast.Struct_Type:
case ^ast.Union_Type, ^ast.Enum_Type, ^ast.Struct_Type, ^ast.Bit_Field_Type:
add_semicolon = false || called_in_stmt
case ^ast.Proc_Lit:
add_semicolon = false
@@ -488,6 +488,37 @@ visit_exprs :: proc(p: ^Printer, list: []^ast.Expr, options := List_Options{}) {
}
}
@(private)
visit_bit_field_fields :: proc(p: ^Printer, list: []^ast.Bit_Field_Field, options := List_Options{}) {
if len(list) == 0 {
return
}
// we have to newline the expressions to respect the source
for v, i in list {
// Don't move the first expression, it looks bad
if i != 0 && .Enforce_Newline in options {
newline_position(p, 1)
} else if i != 0 {
move_line_limit(p, v.pos, 1)
}
visit_expr(p, v.name, options)
push_generic_token(p, .Colon, 0)
visit_expr(p, v.type, options)
push_generic_token(p, .Or, 1)
visit_expr(p, v.bit_size, options)
if (i != len(list) - 1 || .Trailing in options) && .Add_Comma in options {
push_generic_token(p, .Comma, 0)
}
}
if len(list) > 1 && .Enforce_Newline in options {
newline_position(p, 1)
}
}
@(private)
visit_attributes :: proc(p: ^Printer, attributes: [dynamic]^ast.Attribute) {
if len(attributes) == 0 {
@@ -1293,6 +1324,25 @@ visit_expr :: proc(p: ^Printer, expr: ^ast.Expr, options := List_Options{}) {
visit_expr(p, v.column_count)
push_generic_token(p, .Close_Bracket, 0)
visit_expr(p, v.elem)
case ^ast.Bit_Field_Type:
push_generic_token(p, .Bit_Field, 1)
visit_expr(p, v.backing_type)
if len(v.fields) == 0 || v.pos.line == v.close.line {
push_generic_token(p, .Open_Brace, 1)
visit_bit_field_fields(p, v.fields, {.Add_Comma})
push_generic_token(p, .Close_Brace, 0)
} else {
visit_begin_brace(p, v.pos, .Generic, len(v.fields))
newline_position(p, 1)
set_source_position(p, v.fields[0].pos)
visit_bit_field_fields(p, v.fields, {.Add_Comma, .Trailing, .Enforce_Newline})
set_source_position(p, v.close)
visit_end_brace(p, v.close)
}
set_source_position(p, v.close)
case:
panic(fmt.aprint(expr.derived))
}
@@ -1462,9 +1512,9 @@ visit_binary_expr :: proc(p: ^Printer, binary: ^ast.Binary_Expr) {
}
either_implicit_selector := false
if _, ok := binary.left.derived.(^ast.Implicit_Selector_Expr); ok {
if _, lok := binary.left.derived.(^ast.Implicit_Selector_Expr); lok {
either_implicit_selector = true
} else if _, ok := binary.right.derived.(^ast.Implicit_Selector_Expr); ok {
} else if _, rok := binary.right.derived.(^ast.Implicit_Selector_Expr); rok {
either_implicit_selector = true
}
+2
View File
@@ -137,6 +137,7 @@ Token_Kind :: enum u32 {
Union, // union
Enum, // enum
Bit_Set, // bit_set
Bit_Field, // bit_field
Map, // map
Dynamic, // dynamic
Auto_Cast, // auto_cast
@@ -270,6 +271,7 @@ tokens := [Token_Kind.COUNT]string {
"union",
"enum",
"bit_set",
"bit_field",
"map",
"dynamic",
"auto_cast",