| 
						
						
							
								
							
						
						
					 | 
					 | 
					@ -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))?) | 
				
			
			
				
				
			
		
	
		
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					} | 
					 | 
					 | 
					 | 
					} | 
				
			
			
		
	
	
		
		
			
				
					| 
						
						
						
					 | 
					 | 
					
  |