You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
64 lines
1.9 KiB
64 lines
1.9 KiB
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<dyn CrsnExtension>],
|
|
/// Mutable state
|
|
pub state: RefCell<ParserState>,
|
|
}
|
|
|
|
#[derive(Debug)]
|
|
pub struct ParserState {
|
|
/// Register aliases valid globally
|
|
pub global_reg_aliases: HashMap<RegisterAlias, Register>,
|
|
|
|
/// Register aliases within the routine
|
|
pub reg_aliases: HashMap<RegisterAlias, Register>,
|
|
|
|
/// The old reg aliases map is pushed here when entering a routine definition
|
|
pub reg_alias_stack: Vec<HashMap<RegisterAlias, Register>>,
|
|
|
|
/// Global constants
|
|
pub constants: HashMap<ConstantName, Value>,
|
|
|
|
/// 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<ThreadInfo>,
|
|
|
|
/// True if we are in an expression parser context
|
|
pub parsing_expr : bool,
|
|
}
|
|
|
|
pub fn parse(source: &str, pos: &SourcePosition, parsers: &ParserContext) -> Result<Vec<Op>, 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)
|
|
}
|
|
|