1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889 |
- package odin_parser
- import "core:odin/tokenizer"
- import "core:odin/ast"
- import "core:path/filepath"
- import "core:fmt"
- import "core:os"
- import "core:slice"
- collect_package :: proc(path: string) -> (pkg: ^ast.Package, success: bool) {
- NO_POS :: tokenizer.Pos{}
- pkg_path, pkg_path_ok := filepath.abs(path)
- if !pkg_path_ok {
- return
- }
- path_pattern := fmt.tprintf("%s/*.odin", pkg_path)
- matches, err := filepath.glob(path_pattern)
- defer delete(matches)
- if err != nil {
- return
- }
- pkg = ast.new(ast.Package, NO_POS, NO_POS)
- pkg.fullpath = pkg_path
- for match in matches {
- src: []byte
- fullpath, ok := filepath.abs(match)
- if !ok {
- return
- }
- src, ok = os.read_entire_file(fullpath)
- if !ok {
- delete(fullpath)
- return
- }
- file := ast.new(ast.File, NO_POS, NO_POS)
- file.pkg = pkg
- file.src = string(src)
- file.fullpath = fullpath
- pkg.files[fullpath] = file
- }
- success = true
- return
- }
- parse_package :: proc(pkg: ^ast.Package, p: ^Parser = nil) -> bool {
- p := p
- if p == nil {
- p = &Parser{}
- p^ = default_parser()
- }
- ok := true
- files := make([]^ast.File, len(pkg.files), context.temp_allocator)
- i := 0
- for _, file in pkg.files {
- files[i] = file
- i += 1
- }
- slice.sort(files)
- for file in files {
- if !parse_file(p, file) {
- ok = false
- }
- if pkg.name == "" {
- 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)
- }
- }
- return ok
- }
- parse_package_from_path :: proc(path: string, p: ^Parser = nil) -> (pkg: ^ast.Package, ok: bool) {
- pkg, ok = collect_package(path)
- if !ok {
- return
- }
- ok = parse_package(pkg, p)
- return
- }
|