use std::cell::RefCell; use std::collections::HashMap; use std::sync::atomic::AtomicU32; pub use parse_instr::parse_instructions; use sexp::SourcePosition; use crate::asm::data::literal::{ConstantName, RegisterAlias, Value}; use crate::asm::data::Register; use crate::asm::error::CrsnError; use crate::asm::instr::Op; use crate::asm::parse::sexp_expect::expect_list; use crate::module::CrsnExtension; use crate::runtime::run_thread::{ThreadInfo, RunState}; use std::sync::Arc; pub mod parse_cond; pub mod parse_instr; pub mod parse_data; pub mod sexp_expect; pub mod parse_op; pub mod arg_parser; pub mod parse_routine; #[derive(Debug)] pub struct ParserContext<'a> { /// Extension modules pub parsers: &'a [Box], /// Mutable state pub state: RefCell, } #[derive(Debug)] pub struct ParserState { /// Register aliases valid globally pub global_reg_aliases: HashMap, /// Register aliases within the routine pub reg_aliases: HashMap, /// The old reg aliases map is pushed here when entering a routine definition pub reg_alias_stack: Vec>, /// Global constants pub constants: HashMap, /// Dummy run state used for const eval pub const_eval: RunState, // ThreadInfo is needed separately from RunState. TODO check if this can be refactored pub const_eval_ti: Arc, /// True if we are in an expression parser context pub parsing_expr : bool, /// Label numberer pub label_num : Arc, } impl ParserState { pub fn reset(&mut self) { self.global_reg_aliases.clear(); self.reg_aliases.clear(); self.reg_alias_stack.clear(); self.constants.clear(); self.parsing_expr = false; self.const_eval.reset(); } } pub fn parse(source: &str, pos: &SourcePosition, parsers: &ParserContext) -> Result, CrsnError> { let (items, _pos) = expect_list(sexp::parse(source)?, true)?; parse_instructions(items.into_iter(), pos, parsers)? .flatten(&parsers.state.borrow().label_num) }