diff --git a/crsn/src/asm/parse/parse_data.rs b/crsn/src/asm/parse/parse_data.rs index ce2f5dc..8d796d9 100644 --- a/crsn/src/asm/parse/parse_data.rs +++ b/crsn/src/asm/parse/parse_data.rs @@ -6,6 +6,7 @@ use crate::asm::data::{DataDisp, Rd, RdData, reg, Wr, WrData}; use crate::asm::data::literal::Label; use crate::asm::error::CrsnError; use crate::asm::parse::sexp_expect::expect_string_atom; +use std::borrow::Cow; /// Parse a label pub fn parse_label(name: Option) -> Result { @@ -47,12 +48,17 @@ pub fn parse_data_disp(tok: Option) -> Result { } pub fn parse_u64(literal: &str) -> anyhow::Result { - if let Some(hex) = literal.strip_prefix("0x") { + let mut without_underscores = Cow::Borrowed(literal); + if without_underscores.contains('_') { + without_underscores = without_underscores.replace('_', "").into(); + } + + if let Some(hex) = without_underscores.strip_prefix("0x") { Ok(u64::from_str_radix(hex, 16)?) - } else if let Some(hex) = literal.strip_prefix("0b") { + } else if let Some(hex) = without_underscores.strip_prefix("0b") { Ok(u64::from_str_radix(hex, 2)?) } else { - Ok(u64::from_str_radix(literal, 10)?) + Ok(u64::from_str_radix(&without_underscores, 10)?) } } diff --git a/crsn/src/builtin/defs.rs b/crsn/src/builtin/defs.rs index b74a6f9..566e6c8 100644 --- a/crsn/src/builtin/defs.rs +++ b/crsn/src/builtin/defs.rs @@ -8,6 +8,10 @@ pub enum BuiltinOp { Nop, /// Stop execution Halt, + /// Sleep + Sleep { + micros: Rd, + }, /// Mark a jump target. Label(Label), /// Jump to a label diff --git a/crsn/src/builtin/exec.rs b/crsn/src/builtin/exec.rs index ba0fb6b..ad5f08d 100644 --- a/crsn/src/builtin/exec.rs +++ b/crsn/src/builtin/exec.rs @@ -6,6 +6,7 @@ use crate::module::{EvalRes, OpTrait}; use crate::runtime::fault::Fault; use crate::runtime::frame::StackFrame; use crate::runtime::run_thread::{state::RunState, ThreadInfo}; +use std::time::Duration; impl OpTrait for BuiltinOp { fn execute(&self, info: &ThreadInfo, state: &mut RunState) -> Result { @@ -137,6 +138,9 @@ impl OpTrait for BuiltinOp { let x = state.read(*src)?; state.frame.status.load(x); } + BuiltinOp::Sleep { micros } => { + std::thread::sleep(Duration::from_micros(state.read(*micros)?)) + } BuiltinOp::Drop(obj) => { let x = state.read(Rd::new(RdData::Register(obj.reg())))?; diff --git a/crsn/src/builtin/parse.rs b/crsn/src/builtin/parse.rs index ff34ec9..bbae512 100644 --- a/crsn/src/builtin/parse.rs +++ b/crsn/src/builtin/parse.rs @@ -38,6 +38,12 @@ impl CrsnExtension for BuiltinOps { BuiltinOp::Halt } + "sleep" => { + BuiltinOp::Sleep { + micros: args.next_rd()?, + } + } + "j" => { let dest = parse_label(args.next())?; BuiltinOp::Jump(dest) diff --git a/launcher/src/main.rs b/launcher/src/main.rs index 0e34b8d..29124b0 100644 --- a/launcher/src/main.rs +++ b/launcher/src/main.rs @@ -77,29 +77,29 @@ fn main() { let program = " ( (main - (sc-init 640 480) + (sc-init 800 600) (sc-opt 1 0) ; auto blit (sc-opt 2 60) ; frame rate - (ld r0 39) ; x + (ld r0 5) ; x (ld r1 0) ; y (ld r2 1) ; dx (ld r3 1) ; dy - (ld r5 0xffffff) + (ld r5 0x3300ff) (:loop) - (add r5 0x010001) + (add r5 0x000001) (and r5 0xffffff) (sc-px r0 r1 r5) - (sc-blit 0) (add r0 r2) (add r1 r3) - (cmp r0 639 (eq? (ld r2 -1))) + (cmp r0 799 (eq? (ld r2 -1))) (cmp r0 0 (eq? (ld r2 1))) - (cmp r1 479 (eq? (ld r3 -1))) + (cmp r1 599 (eq? (ld r3 -1))) (cmp r1 0 (eq? (ld r3 1))) + (sc-blit 0) (j :loop) ) )