| 
						
						
						
					 | 
					 | 
					@ -1,13 +1,15 @@ | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					use std::borrow::Cow; | 
					 | 
					 | 
					 | 
					use std::borrow::Cow; | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					use std::convert::TryFrom; | 
					 | 
					 | 
					 | 
					use std::convert::TryFrom; | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					
 | 
					 | 
					 | 
					 | 
					
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					use sexp::{Atom, Sexp}; | 
					 | 
					 | 
					 | 
					use sexp::{Atom, Sexp, SourcePosition}; | 
				
			
			
				
				
			
		
	
		
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					
 | 
					 | 
					 | 
					 | 
					
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					use crate::asm::data::{DataDisp, Rd, RdData, reg, Wr, WrData}; | 
					 | 
					 | 
					 | 
					use crate::asm::data::{DataDisp, Rd, RdData, reg, Wr, WrData}; | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					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; | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					use crate::asm::parse::sexp_expect::expect_string_atom; | 
					 | 
					 | 
					 | 
					use crate::asm::parse::sexp_expect::expect_string_atom; | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					use std::num::TryFromIntError; | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					use crate::asm::patches::ErrWithPos; | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					
 | 
					 | 
					 | 
					 | 
					
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					fn is_valid_identifier(name: &str) -> bool { | 
					 | 
					 | 
					 | 
					fn is_valid_identifier(name: &str) -> bool { | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					    name.starts_with(|c: char| c.is_ascii_alphabetic() || c == '_') | 
					 | 
					 | 
					 | 
					    name.starts_with(|c: char| c.is_ascii_alphabetic() || c == '_') | 
				
			
			
		
	
	
		
		
			
				
					| 
						
						
						
							
								
							
						
					 | 
					 | 
					@ -15,65 +17,60 @@ fn is_valid_identifier(name: &str) -> bool { | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					} | 
					 | 
					 | 
					 | 
					} | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					
 | 
					 | 
					 | 
					 | 
					
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					/// Parse register alias
 | 
					 | 
					 | 
					 | 
					/// Parse register alias
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					pub fn parse_reg_alias(name: Option<Sexp>) -> Result<RegisterAlias, CrsnError> { | 
					 | 
					 | 
					 | 
					pub fn parse_reg_alias(name: Sexp) -> Result<(RegisterAlias, SourcePosition), CrsnError> { | 
				
			
			
				
				
			
		
	
		
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					    // trace!("parse reg alias: {:?}", name);
 | 
					 | 
					 | 
					 | 
					    // trace!("parse reg alias: {:?}", name);
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					
 | 
					 | 
					 | 
					 | 
					
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					    let name = expect_string_atom(name)?; | 
					 | 
					 | 
					 | 
					    let (name, namepos) = expect_string_atom(name)?; | 
				
			
			
				
				
			
		
	
		
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					
 | 
					 | 
					 | 
					 | 
					
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					    if !is_valid_identifier(&name) { | 
					 | 
					 | 
					 | 
					    if !is_valid_identifier(&name) { | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					        return Err(CrsnError::Parse(format!("\"{}\" is not an allowed register alias.", name).into())); | 
					 | 
					 | 
					 | 
					        return Err(CrsnError::Parse(format!("\"{}\" is not an allowed register alias.", name).into(), namepos)); | 
				
			
			
				
				
			
		
	
		
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					    } | 
					 | 
					 | 
					 | 
					    } | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					
 | 
					 | 
					 | 
					 | 
					
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					    Ok(name) | 
					 | 
					 | 
					 | 
					    Ok((name, namepos)) | 
				
			
			
				
				
			
		
	
		
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					} | 
					 | 
					 | 
					 | 
					} | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					
 | 
					 | 
					 | 
					 | 
					
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					/// Parse constant name
 | 
					 | 
					 | 
					 | 
					/// Parse constant name
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					pub fn parse_constant_name(name: Option<Sexp>) -> Result<ConstantName, CrsnError> { | 
					 | 
					 | 
					 | 
					pub fn parse_constant_name(name: Sexp) -> Result<(ConstantName, SourcePosition), CrsnError> { | 
				
			
			
				
				
			
		
	
		
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					    // trace!("parse const name: {:?}", name);
 | 
					 | 
					 | 
					 | 
					    // trace!("parse const name: {:?}", name);
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					
 | 
					 | 
					 | 
					 | 
					
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					    let name = expect_string_atom(name)?; | 
					 | 
					 | 
					 | 
					    let (name, namepos) = expect_string_atom(name)?; | 
				
			
			
				
				
			
		
	
		
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					
 | 
					 | 
					 | 
					 | 
					
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					    if !is_valid_identifier(&name) { | 
					 | 
					 | 
					 | 
					    if !is_valid_identifier(&name) { | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					        return Err(CrsnError::Parse(format!("\"{}\" is not an allowed constant name.", name).into())); | 
					 | 
					 | 
					 | 
					        return Err(CrsnError::Parse(format!("\"{}\" is not an allowed constant name.", name).into(), namepos)); | 
				
			
			
				
				
			
		
	
		
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					    } | 
					 | 
					 | 
					 | 
					    } | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					
 | 
					 | 
					 | 
					 | 
					
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					    Ok(name) | 
					 | 
					 | 
					 | 
					    Ok((name, namepos)) | 
				
			
			
				
				
			
		
	
		
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					} | 
					 | 
					 | 
					 | 
					} | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					
 | 
					 | 
					 | 
					 | 
					
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					/// Parse a label
 | 
					 | 
					 | 
					 | 
					/// Parse a label
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					pub fn parse_label(name: Option<Sexp>) -> Result<Label, CrsnError> { | 
					 | 
					 | 
					 | 
					pub fn parse_label(name: Sexp) -> Result<Label, CrsnError> { | 
				
			
			
				
				
			
		
	
		
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					    // trace!("parse label: {:?}", name);
 | 
					 | 
					 | 
					 | 
					    // trace!("parse label: {:?}", name);
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					    let name = expect_string_atom(name)?; | 
					 | 
					 | 
					 | 
					    let (name, namepos) = expect_string_atom(name)?; | 
				
			
			
				
				
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					    Ok(parse_label_str(&name)?) | 
					 | 
					 | 
					 | 
					    Ok(parse_label_str(&name, namepos)?) | 
				
			
			
				
				
			
		
	
		
		
	
		
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					} | 
					 | 
					 | 
					 | 
					} | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					
 | 
					 | 
					 | 
					 | 
					
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					pub fn parse_label_str(name: &str) -> Result<Label, CrsnError> { | 
					 | 
					 | 
					 | 
					pub fn parse_label_str(name: &str, pos: SourcePosition) -> Result<Label, CrsnError> { | 
				
			
			
				
				
			
		
	
		
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					    let label = name.trim_start_matches(':'); | 
					 | 
					 | 
					 | 
					    let label = name.trim_start_matches(':'); | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					
 | 
					 | 
					 | 
					 | 
					
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					    Ok(if label.starts_with('#') { | 
					 | 
					 | 
					 | 
					    Ok(if label.starts_with('#') { | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					        Label::Numbered(u32::try_from(parse_u64(&label[1..])?).expect("numbered label fit in u32")) | 
					 | 
					 | 
					 | 
					        let val = parse_u64(&label[1..], pos.clone())?; | 
				
			
			
				
				
			
		
	
		
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					        Label::Numbered(u32::try_from(val).err_pos(pos)?) | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					    } else { | 
					 | 
					 | 
					 | 
					    } else { | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					        Label::Named(label.to_string()) | 
					 | 
					 | 
					 | 
					        Label::Named(label.to_string()) | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					    }) | 
					 | 
					 | 
					 | 
					    }) | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					} | 
					 | 
					 | 
					 | 
					} | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					
 | 
					 | 
					 | 
					 | 
					
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					/// Parse data disposition (address/value, without the read/write restriction)
 | 
					 | 
					 | 
					 | 
					/// Parse data disposition (address/value, without the read/write restriction)
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					pub fn parse_data_disp(tok: Option<Sexp>, pcx: &ParserContext) -> Result<DataDisp, CrsnError> { | 
					 | 
					 | 
					 | 
					pub fn parse_data_disp(tok: Sexp, pcx: &ParserContext) -> Result<DataDisp, CrsnError> { | 
				
			
			
				
				
			
		
	
		
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					    // trace!("parse data: {:?}", tok);
 | 
					 | 
					 | 
					 | 
					    // trace!("parse data: {:?}", tok);
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					
 | 
					 | 
					 | 
					 | 
					
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					    let tok = if let Some(tok) = tok { | 
					 | 
					 | 
					 | 
					 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					        tok | 
					 | 
					 | 
					 | 
					 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					    } else { | 
					 | 
					 | 
					 | 
					 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					        return Err(CrsnError::Parse("Expected data disposition token".into())); | 
					 | 
					 | 
					 | 
					 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					    }; | 
					 | 
					 | 
					 | 
					 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					
 | 
					 | 
					 | 
					 | 
					 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					    // TODO implement masks
 | 
					 | 
					 | 
					 | 
					    // TODO implement masks
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					
 | 
					 | 
					 | 
					 | 
					
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					    match &tok { | 
					 | 
					 | 
					 | 
					    match tok { | 
				
			
			
				
				
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					        Sexp::Atom(Atom::I(val)) => { | 
					 | 
					 | 
					 | 
					        Sexp::Atom(Atom::I(val), pos) => { | 
				
			
			
				
				
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					            Ok(DataDisp::Immediate(unsafe { std::mem::transmute(*val) })) | 
					 | 
					 | 
					 | 
					            Ok(DataDisp::Immediate(unsafe { std::mem::transmute(val) })) | 
				
			
			
				
				
			
		
	
		
		
	
		
		
	
		
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					        } | 
					 | 
					 | 
					 | 
					        } | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					        Sexp::Atom(Atom::S(s)) => { | 
					 | 
					 | 
					 | 
					        Sexp::Atom(Atom::S(s), pos) => { | 
				
			
			
				
				
			
		
	
		
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					            if s == "_" { | 
					 | 
					 | 
					 | 
					            if s == "_" { | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					                return Ok(DataDisp::Discard); | 
					 | 
					 | 
					 | 
					                return Ok(DataDisp::Discard); | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					            } | 
					 | 
					 | 
					 | 
					            } | 
				
			
			
		
	
	
		
		
			
				
					| 
						
						
						
							
								
							
						
					 | 
					 | 
					@ -81,11 +78,11 @@ pub fn parse_data_disp(tok: Option<Sexp>, pcx: &ParserContext) -> Result<DataDis | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					            // check if we have an alias defined
 | 
					 | 
					 | 
					 | 
					            // check if we have an alias defined
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					            { | 
					 | 
					 | 
					 | 
					            { | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					                let pstate = pcx.state.borrow(); | 
					 | 
					 | 
					 | 
					                let pstate = pcx.state.borrow(); | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					                if let Some(val) = pstate.constants.get(s) { | 
					 | 
					 | 
					 | 
					                if let Some(val) = pstate.constants.get(&s) { | 
				
			
			
				
				
			
		
	
		
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					                    return Ok(DataDisp::Immediate(*val)); | 
					 | 
					 | 
					 | 
					                    return Ok(DataDisp::Immediate(*val)); | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					                } | 
					 | 
					 | 
					 | 
					                } | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					
 | 
					 | 
					 | 
					 | 
					
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					                if let Some(val) = pstate.reg_aliases.get(s) { | 
					 | 
					 | 
					 | 
					                if let Some(val) = pstate.reg_aliases.get(&s) { | 
				
			
			
				
				
			
		
	
		
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					                    return Ok(DataDisp::Register(*val)); | 
					 | 
					 | 
					 | 
					                    return Ok(DataDisp::Register(*val)); | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					                } | 
					 | 
					 | 
					 | 
					                } | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					            } | 
					 | 
					 | 
					 | 
					            } | 
				
			
			
		
	
	
		
		
			
				
					| 
						
						
						
							
								
							
						
					 | 
					 | 
					@ -95,63 +92,55 @@ pub fn parse_data_disp(tok: Option<Sexp>, pcx: &ParserContext) -> Result<DataDis | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					                if let Some(val) = pstate.reg_aliases.get(reference) { | 
					 | 
					 | 
					 | 
					                if let Some(val) = pstate.reg_aliases.get(reference) { | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					                    Ok(DataDisp::ObjectPtr(*val)) | 
					 | 
					 | 
					 | 
					                    Ok(DataDisp::ObjectPtr(*val)) | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					                } else { | 
					 | 
					 | 
					 | 
					                } else { | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					                    let reg = reg::parse_reg(reference)?; | 
					 | 
					 | 
					 | 
					                    let reg = reg::parse_reg(reference, pos.clone())?; | 
				
			
			
				
				
			
		
	
		
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					
 | 
					 | 
					 | 
					 | 
					
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					                    if pstate.reg_aliases.values().find(|v| **v == reg).is_some() { | 
					 | 
					 | 
					 | 
					                    if pstate.reg_aliases.values().find(|v| **v == reg).is_some() { | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					                        Err(CrsnError::Parse(format!("Sym exists for register {}, direct access denied. Unsym it if needed.", reg).into())) | 
					 | 
					 | 
					 | 
					                        Err(CrsnError::Parse(format!("Sym exists for register {}, direct access denied. Unsym it if needed.", reg).into(), pos)) | 
				
			
			
				
				
			
		
	
		
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					                    } else { | 
					 | 
					 | 
					 | 
					                    } else { | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					                        Ok(DataDisp::ObjectPtr(reg)) | 
					 | 
					 | 
					 | 
					                        Ok(DataDisp::ObjectPtr(reg)) | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					                    } | 
					 | 
					 | 
					 | 
					                    } | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					                } | 
					 | 
					 | 
					 | 
					                } | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					            } else if s.starts_with(|c: char| c.is_ascii_digit()) { | 
					 | 
					 | 
					 | 
					            } else if s.starts_with(|c: char| c.is_ascii_digit()) { | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					                Ok(DataDisp::Immediate(unsafe { std::mem::transmute(parse_i64(s)?) })) | 
					 | 
					 | 
					 | 
					                Ok(DataDisp::Immediate(unsafe { std::mem::transmute(parse_i64(&s, pos)?) })) | 
				
			
			
				
				
			
		
	
		
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					            } else { | 
					 | 
					 | 
					 | 
					            } else { | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					                let reg = reg::parse_reg(s)?; | 
					 | 
					 | 
					 | 
					                let reg = reg::parse_reg(&s, pos.clone())?; | 
				
			
			
				
				
			
		
	
		
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					
 | 
					 | 
					 | 
					 | 
					
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					                let pstate = pcx.state.borrow(); | 
					 | 
					 | 
					 | 
					                let pstate = pcx.state.borrow(); | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					                if pstate.reg_aliases.values().find(|v| **v == reg).is_some() { | 
					 | 
					 | 
					 | 
					                if pstate.reg_aliases.values().find(|v| **v == reg).is_some() { | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					                    Err(CrsnError::Parse(format!("Sym exists for register {}, direct access denied. Unsym it if needed.", reg).into())) | 
					 | 
					 | 
					 | 
					                    Err(CrsnError::Parse(format!("Sym exists for register {}, direct access denied. Unsym it if needed.", reg).into(), pos)) | 
				
			
			
				
				
			
		
	
		
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					                } else { | 
					 | 
					 | 
					 | 
					                } else { | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					                    Ok(DataDisp::Register(reg)) | 
					 | 
					 | 
					 | 
					                    Ok(DataDisp::Register(reg)) | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					                } | 
					 | 
					 | 
					 | 
					                } | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					            } | 
					 | 
					 | 
					 | 
					            } | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					        } | 
					 | 
					 | 
					 | 
					        } | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					        _ => { | 
					 | 
					 | 
					 | 
					        other => { | 
				
			
			
				
				
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					            Err(CrsnError::Parse(format!("bad data disp: {:?}", tok).into())) | 
					 | 
					 | 
					 | 
					            Err(CrsnError::Parse(format!("bad data disp: {:?}", other).into(), other.pos().clone())) | 
				
			
			
				
				
			
		
	
		
		
	
		
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					        } | 
					 | 
					 | 
					 | 
					        } | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					    } | 
					 | 
					 | 
					 | 
					    } | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					} | 
					 | 
					 | 
					 | 
					} | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					
 | 
					 | 
					 | 
					 | 
					
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					/// Parse immediate value
 | 
					 | 
					 | 
					 | 
					/// Parse immediate value
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					pub fn parse_value(tok: Option<Sexp>, pcx: &ParserContext) -> Result<Value, CrsnError> { | 
					 | 
					 | 
					 | 
					pub fn parse_value(tok: Sexp, pcx: &ParserContext) -> Result<Value, CrsnError> { | 
				
			
			
				
				
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					    let tok = if let Some(tok) = tok { | 
					 | 
					 | 
					 | 
					    match tok { | 
				
			
			
				
				
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					        tok | 
					 | 
					 | 
					 | 
					        Sexp::Atom(Atom::I(val), pos) => { | 
				
			
			
				
				
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					    } else { | 
					 | 
					 | 
					 | 
					            Ok(unsafe { std::mem::transmute(val) }) | 
				
			
			
				
				
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					        return Err(CrsnError::Parse("Expected value token".into())); | 
					 | 
					 | 
					 | 
					 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					    }; | 
					 | 
					 | 
					 | 
					 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					
 | 
					 | 
					 | 
					 | 
					 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					    // trace!("parse value: {:?}", tok);
 | 
					 | 
					 | 
					 | 
					 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					
 | 
					 | 
					 | 
					 | 
					 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					    match &tok { | 
					 | 
					 | 
					 | 
					 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					        Sexp::Atom(Atom::I(val)) => { | 
					 | 
					 | 
					 | 
					 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					            Ok(unsafe { std::mem::transmute(*val) }) | 
					 | 
					 | 
					 | 
					 | 
				
			
			
		
	
		
		
	
		
		
	
		
		
	
		
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					        } | 
					 | 
					 | 
					 | 
					        } | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					        Sexp::Atom(Atom::S(s)) => { | 
					 | 
					 | 
					 | 
					        Sexp::Atom(Atom::S(s), pos) => { | 
				
			
			
				
				
			
		
	
		
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					            let pstate = pcx.state.borrow(); | 
					 | 
					 | 
					 | 
					            let pstate = pcx.state.borrow(); | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					            if let Some(val) = pstate.constants.get(s) { | 
					 | 
					 | 
					 | 
					            if let Some(val) = pstate.constants.get(&s) { | 
				
			
			
				
				
			
		
	
		
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					                return Ok(*val); | 
					 | 
					 | 
					 | 
					                return Ok(*val); | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					            } | 
					 | 
					 | 
					 | 
					            } | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					
 | 
					 | 
					 | 
					 | 
					
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					            Ok(unsafe { std::mem::transmute(parse_i64(s)?) }) | 
					 | 
					 | 
					 | 
					            Ok(unsafe { std::mem::transmute(parse_i64(&s, pos)?) }) | 
				
			
			
				
				
			
		
	
		
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					        } | 
					 | 
					 | 
					 | 
					        } | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					        _ => { | 
					 | 
					 | 
					 | 
					        other => { | 
				
			
			
				
				
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					            Err(CrsnError::Parse(format!("bad value format: {:?}", tok).into())) | 
					 | 
					 | 
					 | 
					            Err(CrsnError::Parse(format!("bad value format: {:?}", other).into(), other.pos().clone())) | 
				
			
			
				
				
			
		
	
		
		
	
		
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					        } | 
					 | 
					 | 
					 | 
					        } | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					    } | 
					 | 
					 | 
					 | 
					    } | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					} | 
					 | 
					 | 
					 | 
					} | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					
 | 
					 | 
					 | 
					 | 
					
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					
 | 
					 | 
					 | 
					 | 
					
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					pub fn parse_u64(literal: &str) -> anyhow::Result<u64> { | 
					 | 
					 | 
					 | 
					pub fn parse_u64(literal: &str, pos: SourcePosition) -> Result<u64, CrsnError> { | 
				
			
			
				
				
			
		
	
		
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					    // trace!("parse u64 from {}", literal);
 | 
					 | 
					 | 
					 | 
					    // trace!("parse u64 from {}", literal);
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					    let mut without_underscores = Cow::Borrowed(literal); | 
					 | 
					 | 
					 | 
					    let mut without_underscores = Cow::Borrowed(literal); | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					    if without_underscores.contains('_') { | 
					 | 
					 | 
					 | 
					    if without_underscores.contains('_') { | 
				
			
			
		
	
	
		
		
			
				
					| 
						
						
						
							
								
							
						
					 | 
					 | 
					@ -159,27 +148,29 @@ pub fn parse_u64(literal: &str) -> anyhow::Result<u64> { | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					    } | 
					 | 
					 | 
					 | 
					    } | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					
 | 
					 | 
					 | 
					 | 
					
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					    if let Some(hex) = without_underscores.strip_prefix("0x") { | 
					 | 
					 | 
					 | 
					    if let Some(hex) = without_underscores.strip_prefix("0x") { | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					        Ok(u64::from_str_radix(hex, 16)?) | 
					 | 
					 | 
					 | 
					        Ok(u64::from_str_radix(hex, 16).err_pos(pos)?) | 
				
			
			
				
				
			
		
	
		
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					    } else if let Some(hex) = without_underscores.strip_prefix("0b") { | 
					 | 
					 | 
					 | 
					    } else if let Some(hex) = without_underscores.strip_prefix("0b") { | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					        Ok(u64::from_str_radix(hex, 2)?) | 
					 | 
					 | 
					 | 
					        Ok(u64::from_str_radix(hex, 2).err_pos(pos)?) | 
				
			
			
				
				
			
		
	
		
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					    } else { | 
					 | 
					 | 
					 | 
					    } else { | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					        Ok(u64::from_str_radix(&without_underscores, 10)?) | 
					 | 
					 | 
					 | 
					        Ok(u64::from_str_radix(&without_underscores, 10).err_pos(pos)?) | 
				
			
			
				
				
			
		
	
		
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					    } | 
					 | 
					 | 
					 | 
					    } | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					} | 
					 | 
					 | 
					 | 
					} | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					
 | 
					 | 
					 | 
					 | 
					
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					pub fn parse_i64(literal: &str) -> anyhow::Result<i64> { | 
					 | 
					 | 
					 | 
					pub fn parse_i64(literal: &str, pos: SourcePosition) -> Result<i64, CrsnError> { | 
				
			
			
				
				
			
		
	
		
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					    // trace!("parse i64 from {}", literal);
 | 
					 | 
					 | 
					 | 
					    // trace!("parse i64 from {}", literal);
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					    if let Some(_value) = literal.strip_prefix("-") { | 
					 | 
					 | 
					 | 
					    if let Some(_value) = literal.strip_prefix("-") { | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					        Ok(-1 * i64::try_from(parse_u64(literal)?)?) | 
					 | 
					 | 
					 | 
					        Ok(-1 * i64::try_from(parse_u64(literal, pos.clone())?).err_pos(pos)?) | 
				
			
			
				
				
			
		
	
		
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					    } else { | 
					 | 
					 | 
					 | 
					    } else { | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					        Ok(i64::try_from(parse_u64(literal)?)?) | 
					 | 
					 | 
					 | 
					        Ok(i64::try_from(parse_u64(literal, pos.clone())?).err_pos(pos)?) | 
				
			
			
				
				
			
		
	
		
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					    } | 
					 | 
					 | 
					 | 
					    } | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					} | 
					 | 
					 | 
					 | 
					} | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					
 | 
					 | 
					 | 
					 | 
					
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					pub fn parse_rd(tok: Option<Sexp>, pcx: &ParserContext) -> anyhow::Result<Rd> { | 
					 | 
					 | 
					 | 
					pub fn parse_rd(tok: Sexp, pcx: &ParserContext) -> Result<Rd, CrsnError> { | 
				
			
			
				
				
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					    Ok(Rd::new(RdData::try_from(parse_data_disp(tok, pcx)?)?)) | 
					 | 
					 | 
					 | 
					    let pos = tok.pos().clone(); | 
				
			
			
				
				
			
		
	
		
		
	
		
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					    Ok(Rd::new(RdData::try_from(parse_data_disp(tok, pcx)?).err_pos(pos)?)) | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					} | 
					 | 
					 | 
					 | 
					} | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					
 | 
					 | 
					 | 
					 | 
					
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					pub fn parse_wr(tok: Option<Sexp>, pcx: &ParserContext) -> anyhow::Result<Wr> { | 
					 | 
					 | 
					 | 
					pub fn parse_wr(tok: Sexp, pcx: &ParserContext) -> Result<Wr, CrsnError> { | 
				
			
			
				
				
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					    Ok(Wr::new(WrData::try_from(parse_data_disp(tok, pcx)?)?)) | 
					 | 
					 | 
					 | 
					    let pos = tok.pos().clone(); | 
				
			
			
				
				
			
		
	
		
		
	
		
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					    Ok(Wr::new(WrData::try_from(parse_data_disp(tok, pcx)?).err_pos(pos)?)) | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					} | 
					 | 
					 | 
					 | 
					} | 
				
			
			
		
	
	
		
		
			
				
					| 
						
						
						
					 | 
					 | 
					
  |