|  |  | @ -6,9 +6,12 @@ use sexp::{Atom, Sexp, SourcePosition}; | 
			
		
	
		
		
			
				
					
					|  |  |  | use crate::asm::data::{DataDisp, Rd, RdData, reg, Wr, WrData, RdWr}; |  |  |  | use crate::asm::data::{DataDisp, Rd, RdData, reg, Wr, WrData, RdWr}; | 
			
		
	
		
		
			
				
					
					|  |  |  | use crate::asm::data::literal::{ConstantName, Label, RegisterAlias, Value}; |  |  |  | use crate::asm::data::literal::{ConstantName, Label, RegisterAlias, Value}; | 
			
		
	
		
		
			
				
					
					|  |  |  | use crate::asm::error::CrsnError; |  |  |  | use crate::asm::error::CrsnError; | 
			
		
	
		
		
			
				
					
					|  |  |  | use crate::asm::parse::ParserContext; |  |  |  | use crate::asm::parse::{ParserContext, parse_instructions}; | 
			
				
				
			
		
	
		
		
	
		
		
			
				
					
					|  |  |  | use crate::asm::parse::sexp_expect::expect_string_atom; |  |  |  | use crate::asm::parse::sexp_expect::expect_string_atom; | 
			
		
	
		
		
			
				
					
					|  |  |  | use crate::asm::patches::ErrWithPos; |  |  |  | use crate::asm::patches::ErrWithPos; | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | use std::sync::atomic::AtomicU32; | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | use crate::module::OpTrait; | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | use crate::asm::instr::Cond; | 
			
		
	
		
		
			
				
					
					|  |  |  | 
 |  |  |  | 
 | 
			
		
	
		
		
			
				
					
					|  |  |  | fn is_valid_identifier(name: &str) -> bool { |  |  |  | fn is_valid_identifier(name: &str) -> bool { | 
			
		
	
		
		
			
				
					
					|  |  |  |     // ascii symbols "!\"#$_&'()*+,-./:;<=>?@[\\]^_`{|}~"
 |  |  |  |     // ascii symbols "!\"#$_&'()*+,-./:;<=>?@[\\]^_`{|}~"
 | 
			
		
	
	
		
		
			
				
					|  |  | @ -87,7 +90,51 @@ pub fn parse_data_disp(tok: Sexp, pcx: &ParserContext) -> Result<DataDisp, CrsnE | 
			
		
	
		
		
			
				
					
					|  |  |  |         Sexp::Atom(Atom::QS(_s), pos) => { |  |  |  |         Sexp::Atom(Atom::QS(_s), pos) => { | 
			
		
	
		
		
			
				
					
					|  |  |  |             Err(CrsnError::Parse("Quoted string not expected here".into(), pos)) |  |  |  |             Err(CrsnError::Parse("Quoted string not expected here".into(), pos)) | 
			
		
	
		
		
			
				
					
					|  |  |  |         } |  |  |  |         } | 
			
		
	
		
		
			
				
					
					|  |  |  |         Sexp::List(_list, pos) => { |  |  |  |         Sexp::List(list, pos) => { | 
			
				
				
			
		
	
		
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |             if let Some(Sexp::Atom(Atom::S(s), s_pos)) = list.first() { | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |                 let parsing_expr = pcx.state.borrow().parsing_expr; | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | 
 | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |                 if !s.starts_with('=') && !parsing_expr { | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |                     return Err(CrsnError::Parse(format!("Invalid syntax, did you mean \"={}\"?", s).into(), s_pos.clone())); | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |                 } | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | 
 | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |                 // start expr parsing mode
 | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |                 let orig_parsing_expr = pcx.state.borrow().parsing_expr; | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |                 pcx.state.borrow_mut().parsing_expr = true; | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | 
 | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |                 let lmut = AtomicU32::new(0); | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | 
 | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |                 let mut expr_ops = parse_instructions( | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |                     // TODO avoid this madness
 | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |                     vec![Sexp::List(list, pos.clone())].into_iter(), | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |                     &pos, pcx)? | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |                     .flatten(&lmut)?; | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | 
 | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |                 if expr_ops.len() != 1 { | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |                     return Err(CrsnError::Parse(format!("Expected one top level operation in an expression, got: {:?}", expr_ops).into(), pos.clone())); | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |                 } | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | 
 | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |                 let op = expr_ops.remove(0); | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | 
 | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |                 let mut state_mut = pcx.state.borrow_mut(); | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |                 state_mut.const_eval.clear_all(); | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | 
 | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |                 let ticl = state_mut.const_eval.thread_info.clone(); | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |                 op.execute(&ticl, &mut state_mut.const_eval) | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |                     .map_err(|f| CrsnError::ParseOther(Box::new(f), pos.clone()))?; | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | 
 | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |                 if state_mut.const_eval.test_cond(Cond::Invalid) { | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |                     return Err(CrsnError::Parse("Expression evaluation failed - invalid flag set!".into(), pos.clone())); | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |                 } | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | 
 | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |                 if !orig_parsing_expr { | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |                     // exit expr parsing mode
 | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |                     state_mut.parsing_expr = false; | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |                 } | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | 
 | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |                 return Ok(DataDisp::Immediate(state_mut.const_eval.frame.gen[0])); | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |             } | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | 
 | 
			
		
	
		
		
			
				
					
					|  |  |  |             Err(CrsnError::Parse("List not expected here".into(), pos)) |  |  |  |             Err(CrsnError::Parse("List not expected here".into(), pos)) | 
			
		
	
		
		
			
				
					
					|  |  |  |         } |  |  |  |         } | 
			
		
	
		
		
			
				
					
					|  |  |  |         Sexp::Atom(Atom::S(s), pos) => { |  |  |  |         Sexp::Atom(Atom::S(s), pos) => { | 
			
		
	
	
		
		
			
				
					|  |  | 
 |