add extension hook to pre-define constants

pull/21/head
Ondřej Hruška 4 years ago
parent 4115e07ee6
commit a3eae0a8a9
Signed by: MightyPork
GPG Key ID: 2C5FD5035250423D
  1. 24
      crsn/src/asm/parse/parse_data.rs
  2. 9
      crsn/src/module/mod.rs

@ -94,10 +94,19 @@ pub fn parse_data_disp(tok: Sexp, pcx: &ParserContext) -> Result<DataDisp, CrsnE
} }
if let Some(reference) = s.strip_prefix('@') { if let Some(reference) = s.strip_prefix('@') {
/* extension constants (pre-defined handles) */
for p in pcx.parsers {
if let Some(val) = p.get_constant_value(&s) {
return Ok(DataDisp::ImmObject(val));
}
}
/* register aliases */
let pstate = pcx.state.borrow(); let pstate = pcx.state.borrow();
if let Some(reg) = pstate.reg_aliases.get(reference) { if let Some(reg) = pstate.reg_aliases.get(reference) {
Ok(DataDisp::RegObject(*reg)) return Ok(DataDisp::RegObject(*reg))
} else { }
let reg = reg::parse_reg(reference, &pos)?; let reg = reg::parse_reg(reference, &pos)?;
if pstate.reg_aliases.values().find(|v| **v == reg).is_some() { if pstate.reg_aliases.values().find(|v| **v == reg).is_some() {
@ -105,19 +114,28 @@ pub fn parse_data_disp(tok: Sexp, pcx: &ParserContext) -> Result<DataDisp, CrsnE
} else { } else {
Ok(DataDisp::RegObject(reg)) Ok(DataDisp::RegObject(reg))
} }
}
} else if s.starts_with(|c: char| c.is_ascii_digit() || c == '-') { } else if s.starts_with(|c: char| c.is_ascii_digit() || c == '-') {
Ok(DataDisp::Immediate(unsafe { std::mem::transmute(parse_i64(&s, &pos)?) })) Ok(DataDisp::Immediate(unsafe { std::mem::transmute(parse_i64(&s, &pos)?) }))
} else { } else {
/* extension constants */
for p in pcx.parsers {
if let Some(val) = p.get_constant_value(&s) {
return Ok(DataDisp::Immediate(val));
}
}
/* program constants */
let pstate = pcx.state.borrow(); let pstate = pcx.state.borrow();
if let Some(val) = pstate.constants.get(&s) { if let Some(val) = pstate.constants.get(&s) {
return Ok(DataDisp::Immediate(*val)); return Ok(DataDisp::Immediate(*val));
} }
/* register aliases */
if let Some(val) = pstate.reg_aliases.get(&s) { if let Some(val) = pstate.reg_aliases.get(&s) {
return Ok(DataDisp::Register(*val)); return Ok(DataDisp::Register(*val));
} }
/* register */
let reg = reg::parse_reg(&s, &pos)?; let reg = reg::parse_reg(&s, &pos)?;
let pstate = pcx.state.borrow(); let pstate = pcx.state.borrow();

@ -12,7 +12,7 @@ use crate::asm::instr::Flatten;
use crate::asm::instr::op::OpKind; use crate::asm::instr::op::OpKind;
use crate::asm::parse::arg_parser::TokenParser; use crate::asm::parse::arg_parser::TokenParser;
use crate::runtime::fault::Fault; use crate::runtime::fault::Fault;
use crate::runtime::run_thread::state::{RunState}; use crate::runtime::run_thread::state::RunState;
use crate::runtime::run_thread::ThreadInfo; use crate::runtime::run_thread::ThreadInfo;
mod eval_res; mod eval_res;
@ -63,6 +63,13 @@ pub trait CrsnExtension: Debug + Send + Sync + 'static {
Ok(ParseRes::Unknown(tokens)) Ok(ParseRes::Unknown(tokens))
} }
/// Get value of an extension-provided constant.
/// This constant may be an object handle, or a constant value used as argument in some other instruction.
fn get_constant_value<'a>(&self, name: &str) -> Option<Value>
{
None
}
/// Drop an object referenced by a handle /// Drop an object referenced by a handle
fn drop_obj(&self, ti: &ThreadInfo, state: &mut RunState, handle: Value) fn drop_obj(&self, ti: &ThreadInfo, state: &mut RunState, handle: Value)
-> Result<Option<()>, Fault> -> Result<Option<()>, Fault>

Loading…
Cancel
Save