1
0
Fork 0
forked from koniifer/ableos

adding simple cli

This commit is contained in:
mlokr 2024-05-13 00:02:32 +02:00
parent c3cbd054f7
commit 5c38115119
5 changed files with 43 additions and 38 deletions

View file

@ -3,6 +3,10 @@ name = "hblang"
version = "0.1.0" version = "0.1.0"
edition = "2021" edition = "2021"
[[bin]]
name = "hbc"
path = "src/main.rs"
[dependencies] [dependencies]
[dev-dependencies] [dev-dependencies]

View file

@ -307,8 +307,9 @@ impl<'a> std::fmt::Display for TypeDisplay<'a> {
} }
} }
#[derive(Default)]
pub struct Codegen<'a> { pub struct Codegen<'a> {
path: &'a std::path::Path, path: &'a str,
input: &'a [u8], input: &'a [u8],
ret: Type, ret: Type,
gpa: RegAlloc, gpa: RegAlloc,
@ -325,31 +326,7 @@ pub struct Codegen<'a> {
} }
impl<'a> Codegen<'a> { impl<'a> Codegen<'a> {
pub fn new() -> Self { pub fn file(&mut self, path: &'a str, input: &'a [u8], exprs: &'a [parser::Expr<'a>]) {
Self {
path: std::path::Path::new(""),
input: &[],
ret: bt::VOID,
gpa: Default::default(),
code: Default::default(),
temp: Default::default(),
labels: Default::default(),
stack_size: 0,
vars: Default::default(),
ret_relocs: Default::default(),
loops: Default::default(),
records: Default::default(),
pointers: Default::default(),
main: None,
}
}
pub fn file(
&mut self,
path: &'a std::path::Path,
input: &'a [u8],
exprs: &'a [parser::Expr<'a>],
) -> std::fmt::Result {
self.path = path; self.path = path;
self.input = input; self.input = input;
@ -442,7 +419,6 @@ impl<'a> Codegen<'a> {
_ => unreachable!(), _ => unreachable!(),
} }
} }
Ok(())
} }
fn align_of(&self, ty: Type) -> u64 { fn align_of(&self, ty: Type) -> u64 {
@ -1168,7 +1144,7 @@ impl<'a> Codegen<'a> {
fn report(&self, pos: parser::Pos, msg: impl std::fmt::Display) -> ! { fn report(&self, pos: parser::Pos, msg: impl std::fmt::Display) -> ! {
let (line, col) = lexer::line_col(self.input, pos); let (line, col) = lexer::line_col(self.input, pos);
println!("{}:{}:{}: {}", self.path.display(), line, col, msg); println!("{}:{}:{}: {}", self.path, line, col, msg);
unreachable!(); unreachable!();
} }
} }
@ -1276,12 +1252,12 @@ mod tests {
} }
fn generate(input: &'static str, output: &mut String) { fn generate(input: &'static str, output: &mut String) {
let path = std::path::Path::new("test"); let path = "test";
let arena = crate::parser::Arena::default(); let arena = crate::parser::Arena::default();
let mut parser = super::parser::Parser::new(input, path, &arena); let mut parser = super::parser::Parser::new(input, path, &arena);
let exprs = parser.file(); let exprs = parser.file();
let mut codegen = super::Codegen::new(); let mut codegen = super::Codegen::default();
codegen.file(path, input.as_bytes(), &exprs).unwrap(); codegen.file(path, input.as_bytes(), &exprs);
let mut out = Vec::new(); let mut out = Vec::new();
codegen.dump(&mut out).unwrap(); codegen.dump(&mut out).unwrap();

View file

@ -15,12 +15,12 @@ macro_rules! run_tests {
)*}; )*};
} }
mod codegen; pub mod codegen;
mod ident; mod ident;
mod instrs; mod instrs;
mod lexer; mod lexer;
mod log; mod log;
mod parser; pub mod parser;
mod tests; mod tests;
mod typechk; mod typechk;

25
hblang/src/main.rs Normal file
View file

@ -0,0 +1,25 @@
use std::io;
use hblang::{codegen, parser};
fn main() -> io::Result<()> {
if std::env::args().len() == 1 {
eprintln!("Usage: hblang <file1> <file2> ...");
eprintln!(" 1. compiled binary will be printed to stdout");
eprintln!(" 2. order of files matters");
std::process::exit(1);
}
let files = std::env::args()
.skip(1)
.map(|path| std::fs::read_to_string(&path).map(|src| (path, src)))
.collect::<io::Result<Vec<_>>>()?;
let mut arena = parser::Arena::default();
let mut codegen = codegen::Codegen::default();
for (path, content) in files.iter() {
let file = parser::Parser::new(content, path, &arena).file();
codegen.file(path, content.as_bytes(), file);
arena.clear();
}
codegen.dump(&mut std::io::stdout())
}

View file

@ -15,7 +15,7 @@ struct ScopeIdent<'a> {
} }
pub struct Parser<'a, 'b> { pub struct Parser<'a, 'b> {
path: &'a std::path::Path, path: &'a str,
lexer: Lexer<'a>, lexer: Lexer<'a>,
arena: &'b Arena<'a>, arena: &'b Arena<'a>,
token: Token, token: Token,
@ -23,7 +23,7 @@ pub struct Parser<'a, 'b> {
} }
impl<'a, 'b> Parser<'a, 'b> { impl<'a, 'b> Parser<'a, 'b> {
pub fn new(input: &'a str, path: &'a std::path::Path, arena: &'b Arena<'a>) -> Self { pub fn new(input: &'a str, path: &'a str, arena: &'b Arena<'a>) -> Self {
let mut lexer = Lexer::new(input); let mut lexer = Lexer::new(input);
let token = lexer.next(); let token = lexer.next();
Self { Self {
@ -43,7 +43,7 @@ impl<'a, 'b> Parser<'a, 'b> {
let (line, col) = self.lexer.line_col(ident::pos(id.ident)); let (line, col) = self.lexer.line_col(ident::pos(id.ident));
eprintln!( eprintln!(
"{}:{}:{} => undeclared identifier: {}", "{}:{}:{} => undeclared identifier: {}",
self.path.display(), self.path,
line, line,
col, col,
self.lexer.slice(ident::range(id.ident)) self.lexer.slice(ident::range(id.ident))
@ -327,7 +327,7 @@ impl<'a, 'b> Parser<'a, 'b> {
fn report(&self, msg: impl std::fmt::Display) -> ! { fn report(&self, msg: impl std::fmt::Display) -> ! {
let (line, col) = self.lexer.line_col(self.token.start); let (line, col) = self.lexer.line_col(self.token.start);
eprintln!("{}:{}:{} => {}", self.path.display(), line, col, msg); eprintln!("{}:{}:{} => {}", self.path, line, col, msg);
unreachable!(); unreachable!();
} }
} }
@ -717,7 +717,7 @@ mod tests {
fn parse(input: &'static str, output: &mut String) { fn parse(input: &'static str, output: &mut String) {
use std::fmt::Write; use std::fmt::Write;
let mut arena = super::Arena::default(); let mut arena = super::Arena::default();
let mut parser = super::Parser::new(input, std::path::Path::new("test"), &arena); let mut parser = super::Parser::new(input, "test", &arena);
for expr in parser.file() { for expr in parser.file() {
writeln!(output, "{}", expr).unwrap(); writeln!(output, "{}", expr).unwrap();
} }