|
|
@ -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) => { |
|
|
|