diff --git a/Cargo.toml b/Cargo.toml index 4c3e086..dcabde3 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -1,6 +1,6 @@ [package] -name = "befunge" -version = "2022.12.1" +name = "rusty_funge" +version = "2022.12.2" edition = "2021" # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html diff --git a/examples/99.bf b/examples/99.bf index 153f7c7..d4b6e68 100755 --- a/examples/99.bf +++ b/examples/99.bf @@ -1,4 +1,4 @@ -#!/usr/bin/env befunge +#!/usr/bin/env rusty_funge 992+*: v: < v" ".:<_091+".reeb fo selttob erom on ,llaw eht no reeb fo selttob erom oN">:v ,v"Go to the store and buy some more, 99 bottles of beer on the wall."+910<^,_v diff --git a/examples/cat_v.bf b/examples/cat_v.bf index fb2c8da..a3c3a6c 100755 --- a/examples/cat_v.bf +++ b/examples/cat_v.bf @@ -1,4 +1,4 @@ -#!/usr/bin/env befunge +#!/usr/bin/env rusty_funge w4110'vin10 ">#,:#<_@ \ No newline at end of file diff --git a/examples/concurrent.bf b/examples/concurrent.bf index c2b5959..370cbe8 100755 --- a/examples/concurrent.bf +++ b/examples/concurrent.bf @@ -1,3 +1,3 @@ -#!/usr/bin/env befunge +#!/usr/bin/env rusty_funge v @000_1t111@ \ No newline at end of file diff --git a/examples/dna.bf b/examples/dna.bf index 60d2cca..4fdcdb2 100755 --- a/examples/dna.bf +++ b/examples/dna.bf @@ -1,4 +1,4 @@ -#!/usr/bin/env befunge +#!/usr/bin/env rusty_funge 7^DN>vA v_#v? v 7^<"""" diff --git a/examples/ex1.bf b/examples/ex1.bf index c5568e2..4110acf 100755 --- a/examples/ex1.bf +++ b/examples/ex1.bf @@ -1,3 +1,4 @@ +#!/usr/bin/env rusty_funge v < >?"/",^ >"\",^ diff --git a/examples/factorial.bf b/examples/factorial.bf index dc2ad20..c61fed0 100755 --- a/examples/factorial.bf +++ b/examples/factorial.bf @@ -1,3 +1,4 @@ +#!/usr/bin/env rusty_funge " ?tupni",v v.:&,,,,,,< >" = !",,,v diff --git a/examples/factorial0.bf b/examples/factorial0.bf index c5d1b17..07a86ec 100755 --- a/examples/factorial0.bf +++ b/examples/factorial0.bf @@ -1,4 +1,4 @@ -#!/usr/bin/env befunge +#!/usr/bin/env rusty_funge v & >>:1v diff --git a/examples/factorial_eso.bf b/examples/factorial_eso.bf index 35c4c04..1f39669 100755 --- a/examples/factorial_eso.bf +++ b/examples/factorial_eso.bf @@ -1,3 +1,3 @@ -#!/usr/bin/env befunge +#!/usr/bin/env rusty_funge &>:1-:v v *_$.@ ^ _$>\:^ \ No newline at end of file diff --git a/examples/factorial_heap.bf b/examples/factorial_heap.bf index c85b5d4..d096f13 100755 --- a/examples/factorial_heap.bf +++ b/examples/factorial_heap.bf @@ -1,3 +1,3 @@ -#!/usr/bin/env befunge +#!/usr/bin/env rusty_funge &:>00p1-::v ^ *g00 _g.25*,@ diff --git a/examples/fibonacci.bf b/examples/fibonacci.bf index 6ddfb0d..198c081 100755 --- a/examples/fibonacci.bf +++ b/examples/fibonacci.bf @@ -1,2 +1,2 @@ -#!/usr/bin/env befunge +#!/usr/bin/env rusty_funge j1\:b0p+:.' 1 \ No newline at end of file diff --git a/examples/guess.bf b/examples/guess.bf index 9cd5771..cf2ab84 100755 --- a/examples/guess.bf +++ b/examples/guess.bf @@ -1,4 +1,4 @@ -#!/usr/bin/env befunge +#!/usr/bin/env rusty_funge vv < < 2 ^ v< diff --git a/examples/guess2.bf b/examples/guess2.bf index 9f138a2..0559b35 100755 --- a/examples/guess2.bf +++ b/examples/guess2.bf @@ -1,4 +1,4 @@ -#!/usr/bin/env befunge +#!/usr/bin/env rusty_funge v>>> > v>>> > v 012 3 012 3 ^?^ ^?^ diff --git a/examples/hello_b98.bf b/examples/hello_b98.bf index 621d2ab..116e0ea 100755 --- a/examples/hello_b98.bf +++ b/examples/hello_b98.bf @@ -1,2 +1,2 @@ -#!/usr/bin/env befunge +#!/usr/bin/env rusty_funge <>:#,_# @#"Hello, World!" \ No newline at end of file diff --git a/examples/hello_world.bf b/examples/hello_world.bf index 7ccf6d1..e088383 100755 --- a/examples/hello_world.bf +++ b/examples/hello_world.bf @@ -1,3 +1,4 @@ +#!/usr/bin/env rusty_funge > v v ,,,,,"Hello"< >48*, v diff --git a/examples/hello_world2.bf b/examples/hello_world2.bf index 2c3185c..4d11e57 100755 --- a/examples/hello_world2.bf +++ b/examples/hello_world2.bf @@ -1,3 +1,4 @@ +#!/usr/bin/env rusty_funge >25*"!dlrow ,olleH":v v:,_@ > ^ diff --git a/examples/mill.bf b/examples/mill.bf index d7d9b4a..990d8ae 100755 --- a/examples/mill.bf +++ b/examples/mill.bf @@ -1,4 +1,4 @@ -#!/usr/bin/env befunge +#!/usr/bin/env rusty_funge ] v >v v?t1? diff --git a/examples/multiplier.bf b/examples/multiplier.bf index 61112ca..44a823a 100755 --- a/examples/multiplier.bf +++ b/examples/multiplier.bf @@ -1 +1,2 @@ +#!/usr/bin/env rusty_funge &&*.25*,@ \ No newline at end of file diff --git a/examples/pi.bf b/examples/pi.bf index f7c90ba..6bfb087 100755 --- a/examples/pi.bf +++ b/examples/pi.bf @@ -1,4 +1,4 @@ -#!/usr/bin/env befunge +#!/usr/bin/env rusty_funge "^a&EPm=kY}t/qYC+i9wHye$m N@~x+"v "|DsY<"-"z6n<[Yo2x|UP5VD:">:#v_@> -:19+/"0"+,19+%"0"+, ^ >39* \ No newline at end of file diff --git a/examples/quine1.bf b/examples/quine1.bf index 724c8b1..dc36e40 100755 --- a/examples/quine1.bf +++ b/examples/quine1.bf @@ -1,2 +1,2 @@ -#!/usr/bin/env befunge +#!/usr/bin/env rusty_funge 01->1# +# :# 0# g# ,# :# 5# 8# *# 4# +# -# _@ \ No newline at end of file diff --git a/examples/random.bf b/examples/random.bf index 4ea14af..d450b68 100755 --- a/examples/random.bf +++ b/examples/random.bf @@ -1,3 +1,4 @@ +#!/usr/bin/env rusty_funge v>>>>>v 12345 ^?^ diff --git a/examples/random_n.bf b/examples/random_n.bf index bab7643..d30a270 100755 --- a/examples/random_n.bf +++ b/examples/random_n.bf @@ -1,4 +1,4 @@ -#!/usr/bin/env befunge +#!/usr/bin/env rusty_funge & :v>00g2/.@ v00_^#!`/2g00:< >0p:1>>:10p` !| diff --git a/examples/sieve.bf b/examples/sieve.bf index 30d8810..036815e 100755 --- a/examples/sieve.bf +++ b/examples/sieve.bf @@ -1,4 +1,4 @@ -#!/usr/bin/env befunge +#!/usr/bin/env rusty_funge 2>:3g" "-!v\ g30 < |!`"O":+1_:.:03p>03g+:"O"`| @ ^ p3\" ":< diff --git a/examples/soup.bf b/examples/soup.bf index abfe598..26867a5 100755 --- a/examples/soup.bf +++ b/examples/soup.bf @@ -1,4 +1,4 @@ -#!/usr/bin/env befunge +#!/usr/bin/env rusty_funge 060p070 p'O80v pb2*90p4$4> $4$>v> v4$>4$>4$>4$># ARGH>! diff --git a/examples/test.bf b/examples/test.bf index 5c61223..f132b05 100755 --- a/examples/test.bf +++ b/examples/test.bf @@ -1,2 +1,2 @@ -#!/usr/bin/env befunge -45*1-y>>#,:#<_$:w@ \ No newline at end of file +#!/usr/bin/env rusty_funge +00gg00@ \ No newline at end of file diff --git a/src/lib.rs b/src/lib.rs index 3c730bd..f7c43f4 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -1,13 +1,10 @@ use std::collections::HashMap; -use std::{fmt, fs}; -use std::fmt::{Debug, Display, Formatter}; +use std::{env, fs, fmt, fmt::{Debug, Display, Formatter}}; use std::io::stdin; -use std::ops::{Index, IndexMut}; -use std::error::Error; -use std::path::Path; -use chrono::{Datelike, Timelike}; +use std::ops::{Deref, DerefMut, Index, IndexMut}; +use std::{error::Error, hash::Hash, path::Path}; +use chrono::{offset::Local, {Datelike, Timelike}}; use rand::Rng; -use chrono::offset::Local; const VERSION: &str = env!("CARGO_PKG_VERSION"); @@ -83,7 +80,7 @@ struct Output { impl Output { fn print(&mut self, string: String) { match self.sink { - OutputEnum::StdOut => println!("{}", string), + OutputEnum::StdOut => print!("{}", string), OutputEnum::Vector(ref mut v) => v.push(string) } } @@ -254,11 +251,7 @@ impl IP { } fn op(&self, funge: &Funge) -> isize { - if funge.code.contains_key(&self.position) { - funge.code[&self.position] - } else { - 32 - } + funge.code[&self.position] } fn reverse(&mut self) { @@ -346,25 +339,25 @@ impl IP { 2 => { vec![isize::BITS as isize] } 3 => { let mut f = 0; - for (i, c) in "wpfunge".chars().enumerate() { + for (i, c) in "wprustyfunge".chars().enumerate() { f += (256 as isize).pow(i as u32) * ord(c)?; } vec![f] } - 4 => { vec![VERSION.replace(".", "").parse()?] } - 5 => { vec![1] } - 6 => { vec![ord(std::path::MAIN_SEPARATOR)?] } - 7 => { vec![2] } - 8 => { vec![self.id as isize] } - 9 => { vec![0] } - 10 => { self.position.to_owned() } - 11 => { self.delta.to_owned() } - 12 => { self.offset.to_owned() } - 13 => { funge.extent.chunks(2).map(|i| i[0]).collect() } - 14 => { funge.extent.chunks(2).map(|i| i[1]).collect() } - 15 => { vec![((time.year() as isize) - 1900) * 256 * 256 + (time.month() as isize) * 256 + (time.day() as isize)] } - 16 => { vec![(time.hour() as isize) * 256 * 256 + (time.minute() as isize) * 256 + (time.second() as isize)] } - 17 => { vec![self.stack.len_stack() as isize] } + 4 => vec![VERSION.replace(".", "").parse()?], + 5 => vec![1], + 6 => vec![ord(std::path::MAIN_SEPARATOR)?], + 7 => vec![2], + 8 => vec![*&self.id as isize], + 9 => vec![0], + 10 => self.position.to_owned(), + 11 => self.delta.to_owned(), + 12 => self.offset.to_owned(), + 13 => funge.extent.chunks(2).map(|i| i[0]).collect(), + 14 => funge.extent.chunks(2).map(|i| i[1]).collect(), + 15 => vec![((time.year() as isize) - 1900) * 256 * 256 + (time.month() as isize) * 256 + (time.day() as isize)], + 16 => vec![(time.hour() as isize) * 256 * 256 + (time.minute() as isize) * 256 + (time.second() as isize)], + 17 => vec![self.stack.len_stack() as isize], 18 => { let mut l = Vec::new(); for stack in &self.stack.stackstack { @@ -375,17 +368,16 @@ impl IP { } 19 => { let mut r = Vec::new(); - let mut args = std::env::args(); - if args.len() > 2 { - for i in 2..args.len() { - let j: Vec = args.nth(i).expect("We checked the length.") - .chars().map(|i| ord(i).expect("")).collect(); + let args: Vec = env::args().collect(); + if args.len() > 1 { + for i in 1..args.len() { + let j: Vec = args[i].chars().map(|i| ord(i).expect("")).collect(); r.extend(j); r.push(0); } } r.push(0); - let file = args.nth(1).expect("We checked the length."); + let file = &args[0]; let path = Path::new(&file); let j: Vec = path.file_name().ok_or("No file name.")? .to_str().ok_or("Cannot convert String.")? @@ -398,7 +390,7 @@ impl IP { } 20 => { let mut r = Vec::new(); - let vars = std::env::vars(); + let vars = env::vars(); for (key, value) in vars { let j: Vec = key.chars().map(|i| ord(i).expect("")).collect(); r.extend(j); @@ -457,7 +449,11 @@ impl IP { 47 => { // / let b = self.stack.pop(); let a = self.stack.pop(); - self.stack.push(a / b); + if b == 0 { + self.stack.push(0); + } else { + self.stack.push(a / b); + } } 37 => { // % let b = self.stack.pop(); @@ -466,7 +462,11 @@ impl IP { } 33 => { // ! let a = self.stack.pop(); - self.stack.push(!a as isize); + if a == 0 { + self.stack.push(1); + } else { + self.stack.push(0); + } } 96 => { // ` let b = self.stack.pop(); @@ -771,10 +771,46 @@ impl IP { } } + +#[derive(Clone)] +struct DefaultHashMap { + hashmap: HashMap, + default: V +} + +impl DefaultHashMap { + fn new(default: V) -> Self { + Self { hashmap: HashMap::new(), default } + } +} + +impl Deref for DefaultHashMap { + type Target = HashMap; + + fn deref(&self) -> &Self::Target { + &self.hashmap + } +} + +impl DerefMut for DefaultHashMap { + fn deref_mut(&mut self) -> &mut Self::Target { + &mut self.hashmap + } +} + +impl Index<&K> for DefaultHashMap { + type Output = V; + + fn index(&self, index: &K) -> &Self::Output { + self.hashmap.get(&index).unwrap_or(&self.default) + } +} + + #[derive(Clone)] pub struct Funge { extent: Vec, - code: HashMap, isize>, + code: DefaultHashMap, isize>, steps: isize, ips: Vec, inputs: Input, @@ -786,7 +822,7 @@ impl Funge { pub fn new(code: T) -> Result> { let mut new = Self { extent: vec![0, 0, 0, 0], - code: HashMap::new(), + code: DefaultHashMap::new(32), steps: 0, ips: Vec::new(), inputs: Input { source: InputEnum::StdIn }, @@ -794,7 +830,8 @@ impl Funge { terminated: false }; let mut code: Vec = code.to_string().lines().map(|i| String::from(i)).collect(); - if code[0].starts_with(r"#!/usr/bin/env befunge") | code[0].starts_with(r"#!/usr/bin/env -S befunge") { + let exe = env::current_exe()?.file_name().ok_or("No exe name")?.to_str().unwrap().to_string(); + if code[0].starts_with(&*format!(r"#!/usr/bin/env {}", exe)) | code[0].starts_with(&*format!(r"#!/usr/bin/env -S {}", exe)) { code.remove(0); } new.insert_code(code, 0, 0)?; @@ -885,7 +922,7 @@ impl Funge { fn to_string(&self, show_ips: bool) -> String { let mut lines = Vec::new(); - for (key, value) in (&self.code).into_iter() { + for (key, value) in (&*self.code).into_iter() { let x= key[0] as usize; let y= key[1] as usize; while lines.len() <= y { @@ -894,7 +931,7 @@ impl Funge { while lines[y].len() <= x { lines[y].push(String::from(" ")); } - if ((32 <= *value) & (*value <= 126)) | ((161 <= *value) & (*value <= 255)) { + if ((&32 <= value) & (value <= &126)) | ((&161 <= value) & (value <= &255)) { lines[y][x] = chr(*value).unwrap().to_string(); } else { lines[y][x] = chr(164).unwrap().to_string(); @@ -912,15 +949,13 @@ impl Funge { let mut string = String::from("grid:\n"); string.push_str(&join(&lines.iter().map(|i| join(&i, "")).collect(), "\n")); string.push_str("\n\nstacks:\n"); - for ip in &self.ips { - string.push_str(&ip.stack.to_string()); - } + string.push_str(&join(&(&self.ips).iter().map(|ip| ip.stack.to_string()).collect(), "\n")); match &self.output.sink { OutputEnum::StdOut => { }, OutputEnum::Vector(v) => { string.push_str("\n\nOutput:\n"); - string.push_str(&*join(&v, "")); + string.push_str(&join(&v, "")); } }; diff --git a/src/main.rs b/src/main.rs index 1a8d054..830a5a2 100644 --- a/src/main.rs +++ b/src/main.rs @@ -2,7 +2,7 @@ mod debug; use std::error::Error; use clap::Parser; -use befunge::Funge; +use rusty_funge::Funge; use debug::FungeView; @@ -27,7 +27,7 @@ fn main() -> Result<(), Box> { } match args.debug { - Some(interval) => FungeView::new(funge)?.debug(interval)?, + Some(interval) => FungeView::new(funge)?.debug(interval).unwrap(), None => { funge.run()?; } } Ok(())