update self-host compiler

This commit is contained in:
ValKmjolnir 2024-11-08 00:31:51 +08:00
parent 6aca86725c
commit e36e9aca82
8 changed files with 115 additions and 98 deletions

View File

@ -68,3 +68,4 @@ See simple tutorial in [bootstrap/README.md](./bootstrap/README.md).
3. develop bootstrapped compiler
4. conditional compilation
5. array type like `[i32; 128]`
6. optional compile syntax feature: `#[feature(...)]`

View File

@ -1,4 +1,5 @@
use std::io::{ io };
use std::libc::{ exit };
pub struct cli_option {
OPTION_VIEW_TOKEN: bool,
@ -29,7 +30,7 @@ impl cli_option {
}
pub func version() -> i8* {
return "colgm compiler version 0.2";
return "colgm compiler version 0.2 (beta)";
}
pub func help() {
@ -53,7 +54,7 @@ pub func help() {
.endln();
}
pub func logo(executable_path: i8*) {
pub func logo(executable: i8*) {
io::stdout()
.green().out(" __ \n")
.green().out(" _________ / /___ _____ ___ \n")
@ -64,5 +65,34 @@ pub func logo(executable_path: i8*) {
.reset()
.out("ver : ").out(version()).out("\n")
.out("repo : https://github.com/colgm/colgm\n\n")
.out("input <").out(executable_path).out(" -h> to get help.\n\n");
.out("input <").out(executable).out(" -h> to get help.\n\n");
}
pub func report_missing_given_info(info: i8*) {
io::stderr().red().out("Error:").reset()
.out(" missing ").out(info).out("\n\n");
exit(-1 => i32);
}
pub func report_multiple_given_info(info: i8*) {
io::stderr().red().out("Error:").reset()
.out(" multiple ").out(info).out(" specified\n\n");
exit(-1 => i32);
}
pub func report_invalid_given_info(info: i8*, actual: i8*) {
io::stderr().red().out("Error:").reset()
.out(" invalid ").out(info)
.red().out(" <").out(actual).out(">").reset()
.out("\n\n");
exit(-1 => i32);
}
pub func report_invalid_argument(arg: i8*) {
io::stderr().red().out("Error:").reset()
.out(" invalid argument ")
.red().out(arg).reset()
.out(", use ").green().out("--help").reset()
.out(" for help.\n\n");
exit(-1 => i32);
}

View File

@ -190,7 +190,7 @@ impl lexer {
}
impl lexer {
func tok_kind_to_str(kind: tok_kind) -> i8* {
func tok_kind_to_str(kind: tok_kind) -> const i8* {
match(kind) {
tok_kind::tok_null => return "[tok_null ]";
tok_kind::tok_num => return "[tok_num ]";

View File

@ -1,4 +1,4 @@
use std::libc::{ streq, strlen, exit };
use std::libc::{ streq, strlen };
use err::span::*;
use cli::*;
use std::io::{ readfile_into_string, io };
@ -9,24 +9,23 @@ func compile(option: cli_option) {
var err = io::stderr();
if (!fs::exists(option.input_file)) {
err.red().out("Error: ").reset();
err.out("failed to load file <").out(option.input_file)
.out(">, check if exists and is readable\n");
err.out("failed to load file <").out(option.input_file);
err.out(">, check if exists and is readable\n");
return;
}
// if (option.library_path != nil &&
// !fs::is_dir(option.library_path)) {
// if (option.library_path != nil && !fs::is_dir(option.library_path)) {
// err.red().out("Error: ").reset();
// err.out("failed to load library path <").out(option.library_path)
// .out(">, check if exists and is directory\n");
// err.out("failed to load library path <").out(option.library_path);
// err.out(">, check if exists and is directory\n");
// return;
// }
err.out("[").green().out("colgm").reset().out("]")
.out(" source file : ").out(option.input_file).out("\n");
err.out("[").green().out("colgm").reset().out("]")
.out(" output file : ").out(option.output_file).out("\n");
err.out("[").green().out("colgm").reset().out("]")
.out(" library path : ").out(option.library_path).out("\n");
err.out("[").green().out("colgm").reset().out("]");
err.out(" source file : ").out(option.input_file).out("\n");
err.out("[").green().out("colgm").reset().out("]");
err.out(" output file : ").out(option.output_file).out("\n");
err.out("[").green().out("colgm").reset().out("]");
err.out(" library path : ").out(option.library_path).out("\n");
var cc = compiler::instance();
cc.pkg->library_path = option.library_path;
@ -59,35 +58,6 @@ func compile(option: cli_option) {
cc.delete();
}
func report_missing_given_info(info: i8*) {
io::stderr().red().out("Error:").reset()
.out(" missing ").out(info).out("\n\n");
exit(-1 => i32);
}
func report_multiple_given_info(info: i8*) {
io::stderr().red().out("Error:").reset()
.out(" multiple ").out(info).out(" specified\n\n");
exit(-1 => i32);
}
func report_invalid_given_info(info: i8*, actual: i8*) {
io::stderr().red().out("Error:").reset()
.out(" invalid ").out(info)
.red().out(" <").out(actual).out(">").reset()
.out("\n\n");
exit(-1 => i32);
}
func report_invalid_argument(arg: i8*) {
io::stderr().red().out("Error:").reset()
.out(" invalid argument ")
.red().out(arg).reset()
.out(", use ").green().out("--help").reset()
.out(" for help.\n\n");
exit(-1 => i32);
}
func main(argc: i32, argv: i8**) -> i32 {
if (argc==(1 => i32)) {
logo(argv[0]);

View File

@ -15,7 +15,7 @@ pub struct parser {
}
impl parser {
func tok_kind_to_content(kind: tok_kind) -> i8* {
func tok_kind_to_content(kind: tok_kind) -> const i8* {
match(kind) {
tok_kind::tok_null => return "<null>";
tok_kind::tok_num => return "<number-literal>";

View File

@ -1,45 +1,6 @@
use std::io::{ flag };
use std::libc::{ open, close, free };
enum stat_flag {
S_IFMT = 0xF000,
S_IFDIR = 0x4000,
S_IFCHR = 0x2000,
S_IFIFO = 0x1000,
S_IFREG = 0x8000,
S_IREAD = 0x0100,
S_IWRITE = 0x0080,
S_IEXEC = 0x0040,
S_IFBLK = 0x3000
}
struct stat_info {
st_dev: i32,
st_mode: u16,
st_nlink: u16,
st_ino: u64,
st_uid: u32,
st_gid: u32,
st_rdev: i32,
st_atime: i32,
st_atime_nsec: i32,
st_mtime: i32,
st_mtime_nsec: i32,
st_ctime: i32,
st_ctime_nsec: i32,
st_birthtime: i32,
st_birthtime_nsec: i32,
st_size: i64,
st_blocks: i64,
st_blksize: i32,
st_flags: u32,
st_gen: u32,
st_lspare: i32,
st_qspare_0: i64,
st_qspare_1: i64
}
extern func stat(filename: i8*, stat_ptr: stat_info*) -> i32;
use std::libc::{ open, close, free, stat };
use std::sys::{ stat_flag, macOS_stat_info, linux_stat_info };
pub struct fs {}
@ -53,14 +14,13 @@ impl fs {
return true;
}
func is_dir(filename: i8*) -> bool {
var info = stat_info::__alloc__();
if (stat(filename, info) == (-1 => i32)) {
free(info => i8*);
// FIXME: This is linux specific, make it cross platform
pub func is_dir(filename: i8*) -> bool {
var info = linux_stat_info {};
if (stat(filename, info.__ptr__() => i8*) == (-1 => i32)) {
return false;
}
var res = (info->st_mode & (stat_flag::S_IFMT => u16)) => stat_flag == stat_flag::S_IFDIR;
free(info => i8*);
return res;
var ifmt = info.st_mode & (stat_flag::S_IFMT => u32);
return (ifmt => stat_flag) == stat_flag::S_IFDIR;
}
}

View File

@ -10,6 +10,8 @@ pub extern func write(fd: i32, buf: i8*, count: i64) -> i64;
pub extern func close(fd: i32) -> i32;
pub extern func exit(code: i32);
pub extern func stat(filename: i8*, stat_ptr: i8*) -> i32;
pub extern func puts(str: i8*) -> i32;
pub extern func srand(seed: u32);

View File

@ -1,8 +1,62 @@
// ubuntu 22.04 x86_64
// %struct.stat = type { i64, i64, i64, i32, i32, i32, i32, i64, i64, i64, i64, %struct.timespec, %struct.timespec, %struct.timespec, [3 x i64] }
// %struct.timespec = type { i64, i64 }
pub enum stat_flag {
S_IFMT = 0xF000,
S_IFDIR = 0x4000,
S_IFCHR = 0x2000,
S_IFIFO = 0x1000,
S_IFREG = 0x8000,
S_IREAD = 0x0100,
S_IWRITE = 0x0080,
S_IEXEC = 0x0040,
S_IFBLK = 0x3000
}
pub struct timespec {
tv_sec: i64,
tv_nsec: i64,
}
// #[enable_if(target_os = "macos", arch = "aarch64")]
pub struct macOS_stat_info {
st_dev: i32,
st_mode: u16,
st_nlink: u16,
st_ino: u64,
st_uid: u32,
st_gid: u32,
st_rdev: i32,
st_atime: timespec,
st_mtime: timespec,
st_ctime: timespec,
st_birthtime: timespec,
st_size: i64,
st_blocks: i64,
st_blksize: i32,
st_flags: u32,
st_gen: u32,
st_lspare: i32,
// reserved
st_qspare_0: i64,
st_qspare_1: i64
}
// #[enable_if(target_os = "linux", arch = "x86_64")]
pub struct linux_stat_info {
st_dev: u64,
st_ino: u64,
st_nlink: u64,
st_mode: u32,
st_uid: u32,
st_gid: u32,
__pad0: i32,
st_rdev: u64,
st_size: i64,
st_blksize: i64,
st_blocks: i64,
st_atim: timespec,
st_mtim: timespec,
st_ctim: timespec,
// reserved
__glibc_reserved_0: i64,
__glibc_reserved_1: i64,
__glibc_reserved_2: i64
}