Simplify ast parsing for prefixes

This commit is contained in:
gingerBill
2022-08-01 13:07:49 +01:00
parent a0135080b3
commit 83c8c48ed7
2 changed files with 65 additions and 28 deletions

View File

@@ -553,12 +553,16 @@ unparen_expr :: proc(expr: ^Expr) -> (val: ^Expr) {
}
Field_Flag :: enum {
Unknown,
Ellipsis,
Using,
No_Alias,
C_Vararg,
Auto_Cast,
Any_Int,
Subtype,
By_Ptr,
Results,
Tags,
@@ -566,11 +570,31 @@ Field_Flag :: enum {
Typeid_Token,
}
field_flag_strings := [Field_Flag]string{
.Unknown = "",
.Ellipsis = "..",
.Using = "using",
.No_Alias = "#no_alias",
.C_Vararg = "#c_vararg",
.Auto_Cast = "auto_cast",
.Any_Int = "#any_int",
.Subtype = "#subtype",
.By_Ptr = "#by_ptr",
.Results = "results",
.Tags = "field tag",
.Default_Parameters = "default parameters",
.Typeid_Token = "typeid",
}
Field_Flags :: distinct bit_set[Field_Flag]
Field_Flags_Struct :: Field_Flags{
.Using,
.Tags,
.Subtype,
}
Field_Flags_Record_Poly_Params :: Field_Flags{
.Typeid_Token,
@@ -583,6 +607,7 @@ Field_Flags_Signature :: Field_Flags{
.C_Vararg,
.Auto_Cast,
.Any_Int,
.By_Ptr,
.Default_Parameters,
}

View File

@@ -1621,6 +1621,34 @@ Field_Prefix :: enum {
C_Vararg,
Auto_Cast,
Any_Int,
Subtype,
By_Ptr,
}
field_prefix_strings := [Field_Prefix]string{
.Invalid = "invalid",
.Unknown = "unknown",
.Using = "using",
.Auto_Cast = "auto_cast",
.No_Alias = "#no_alias",
.C_Vararg = "#c_vararg",
.Any_Int = "#any_int",
.Subtype = "#subtype",
.By_Ptr = "#by_ptr",
}
field_prefix_to_flag := [Field_Prefix]ast.Field_Flag{
.Invalid = .Unknown,
.Unknown = .Unknown,
.Using = .Using,
.No_Alias = .No_Alias,
.C_Vararg = .C_Vararg,
.Auto_Cast = .Auto_Cast,
.Any_Int = .Any_Int,
.Subtype = .Subtype,
.By_Ptr = .By_Ptr,
}
Field_Prefixes :: distinct bit_set[Field_Prefix]
@@ -1688,6 +1716,10 @@ is_token_field_prefix :: proc(p: ^Parser) -> Field_Prefix {
return .C_Vararg
case "any_int":
return .Any_Int
case "subtype":
return .Subtype
case "by_ptr":
return .By_Ptr
}
}
return .Unknown
@@ -1716,23 +1748,11 @@ parse_field_prefixes :: proc(p: ^Parser) -> ast.Field_Flags {
for kind in Field_Prefix {
count := counts[kind]
switch kind {
case .Invalid, .Unknown: // Ignore
case .Using:
if count > 1 { error(p, p.curr_tok.pos, "multiple 'using' in this field list") }
if count > 0 { flags += {.Using} }
case .No_Alias:
if count > 1 { error(p, p.curr_tok.pos, "multiple '#no_alias' in this field list") }
if count > 0 { flags += {.No_Alias} }
case .C_Vararg:
if count > 1 { error(p, p.curr_tok.pos, "multiple '#c_vararg' in this field list") }
if count > 0 { flags += {.C_Vararg} }
case .Auto_Cast:
if count > 1 { error(p, p.curr_tok.pos, "multiple 'auto_cast' in this field list") }
if count > 0 { flags += {.Auto_Cast} }
case .Any_Int:
if count > 1 { error(p, p.curr_tok.pos, "multiple '#any_int' in this field list") }
if count > 0 { flags += {.Any_Int} }
if kind == .Invalid || kind == .Unknown {
// Ignore
} else {
if count > 1 { error(p, p.curr_tok.pos, "multiple '%s' in this field list", field_prefix_strings[kind]) }
if count > 0 { flags += {field_prefix_to_flag[kind]} }
}
}
@@ -1748,19 +1768,11 @@ check_field_flag_prefixes :: proc(p: ^Parser, name_count: int, allowed_flags, se
for flag in ast.Field_Flag {
if flag not_in allowed_flags && flag in flags {
switch flag {
case .Using:
error(p, p.curr_tok.pos, "'using' is not allowed within this field list")
case .No_Alias:
error(p, p.curr_tok.pos, "'#no_alias' is not allowed within this field list")
case .C_Vararg:
error(p, p.curr_tok.pos, "'#c_vararg' is not allowed within this field list")
case .Auto_Cast:
error(p, p.curr_tok.pos, "'auto_cast' is not allowed within this field list")
case .Any_Int:
error(p, p.curr_tok.pos, "'#any_int' is not allowed within this field list")
#partial switch flag {
case .Tags, .Ellipsis, .Results, .Default_Parameters, .Typeid_Token:
panic("Impossible prefixes")
case:
error(p, p.curr_tok.pos, "'%s' is not allowed within this field list", ast.field_flag_strings[flag])
}
flags -= {flag}
}