- rename crate to rusty_funge

- shebang in examples, and fix finding shebangs
- wrap HashMap into DefaultHashMap
- fix y19, / and ! instructions
This commit is contained in:
Wim Pomp
2022-12-13 18:05:07 +01:00
parent e549c72746
commit fa005b45d4
27 changed files with 110 additions and 69 deletions

View File

@@ -1,6 +1,6 @@
[package] [package]
name = "befunge" name = "rusty_funge"
version = "2022.12.1" version = "2022.12.2"
edition = "2021" edition = "2021"
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html

View File

@@ -1,4 +1,4 @@
#!/usr/bin/env befunge #!/usr/bin/env rusty_funge
992+*: v: < 992+*: v: <
v" ".:<_091+".reeb fo selttob erom on ,llaw eht no reeb fo selttob erom oN">: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 ,v"Go to the store and buy some more, 99 bottles of beer on the wall."+910<^,_v

View File

@@ -1,4 +1,4 @@
#!/usr/bin/env befunge #!/usr/bin/env rusty_funge
w4110'vin10 w4110'vin10
"<v" "<v"
>>#,:#<_@ >>#,:#<_@

View File

@@ -1,3 +1,3 @@
#!/usr/bin/env befunge #!/usr/bin/env rusty_funge
v v
@000_1t111@ @000_1t111@

View File

@@ -1,4 +1,4 @@
#!/usr/bin/env befunge #!/usr/bin/env rusty_funge
7^DN>vA 7^DN>vA
v_#v? v v_#v? v
7^<"""" 7^<""""

View File

@@ -1,3 +1,4 @@
#!/usr/bin/env rusty_funge
v < v <
>?"/",^ >?"/",^
>"\",^ >"\",^

View File

@@ -1,3 +1,4 @@
#!/usr/bin/env rusty_funge
" ?tupni",v " ?tupni",v
v.:&,,,,,,< v.:&,,,,,,<
>" = !",,,v >" = !",,,v

View File

@@ -1,4 +1,4 @@
#!/usr/bin/env befunge #!/usr/bin/env rusty_funge
v v
& &
>>:1v >>:1v

View File

@@ -1,3 +1,3 @@
#!/usr/bin/env befunge #!/usr/bin/env rusty_funge
&>:1-:v v *_$.@ &>:1-:v v *_$.@
^ _$>\:^ ^ _$>\:^

View File

@@ -1,3 +1,3 @@
#!/usr/bin/env befunge #!/usr/bin/env rusty_funge
&:>00p1-::v &:>00p1-::v
^ *g00 _g.25*,@ ^ *g00 _g.25*,@

View File

@@ -1,2 +1,2 @@
#!/usr/bin/env befunge #!/usr/bin/env rusty_funge
j1\:b0p+:.' 1 j1\:b0p+:.' 1

View File

@@ -1,4 +1,4 @@
#!/usr/bin/env befunge #!/usr/bin/env rusty_funge
vv < < vv < <
2 2
^ v< ^ v<

View File

@@ -1,4 +1,4 @@
#!/usr/bin/env befunge #!/usr/bin/env rusty_funge
v>>> > v>>> > v v>>> > v>>> > v
012 3 012 3 012 3 012 3
^?^ ^?^ ^?^ ^?^

View File

@@ -1,2 +1,2 @@
#!/usr/bin/env befunge #!/usr/bin/env rusty_funge
<>:#,_# @#"Hello, World!" <>:#,_# @#"Hello, World!"

View File

@@ -1,3 +1,4 @@
#!/usr/bin/env rusty_funge
> v > v
v ,,,,,"Hello"< v ,,,,,"Hello"<
>48*, v >48*, v

View File

@@ -1,3 +1,4 @@
#!/usr/bin/env rusty_funge
>25*"!dlrow ,olleH":v >25*"!dlrow ,olleH":v
v:,_@ v:,_@
> ^ > ^

View File

@@ -1,4 +1,4 @@
#!/usr/bin/env befunge #!/usr/bin/env rusty_funge
] v ] v
>v >v
v?t1? v?t1?

View File

@@ -1 +1,2 @@
#!/usr/bin/env rusty_funge
&&*.25*,@ &&*.25*,@

View File

@@ -1,4 +1,4 @@
#!/usr/bin/env befunge #!/usr/bin/env rusty_funge
"^a&EPm=kY}t/qYC+i9wHye$m N@~x+"v "^a&EPm=kY}t/qYC+i9wHye$m N@~x+"v
"|DsY<"-"z6n<[Yo2x|UP5VD:">:#v_@> "|DsY<"-"z6n<[Yo2x|UP5VD:">:#v_@>
-:19+/"0"+,19+%"0"+, ^ >39* -:19+/"0"+,19+%"0"+, ^ >39*

View File

@@ -1,2 +1,2 @@
#!/usr/bin/env befunge #!/usr/bin/env rusty_funge
01->1# +# :# 0# g# ,# :# 5# 8# *# 4# +# -# _@ 01->1# +# :# 0# g# ,# :# 5# 8# *# 4# +# -# _@

View File

@@ -1,3 +1,4 @@
#!/usr/bin/env rusty_funge
v>>>>>v v>>>>>v
12345 12345
^?^ ^?^

View File

@@ -1,4 +1,4 @@
#!/usr/bin/env befunge #!/usr/bin/env rusty_funge
& :v>00g2/.@ & :v>00g2/.@
v00_^#!`/2g00:< v00_^#!`/2g00:<
>0p:1>>:10p` !| >0p:1>>:10p` !|

View File

@@ -1,4 +1,4 @@
#!/usr/bin/env befunge #!/usr/bin/env rusty_funge
2>:3g" "-!v\ g30 < 2>:3g" "-!v\ g30 <
|!`"O":+1_:.:03p>03g+:"O"`| |!`"O":+1_:.:03p>03g+:"O"`|
@ ^ p3\" ":< @ ^ p3\" ":<

View File

@@ -1,4 +1,4 @@
#!/usr/bin/env befunge #!/usr/bin/env rusty_funge
060p070 p'O80v 060p070 p'O80v
pb2*90p4$4> $4$>v> pb2*90p4$4> $4$>v>
v4$>4$>4$>4$># ARGH>! v4$>4$>4$>4$># ARGH>!

View File

@@ -1,2 +1,2 @@
#!/usr/bin/env befunge #!/usr/bin/env rusty_funge
45*1-y>>#,:#<_$:w@ 00gg00@

View File

@@ -1,13 +1,10 @@
use std::collections::HashMap; use std::collections::HashMap;
use std::{fmt, fs}; use std::{env, fs, fmt, fmt::{Debug, Display, Formatter}};
use std::fmt::{Debug, Display, Formatter};
use std::io::stdin; use std::io::stdin;
use std::ops::{Index, IndexMut}; use std::ops::{Deref, DerefMut, Index, IndexMut};
use std::error::Error; use std::{error::Error, hash::Hash, path::Path};
use std::path::Path; use chrono::{offset::Local, {Datelike, Timelike}};
use chrono::{Datelike, Timelike};
use rand::Rng; use rand::Rng;
use chrono::offset::Local;
const VERSION: &str = env!("CARGO_PKG_VERSION"); const VERSION: &str = env!("CARGO_PKG_VERSION");
@@ -83,7 +80,7 @@ struct Output {
impl Output { impl Output {
fn print(&mut self, string: String) { fn print(&mut self, string: String) {
match self.sink { match self.sink {
OutputEnum::StdOut => println!("{}", string), OutputEnum::StdOut => print!("{}", string),
OutputEnum::Vector(ref mut v) => v.push(string) OutputEnum::Vector(ref mut v) => v.push(string)
} }
} }
@@ -254,11 +251,7 @@ impl IP {
} }
fn op(&self, funge: &Funge) -> isize { fn op(&self, funge: &Funge) -> isize {
if funge.code.contains_key(&self.position) {
funge.code[&self.position] funge.code[&self.position]
} else {
32
}
} }
fn reverse(&mut self) { fn reverse(&mut self) {
@@ -346,25 +339,25 @@ impl IP {
2 => { vec![isize::BITS as isize] } 2 => { vec![isize::BITS as isize] }
3 => { 3 => {
let mut f = 0; 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)?; f += (256 as isize).pow(i as u32) * ord(c)?;
} }
vec![f] vec![f]
} }
4 => { vec![VERSION.replace(".", "").parse()?] } 4 => vec![VERSION.replace(".", "").parse()?],
5 => { vec![1] } 5 => vec![1],
6 => { vec![ord(std::path::MAIN_SEPARATOR)?] } 6 => vec![ord(std::path::MAIN_SEPARATOR)?],
7 => { vec![2] } 7 => vec![2],
8 => { vec![self.id as isize] } 8 => vec![*&self.id as isize],
9 => { vec![0] } 9 => vec![0],
10 => { self.position.to_owned() } 10 => self.position.to_owned(),
11 => { self.delta.to_owned() } 11 => self.delta.to_owned(),
12 => { self.offset.to_owned() } 12 => self.offset.to_owned(),
13 => { funge.extent.chunks(2).map(|i| i[0]).collect() } 13 => funge.extent.chunks(2).map(|i| i[0]).collect(),
14 => { funge.extent.chunks(2).map(|i| i[1]).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)] } 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)] } 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] } 17 => vec![self.stack.len_stack() as isize],
18 => { 18 => {
let mut l = Vec::new(); let mut l = Vec::new();
for stack in &self.stack.stackstack { for stack in &self.stack.stackstack {
@@ -375,17 +368,16 @@ impl IP {
} }
19 => { 19 => {
let mut r = Vec::new(); let mut r = Vec::new();
let mut args = std::env::args(); let args: Vec<String> = env::args().collect();
if args.len() > 2 { if args.len() > 1 {
for i in 2..args.len() { for i in 1..args.len() {
let j: Vec<isize> = args.nth(i).expect("We checked the length.") let j: Vec<isize> = args[i].chars().map(|i| ord(i).expect("")).collect();
.chars().map(|i| ord(i).expect("")).collect();
r.extend(j); r.extend(j);
r.push(0); r.push(0);
} }
} }
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 path = Path::new(&file);
let j: Vec<isize> = path.file_name().ok_or("No file name.")? let j: Vec<isize> = path.file_name().ok_or("No file name.")?
.to_str().ok_or("Cannot convert String.")? .to_str().ok_or("Cannot convert String.")?
@@ -398,7 +390,7 @@ impl IP {
} }
20 => { 20 => {
let mut r = Vec::new(); let mut r = Vec::new();
let vars = std::env::vars(); let vars = env::vars();
for (key, value) in vars { for (key, value) in vars {
let j: Vec<isize> = key.chars().map(|i| ord(i).expect("")).collect(); let j: Vec<isize> = key.chars().map(|i| ord(i).expect("")).collect();
r.extend(j); r.extend(j);
@@ -457,8 +449,12 @@ impl IP {
47 => { // / 47 => { // /
let b = self.stack.pop(); let b = self.stack.pop();
let a = self.stack.pop(); let a = self.stack.pop();
if b == 0 {
self.stack.push(0);
} else {
self.stack.push(a / b); self.stack.push(a / b);
} }
}
37 => { // % 37 => { // %
let b = self.stack.pop(); let b = self.stack.pop();
let a = self.stack.pop(); let a = self.stack.pop();
@@ -466,7 +462,11 @@ impl IP {
} }
33 => { // ! 33 => { // !
let a = self.stack.pop(); let a = self.stack.pop();
self.stack.push(!a as isize); if a == 0 {
self.stack.push(1);
} else {
self.stack.push(0);
}
} }
96 => { // ` 96 => { // `
let b = self.stack.pop(); let b = self.stack.pop();
@@ -771,10 +771,46 @@ impl IP {
} }
} }
#[derive(Clone)]
struct DefaultHashMap<K: Eq + Hash, V: Clone> {
hashmap: HashMap<K, V>,
default: V
}
impl<K: Eq + Hash, V: Clone> DefaultHashMap<K, V> {
fn new(default: V) -> Self {
Self { hashmap: HashMap::new(), default }
}
}
impl<K: Eq + Hash, V: Clone> Deref for DefaultHashMap<K, V> {
type Target = HashMap<K, V>;
fn deref(&self) -> &Self::Target {
&self.hashmap
}
}
impl<K: Eq + Hash, V: Clone> DerefMut for DefaultHashMap<K, V> {
fn deref_mut(&mut self) -> &mut Self::Target {
&mut self.hashmap
}
}
impl<K: Eq + Hash, V: Clone> Index<&K> for DefaultHashMap<K, V> {
type Output = V;
fn index(&self, index: &K) -> &Self::Output {
self.hashmap.get(&index).unwrap_or(&self.default)
}
}
#[derive(Clone)] #[derive(Clone)]
pub struct Funge { pub struct Funge {
extent: Vec<isize>, extent: Vec<isize>,
code: HashMap<Vec<isize>, isize>, code: DefaultHashMap<Vec<isize>, isize>,
steps: isize, steps: isize,
ips: Vec<IP>, ips: Vec<IP>,
inputs: Input, inputs: Input,
@@ -786,7 +822,7 @@ impl Funge {
pub fn new<T: ToString>(code: T) -> Result<Self, Box<dyn Error>> { pub fn new<T: ToString>(code: T) -> Result<Self, Box<dyn Error>> {
let mut new = Self { let mut new = Self {
extent: vec![0, 0, 0, 0], extent: vec![0, 0, 0, 0],
code: HashMap::new(), code: DefaultHashMap::new(32),
steps: 0, steps: 0,
ips: Vec::new(), ips: Vec::new(),
inputs: Input { source: InputEnum::StdIn }, inputs: Input { source: InputEnum::StdIn },
@@ -794,7 +830,8 @@ impl Funge {
terminated: false terminated: false
}; };
let mut code: Vec<String> = code.to_string().lines().map(|i| String::from(i)).collect(); let mut code: Vec<String> = 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); code.remove(0);
} }
new.insert_code(code, 0, 0)?; new.insert_code(code, 0, 0)?;
@@ -885,7 +922,7 @@ impl Funge {
fn to_string(&self, show_ips: bool) -> String { fn to_string(&self, show_ips: bool) -> String {
let mut lines = Vec::new(); 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 x= key[0] as usize;
let y= key[1] as usize; let y= key[1] as usize;
while lines.len() <= y { while lines.len() <= y {
@@ -894,7 +931,7 @@ impl Funge {
while lines[y].len() <= x { while lines[y].len() <= x {
lines[y].push(String::from(" ")); 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(); lines[y][x] = chr(*value).unwrap().to_string();
} else { } else {
lines[y][x] = chr(164).unwrap().to_string(); lines[y][x] = chr(164).unwrap().to_string();
@@ -912,15 +949,13 @@ impl Funge {
let mut string = String::from("grid:\n"); let mut string = String::from("grid:\n");
string.push_str(&join(&lines.iter().map(|i| join(&i, "")).collect(), "\n")); string.push_str(&join(&lines.iter().map(|i| join(&i, "")).collect(), "\n"));
string.push_str("\n\nstacks:\n"); string.push_str("\n\nstacks:\n");
for ip in &self.ips { string.push_str(&join(&(&self.ips).iter().map(|ip| ip.stack.to_string()).collect(), "\n"));
string.push_str(&ip.stack.to_string());
}
match &self.output.sink { match &self.output.sink {
OutputEnum::StdOut => { }, OutputEnum::StdOut => { },
OutputEnum::Vector(v) => { OutputEnum::Vector(v) => {
string.push_str("\n\nOutput:\n"); string.push_str("\n\nOutput:\n");
string.push_str(&*join(&v, "")); string.push_str(&join(&v, ""));
} }
}; };

View File

@@ -2,7 +2,7 @@ mod debug;
use std::error::Error; use std::error::Error;
use clap::Parser; use clap::Parser;
use befunge::Funge; use rusty_funge::Funge;
use debug::FungeView; use debug::FungeView;
@@ -27,7 +27,7 @@ fn main() -> Result<(), Box<dyn Error>> {
} }
match args.debug { match args.debug {
Some(interval) => FungeView::new(funge)?.debug(interval)?, Some(interval) => FungeView::new(funge)?.debug(interval).unwrap(),
None => { funge.run()?; } None => { funge.run()?; }
} }
Ok(()) Ok(())