mirror of
https://github.com/Ed94/Odin.git
synced 2026-08-06 23:58:50 +00:00
core/odin: Added new file tag syntax as token. parse_file stores a list of tags that the file tag parser can use later.
This commit is contained in:
@@ -69,6 +69,7 @@ File :: struct {
|
|||||||
fullpath: string,
|
fullpath: string,
|
||||||
src: string,
|
src: string,
|
||||||
|
|
||||||
|
tags: [dynamic]tokenizer.Token,
|
||||||
docs: ^Comment_Group,
|
docs: ^Comment_Group,
|
||||||
|
|
||||||
pkg_decl: ^Package_Decl,
|
pkg_decl: ^Package_Decl,
|
||||||
|
|||||||
@@ -51,7 +51,7 @@ get_build_arch_from_string :: proc(str: string) -> runtime.Odin_Arch_Type {
|
|||||||
parse_file_tags :: proc(file: ast.File, allocator := context.allocator) -> (tags: File_Tags) {
|
parse_file_tags :: proc(file: ast.File, allocator := context.allocator) -> (tags: File_Tags) {
|
||||||
context.allocator = allocator
|
context.allocator = allocator
|
||||||
|
|
||||||
if file.docs == nil {
|
if file.docs == nil && file.tags == nil {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -95,11 +95,9 @@ parse_file_tags :: proc(file: ast.File, allocator := context.allocator) -> (tags
|
|||||||
build_project_names: [dynamic][]string
|
build_project_names: [dynamic][]string
|
||||||
defer shrink(&build_project_names)
|
defer shrink(&build_project_names)
|
||||||
|
|
||||||
for comment in file.docs.list {
|
parse_tag :: proc(text: string, tags: ^File_Tags, build_kinds: ^[dynamic]Build_Kind,
|
||||||
if len(comment.text) < 3 || comment.text[:2] != "//" {
|
build_project_name_strings: ^[dynamic]string,
|
||||||
continue
|
build_project_names: ^[dynamic][]string) {
|
||||||
}
|
|
||||||
text := comment.text[2:]
|
|
||||||
i := 0
|
i := 0
|
||||||
|
|
||||||
skip_whitespace(text, &i)
|
skip_whitespace(text, &i)
|
||||||
@@ -124,7 +122,7 @@ parse_file_tags :: proc(file: ast.File, allocator := context.allocator) -> (tags
|
|||||||
groups_loop: for {
|
groups_loop: for {
|
||||||
index_start := len(build_project_name_strings)
|
index_start := len(build_project_name_strings)
|
||||||
|
|
||||||
defer append(&build_project_names, build_project_name_strings[index_start:])
|
defer append(build_project_names, build_project_name_strings[index_start:])
|
||||||
|
|
||||||
for {
|
for {
|
||||||
skip_whitespace(text, &i)
|
skip_whitespace(text, &i)
|
||||||
@@ -143,10 +141,10 @@ parse_file_tags :: proc(file: ast.File, allocator := context.allocator) -> (tags
|
|||||||
}
|
}
|
||||||
|
|
||||||
scan_value(text, &i)
|
scan_value(text, &i)
|
||||||
append(&build_project_name_strings, text[name_start:i])
|
append(build_project_name_strings, text[name_start:i])
|
||||||
}
|
}
|
||||||
|
|
||||||
append(&build_project_names, build_project_name_strings[index_start:])
|
append(build_project_names, build_project_name_strings[index_start:])
|
||||||
}
|
}
|
||||||
case "build":
|
case "build":
|
||||||
kinds_loop: for {
|
kinds_loop: for {
|
||||||
@@ -156,7 +154,7 @@ parse_file_tags :: proc(file: ast.File, allocator := context.allocator) -> (tags
|
|||||||
arch_positive: runtime.Odin_Arch_Types
|
arch_positive: runtime.Odin_Arch_Types
|
||||||
arch_negative: runtime.Odin_Arch_Types
|
arch_negative: runtime.Odin_Arch_Types
|
||||||
|
|
||||||
defer append(&build_kinds, Build_Kind{
|
defer append(build_kinds, Build_Kind{
|
||||||
os = (os_positive == {} ? runtime.ALL_ODIN_OS_TYPES : os_positive) -os_negative,
|
os = (os_positive == {} ? runtime.ALL_ODIN_OS_TYPES : os_positive) -os_negative,
|
||||||
arch = (arch_positive == {} ? runtime.ALL_ODIN_ARCH_TYPES : arch_positive)-arch_negative,
|
arch = (arch_positive == {} ? runtime.ALL_ODIN_ARCH_TYPES : arch_positive)-arch_negative,
|
||||||
})
|
})
|
||||||
@@ -200,6 +198,27 @@ parse_file_tags :: proc(file: ast.File, allocator := context.allocator) -> (tags
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if file.docs != nil {
|
||||||
|
for comment in file.docs.list {
|
||||||
|
if len(comment.text) < 3 || comment.text[:2] != "//" {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
text := comment.text[2:]
|
||||||
|
|
||||||
|
parse_tag(text, &tags, &build_kinds, &build_project_name_strings, &build_project_names)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
for tag in file.tags {
|
||||||
|
if len(tag.text) < 3 || tag.text[:2] != "#+" {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
// Only skip # because parse_tag skips the plus
|
||||||
|
text := tag.text[1:]
|
||||||
|
|
||||||
|
parse_tag(text, &tags, &build_kinds, &build_project_name_strings, &build_project_names)
|
||||||
|
}
|
||||||
|
|
||||||
tags.build = build_kinds[:]
|
tags.build = build_kinds[:]
|
||||||
tags.build_project_name = build_project_names[:]
|
tags.build_project_name = build_project_names[:]
|
||||||
|
|
||||||
|
|||||||
@@ -77,9 +77,7 @@ parse_package :: proc(pkg: ^ast.Package, p: ^Parser = nil) -> bool {
|
|||||||
if !parse_file(p, file) {
|
if !parse_file(p, file) {
|
||||||
ok = false
|
ok = false
|
||||||
}
|
}
|
||||||
if file.pkg_decl == nil {
|
if pkg.name == "" {
|
||||||
error(p, p.curr_tok.pos, "Expected a package declaration at the start of the file")
|
|
||||||
} else if pkg.name == "" {
|
|
||||||
pkg.name = file.pkg_decl.name
|
pkg.name = file.pkg_decl.name
|
||||||
} else if pkg.name != file.pkg_decl.name {
|
} else if pkg.name != file.pkg_decl.name {
|
||||||
error(p, file.pkg_decl.pos, "different package name, expected '%s', got '%s'", pkg.name, file.pkg_decl.name)
|
error(p, file.pkg_decl.pos, "different package name, expected '%s', got '%s'", pkg.name, file.pkg_decl.name)
|
||||||
|
|||||||
@@ -161,8 +161,33 @@ parse_file :: proc(p: ^Parser, file: ^ast.File) -> bool {
|
|||||||
|
|
||||||
docs := p.lead_comment
|
docs := p.lead_comment
|
||||||
|
|
||||||
|
invalid_pre_package_token: Maybe(tokenizer.Token)
|
||||||
|
|
||||||
|
for p.curr_tok.kind != .Package && p.curr_tok.kind != .EOF {
|
||||||
|
if p.curr_tok.kind == .Comment {
|
||||||
|
consume_comment_groups(p, p.prev_tok)
|
||||||
|
} else if p.curr_tok.kind == .File_Tag {
|
||||||
|
append(&p.file.tags, p.curr_tok)
|
||||||
|
advance_token(p)
|
||||||
|
} else {
|
||||||
|
if invalid_pre_package_token == nil {
|
||||||
|
invalid_pre_package_token = p.curr_tok
|
||||||
|
}
|
||||||
|
|
||||||
|
advance_token(p)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if p.curr_tok.kind != .Package {
|
||||||
|
t := invalid_pre_package_token.? or_else p.curr_tok
|
||||||
|
error(p, t.pos, "Expected a package declaration at the start of the file")
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
p.file.pkg_token = expect_token(p, .Package)
|
p.file.pkg_token = expect_token(p, .Package)
|
||||||
if p.file.pkg_token.kind != .Package {
|
|
||||||
|
if ippt, ok := invalid_pre_package_token.?; ok {
|
||||||
|
error(p, ippt.pos, "Expected only comments or lines starting with '#+' before the package declaration")
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -32,6 +32,7 @@ Token_Kind :: enum u32 {
|
|||||||
Invalid,
|
Invalid,
|
||||||
EOF,
|
EOF,
|
||||||
Comment,
|
Comment,
|
||||||
|
File_Tag,
|
||||||
|
|
||||||
B_Literal_Begin,
|
B_Literal_Begin,
|
||||||
Ident, // main
|
Ident, // main
|
||||||
@@ -166,6 +167,7 @@ tokens := [Token_Kind.COUNT]string {
|
|||||||
"Invalid",
|
"Invalid",
|
||||||
"EOF",
|
"EOF",
|
||||||
"Comment",
|
"Comment",
|
||||||
|
"FileTag",
|
||||||
|
|
||||||
"",
|
"",
|
||||||
"identifier",
|
"identifier",
|
||||||
|
|||||||
@@ -206,6 +206,23 @@ scan_comment :: proc(t: ^Tokenizer) -> string {
|
|||||||
return string(lit)
|
return string(lit)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
scan_file_tag :: proc(t: ^Tokenizer) -> string {
|
||||||
|
offset := t.offset - 1
|
||||||
|
|
||||||
|
for t.ch != '\n' {
|
||||||
|
if t.ch == '/' {
|
||||||
|
next := peek_byte(t, 0)
|
||||||
|
|
||||||
|
if next == '/' || next == '*' {
|
||||||
|
break
|
||||||
|
}
|
||||||
|
}
|
||||||
|
advance_rune(t)
|
||||||
|
}
|
||||||
|
|
||||||
|
return string(t.src[offset : t.offset])
|
||||||
|
}
|
||||||
|
|
||||||
scan_identifier :: proc(t: ^Tokenizer) -> string {
|
scan_identifier :: proc(t: ^Tokenizer) -> string {
|
||||||
offset := t.offset
|
offset := t.offset
|
||||||
|
|
||||||
@@ -636,6 +653,9 @@ scan :: proc(t: ^Tokenizer) -> Token {
|
|||||||
if t.ch == '!' {
|
if t.ch == '!' {
|
||||||
kind = .Comment
|
kind = .Comment
|
||||||
lit = scan_comment(t)
|
lit = scan_comment(t)
|
||||||
|
} else if t.ch == '+' {
|
||||||
|
kind = .File_Tag
|
||||||
|
lit = scan_file_tag(t)
|
||||||
}
|
}
|
||||||
case '/':
|
case '/':
|
||||||
kind = .Quo
|
kind = .Quo
|
||||||
|
|||||||
Reference in New Issue
Block a user