diff --git a/Cargo.toml b/Cargo.toml index 28abd70..c8416bb 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -11,4 +11,9 @@ publish = false [profile.dev] overflow-checks = false +[profile.release] +strip = true +lto = true +panic = "abort" + [dependencies] diff --git a/README.md b/README.md index 9af8bc7..0b714b7 100644 --- a/README.md +++ b/README.md @@ -2,4 +2,4 @@ A zero-dependencies Labaski interpreter written in Rust. Fully supports [Labashki specs 1.4.1](./SPECIFICATION.md). ## Examples -See `example-scripts` directory. \ No newline at end of file +See `scripts` directory. \ No newline at end of file diff --git a/build.bat b/build.bat index 27b6875..9bf316b 100644 --- a/build.bat +++ b/build.bat @@ -1,5 +1,9 @@ @echo off +echo Building for Windows... cargo build --release +echo Building for Linux... cargo zigbuild --release --target x86_64-unknown-linux-gnu +echo Copy to bin... copy target\release\labast.exe bin\ /Y -copy target\x86_64-unknown-linux-gnu\release\labast bin\ /Y \ No newline at end of file +copy target\x86_64-unknown-linux-gnu\release\labast bin\ /Y +echo Done! \ No newline at end of file diff --git a/example-scripts/expr.lb b/scripts/expr.lb similarity index 100% rename from example-scripts/expr.lb rename to scripts/expr.lb diff --git a/example-scripts/hello-world.lb b/scripts/hello-world.lb similarity index 100% rename from example-scripts/hello-world.lb rename to scripts/hello-world.lb diff --git a/example-scripts/labels.lb b/scripts/labels.lb similarity index 100% rename from example-scripts/labels.lb rename to scripts/labels.lb diff --git a/example-scripts/math.lb b/scripts/math.lb similarity index 100% rename from example-scripts/math.lb rename to scripts/math.lb diff --git a/example-scripts/modules/main.lb b/scripts/modules/main.lb similarity index 100% rename from example-scripts/modules/main.lb rename to scripts/modules/main.lb diff --git a/example-scripts/modules/second_part.lb b/scripts/modules/second_part.lb similarity index 100% rename from example-scripts/modules/second_part.lb rename to scripts/modules/second_part.lb diff --git a/example-scripts/pick.lb b/scripts/pick.lb similarity index 100% rename from example-scripts/pick.lb rename to scripts/pick.lb diff --git a/example-scripts/size.lb b/scripts/size.lb similarity index 100% rename from example-scripts/size.lb rename to scripts/size.lb diff --git a/scripts/std/rev.lb b/scripts/std/rev.lb new file mode 100644 index 0000000..21f9056 --- /dev/null +++ b/scripts/std/rev.lb @@ -0,0 +1,4 @@ +; Labashki standard library +; Written by Labashki developer - aeris + +ARGS 0 \ No newline at end of file diff --git a/scripts/std/rot.lb b/scripts/std/rot.lb new file mode 100644 index 0000000..469cf7f --- /dev/null +++ b/scripts/std/rot.lb @@ -0,0 +1,4 @@ +; Labashki standard library +; Written by Labashki developer - aeris + +ARGS 3 \ No newline at end of file diff --git a/scripts/std/unix/ВАРЁНЫЙНОСОК.lb b/scripts/std/unix/ВАРЁНЫЙНОСОК.lb new file mode 100644 index 0000000..99a2bcf --- /dev/null +++ b/scripts/std/unix/ВАРЁНЫЙНОСОК.lb @@ -0,0 +1,17 @@ +; Labashki standard library +; Written by Labashki developer - aeris + +MAXSIZE +ARGS 1 ; Насколько сварить носок +SUB + +@ 1 + JNZ 2 + QUIT + +@ 2 + #EXPR - + PUSH -1 + _UNIX_RANDOM + SWAP + JMP 1 \ No newline at end of file diff --git a/scripts/vareniynosok.lb b/scripts/vareniynosok.lb new file mode 100644 index 0000000..3c600cc --- /dev/null +++ b/scripts/vareniynosok.lb @@ -0,0 +1,2 @@ +SIZE +#EXEC std\unix\ВАРЁНЫЙНОСОК.lb \ No newline at end of file diff --git a/src/execute.rs b/src/execute.rs index 51fae58..19ac571 100644 --- a/src/execute.rs +++ b/src/execute.rs @@ -49,6 +49,7 @@ pub fn execute(stack: &mut Stack, mut origin_stack: Option<&mut Stack>, mod_name "MEOW" => instructions::meow::meow(&mut stack.memory), "DUMP" => instructions::dump::dump(&mut stack.memory), "SIZE" => instructions::size::size(&mut stack.memory), + "MAXSIZE" => instructions::maxsize::maxsize(&mut stack.memory), "#EXPR" => instructions::expr::expr(&mut stack.memory, &instruction.arg), @@ -72,6 +73,9 @@ pub fn execute(stack: &mut Stack, mut origin_stack: Option<&mut Stack>, mod_name "ARGS" => instructions::args::args(&mut stack.memory, &mut origin_stack, &instruction.data), "#EXEC" => instructions::exec::exec(stack, &instruction.arg.clone(), &mod_name), + #[cfg(target_family = "unix")] + "_UNIX_RANDOM" => instructions::_unix_random::_unix_random(&mut stack.memory), + // ? "NOP" => continue, "EXIT" => instructions::exit::exit(&instruction.data), diff --git a/src/instructions/_unix_random.rs b/src/instructions/_unix_random.rs new file mode 100644 index 0000000..79258c1 --- /dev/null +++ b/src/instructions/_unix_random.rs @@ -0,0 +1,14 @@ +use std::fs::File; +use std::io::Read; +use crate::RunError; + +#[cfg(target_family = "unix")] +pub fn _unix_random(memory: &mut Vec) { + let mut rng = File::open("/dev/urandom").unwrap(); + + let mut buffer = [0u8; 1]; + rng.read_exact(&mut buffer).unwrap(); + + let data = &memory.pop().expect(&format!("{}", RunError::MemoryEmpty)); + memory.push((buffer[0] as u16) % (*data - 1)); +} \ No newline at end of file diff --git a/src/instructions/args.rs b/src/instructions/args.rs index 8bbeebe..a80bec1 100644 --- a/src/instructions/args.rs +++ b/src/instructions/args.rs @@ -1,7 +1,7 @@ use crate::{errors::RunError, stack::Stack}; pub fn args(memory: &mut Vec, origin_stack: &mut Option<&mut Stack>, data: &u16) { - let origin_memory = &mut origin_stack.as_mut().expect("msg").memory; + let origin_memory = &mut origin_stack.as_mut().expect(&format!("{}", RunError::RequestArgsInMainModule)).memory; if *origin_memory == *memory { eprintln!("{}", RunError::RequestArgsInMainModule); diff --git a/src/instructions/dump.rs b/src/instructions/dump.rs index a2df7f4..bfd1825 100644 --- a/src/instructions/dump.rs +++ b/src/instructions/dump.rs @@ -1,4 +1,9 @@ pub fn dump(memory: &mut Vec) { + if memory.is_empty() { + println!("Stack is empty."); + return; + } + for (i, entry) in memory.iter().enumerate() { println!("{0}: {1}", i, entry); } diff --git a/src/instructions/jnz.rs b/src/instructions/jnz.rs index 2093234..4216cd4 100644 --- a/src/instructions/jnz.rs +++ b/src/instructions/jnz.rs @@ -6,7 +6,7 @@ pub fn jnz(memory: &mut Vec, labels: &mut [Option; 256], program_count std::process::exit(2); } - if memory.pop() != Some(0) { + if memory.last() != Some(&0) { *program_counter = (labels[*data as usize].unwrap() - 1) as u16; } } \ No newline at end of file diff --git a/src/instructions/jz.rs b/src/instructions/jz.rs index f85838d..cc2fcba 100644 --- a/src/instructions/jz.rs +++ b/src/instructions/jz.rs @@ -6,7 +6,7 @@ pub fn jz(memory: &mut Vec, labels: &mut [Option; 256], program_counte std::process::exit(2); } - if memory.pop() == Some(0) { + if memory.last() == Some(&0) { *program_counter = (labels[*data as usize].unwrap() - 1) as u16; } } \ No newline at end of file diff --git a/src/instructions/maxsize.rs b/src/instructions/maxsize.rs new file mode 100644 index 0000000..5d7769d --- /dev/null +++ b/src/instructions/maxsize.rs @@ -0,0 +1,3 @@ +pub fn maxsize(memory: &mut Vec) { + memory.push(65535); +} \ No newline at end of file diff --git a/src/instructions/mod.rs b/src/instructions/mod.rs index 1fa4217..6cf89ee 100644 --- a/src/instructions/mod.rs +++ b/src/instructions/mod.rs @@ -19,4 +19,7 @@ pub mod exec; pub mod args; pub mod expr; pub mod size; -pub mod exit; \ No newline at end of file +pub mod exit; +pub mod maxsize; +#[cfg(target_family = "unix")] +pub mod _unix_random; diff --git a/src/parse.rs b/src/parse.rs index b05e6d1..96dc0e0 100644 --- a/src/parse.rs +++ b/src/parse.rs @@ -24,7 +24,13 @@ pub fn parse(stack: &mut Stack, file_content: &str) { if command.len() >= 2 { match name.chars().nth(0) { Some('#') => arg = command[1].to_string(), - _ => data = command[1].parse().expect(&format!("{}", ParseError::DataNotAUInt(command[0].to_string(), i + 1))), + _ => { + if command[1] == "-1" { // required for _UNIX_RANDOM instruction + data = 65535; + } else { + data = command[1].parse().expect(&format!("{}", ParseError::DataNotAUInt(command[0].to_string(), i + 1))) + } + } } }