make macros for logger

This commit is contained in:
MCorange 2023-03-19 13:09:10 +02:00
parent d68b12fdf8
commit 5cc80619c2
11 changed files with 67 additions and 36 deletions

1
.gitignore vendored
View File

@ -1 +1,2 @@
/target /target
a

View File

@ -3,14 +3,14 @@ mem 98 + 1 @8
0 while dup 98 < do 0 while dup 98 < do
0 while dup 100 < do 0 while dup 100 < do
dup mem + !8 if dup mem + !8 if
dup mem + 100 + "*" @8 dup mem + 100 + 42 @8
else else
dup mem + 100 + " " @8 dup mem + 100 + 32 @8
end end
1 + 1 +
end end
mem + 100 + "\n" @8 mem + 100 + 10 @8
101 mem 100 + 1 1 syscall3 drop 101 mem 100 + 1 1 syscall3 drop

View File

@ -1,7 +1,7 @@
use std::path::PathBuf; use std::path::PathBuf;
use std::process::{Command, Stdio}; use std::process::{Command, Stdio};
use color_eyre::Result; use color_eyre::Result;
use crate::util::logger; use crate::info;
pub fn linux_x86_64_compile_and_link(of_a: &PathBuf, of_o: &PathBuf, of_c: &PathBuf, quiet: bool) -> Result<()> { pub fn linux_x86_64_compile_and_link(of_a: &PathBuf, of_o: &PathBuf, of_c: &PathBuf, quiet: bool) -> Result<()> {
@ -29,12 +29,12 @@ pub fn linux_x86_64_compile_and_link(of_a: &PathBuf, of_o: &PathBuf, of_c: &Path
.spawn()? .spawn()?
}; };
if !quiet { if !quiet {
logger::info(format!("running 'nasm {}'", nasm_args.join(" ")).as_str()); info!("running 'nasm {}'", nasm_args.join(" "));
} }
let exit = proc.wait()?; let exit = proc.wait()?;
if !quiet { if !quiet {
logger::info(format!("nasm process exited with code {}", exit).as_str()); info!("nasm process exited with code {}", exit);
} }
@ -48,11 +48,11 @@ pub fn linux_x86_64_compile_and_link(of_a: &PathBuf, of_o: &PathBuf, of_c: &Path
.spawn()? .spawn()?
}; };
if !quiet { if !quiet {
logger::info(format!("running 'ld {}'", ld_args.join(" ")).as_str()); info!("running 'ld {}'", ld_args.join(" "));
} }
let exit2 = proc2.wait()?; let exit2 = proc2.wait()?;
if !quiet { if !quiet {
logger::info(format!("ld process exited with code {}", exit2).as_str()); info!("ld process exited with code {}", exit2);
} }
@ -77,11 +77,11 @@ pub fn linux_x86_64_run(_bin: &PathBuf, args: Vec<String>, quiet: bool) -> Resul
}; };
// println!("{}", quiet); // println!("{}", quiet);
if !quiet { if !quiet {
logger::info(format!("running {} {}", _bin.to_string_lossy(), args.join(" ")).as_str()); info!("running {} {}", _bin.to_string_lossy(), args.join(" "));
} }
let exit = proc.wait()?; let exit = proc.wait()?;
if !quiet { if !quiet {
logger::info(format!("{} process exited with code {}", _bin.to_string_lossy(), exit).as_str()); info!("{} process exited with code {}", _bin.to_string_lossy(), exit);
} }
Ok(exit.code().unwrap_or(0)) Ok(exit.code().unwrap_or(0))

View File

@ -8,8 +8,15 @@ use super::commands::linux_x86_64_run;
pub fn compile(tokens: Vec<Operator>, args: Args) -> Result<()>{ pub fn compile(tokens: Vec<Operator>, args: Args) -> Result<()>{
let mut of_c = PathBuf::from(&args.out_file); let mut of_c = PathBuf::from(&args.out_file);
let mut of_o = PathBuf::from(&args.out_file); let (mut of_o, mut of_a) = if &args.out_file == &crate::DEFAULT_OUT_FILE.to_string() {
let mut of_a = PathBuf::from(&args.out_file); let of_o = PathBuf::from("/tmp/mclang_comp.o");
let of_a = PathBuf::from("/tmp/mclang_comp.nasm");
(of_o, of_a)
} else {
let of_o = PathBuf::from(&args.out_file);
let of_a = PathBuf::from(&args.out_file);
(of_o, of_a)
};
of_c.set_extension(""); of_c.set_extension("");
of_o.set_extension("o"); of_o.set_extension("o");
@ -75,7 +82,7 @@ pub fn compile(tokens: Vec<Operator>, args: Args) -> Result<()>{
ti += 1; ti += 1;
}, },
OpType::PushStr => { OpType::PushStr => {
writeln!(writer, " ;; -- push str \"{}\"", token.text)?; writeln!(writer, " ;; -- push str \"{}\"", token.text.escape_default())?;
writeln!(writer, " mov rax, {}", token.text.len())?; writeln!(writer, " mov rax, {}", token.text.len())?;
writeln!(writer, " push rax")?; writeln!(writer, " push rax")?;
writeln!(writer, " push str_{}", strings.len())?; writeln!(writer, " push str_{}", strings.len())?;

View File

@ -91,3 +91,5 @@ pub enum TokenType {
String, String,
//TODO: Add char //TODO: Add char
} }
pub type Loc = (String, u32, u32);

View File

@ -1,4 +1,4 @@
use crate::{constants::OpType, util::{logger, self}}; use crate::{constants::OpType, lerror, error};
// use crate::util::logger; // use crate::util::logger;
use color_eyre::Result; use color_eyre::Result;
use eyre::eyre; use eyre::eyre;
@ -8,7 +8,7 @@ fn stack_pop(stack: &mut Vec<u64>, pos: &(String, u32, u32)) -> Result<u64> {
match stack.pop() { match stack.pop() {
Some(i) => Ok(i), Some(i) => Ok(i),
None => { None => {
util::logger::pos_error(&pos.clone(), "Stack underflow"); lerror!(&pos.clone(), "Stack underflow");
Err(eyre!("Stack underflow")) Err(eyre!("Stack underflow"))
}, },
} }
@ -245,7 +245,7 @@ pub fn run(tokens: Vec<crate::constants::Operator>) -> Result<()>{
let ret = match rax { let ret = match rax {
1 => syscalls::sys_write(rax, rdi, rsi, rdx, &mem), 1 => syscalls::sys_write(rax, rdi, rsi, rdx, &mem),
_ => { _ => {
logger::error(format!("Syscall(3) #{} is not implemented", rax).as_str()); error!("Syscall(3) #{} is not implemented", rax);
return Err(eyre!("Syscall not implemented")); return Err(eyre!("Syscall not implemented"));
} }
}; };

View File

@ -35,6 +35,9 @@ fn lex_line(text: String) -> Result<Vec<(u32, String, TokenType)>> {
let mut col = find_col(text.clone(), 0, |x, _| !x.is_whitespace())?; let mut col = find_col(text.clone(), 0, |x, _| !x.is_whitespace())?;
let mut col_end: u32 = 0; let mut col_end: u32 = 0;
while col_end < text.clone().len() as u32 { while col_end < text.clone().len() as u32 {
if (text.len() - col as usize) < 1 {
return Ok(tokens);
}
if &text[(col as usize)..(col + 1) as usize] == "\"" { if &text[(col as usize)..(col + 1) as usize] == "\"" {
col_end = find_col(text.clone(), col + 1, |x, x2| x == '"' && x2 != '\\')?; col_end = find_col(text.clone(), col + 1, |x, x2| x == '"' && x2 != '\\')?;
let t = &text[((col + 1) as usize)..(col_end as usize)]; let t = &text[((col + 1) as usize)..(col_end as usize)];

View File

@ -10,6 +10,8 @@ use std::fs;
use color_eyre::Result; use color_eyre::Result;
use clap::Parser; use clap::Parser;
pub const DEFAULT_OUT_FILE: &str = "a.out";
#[derive(Parser, Debug, Clone)] #[derive(Parser, Debug, Clone)]
#[command(author, version, about, long_about = None)] #[command(author, version, about, long_about = None)]
pub struct Args { pub struct Args {
@ -18,7 +20,7 @@ pub struct Args {
in_file: String, in_file: String,
/// Output compiled file /// Output compiled file
#[arg(long, short, default_value_t=String::from("a.out"))] #[arg(long, short, default_value_t=String::from(DEFAULT_OUT_FILE))]
out_file: String, out_file: String,
/// Compile /// Compile
@ -53,13 +55,13 @@ fn main() -> Result<()> {
let mut parser = parser::Parser::new(tokens); let mut parser = parser::Parser::new(tokens);
let tokens = parser.parse()?; let tokens = parser.parse()?;
if args.compile && args.interpret { if args.compile && args.interpret {
util::logger::error("Cannot compile and interpret at the same time"); error!("Cannot compile and interpret at the same time");
} else if args.interpret { } else if args.interpret {
interpret::linux_x86_64::run(tokens)?; interpret::linux_x86_64::run(tokens)?;
} else if args.compile { } else if args.compile {
compile::linux_x86_64::compile(tokens, args)?; compile::linux_x86_64::compile(tokens, args)?;
} else { } else {
util::logger::error("Did not choose to compile or to interpret, exiting"); error!("Did not choose to compile or to interpret, exiting");
} }
Ok(()) Ok(())
} }

View File

@ -1,6 +1,6 @@
use std::{collections::HashMap, ops::Deref}; use std::{collections::HashMap, ops::Deref};
use crate::{constants::{Operator, OpType, Token, TokenType}, util}; use crate::{constants::{Operator, OpType, Token, TokenType}, lerror};
use color_eyre::Result; use color_eyre::Result;
use eyre::eyre; use eyre::eyre;
@ -15,7 +15,7 @@ pub fn cross_ref(mut program: Vec<Operator>) -> Result<Vec<Operator>> {
OpType::Else => { OpType::Else => {
let if_ip = stack.pop().unwrap(); let if_ip = stack.pop().unwrap();
if program[if_ip as usize].typ != OpType::If { if program[if_ip as usize].typ != OpType::If {
util::logger::pos_error(&op.clone().pos,"'end' can only close 'if' blocks"); lerror!(&op.clone().pos,"'end' can only close 'if' blocks");
return Err(eyre!("Bad block")); return Err(eyre!("Bad block"));
} }
@ -37,8 +37,8 @@ pub fn cross_ref(mut program: Vec<Operator>) -> Result<Vec<Operator>> {
program[ip].jmp = program[block_ip as usize].jmp; program[ip].jmp = program[block_ip as usize].jmp;
program[block_ip as usize].jmp = (ip + 1) as i32; program[block_ip as usize].jmp = (ip + 1) as i32;
} else { } else {
util::logger::pos_error(&op.clone().pos,"'end' can only close 'if' blocks"); lerror!(&op.clone().pos,"'end' can only close 'if' blocks");
std::process::exit(1); // idc return Err(eyre!(""));
} }
} }
@ -55,7 +55,7 @@ pub fn cross_ref(mut program: Vec<Operator>) -> Result<Vec<Operator>> {
} }
if stack.len() > 0 { if stack.len() > 0 {
util::logger::pos_error(&program[stack.pop().expect("Empy stack") as usize].clone().pos,"Unclosed block"); lerror!(&program[stack.pop().expect("Empy stack") as usize].clone().pos,"Unclosed block");
return Err(eyre!("Unclosed block")); return Err(eyre!("Unclosed block"));
} }
@ -151,7 +151,7 @@ fn lookup_word<P: Deref<Target = (String, u32, u32)>>(s: String, pos: P) -> Resu
match lookup_table.get(s.as_str()) { match lookup_table.get(s.as_str()) {
Some(v) => Ok(v.clone()), Some(v) => Ok(v.clone()),
None => { None => {
util::logger::pos_error(pos, format!("Unknown word '{}'", s).as_str()); lerror!(pos, "Unknown word '{}'", s);
return Err(eyre!("Unknown word")) return Err(eyre!("Unknown word"))
} }
} }

View File

@ -32,7 +32,7 @@ pub mod logger {
#![allow(dead_code)] #![allow(dead_code)]
use std::ops::Deref; use std::ops::Deref;
use crate::util::color; use crate::{util::color, constants::Loc};
pub fn error(msg: &str) { pub fn error(msg: &str) {
println!("{red}error{r}: {msg}", red=color::FG_RED, r=color::RESET); println!("{red}error{r}: {msg}", red=color::FG_RED, r=color::RESET);
@ -51,20 +51,31 @@ pub mod logger {
} }
pub fn pos_error<P: Deref<Target = (String, u32, u32)>>(pos: P, msg: &str) { pub fn lerror<P: Deref<Target = Loc>>(loc: P, msg: &str) {
println!("{f}:{r}:{c} {red}error{rs}: {msg}", red=color::FG_RED, rs=color::RESET, f=pos.0, r=pos.1, c=pos.2); println!("{f}:{r}:{c} {red}error{rs}: {msg}", red=color::FG_RED, rs=color::RESET, f=loc.0, r=loc.1, c=loc.2);
} }
pub fn pos_warn<P: Deref<Target = (String, u32, u32)>>(pos: P, msg: &str) { pub fn lwarn<P: Deref<Target = Loc>>(loc: P, msg: &str) {
println!("{f}:{r}:{c} {yellow}warn{rs}: {msg}", yellow=color::FG_YELLOW, rs=color::RESET, f=pos.0, r=pos.1, c=pos.2); println!("{f}:{r}:{c} {yellow}warn{rs}: {msg}", yellow=color::FG_YELLOW, rs=color::RESET, f=loc.0, r=loc.1, c=loc.2);
} }
pub fn pos_info<P: Deref<Target = (String, u32, u32)>>(pos: P, msg: &str) { pub fn linfo<P: Deref<Target = Loc>>(loc: P, msg: &str) {
println!("{f}:{r}:{c} {green}info{rs}: {msg}", green=color::FG_GREEN, rs=color::RESET, f=pos.0, r=pos.1, c=pos.2); println!("{f}:{r}:{c} {green}info{rs}: {msg}", green=color::FG_GREEN, rs=color::RESET, f=loc.0, r=loc.1, c=loc.2);
} }
pub fn pos_note<P: Deref<Target = (String, u32, u32)>>(pos: P, msg: &str) { pub fn lnote<P: Deref<Target = Loc>>(loc: P, msg: &str) {
println!("{f}:{r}:{c} {blue}note{rs}: {msg}", blue=color::FG_BLUE, rs=color::RESET, f=pos.0, r=pos.1, c=pos.2); println!("{f}:{r}:{c} {blue}note{rs}: {msg}", blue=color::FG_BLUE, rs=color::RESET, f=loc.0, r=loc.1, c=loc.2);
}
pub mod macros {
#[macro_export] macro_rules! error { ($($arg:tt)*) => { $crate::util::logger::error(std::format_args!($($arg)*).to_string().as_str()) }; }
#[macro_export] macro_rules! warn { ($($arg:tt)*) => { $crate::util::logger::warn( std::format_args!($($arg)*).to_string().as_str()) }; }
#[macro_export] macro_rules! info { ($($arg:tt)*) => { $crate::util::logger::info( std::format_args!($($arg)*).to_string().as_str()) }; }
#[macro_export] macro_rules! note { ($($arg:tt)*) => { $crate::util::logger::note( std::format_args!($($arg)*).to_string().as_str()) }; }
#[macro_export] macro_rules! lerror { ($dst:expr, $($arg:tt)*) => { $crate::util::logger::lerror($dst, std::format_args!($($arg)*).to_string().as_str()) }; }
#[macro_export] macro_rules! lwarn { ($dst:expr, $($arg:tt)*) => { $crate::util::logger::lwarn($dst, std::format_args!($($arg)*).to_string().as_str()) }; }
#[macro_export] macro_rules! linfo { ($dst:expr, $($arg:tt)*) => { $crate::util::logger::linfo($dst, std::format_args!($($arg)*).to_string().as_str()) }; }
#[macro_export] macro_rules! lnote { ($dst:expr, $($arg:tt)*) => { $crate::util::logger::lnote($dst, std::format_args!($($arg)*).to_string().as_str()) }; }
} }
} }

View File

@ -1 +1,6 @@
"Hello world!\n\n\n\n\n\n" 1 1 syscall3 drop mem 0 @8
while mem !8 10 < do
"Hello world!\n" 1 1 syscall3 drop
mem !8 1 + mem swap @8
end drop