Croissant Runtime
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.
 
 
crsn/crsn/src/asm/parse/mod.rs

82 lines
2.3 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;
use std::path::PathBuf;
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,
/// Label numberer
pub label_num : Arc<AtomicU32>,
/// Numbered files
pub files : Vec<PathBuf>,
/// Active file number. Is backed up before descending into a sub-file, and restored afterwards.
pub active_file: usize,
}
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<Vec<Op>, CrsnError> {
let (items, _pos) = expect_list(sexp::parse(source)?, true)?;
parse_instructions(items.into_iter(), pos, parsers)?
.flatten(&parsers.state.borrow().label_num)
}