assembler still very broken, dependency resolution works, now working on expanding pseudoinstructions
This commit is contained in:
+92
-3
@@ -1,14 +1,91 @@
|
||||
use core::fmt;
|
||||
use std::{
|
||||
collections::HashSet,
|
||||
fs,
|
||||
hash::{DefaultHasher, Hash, Hasher},
|
||||
path::PathBuf,
|
||||
};
|
||||
|
||||
use common::prelude::Instruction;
|
||||
|
||||
use crate::{lexer::Token, parser::TokenType};
|
||||
use crate::{
|
||||
model::{Node, Token, TokenType},
|
||||
parser::{Parser, Program},
|
||||
};
|
||||
|
||||
pub mod lexer;
|
||||
pub mod model;
|
||||
pub mod parser;
|
||||
|
||||
pub fn assemble(_src: &str) -> Vec<Instruction> {
|
||||
todo!()
|
||||
pub fn assemble(src: &PathBuf) -> Vec<Instruction> {
|
||||
let mut modules = HashSet::<u64>::new();
|
||||
let mut program = Program::new();
|
||||
|
||||
let hash = quick_hash(src);
|
||||
modules.insert(hash);
|
||||
|
||||
match prepare_dependency(src.clone(), &mut modules, &mut program) {
|
||||
Ok(_) => {}
|
||||
Err(err) => println!("BIG ERROR {:?}", err),
|
||||
}
|
||||
|
||||
for node in program.nodes {
|
||||
println!("{:?}", node);
|
||||
}
|
||||
|
||||
vec![]
|
||||
}
|
||||
|
||||
fn prepare_dependency(
|
||||
path: PathBuf,
|
||||
modules: &mut HashSet<u64>,
|
||||
program: &mut Program,
|
||||
) -> Result<(), AssembleError> {
|
||||
let filename = path.file_name().unwrap().to_str().unwrap();
|
||||
if let Ok(path) = path.canonicalize() {
|
||||
log(&format!(
|
||||
"{:20} {:20} [{}]",
|
||||
"Building",
|
||||
filename,
|
||||
path.display()
|
||||
));
|
||||
}
|
||||
|
||||
let src = fs::read_to_string(&path)
|
||||
.map_err(|_| AssembleError::InvalidFile(path.clone()))?;
|
||||
let file_hash = quick_hash(&path);
|
||||
|
||||
log(&format!("{:20} {:20}", "Tokenising", filename));
|
||||
let tokens = lexer::lexer(src, file_hash)?;
|
||||
|
||||
log(&format!("{:20} {:20}", "Parsing", filename));
|
||||
let mut parser = Parser::new(tokens);
|
||||
|
||||
log(&format!("{:20} {:20}", "Resolving Deps", filename));
|
||||
let deps = parser
|
||||
.parse_nodes()?
|
||||
.resolve_dependencies()?
|
||||
.get_dependencies()?;
|
||||
program.add_module(parser.get());
|
||||
|
||||
for dep in deps {
|
||||
log(&format!(
|
||||
"{:20} {:20}",
|
||||
"Including",
|
||||
dep.file_name().unwrap().to_str().unwrap()
|
||||
));
|
||||
|
||||
if !modules.contains(&quick_hash(&dep)) {
|
||||
modules.insert(quick_hash(&dep));
|
||||
prepare_dependency(dep, modules, program)?
|
||||
}
|
||||
}
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn build(src: Vec<Node>) -> Result<Vec<Instruction>, AssembleError> {
|
||||
Ok(vec![])
|
||||
}
|
||||
|
||||
/// TODO: disassembling functionality
|
||||
@@ -23,6 +100,7 @@ pub fn disassemble(_: Vec<Instruction>) -> String {
|
||||
#[derive(Debug)]
|
||||
pub enum AssembleError {
|
||||
Generic,
|
||||
InvalidFile(PathBuf),
|
||||
UnexpectedToken(Token, TokenType),
|
||||
}
|
||||
|
||||
@@ -33,6 +111,17 @@ impl fmt::Display for AssembleError {
|
||||
AssembleError::UnexpectedToken(tok, expected) => {
|
||||
write!(f, "Unexpected token {tok:?}, expected {expected:?}")
|
||||
}
|
||||
AssembleError::InvalidFile(path) => write!(f, "Invalid file {path:?}"),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fn quick_hash(value: &PathBuf) -> u64 {
|
||||
let mut hasher = DefaultHasher::new();
|
||||
value.canonicalize().unwrap().to_str().hash(&mut hasher);
|
||||
hasher.finish()
|
||||
}
|
||||
|
||||
fn log(message: &str) {
|
||||
println!("\x1b[32mINFO:\x1b[0m {}", message);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user