generalize parsing to allow extensions to add arbitrary syntax; add 'proc' keyword to introduce a routine.

pull/21/head
Ondřej Hruška 4 years ago
parent d47d0f2345
commit 4be5b4e05b
Signed by: MightyPork
GPG Key ID: 2C5FD5035250423D
  1. 25
      crsn/src/asm/instr/flatten.rs
  2. 6
      crsn/src/asm/instr/mod.rs
  3. 9
      crsn/src/asm/parse/arg_parser.rs
  4. 16
      crsn/src/asm/parse/mod.rs
  5. 6
      crsn/src/asm/parse/parse_cond.rs
  6. 57
      crsn/src/asm/parse/parse_instr.rs
  7. 10
      crsn/src/asm/parse/parse_op.rs
  8. 23
      crsn/src/asm/parse/parse_routines.rs
  9. 14
      crsn/src/builtin/parse.rs
  10. 45
      crsn/src/module/mod.rs
  11. 6
      crsn_arith/src/lib.rs
  12. 10
      crsn_arith/src/parse.rs
  13. 6
      crsn_screen/src/lib.rs
  14. 10
      crsn_screen/src/parse.rs
  15. 6
      crsn_stacks/src/lib.rs
  16. 10
      crsn_stacks/src/parse.rs
  17. 4
      examples/factorial.csn
  18. 22
      examples/screen_bounce.csn

@ -9,11 +9,11 @@ use crate::builtin::defs::BuiltinOp;
/// A trait for something that can turn into multiple instructions /// A trait for something that can turn into multiple instructions
pub trait Flatten { pub trait Flatten {
fn flatten(self, label_num: &AtomicU32) -> Result<Vec<Op>, CrsnError>; fn flatten(self: Box<Self>, label_num: &AtomicU32) -> Result<Vec<Op>, CrsnError>;
} }
impl Flatten for Instr { impl Flatten for Instr {
fn flatten(self, label_num: &AtomicU32) -> Result<Vec<Op>, CrsnError> { fn flatten(self: Box<Self>, label_num: &AtomicU32) -> Result<Vec<Op>, CrsnError> {
let mut ops = vec![self.op]; let mut ops = vec![self.op];
if let Some(branches) = self.branches { if let Some(branches) = self.branches {
@ -31,10 +31,7 @@ impl Flatten for Instr {
Label::unique(label_num) Label::unique(label_num)
}; };
ops.push(BuiltinOp::JumpIf(!cond, next_lbl.clone()).into()); ops.push(BuiltinOp::JumpIf(!cond, next_lbl.clone()).into());
ops.extend(branch.flatten(label_num)?);
for branch_instr in branch {
ops.extend(branch_instr.flatten(label_num)?);
}
if cnt != branch_count - 1 { if cnt != branch_count - 1 {
ops.push(BuiltinOp::Jump(end_lbl.clone()).into()); ops.push(BuiltinOp::Jump(end_lbl.clone()).into());
@ -48,15 +45,23 @@ impl Flatten for Instr {
} }
} }
impl Flatten for Vec<Box<dyn Flatten>> {
fn flatten(self: Box<Self>, label_num: &AtomicU32) -> Result<Vec<Op>, CrsnError> {
let mut ops = vec![];
for item in self.into_iter() {
ops.extend(item.flatten(label_num)?);
}
Ok(ops)
}
}
impl Flatten for Routine { impl Flatten for Routine {
fn flatten(self, label_num: &AtomicU32) -> Result<Vec<Op>, CrsnError> { fn flatten(self: Box<Self>, label_num: &AtomicU32) -> Result<Vec<Op>, CrsnError> {
let mut ops = vec![ let mut ops = vec![
BuiltinOp::Routine(self.name.clone()).into(), BuiltinOp::Routine(self.name.clone()).into(),
]; ];
for instr in self.body { ops.extend(self.body.flatten(label_num)?);
ops.extend(instr.flatten(label_num)?);
}
ops.push(BuiltinOp::Barrier(Some(format!("Routine \"{}\" overrun", self.name).into())).into()); ops.push(BuiltinOp::Barrier(Some(format!("Routine \"{}\" overrun", self.name).into())).into());

@ -9,15 +9,13 @@ pub mod cond;
mod flatten; mod flatten;
/// A higher-level instruction /// A higher-level instruction
#[derive(Debug)]
pub struct Instr { pub struct Instr {
pub op: Op, pub op: Op,
pub branches: Option<Vec<(Cond, Vec<Instr>)>>, pub branches: Option<Vec<(Cond, Box<dyn Flatten>)>>,
} }
/// A routine /// A routine
pub struct Routine { pub struct Routine {
pub name: RoutineName, pub name: RoutineName,
pub body: Vec<Instr>, pub body: Box<dyn Flatten>,
} }

@ -5,21 +5,22 @@ use crate::asm::parse::parse_data::{parse_rd, parse_wr};
use crate::asm::parse::sexp_expect::expect_string_atom; use crate::asm::parse::sexp_expect::expect_string_atom;
/// Utility for argument parsing /// Utility for argument parsing
pub struct ArgParser { pub struct TokenParser {
orig_len: usize, orig_len: usize,
args: Vec<Sexp>, args: Vec<Sexp>,
} }
impl IntoIterator for ArgParser { impl IntoIterator for TokenParser {
type Item = Sexp; type Item = Sexp;
type IntoIter = std::vec::IntoIter<Sexp>; type IntoIter = std::vec::IntoIter<Sexp>;
fn into_iter(self) -> Self::IntoIter { fn into_iter(mut self) -> Self::IntoIter {
self.args.reverse();
self.args.into_iter() self.args.into_iter()
} }
} }
impl ArgParser { impl TokenParser {
/// Create a new argument parser /// Create a new argument parser
pub fn new(mut args: Vec<Sexp>) -> Self { pub fn new(mut args: Vec<Sexp>) -> Self {
args.reverse(); args.reverse();

@ -1,7 +1,6 @@
use std::sync::atomic::AtomicU32; use std::sync::atomic::{AtomicU32, AtomicU64};
pub use parse_instr::parse_instructions; pub use parse_instr::parse_instructions;
use parse_routines::parse_routines;
use crate::asm::error::CrsnError; use crate::asm::error::CrsnError;
use crate::asm::instr::{Flatten, Op, Routine}; use crate::asm::instr::{Flatten, Op, Routine};
@ -11,22 +10,15 @@ use crate::module::CrsnExtension;
mod parse_cond; mod parse_cond;
mod parse_instr; mod parse_instr;
pub mod parse_data; pub mod parse_data;
mod parse_routines;
pub mod sexp_expect; pub mod sexp_expect;
mod parse_op; mod parse_op;
pub mod arg_parser; pub mod arg_parser;
pub fn parse(source: &str, parsers: &[Box<dyn CrsnExtension>]) -> Result<Vec<Op>, CrsnError> { pub fn parse(source: &str, parsers: &[Box<dyn CrsnExtension>]) -> Result<Vec<Op>, CrsnError> {
let root = sexp::parse(source)?; let items = expect_list(Some(sexp::parse(source)?), true)?;
let subs: Vec<Routine> = parse_routines(expect_list(Some(root), true)?, parsers)?;
let mut combined = vec![];
let label_num = AtomicU32::new(0); let label_num = AtomicU32::new(0);
for sub in subs { parse_instructions(items.into_iter(), parsers)?
combined.extend(sub.flatten(&label_num)?); .flatten(&label_num)
}
Ok(combined)
} }

@ -1,13 +1,13 @@
use sexp::Sexp; use sexp::Sexp;
use crate::asm::error::CrsnError; use crate::asm::error::CrsnError;
use crate::asm::instr::{Cond, cond, Instr}; use crate::asm::instr::{Cond, cond, Instr, Flatten};
use crate::asm::parse::parse_instr::parse_instructions; use crate::asm::parse::parse_instr::parse_instructions;
use crate::asm::parse::sexp_expect::{expect_list, expect_string_atom}; use crate::asm::parse::sexp_expect::{expect_list, expect_string_atom};
use crate::asm::patches::TryRemove; use crate::asm::patches::TryRemove;
use crate::module::CrsnExtension; use crate::module::CrsnExtension;
pub fn parse_cond_branch(tok: Sexp, parsers: &[Box<dyn CrsnExtension>]) -> Result<(Cond, Vec<Instr>), CrsnError> { pub fn parse_cond_branch(tok: Sexp, parsers: &[Box<dyn CrsnExtension>]) -> Result<(Cond, Box<dyn Flatten>), CrsnError> {
let mut list = expect_list(Some(tok), false)?; let mut list = expect_list(Some(tok), false)?;
let kw = expect_string_atom(list.try_remove(0))?; let kw = expect_string_atom(list.try_remove(0))?;
@ -15,6 +15,6 @@ pub fn parse_cond_branch(tok: Sexp, parsers: &[Box<dyn CrsnExtension>]) -> Resul
return Err(CrsnError::Parse(format!("Condition must end with '?': {}", kw).into())); return Err(CrsnError::Parse(format!("Condition must end with '?': {}", kw).into()));
} }
Ok((cond::parse_cond(&kw)?, parse_instructions(list, parsers)?)) Ok((cond::parse_cond(&kw)?, parse_instructions(list.into_iter(), parsers)?))
} }

@ -1,24 +1,49 @@
use sexp::Sexp; use sexp::Sexp;
use crate::asm::error::CrsnError; use crate::asm::error::CrsnError;
use crate::asm::instr::Instr; use crate::asm::instr::{Instr, Flatten, Routine};
use crate::asm::parse::arg_parser::ArgParser; use crate::asm::parse::arg_parser::TokenParser;
use crate::asm::parse::parse_cond::parse_cond_branch; use crate::asm::parse::parse_cond::parse_cond_branch;
use crate::asm::parse::sexp_expect::{expect_list, expect_string_atom}; use crate::asm::parse::sexp_expect::{expect_list, expect_string_atom};
use crate::asm::patches::SexpIsA; use crate::asm::patches::SexpIsA;
use crate::module::CrsnExtension; use crate::module::{CrsnExtension, ParseRes};
use super::parse_op::parse_op; use super::parse_op::parse_op;
use crate::asm::data::literal::RoutineName;
pub fn parse_instructions(instrs: Vec<Sexp>, parsers: &[Box<dyn CrsnExtension>]) -> Result<Vec<Instr>, CrsnError> { pub fn parse_instructions(items: impl Iterator<Item=Sexp>, parsers: &[Box<dyn CrsnExtension>]) -> Result<Box<dyn Flatten>, CrsnError> {
let mut parsed = vec![]; let mut parsed = vec![];
for expr in instrs { for expr in items {
let tokens = expect_list(Some(expr), false)?; let tokens = expect_list(Some(expr), false)?;
let mut toki = tokens.into_iter(); let mut toki = tokens.into_iter();
let name = expect_string_atom(toki.next())?; let name = expect_string_atom(toki.next())?;
let arg_tokens = ArgParser::new(toki.clone().take_while(|e| e.is_atom()).collect()); if name == "proc" {
parsed.push(parse_routine(toki, parsers)?);
continue;
}
let mut token_parser = TokenParser::new(toki.collect());
for p in parsers {
token_parser = match p.parse_syntax(&name, token_parser, parsers) {
Ok(ParseRes::Parsed(op)) => return Ok(op),
Ok(ParseRes::Unknown(to_reuse)) => {
if to_reuse.parsing_started() {
panic!("Module \"{}\" started parsing syntax, but returned Unknown!", p.name());
}
to_reuse
}
Err(err) => {
return Err(err);
}
}
}
// Get back the original iterator
let toki = token_parser.into_iter();
let arg_tokens = TokenParser::new(toki.clone().take_while(|e| e.is_atom()).collect());
let branch_tokens = toki let branch_tokens = toki
.skip_while(|e| e.is_atom()) .skip_while(|e| e.is_atom())
.take_while(|e| e.is_list()); .take_while(|e| e.is_list());
@ -35,11 +60,25 @@ pub fn parse_instructions(instrs: Vec<Sexp>, parsers: &[Box<dyn CrsnExtension>])
} }
}; };
parsed.push(Instr { parsed.push(Box::new(Instr {
op: parse_op(name.as_str(), arg_tokens, parsers)?, op: parse_op(name.as_str(), arg_tokens, parsers)?,
branches, branches,
}); }));
} }
Ok(parsed) Ok(Box::new(parsed))
} }
fn parse_routine(mut toki : impl Iterator<Item=Sexp> + Clone, parsers: &[Box<dyn CrsnExtension>]) -> Result<Box<dyn Flatten>, CrsnError> {
let name = expect_string_atom(toki.next())?;
let arg_tokens = TokenParser::new(toki.clone().take_while(|e| e.is_atom()).collect());
// TODO parse arg tokens
let body = parse_instructions(toki, parsers)?;
return Ok(Box::new(Routine {
name: RoutineName(name),
body
}))
}

@ -1,17 +1,17 @@
use crate::asm::error::CrsnError; use crate::asm::error::CrsnError;
use crate::asm::instr::Op; use crate::asm::instr::Op;
use crate::asm::parse::arg_parser::ArgParser; use crate::asm::parse::arg_parser::TokenParser;
use crate::builtin::parse::BuiltinOps; use crate::builtin::parse::BuiltinOps;
use crate::module::{CrsnExtension, ParseOpRes}; use crate::module::{CrsnExtension, ParseRes};
pub fn parse_op(keyword: &str, mut arg_tokens: ArgParser, parsers: &[Box<dyn CrsnExtension>]) -> Result<Op, CrsnError> { pub fn parse_op(keyword: &str, mut arg_tokens: TokenParser, parsers: &[Box<dyn CrsnExtension>]) -> Result<Op, CrsnError> {
// Include built-in instructions // Include built-in instructions
let builtins = [BuiltinOps::new()]; let builtins = [BuiltinOps::new()];
for p in builtins.iter().chain(parsers) { for p in builtins.iter().chain(parsers) {
arg_tokens = match p.parse_op(keyword, arg_tokens) { arg_tokens = match p.parse_op(keyword, arg_tokens) {
Ok(ParseOpRes::Parsed(op)) => return Ok(op), Ok(ParseRes::Parsed(op)) => return Ok(op),
Ok(ParseOpRes::Unknown(to_reuse)) => { Ok(ParseRes::Unknown(to_reuse)) => {
if to_reuse.parsing_started() { if to_reuse.parsing_started() {
panic!("Module \"{}\" started parsing {}, but returned Unknown!", p.name(), keyword); panic!("Module \"{}\" started parsing {}, but returned Unknown!", p.name(), keyword);
} }

@ -1,23 +0,0 @@
use sexp::Sexp;
use crate::asm::data::literal::RoutineName;
use crate::asm::error::CrsnError;
use crate::asm::instr::Routine;
use crate::asm::parse::parse_instr::parse_instructions;
use crate::asm::parse::sexp_expect::{expect_list, expect_string_atom};
use crate::asm::patches::TryRemove;
use crate::module::CrsnExtension;
pub fn parse_routines(routines: Vec<Sexp>, parsers: &[Box<dyn CrsnExtension>]) -> Result<Vec<Routine>, CrsnError> {
let mut parsed = vec![];
for rt in routines {
let mut def = expect_list(Some(rt), false)?;
let name = expect_string_atom(def.try_remove(0))?;
let body = parse_instructions(def, parsers)?;
parsed.push(Routine {
name: RoutineName(name),
body,
})
}
Ok(parsed)
}

@ -4,11 +4,11 @@ use crate::asm::data::literal::{Label, RoutineName};
use crate::asm::error::CrsnError; use crate::asm::error::CrsnError;
use crate::asm::instr::cond::parse_cond; use crate::asm::instr::cond::parse_cond;
use crate::asm::instr::Op; use crate::asm::instr::Op;
use crate::asm::parse::arg_parser::ArgParser; use crate::asm::parse::arg_parser::TokenParser;
use crate::asm::parse::parse_data::{parse_label, parse_rd}; use crate::asm::parse::parse_data::{parse_label, parse_rd};
use crate::asm::parse::sexp_expect::expect_string_atom; use crate::asm::parse::sexp_expect::expect_string_atom;
use crate::builtin::defs::BuiltinOp; use crate::builtin::defs::BuiltinOp;
use crate::module::{CrsnExtension, ParseOpRes}; use crate::module::{CrsnExtension, ParseRes};
#[derive(Debug, Clone)] #[derive(Debug, Clone)]
pub struct BuiltinOps { pub struct BuiltinOps {
@ -28,8 +28,8 @@ impl CrsnExtension for BuiltinOps {
"builtin" "builtin"
} }
fn parse_op(&self, keyword: &str, mut args: ArgParser) -> Result<ParseOpRes<Op>, CrsnError> { fn parse_op(&self, keyword: &str, mut args: TokenParser) -> Result<ParseRes<Op>, CrsnError> {
Ok(ParseOpRes::Parsed(Op::BuiltIn(match keyword { Ok(ParseRes::Parsed(Op::BuiltIn(match keyword {
"nop" => { "nop" => {
BuiltinOp::Nop BuiltinOp::Nop
} }
@ -142,10 +142,10 @@ impl CrsnExtension for BuiltinOps {
let label = Label::Named(label.to_string()); let label = Label::Named(label.to_string());
BuiltinOp::FarLabel(label) BuiltinOp::FarLabel(label)
} else { } else {
return Ok(ParseOpRes::Unknown(args)); return Ok(ParseRes::Unknown(args));
} }
} else { } else {
return Ok(ParseOpRes::Unknown(args)); return Ok(ParseRes::Unknown(args));
} }
} }
@ -154,7 +154,7 @@ impl CrsnExtension for BuiltinOps {
let label = Label::Named(label.to_string()); let label = Label::Named(label.to_string());
BuiltinOp::Label(label) BuiltinOp::Label(label)
} else { } else {
return Ok(ParseOpRes::Unknown(args)); return Ok(ParseRes::Unknown(args));
} }
} }
}))) })))

@ -1,3 +1,5 @@
#![allow(unused_variables)]
use std::fmt::Debug; use std::fmt::Debug;
pub use eval_res::EvalRes; pub use eval_res::EvalRes;
@ -5,8 +7,8 @@ pub use eval_res::EvalRes;
use crate::asm::data::literal::Value; use crate::asm::data::literal::Value;
use crate::asm::data::Mask; use crate::asm::data::Mask;
use crate::asm::error::CrsnError; use crate::asm::error::CrsnError;
use crate::asm::instr::Op; use crate::asm::instr::{Op, Flatten};
use crate::asm::parse::arg_parser::ArgParser; 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;
@ -14,14 +16,14 @@ use crate::runtime::run_thread::ThreadInfo;
mod eval_res; mod eval_res;
/// Result type returned from the op parser. This is the Ok variant of a Result. /// Result type returned from the op parser. This is the Ok variant of a Result.
pub enum ParseOpRes<T> { pub enum ParseRes<T> {
/// Parsing successful. /// Parsing successful.
Parsed(T), Parsed(T),
/// Instruction not recognized, but there was no error. /// Instruction not recognized, but there was no error.
Unknown(ArgParser), Unknown(TokenParser),
} }
impl ParseOpRes<Op> { impl ParseRes<Op> {
/// Helper to construct an extension op /// Helper to construct an extension op
pub fn ext(op: impl OpTrait) -> Self { pub fn ext(op: impl OpTrait) -> Self {
Self::Parsed(Op::Ext(Box::new(op))) Self::Parsed(Op::Ext(Box::new(op)))
@ -41,36 +43,35 @@ pub trait CrsnExtension: Debug + Send + Sync + 'static {
/// the argument list and either return Ok or Err. /// the argument list and either return Ok or Err.
/// ///
/// If the instruction keyword is not recognized, return Unknown with the unchanged argument list. /// If the instruction keyword is not recognized, return Unknown with the unchanged argument list.
fn parse_op(&self, keyword: &str, arg_tokens: ArgParser) -> Result<ParseOpRes<Op>, CrsnError>; fn parse_op(&self, keyword: &str, arg_tokens: TokenParser) -> Result<ParseRes<Op>, CrsnError>;
/// Parse a generic S-expression (non-op)
fn parse_syntax(&self, keyword: &str, tokens: TokenParser, parsers: &[Box<dyn CrsnExtension>])
-> Result<ParseRes<Box<dyn Flatten>>, CrsnError>
{
Ok(ParseRes::Unknown(tokens))
}
/// Drop an object referenced by a handle /// Drop an object referenced by a handle
fn drop_obj(&self, fn drop_obj(&self, ti: &ThreadInfo, state: &mut RunState, handle: Value)
#[allow(unused)] ti: &ThreadInfo, -> Result<Option<()>, Fault>
#[allow(unused)] state: &mut RunState,
#[allow(unused)] handle: Value) -> Result<Option<()>, Fault>
{ {
// Default impl - we do not support dropping this object // Default impl - we do not support dropping this object
Ok(None) Ok(None)
} }
/// Run-time method called to read an object (using the object handle syntax) /// Run-time method called to read an object (using the object handle syntax)
fn read_obj(&self, fn read_obj(&self, ti: &ThreadInfo, state: &mut RunState, handle: Value, _mask: Mask)
#[allow(unused)] ti: &ThreadInfo, -> Result<Option<Value>, Fault>
#[allow(unused)] state: &mut RunState, {
#[allow(unused)] handle: Value,
#[allow(unused)] mask: Mask,
) -> Result<Option<Value>, Fault> {
// Default impl - we do not support reading this object // Default impl - we do not support reading this object
Ok(None) Ok(None)
} }
/// Run-time method called to write an object (using the object handle syntax) /// Run-time method called to write an object (using the object handle syntax)
fn write_obj(&self, fn write_obj(&self, ti: &ThreadInfo, state: &mut RunState, handle: Value, mask: Mask)
#[allow(unused)] ti: &ThreadInfo, -> Result<Option<()>, Fault>
#[allow(unused)] state: &mut RunState, {
#[allow(unused)] handle: Value,
#[allow(unused)] mask: Mask,
) -> Result<Option<()>, Fault> {
// Default impl - we do not support writing this object // Default impl - we do not support writing this object
Ok(None) Ok(None)
} }

@ -1,7 +1,7 @@
use crsn::asm::error::CrsnError; use crsn::asm::error::CrsnError;
use crsn::asm::instr::Op; use crsn::asm::instr::Op;
use crsn::asm::parse::arg_parser::ArgParser; use crsn::asm::parse::arg_parser::TokenParser;
use crsn::module::{CrsnExtension, ParseOpRes}; use crsn::module::{CrsnExtension, ParseRes};
mod defs; mod defs;
mod parse; mod parse;
@ -21,7 +21,7 @@ impl CrsnExtension for ArithOps {
"arith" "arith"
} }
fn parse_op(&self, keyword: &str, args: ArgParser) -> Result<ParseOpRes<Op>, CrsnError> { fn parse_op(&self, keyword: &str, args: TokenParser) -> Result<ParseRes<Op>, CrsnError> {
parse::parse(keyword, args) parse::parse(keyword, args)
} }
} }

@ -1,13 +1,13 @@
use crsn::asm::data::{Rd, Wr}; use crsn::asm::data::{Rd, Wr};
use crsn::asm::error::CrsnError; use crsn::asm::error::CrsnError;
use crsn::asm::instr::Op; use crsn::asm::instr::Op;
use crsn::asm::parse::arg_parser::ArgParser; use crsn::asm::parse::arg_parser::TokenParser;
use crsn::module::ParseOpRes; use crsn::module::ParseRes;
use crate::defs::ArithOp; use crate::defs::ArithOp;
pub(crate) fn parse(keyword: &str, mut args: ArgParser) -> Result<ParseOpRes<Op>, CrsnError> { pub(crate) fn parse(keyword: &str, mut args: TokenParser) -> Result<ParseRes<Op>, CrsnError> {
Ok(ParseOpRes::ext(match keyword { Ok(ParseRes::ext(match keyword {
"cmp" => { "cmp" => {
ArithOp::Compare { ArithOp::Compare {
a: args.next_rd()?, a: args.next_rd()?,
@ -430,7 +430,7 @@ pub(crate) fn parse(keyword: &str, mut args: ArgParser) -> Result<ParseOpRes<Op>
} }
_other => { _other => {
return Ok(ParseOpRes::Unknown(args)); return Ok(ParseRes::Unknown(args));
} }
})) }))
} }

@ -3,8 +3,8 @@ extern crate log;
use crsn::asm::error::CrsnError; use crsn::asm::error::CrsnError;
use crsn::asm::instr::Op; use crsn::asm::instr::Op;
use crsn::asm::parse::arg_parser::ArgParser; use crsn::asm::parse::arg_parser::TokenParser;
use crsn::module::{CrsnExtension, ParseOpRes}; use crsn::module::{CrsnExtension, ParseRes};
mod defs; mod defs;
mod parse; mod parse;
@ -24,7 +24,7 @@ impl CrsnExtension for ScreenOps {
"screen" "screen"
} }
fn parse_op(&self, keyword: &str, args: ArgParser) -> Result<ParseOpRes<Op>, CrsnError> { fn parse_op(&self, keyword: &str, args: TokenParser) -> Result<ParseRes<Op>, CrsnError> {
parse::parse(keyword, args) parse::parse(keyword, args)
} }
} }

@ -1,13 +1,13 @@
use crsn::asm::data::Rd; use crsn::asm::data::Rd;
use crsn::asm::error::CrsnError; use crsn::asm::error::CrsnError;
use crsn::asm::instr::Op; use crsn::asm::instr::Op;
use crsn::asm::parse::arg_parser::ArgParser; use crsn::asm::parse::arg_parser::TokenParser;
use crsn::module::ParseOpRes; use crsn::module::ParseRes;
use crate::defs::ScreenOp; use crate::defs::ScreenOp;
pub(crate) fn parse(keyword: &str, mut args: ArgParser) -> Result<ParseOpRes<Op>, CrsnError> { pub(crate) fn parse(keyword: &str, mut args: TokenParser) -> Result<ParseRes<Op>, CrsnError> {
Ok(ParseOpRes::ext(match keyword { Ok(ParseRes::ext(match keyword {
"sc-init" => { "sc-init" => {
ScreenOp::ScreenInit { ScreenOp::ScreenInit {
width: args.next_rd()?, width: args.next_rd()?,
@ -41,7 +41,7 @@ pub(crate) fn parse(keyword: &str, mut args: ArgParser) -> Result<ParseOpRes<Op>
} }
_other => { _other => {
return Ok(ParseOpRes::Unknown(args)); return Ok(ParseRes::Unknown(args));
} }
})) }))
} }

@ -1,8 +1,8 @@
use crsn::asm::data::literal::Value; use crsn::asm::data::literal::Value;
use crsn::asm::error::CrsnError; use crsn::asm::error::CrsnError;
use crsn::asm::instr::Op; use crsn::asm::instr::Op;
use crsn::asm::parse::arg_parser::ArgParser; use crsn::asm::parse::arg_parser::TokenParser;
use crsn::module::{CrsnExtension, ParseOpRes}; use crsn::module::{CrsnExtension, ParseRes};
use crsn::runtime::fault::Fault; use crsn::runtime::fault::Fault;
use crsn::runtime::run_thread::{RunState, ThreadInfo}; use crsn::runtime::run_thread::{RunState, ThreadInfo};
@ -24,7 +24,7 @@ impl CrsnExtension for StackOps {
"stacks" "stacks"
} }
fn parse_op(&self, keyword: &str, args: ArgParser) -> Result<ParseOpRes<Op>, CrsnError> { fn parse_op(&self, keyword: &str, args: TokenParser) -> Result<ParseRes<Op>, CrsnError> {
parse::parse(keyword, args) parse::parse(keyword, args)
} }

@ -1,12 +1,12 @@
use crsn::asm::error::CrsnError; use crsn::asm::error::CrsnError;
use crsn::asm::instr::Op; use crsn::asm::instr::Op;
use crsn::asm::parse::arg_parser::ArgParser; use crsn::asm::parse::arg_parser::TokenParser;
use crsn::module::ParseOpRes; use crsn::module::ParseRes;
use crate::defs::StackOp; use crate::defs::StackOp;
pub(crate) fn parse(keyword: &str, mut args: ArgParser) -> Result<ParseOpRes<Op>, CrsnError> { pub(crate) fn parse(keyword: &str, mut args: TokenParser) -> Result<ParseRes<Op>, CrsnError> {
Ok(ParseOpRes::ext(match keyword { Ok(ParseRes::ext(match keyword {
"stack" => { "stack" => {
StackOp::NewStack { StackOp::NewStack {
dst: args.next_wr()?, dst: args.next_wr()?,
@ -28,7 +28,7 @@ pub(crate) fn parse(keyword: &str, mut args: ArgParser) -> Result<ParseOpRes<Op>
} }
_other => { _other => {
return Ok(ParseOpRes::Unknown(args)); return Ok(ParseRes::Unknown(args));
} }
})) }))
} }

@ -1,10 +1,10 @@
( (
(main (proc main
(call fac 5) (call fac 5)
(ld r0 res0) (ld r0 res0)
(halt) (halt)
) )
(fac (proc fac
(cmp arg0 2 (cmp arg0 2
(eq? (ret 2))) (eq? (ret 2)))
(sub r0 arg0 1) (sub r0 arg0 1)

@ -1,10 +1,10 @@
; Set log level to "info" or above for the best results! ; Set log level to "info" or above for the best results!
( (
(main (proc main
(sc-init 800 600) (sc-init 800 600)
(sc-opt 1 0) ; auto blit (sc-opt 1 1) ; auto blit
(sc-opt 2 60) ; frame rate (sc-opt 2 25) ; frame rate
(ld r0 5) ; x (ld r0 5) ; x
(ld r1 0) ; y (ld r1 0) ; y
@ -15,16 +15,12 @@
(ld r5 0x3300ff) (ld r5 0x3300ff)
(:loop) (:loop)
(add r5 0x000001) (add r5 0x000001)
(and r5 0xffffff) (sc-px r0 r1 r5)
(sc-px r0 r1 r5) (add r0 r2)
(add r0 r2) (add r1 r3)
(add r1 r3) (cmp r0 799 (eq? (ld r2 -1)) (ne? (cmp r0 0 (eq? (ld r2 1)))))
(cmp r0 799 (eq? (ld r2 -1))) (cmp r1 599 (eq? (ld r3 -1)) (ne? (cmp r1 0 (eq? (ld r3 1)))))
(cmp r0 0 (eq? (ld r2 1)))
(cmp r1 599 (eq? (ld r3 -1)))
(cmp r1 0 (eq? (ld r3 1)))
(sc-blit 0)
(j :loop) (j :loop)
) )
) )

Loading…
Cancel
Save