|
|
@ -11,26 +11,25 @@ use crate::builtin::BuiltinOps; |
|
|
|
use crate::runtime::run_thread::{RunState, ThreadInfo, ThreadToken}; |
|
|
|
use crate::runtime::run_thread::{RunState, ThreadInfo, ThreadToken}; |
|
|
|
use crate::runtime::frame::REG_COUNT; |
|
|
|
use crate::runtime::frame::REG_COUNT; |
|
|
|
use std::sync::atomic::AtomicU32; |
|
|
|
use std::sync::atomic::AtomicU32; |
|
|
|
|
|
|
|
use std::path::{Path}; |
|
|
|
|
|
|
|
|
|
|
|
pub mod data; |
|
|
|
pub mod data; |
|
|
|
pub mod error; |
|
|
|
pub mod error; |
|
|
|
pub mod instr; |
|
|
|
pub mod instr; |
|
|
|
pub mod parse; |
|
|
|
pub mod parse; |
|
|
|
pub mod patches; |
|
|
|
pub mod patches; |
|
|
|
|
|
|
|
mod read_file; |
|
|
|
|
|
|
|
use read_file::read_file; |
|
|
|
|
|
|
|
|
|
|
|
/// Parse a program from string and assemble a low level instruction sequence from it.
|
|
|
|
pub(crate) fn read_source_file(path: impl AsRef<Path>) -> Result<String, error::CrsnError> { |
|
|
|
pub fn assemble(source: &str, uniq : &CrsnUniq, mut parsers: Vec<Box<dyn CrsnExtension>>) -> Result<Arc<Program>, error::CrsnError> { |
|
|
|
trace!("Read source file: {}", path.as_ref().display()); |
|
|
|
parsers.insert(0, BuiltinOps::new()); |
|
|
|
|
|
|
|
for p in &mut parsers { |
|
|
|
|
|
|
|
p.init(uniq); |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
let parsers_arc = Arc::new(parsers); |
|
|
|
let source = read_file(path)?; |
|
|
|
|
|
|
|
|
|
|
|
// remove first line if it looks like a shebang
|
|
|
|
// remove first line if it looks like a shebang
|
|
|
|
let source = if source.starts_with("#!") { |
|
|
|
let s = if source.starts_with("#!") { |
|
|
|
if let Some(nl) = source.find('\n') { |
|
|
|
if let Some(nl) = source.find('\n') { |
|
|
|
&source[nl + 1..] |
|
|
|
(&source[nl + 1..]).to_string() |
|
|
|
} else { |
|
|
|
} else { |
|
|
|
source |
|
|
|
source |
|
|
|
} |
|
|
|
} |
|
|
@ -38,10 +37,25 @@ pub fn assemble(source: &str, uniq : &CrsnUniq, mut parsers: Vec<Box<dyn CrsnExt |
|
|
|
source |
|
|
|
source |
|
|
|
}; |
|
|
|
}; |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
Ok(s) |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/// Parse a program from string and assemble a low level instruction sequence from it.
|
|
|
|
|
|
|
|
pub fn assemble(path: impl AsRef<Path>, uniq : &CrsnUniq, mut parsers: Vec<Box<dyn CrsnExtension>>) -> Result<Arc<Program>, error::CrsnError> { |
|
|
|
|
|
|
|
parsers.insert(0, BuiltinOps::new()); |
|
|
|
|
|
|
|
for p in &mut parsers { |
|
|
|
|
|
|
|
p.init(uniq); |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
let path = path.as_ref().canonicalize()?; |
|
|
|
|
|
|
|
let source = read_source_file(&path)?; |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
let parsers_arc = Arc::new(parsers); |
|
|
|
|
|
|
|
|
|
|
|
let ti = Arc::new(ThreadInfo { |
|
|
|
let ti = Arc::new(ThreadInfo { |
|
|
|
id: ThreadToken(0), |
|
|
|
id: ThreadToken(0), |
|
|
|
uniq: Default::default(), |
|
|
|
uniq: Default::default(), |
|
|
|
program: Program::new(vec![], parsers_arc.clone()).unwrap(), |
|
|
|
program: Program::new(vec![], parsers_arc.clone(), vec![path.clone()]).unwrap(), |
|
|
|
cycle_time: Default::default(), |
|
|
|
cycle_time: Default::default(), |
|
|
|
scheduler_interval: Default::default(), |
|
|
|
scheduler_interval: Default::default(), |
|
|
|
extensions: parsers_arc.clone(), |
|
|
|
extensions: parsers_arc.clone(), |
|
|
@ -72,12 +86,27 @@ pub fn assemble(source: &str, uniq : &CrsnUniq, mut parsers: Vec<Box<dyn CrsnExt |
|
|
|
}, |
|
|
|
}, |
|
|
|
const_eval_ti: ti, |
|
|
|
const_eval_ti: ti, |
|
|
|
parsing_expr: false, |
|
|
|
parsing_expr: false, |
|
|
|
label_num: label_num.clone() |
|
|
|
label_num: label_num.clone(), |
|
|
|
|
|
|
|
files: vec![ |
|
|
|
|
|
|
|
path, |
|
|
|
|
|
|
|
], |
|
|
|
|
|
|
|
active_file: 0 |
|
|
|
}), |
|
|
|
}), |
|
|
|
}; |
|
|
|
}; |
|
|
|
|
|
|
|
|
|
|
|
let ops = parse::parse(source, &SourcePosition::default(), &pcx)?; |
|
|
|
let res = do_parse(&source, &pcx, parsers_arc.clone()); |
|
|
|
|
|
|
|
if let Err(e) = &res { |
|
|
|
|
|
|
|
if let Some(pos) = e.pos() { |
|
|
|
|
|
|
|
let f = pcx.state.borrow().files[pos.file as usize].clone(); |
|
|
|
|
|
|
|
eprintln!("Error in source file: {}", f.display()); |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
res |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
fn do_parse(source: &str, pcx : &ParserContext, parsers_arc : Arc<Vec<Box<dyn CrsnExtension>>>) -> Result<Arc<Program>, error::CrsnError> { |
|
|
|
|
|
|
|
let ops = parse::parse(source, &SourcePosition::default(), pcx)?; |
|
|
|
let ops = jumps_to_skips(ops)?; |
|
|
|
let ops = jumps_to_skips(ops)?; |
|
|
|
|
|
|
|
|
|
|
|
Ok(Program::new(ops, parsers_arc)?) |
|
|
|
Ok(Program::new(ops, parsers_arc, pcx.state.borrow_mut().files.split_off(0))?) |
|
|
|
} |
|
|
|
} |
|
|
|