This patch makes it such that if you define an enum inside of a scope, the type checker will remember it. There is currently no support for field accesses. Signed-off-by: Slendi <slendi@socopon.com>
118 lines
2.4 KiB
Odin
118 lines
2.4 KiB
Odin
package main
|
|
|
|
import "core:fmt"
|
|
import "core:os"
|
|
|
|
main :: proc() {
|
|
handle: os.Handle
|
|
file_name := "<stdin>"
|
|
if len(os.args) >= 2 {
|
|
errno: os.Errno
|
|
handle, errno = os.open(os.args[1])
|
|
if errno != 0 {
|
|
fmt.printf("Error opening file\n", errno)
|
|
return
|
|
}
|
|
file_name = os.args[1]
|
|
} else {
|
|
handle = os.stdin
|
|
}
|
|
defer os.close(handle)
|
|
|
|
data, err := os.read_entire_file_from_handle(handle)
|
|
if !err {
|
|
fmt.printf("Error reading file\n", err)
|
|
return
|
|
}
|
|
|
|
u8_arr: [dynamic]u8
|
|
for ch in data {
|
|
append(&u8_arr, u8(ch))
|
|
}
|
|
|
|
lexer := lexer_create(&u8_arr, file_name)
|
|
parser := parser_create(lexer)
|
|
|
|
ast := parser_parse(&parser)
|
|
if len(g_message_list) > 0 {
|
|
contains_errors := false
|
|
for &msg in g_message_list {
|
|
message_print(&msg, &data)
|
|
if msg.level == .Error || msg.level == .Fatal {
|
|
contains_errors = true
|
|
}
|
|
}
|
|
if contains_errors {
|
|
os.exit(1)
|
|
}
|
|
}
|
|
clear(&g_message_list)
|
|
type_check(ast, nil)
|
|
if len(g_message_list) > 0 {
|
|
contains_errors := false
|
|
for &msg in g_message_list {
|
|
message_print(&msg, &data)
|
|
if msg.level == .Error || msg.level == .Fatal {
|
|
contains_errors = true
|
|
}
|
|
}
|
|
if contains_errors {
|
|
os.exit(1)
|
|
}
|
|
}
|
|
|
|
node_print(ast)
|
|
|
|
// name: string
|
|
// if handle == os.stdin {
|
|
// name = "stdin"
|
|
// } else {
|
|
// name = os.args[1]
|
|
// }
|
|
// name_dyn := [dynamic]u8{}
|
|
// for ch in transmute([]u8)name {
|
|
// append(&name_dyn, u8(ch))
|
|
// }
|
|
// module_name := parse_use_path2(name_dyn)
|
|
// module_name = main_module_name_from_filename(module_name)
|
|
// if len(module_name) == 0 {
|
|
// clear(&module_name)
|
|
// append(&module_name, 'm')
|
|
// append(&module_name, 'a')
|
|
// append(&module_name, 'i')
|
|
// append(&module_name, 'n')
|
|
// }
|
|
// ctx := LLVMContextCreate()
|
|
// defer LLVMContextDispose(ctx)
|
|
// module := LLVMModuleCreateWithNameInContext(cstring(raw_data(module_name[:])), ctx)
|
|
// defer LLVMDisposeModule(module)
|
|
// builder := LLVMCreateBuilderInContext(ctx)
|
|
//
|
|
// generate_llvm(ctx, module, builder, ast)
|
|
//
|
|
// append(&module_name, '.')
|
|
// append(&module_name, 'l')
|
|
// append(&module_name, 'l')
|
|
// LLVMPrintModuleToFile(module, cstring(raw_data(module_name[:])), nil)
|
|
}
|
|
|
|
main_module_name_from_filename :: proc(fname: [dynamic]u8) -> (module_name: [dynamic]u8) {
|
|
temp_name := [dynamic]u8{}
|
|
for ch in fname {
|
|
if ch == '/' || ch == '\\' {
|
|
clear(&temp_name)
|
|
} else {
|
|
append(&temp_name, ch)
|
|
}
|
|
}
|
|
|
|
for ch in temp_name {
|
|
if ch == '.' {
|
|
break
|
|
}
|
|
append(&module_name, ch)
|
|
}
|
|
|
|
return
|
|
}
|