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/module/mod.rs

138 lines
4.3 KiB

#![allow(unused_variables)]
use std::fmt::Debug;
pub use eval_res::EvalRes;
use sexp::{Sexp, SourcePosition};
use crate::asm::data::literal::Value;
use crate::asm::error::CrsnError;
use crate::asm::instr::Flatten;
use crate::asm::instr::op::OpKind;
use crate::asm::parse::arg_parser::TokenParser;
use crate::runtime::fault::Fault;
use crate::runtime::run_thread::state::RunState;
use crate::runtime::run_thread::ThreadInfo;
use std::sync::atomic::{AtomicU64, Ordering};
use std::sync::Arc;
use crate::asm::data::Wr;
use crate::builtin::defs::BuiltinOp;
mod eval_res;
/// Result type returned from the op parser. This is the Ok variant of a Result.
pub enum ParseRes<'a, T> {
/// Parsing successful.
Parsed(T),
/// Parsing successful, but did not yield any result
ParsedNone,
/// Instruction not recognized, but there was no error.
Unknown(TokenParser<'a>),
}
impl ParseRes<'static, OpKind> {
pub fn builtin(op: BuiltinOp) -> ParseRes<'static, OpKind> {
Self::Parsed(OpKind::BuiltIn(op))
}
}
impl<'a> ParseRes<'a, OpKind> {
/// Helper to construct an extension op
pub fn ext(op: impl OpTrait) -> Self {
Self::Parsed(OpKind::Ext(Box::new(op)))
}
}
pub trait OpTrait: Debug + Send + Sync + 'static {
fn execute(&self, ti: &ThreadInfo, state: &mut RunState) -> Result<EvalRes, Fault>;
/// Turn into an S-expression that produces this instruction when parsed
fn to_sexp(&self) -> Sexp;
}
/// CRSN initializer object.
/// Only one should be created for the lifespan of the parser and runtime.
#[derive(Default,Debug)]
pub struct CrsnUniq {
object_handle_counter : AtomicU64
}
pub const UNIQ_BASE: u64 = 0x6372_736e_0000_0000;
impl CrsnUniq {
pub fn new() -> Arc<Self> {
Arc::new(Self {
object_handle_counter: AtomicU64::new(UNIQ_BASE),
})
}
pub fn unique_handle(&self) -> u64 {
self.object_handle_counter.fetch_add(1, Ordering::Relaxed)
}
}
pub trait CrsnExtension: Debug + Send + Sync + 'static {
fn init(&mut self, uniq: &CrsnUniq) {
//
}
/// Get name of the module
fn name(&self) -> &'static str;
/// Parse an op.
/// If the keyword matches and the function decides to parse the instruction, it must consume
/// the argument list and either return Ok or Err.
///
/// If the instruction keyword is not recognized, return Unknown with the unchanged argument list.
///
/// pcx is available on the arg_tokens parser
fn parse_op<'a>(&self, pos: &SourcePosition, keyword: &str, arg_tokens: TokenParser<'a>) -> Result<ParseRes<'a, OpKind>, CrsnError>;
/// Parse a generic S-expression (non-op) that started with the given keyword
///
/// pcx is available on the arg_tokens parser
fn parse_syntax<'a>(&self, pos: &SourcePosition, keyword: &str, tokens: TokenParser<'a>)
-> Result<ParseRes<'a, Box<dyn Flatten>>, CrsnError>
{
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
fn drop_obj(&self, ti: &ThreadInfo, state: &mut RunState, handle: Value)
-> Result<Option<()>, Fault>
{
// Default impl - we do not support dropping this object
Ok(None)
}
/// Run-time method called to read an object ("ld" and its variants, using the object handle syntax)
fn read_obj(&self, state: &mut RunState, handle: Value)
-> Result<Option<Value>, Fault>
{
// Default impl - we do not support reading this object
Ok(None)
}
/// Run-time method called to read all values from an object ("lds" using the object handle syntax)
fn read_obj_all(&self, state: &mut RunState, whandle: Wr, rhandle: Value)
-> Result<Option<()>, Fault>
{
// Default impl - we do not support reading this object
Ok(None)
}
/// Run-time method called to write an object (using the object handle syntax)
fn write_obj(&self, state: &mut RunState, handle: Value, value: Value) -> Result<Option<()>, Fault>
{
// Default impl - we do not support writing this object
Ok(None)
}
}