allow keywords as values in enums (and tagged unions)
This commit is contained in:
@@ -10223,6 +10223,93 @@ main func() i32 {
|
||||
testing.expect(t, found_promotion)
|
||||
}
|
||||
|
||||
@(test)
|
||||
keywords_are_valid_enum_members_and_tagged_union_variants :: proc(t: ^testing.T) {
|
||||
testing.expect(t, token.is_keyword(.Keyword_Func))
|
||||
testing.expect(t, token.is_keyword(.Keyword_C_Longdouble))
|
||||
testing.expect(t, !token.is_keyword(.Identifier))
|
||||
testing.expect(t, !token.is_keyword(.Underscore))
|
||||
|
||||
text := `TokenKind :: enum {
|
||||
if
|
||||
else
|
||||
return
|
||||
}
|
||||
Token :: union(TokenKind) {
|
||||
if i32
|
||||
else void
|
||||
return i32
|
||||
}
|
||||
kind func(value bool) TokenKind {
|
||||
if value {
|
||||
return .if
|
||||
}
|
||||
return TokenKind.else
|
||||
}
|
||||
main func() i32 {
|
||||
first TokenKind = kind(true)
|
||||
second TokenKind = .return
|
||||
a Token = Token{ if = 1 }
|
||||
b Token = Token{ else }
|
||||
c Token = .return{2}
|
||||
total i32 = a.if + c.return
|
||||
match first {
|
||||
.if: total = total + 1
|
||||
.else: total = total + 2
|
||||
.return: total = total + 3
|
||||
}
|
||||
match b {
|
||||
.if |value|: total = total + value
|
||||
.else: total = total + 4
|
||||
.return |value|: total = total + value
|
||||
}
|
||||
_ = second
|
||||
return total
|
||||
}
|
||||
`
|
||||
source_file := source.Source{path="test.bro", text=text}
|
||||
diagnostics := source.init_diagnostics(&source_file)
|
||||
defer source.destroy_diagnostics(&diagnostics)
|
||||
symbols := symbol.init_table()
|
||||
defer symbol.destroy_table(&symbols)
|
||||
stream := lexer.lex(&source_file, &diagnostics, &symbols)
|
||||
defer delete(stream.items)
|
||||
ast_module := parser.parse(&stream, &source_file, &diagnostics)
|
||||
defer ast.destroy_module(&ast_module)
|
||||
hir_module := checker.check(&ast_module, &diagnostics, &symbols)
|
||||
defer hir.destroy_module(&hir_module)
|
||||
ir_module := lower.lower(&hir_module)
|
||||
defer ir.destroy_module(&ir_module)
|
||||
llvm_text := llvm.emit(&ir_module, &diagnostics, &symbols)
|
||||
defer delete(llvm_text)
|
||||
|
||||
testing.expect_value(t, len(diagnostics.items), 0)
|
||||
testing.expect(t, len(llvm_text) > 0)
|
||||
}
|
||||
|
||||
@(test)
|
||||
keyword_names_remain_invalid_for_struct_fields :: proc(t: ^testing.T) {
|
||||
text := `Bad :: struct {
|
||||
if i32
|
||||
}
|
||||
`
|
||||
source_file := source.Source{path="test.bro", text=text}
|
||||
diagnostics := source.init_diagnostics(&source_file)
|
||||
defer source.destroy_diagnostics(&diagnostics)
|
||||
symbols := symbol.init_table()
|
||||
defer symbol.destroy_table(&symbols)
|
||||
stream := lexer.lex(&source_file, &diagnostics, &symbols)
|
||||
defer delete(stream.items)
|
||||
module := parser.parse(&stream, &source_file, &diagnostics)
|
||||
defer ast.destroy_module(&module)
|
||||
|
||||
found := false
|
||||
for diagnostic in diagnostics.items {
|
||||
found = found || strings.contains(diagnostic.message, "expected a struct field name")
|
||||
}
|
||||
testing.expect(t, found)
|
||||
}
|
||||
|
||||
@(test)
|
||||
unbacked_enum_uses_global_u16_backing :: proc(t: ^testing.T) {
|
||||
builder := strings.builder_make()
|
||||
|
||||
Reference in New Issue
Block a user