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, } pub fn parse(source: &str, pos: &SourcePosition, parsers: &ParserContext) -> Result, CrsnError> { let (items, _pos) = expect_list(sexp::parse(source)?, true)?; /* numbered labels start with a weird high number to avoid conflicts with user-defined numbered labels */ let label_num = AtomicU32::new(0x7890_0000); parse_instructions(items.into_iter(), pos, parsers)? .flatten(&label_num) }