emit debug flag
This commit is contained in:
@@ -77,12 +77,14 @@ pub struct CodegenX86_64<'a> {
|
|||||||
data_counter: usize,
|
data_counter: usize,
|
||||||
pub symbol_table: &'a SymbolTable,
|
pub symbol_table: &'a SymbolTable,
|
||||||
pub expr_types: &'a HashMap<usize, String>,
|
pub expr_types: &'a HashMap<usize, String>,
|
||||||
|
emit_debug: bool,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'a> CodegenX86_64<'a> {
|
impl<'a> CodegenX86_64<'a> {
|
||||||
pub fn new(
|
pub fn new(
|
||||||
symbol_table: &'a SymbolTable,
|
symbol_table: &'a SymbolTable,
|
||||||
expr_types: &'a HashMap<usize, String>,
|
expr_types: &'a HashMap<usize, String>,
|
||||||
|
emit_debug: bool,
|
||||||
) -> CodegenX86_64<'a> {
|
) -> CodegenX86_64<'a> {
|
||||||
CodegenX86_64 {
|
CodegenX86_64 {
|
||||||
output: String::new(),
|
output: String::new(),
|
||||||
@@ -91,6 +93,7 @@ impl<'a> CodegenX86_64<'a> {
|
|||||||
data_counter: 1,
|
data_counter: 1,
|
||||||
symbol_table,
|
symbol_table,
|
||||||
expr_types,
|
expr_types,
|
||||||
|
emit_debug,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -344,11 +347,15 @@ _builtin_environ:
|
|||||||
body,
|
body,
|
||||||
exported,
|
exported,
|
||||||
} => {
|
} => {
|
||||||
if *exported || name.lexeme == "main" {
|
let name = &name.lexeme;
|
||||||
emit!(&mut self.output, "global {}", name.lexeme);
|
if self.emit_debug || *exported || name == "main" {
|
||||||
|
emit!(
|
||||||
|
&mut self.output,
|
||||||
|
"global {name}:function (__end_{name} - {name})",
|
||||||
|
);
|
||||||
}
|
}
|
||||||
emit!(&mut self.output, "section .text.{}", name.lexeme);
|
emit!(&mut self.output, "section .text.{}", name);
|
||||||
emit!(&mut self.output, "{}:", name.lexeme);
|
emit!(&mut self.output, "{}:", name);
|
||||||
emit!(&mut self.output, " push rbp");
|
emit!(&mut self.output, " push rbp");
|
||||||
emit!(&mut self.output, " mov rbp, rsp");
|
emit!(&mut self.output, " mov rbp, rsp");
|
||||||
|
|
||||||
@@ -398,6 +405,10 @@ _builtin_environ:
|
|||||||
emit!(&mut self.output, " ret");
|
emit!(&mut self.output, " ret");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if self.emit_debug || *exported || name == "main" {
|
||||||
|
emit!(&mut self.output, "__end_{}:", name);
|
||||||
|
}
|
||||||
|
|
||||||
// patch the stack size after we know how much we actually need
|
// patch the stack size after we know how much we actually need
|
||||||
let patch = format!(" sub rsp, {:<10}", (env.next_offset + 15) & !15);
|
let patch = format!(" sub rsp, {:<10}", (env.next_offset + 15) & !15);
|
||||||
self.output
|
self.output
|
||||||
|
|||||||
24
src/main.rs
24
src/main.rs
@@ -54,7 +54,8 @@ fn compile_file(args: Args) -> Result<(), ZernError> {
|
|||||||
typechecker.typecheck_stmt(&mut typechecker::Env::new(), stmt)?;
|
typechecker.typecheck_stmt(&mut typechecker::Env::new(), stmt)?;
|
||||||
}
|
}
|
||||||
|
|
||||||
let mut codegen = codegen_x86_64::CodegenX86_64::new(&symbol_table, &typechecker.expr_types);
|
let mut codegen =
|
||||||
|
codegen_x86_64::CodegenX86_64::new(&symbol_table, &typechecker.expr_types, args.emit_debug);
|
||||||
codegen.emit_prologue(args.use_crt)?;
|
codegen.emit_prologue(args.use_crt)?;
|
||||||
for stmt in statements {
|
for stmt in statements {
|
||||||
codegen.compile_stmt(&mut codegen_x86_64::Env::new(), &stmt)?;
|
codegen.compile_stmt(&mut codegen_x86_64::Env::new(), &stmt)?;
|
||||||
@@ -63,19 +64,18 @@ fn compile_file(args: Args) -> Result<(), ZernError> {
|
|||||||
if !args.emit_only {
|
if !args.emit_only {
|
||||||
let out = args.out.unwrap_or_else(|| "out".into());
|
let out = args.out.unwrap_or_else(|| "out".into());
|
||||||
|
|
||||||
fs::write(format!("{}.s", out), codegen.get_output()).unwrap();
|
fs::write(format!("{out}.s"), codegen.get_output()).unwrap();
|
||||||
|
|
||||||
run_command(format!("nasm -f elf64 -o {}.o {}.s", out, out));
|
run_command(format!("nasm -f elf64 -o {out}.o {out}.s"));
|
||||||
|
|
||||||
if args.use_crt {
|
if args.use_crt {
|
||||||
run_command(format!(
|
run_command(format!(
|
||||||
"cc -no-pie -o {} {}.o -flto -Wl,--gc-sections {}",
|
"cc -no-pie -o {out} {out}.o -flto -Wl,--gc-sections {}",
|
||||||
out, out, args.cflags
|
args.cflags
|
||||||
));
|
));
|
||||||
} else {
|
} else {
|
||||||
run_command(format!(
|
run_command(format!(
|
||||||
"ld -static -o {} {}.o --gc-sections -e _start",
|
"ld -static -o {out} {out}.o --gc-sections -e _start"
|
||||||
out, out
|
|
||||||
));
|
));
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -113,6 +113,7 @@ struct Args {
|
|||||||
path: String,
|
path: String,
|
||||||
out: Option<String>,
|
out: Option<String>,
|
||||||
emit_only: bool,
|
emit_only: bool,
|
||||||
|
emit_debug: bool,
|
||||||
include_stdlib: bool,
|
include_stdlib: bool,
|
||||||
run_exe: bool,
|
run_exe: bool,
|
||||||
use_crt: bool,
|
use_crt: bool,
|
||||||
@@ -127,6 +128,7 @@ impl Args {
|
|||||||
path: String::new(),
|
path: String::new(),
|
||||||
out: None,
|
out: None,
|
||||||
emit_only: false,
|
emit_only: false,
|
||||||
|
emit_debug: false,
|
||||||
include_stdlib: true,
|
include_stdlib: true,
|
||||||
run_exe: false,
|
run_exe: false,
|
||||||
use_crt: false,
|
use_crt: false,
|
||||||
@@ -150,6 +152,8 @@ impl Args {
|
|||||||
out.run_exe = true;
|
out.run_exe = true;
|
||||||
} else if arg == "-m" {
|
} else if arg == "-m" {
|
||||||
out.use_crt = true;
|
out.use_crt = true;
|
||||||
|
} else if arg == "-g" {
|
||||||
|
out.emit_debug = true;
|
||||||
} else if arg == "-C" {
|
} else if arg == "-C" {
|
||||||
match args.next() {
|
match args.next() {
|
||||||
Some(s) => out.cflags = s,
|
Some(s) => out.cflags = s,
|
||||||
@@ -160,16 +164,16 @@ impl Args {
|
|||||||
}
|
}
|
||||||
} else if arg == "-h" || arg == "--help" {
|
} else if arg == "-h" || arg == "--help" {
|
||||||
println!(
|
println!(
|
||||||
"Usage: zern [-o path] [-r] [-m] [-C cflags] [--emit-only] [--no-stdlib] path"
|
"Usage: zern [-o path] [-r] [-m] [-g] [-C cflags] [--emit-only] [--no-stdlib] path"
|
||||||
);
|
);
|
||||||
process::exit(0);
|
process::exit(0);
|
||||||
} else if arg.starts_with('-') {
|
} else if arg.starts_with('-') {
|
||||||
eprintln!("\x1b[91mERROR\x1b[0m: unrecognized option: {}", arg);
|
eprintln!("\x1b[91mERROR\x1b[0m: unrecognized option: {arg}");
|
||||||
process::exit(1);
|
process::exit(1);
|
||||||
} else if out.path.is_empty() {
|
} else if out.path.is_empty() {
|
||||||
out.path = arg
|
out.path = arg
|
||||||
} else {
|
} else {
|
||||||
eprintln!("\x1b[91mERROR\x1b[0m: unrecognized argument: {}", arg);
|
eprintln!("\x1b[91mERROR\x1b[0m: unrecognized argument: {arg}");
|
||||||
process::exit(1);
|
process::exit(1);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -495,9 +495,6 @@ func str.find[haystack: str, needle: str] : i64
|
|||||||
return -1
|
return -1
|
||||||
|
|
||||||
func str.substr[s: str, start: i64, length: i64] : str
|
func str.substr[s: str, start: i64, length: i64] : str
|
||||||
if start < 0 || length < 0 || start + length > str.len(s)
|
|
||||||
panic("str.substr out of bounds")
|
|
||||||
|
|
||||||
out := mem.alloc(length + 1) as str
|
out := mem.alloc(length + 1) as str
|
||||||
mem.copy(s as ptr + start, out as ptr, length)
|
mem.copy(s as ptr + start, out as ptr, length)
|
||||||
out[length] = 0
|
out[length] = 0
|
||||||
@@ -1038,6 +1035,12 @@ func os.exit[code: i64] : void
|
|||||||
func os.getpid[] : i64
|
func os.getpid[] : i64
|
||||||
return _builtin_syscall(SYS_getpid)
|
return _builtin_syscall(SYS_getpid)
|
||||||
|
|
||||||
|
func os.basename[path: str] : str
|
||||||
|
i := path->len() - 1
|
||||||
|
while i >= 0 && path[i] != '/'
|
||||||
|
i -= 1
|
||||||
|
return path->substr(i + 1, path->len() - i - 1)
|
||||||
|
|
||||||
struct os.Timespec
|
struct os.Timespec
|
||||||
tv_sec: i64
|
tv_sec: i64
|
||||||
tv_nsec: i64
|
tv_nsec: i64
|
||||||
|
|||||||
@@ -260,7 +260,7 @@ impl Tokenizer {
|
|||||||
break;
|
break;
|
||||||
} else if self.peek() == '\n' {
|
} else if self.peek() == '\n' {
|
||||||
self.loc.line += 1;
|
self.loc.line += 1;
|
||||||
self.loc.column = 1;
|
self.loc.column = 0;
|
||||||
}
|
}
|
||||||
self.advance();
|
self.advance();
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user