-
-
Save h3nry-d1az/3e58f58c690ec7f52fcda4b0f55825ca to your computer and use it in GitHub Desktop.
Todo lo relacionado con mi lenguaje de programación esotérico 𝚷ᵨ
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Un lenguaje de programación esotérico basado en el teorema fundamental de la aritmética. |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
from math import prod | |
from sympy import isprime | |
from sys import argv | |
from getch import getch | |
from typing import List | |
dbg = True if argv[1] == 'debug' else False | |
S = [int(x) for x in argv[2:]] | |
λ = 0 | |
M = [0]*20 | |
χ = 0 | |
r1 = 0 | |
r2 = 0 | |
r3 = 0 | |
def sep ( | |
n: int | |
) -> List[int]: | |
F = [] | |
for k in range(2, n+1): | |
if (n % k == 0) and \ | |
(isprime(k)): | |
F.append(k) | |
F.append(1) | |
return (F[0], prod(F[1:])) | |
def con( | |
n: int | |
) -> int: | |
match n: | |
case 127: | |
return χ | |
case 131: | |
return M[χ] | |
case 137: | |
tmp = getch() | |
print(tmp.decode('utf-8'), end='', flush=True) | |
return ord(tmp) | |
case 139: | |
return r1 | |
case 149: | |
return r2 | |
case 151: | |
return r3 | |
case _: | |
return n | |
while λ < len(S): | |
α = sep(S[λ]) | |
match α[0]: | |
case 2: | |
χ = con(α[1]) - 1 | |
case 3: | |
χ += con(α[1]) | |
case 5: | |
χ -= con(α[1]) | |
case 7: | |
M[χ] = con(α[1]) - 1 | |
case 11: | |
M[χ] += con(α[1]) | |
case 13: | |
M[χ] -= con(α[1]) | |
case 17: | |
M[χ] *= con(α[1]) | |
case 19: | |
M[χ] //= con(α[1]) | |
case 23: | |
M[χ] %= con(α[1]) | |
case 29: | |
r1 = M[χ] | |
case 31: | |
r2 = M[χ] | |
case 37: | |
r3 = M[χ] | |
case 41: | |
M[con(α[1]) - 1] = M[χ] | |
case 43: | |
aux = M[χ] | |
M[χ] = 0 | |
r1 = aux | |
case 47: | |
aux = M[χ] | |
M[χ] = 0 | |
r2 = aux | |
case 53: | |
aux = M[χ] | |
M[χ] = 0 | |
r3 = aux | |
case 59: | |
aux = M[χ] | |
M[χ] = 0 | |
M[con(α[1]) - 1] = aux | |
case 61: | |
(M[χ], r1) = (r1, M[χ]) | |
case 67: | |
(M[χ], r2) = (r2, M[χ]) | |
case 71: | |
(M[χ], r3) = (r3, M[χ]) | |
case 73: | |
(M[χ], M[con(α[1]) - 1]) = (M[con(α[1]) - 1], M[χ]) | |
case 79: | |
print(chr(con(α[1])), end="") | |
case 83: | |
print(con(α[1]), end="") | |
case 89: | |
if M[χ] == (con(α[1])-1): | |
pass | |
else: | |
print(M[χ], con(α[1])-1) | |
λ += 1 | |
case 97: | |
if not(M[χ] == (con(α[1])-1)): | |
pass | |
else: | |
λ += 1 | |
case 101: | |
λ = (con(α[1]) - 2) | |
case 103: | |
λ += con(α[1]) | |
case 107: | |
λ -= con(α[1]) | |
case 109: | |
pass | |
case 113: | |
exit(0) | |
case _: | |
exit(1) | |
λ += 1 | |
if dbg: | |
print(f'\n{M}') |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#![allow(non_snake_case)] | |
use std::env::args; | |
use std::io::{stdout, Write, Stdout}; | |
use std::process::exit; | |
use std::fmt; | |
use std::convert::TryInto; | |
use std::error::Error; | |
extern crate console; | |
use console::Term; | |
pub fn is_prime(n: usize) -> bool { | |
for i in 2..(n / 2 + 1) { | |
if n % i == 0 { | |
return false; | |
} | |
} | |
n > 1 | |
} | |
struct Writer { out: Stdout } | |
impl Writer { | |
fn new() -> Writer { | |
Writer{ | |
out: stdout() | |
} | |
} | |
fn print(&mut self, txt: String) -> std::io::Result<()> { | |
write!(self.out, "{}", txt)?; | |
self.out.flush()?; | |
Ok(()) | |
} | |
fn println(&mut self, txt: String) -> std::io::Result<()> { | |
writeln!(self.out, "{}\n", txt)?; | |
self.out.flush()?; | |
Ok(()) | |
} | |
} | |
#[derive(Debug, Clone)] | |
struct UndefinedInstructionError; | |
impl fmt::Display for UndefinedInstructionError { | |
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { | |
write!(f, "undefined instruction given") | |
} | |
} | |
impl Error for UndefinedInstructionError { | |
fn description(&self) -> &str { | |
"undefined instruction given" | |
} | |
} | |
trait Algo { | |
fn sep(self, n: usize) -> (usize, usize); | |
fn con(self, n: usize) -> usize; | |
} | |
#[derive(Debug, Clone, Copy)] | |
pub struct Regs { | |
r1: isize, | |
r2: isize, | |
r3: isize | |
} | |
impl Regs { | |
fn new() -> Regs { | |
Regs { | |
r1: 0, | |
r2: 0, | |
r3: 0 | |
} | |
} | |
} | |
#[derive(Debug, Clone, Copy)] | |
pub struct Interpreter { | |
debug: bool, | |
λ: isize, | |
M: [isize; 64], | |
χ: usize, | |
regs: Regs | |
} | |
impl Algo for Interpreter { | |
fn sep(self, n: usize) -> (usize, usize) { | |
let mut F: Vec<usize> = Vec::new(); | |
for k in 2..=n { | |
if (n % k == 0) && (is_prime(k)) { | |
F.push(k); | |
} | |
} | |
F.push(1); | |
(F[0], F[1..].to_vec().iter().copied() | |
.reduce(|x,y| x*y).unwrap_or(1)) | |
} | |
fn con(self, n: usize) -> usize { | |
match n { | |
127 => self.χ, | |
131 => self.M[self.χ].try_into().unwrap(), | |
137 => { | |
let _tmp = Term::stdout().read_char().unwrap(); | |
print!("{_tmp}"); | |
_tmp as usize | |
}, | |
139 => self.regs.r1.try_into().unwrap(), | |
149 => self.regs.r2.try_into().unwrap(), | |
151 => self.regs.r3.try_into().unwrap(), | |
_ => n | |
} | |
} | |
} | |
impl Interpreter { | |
fn new(dbg: bool) -> Interpreter { | |
Interpreter { | |
debug: dbg, | |
λ: 0, | |
M: [0; 64], | |
χ: 0, | |
regs: Regs::new() | |
} | |
} | |
fn reset(&mut self) { | |
self.λ = 0; | |
self.M = [0; 64]; | |
self.χ = 0; | |
self.regs = Regs::new(); | |
} | |
fn quit(self, code: i32) -> ! { | |
if self.debug { | |
println!("\nInterpreter memory: {:?}", self.M); | |
println!("Interpreter registers: {:?}", self.regs); | |
println!("Interpreter struct: {:?}", self); | |
} | |
exit(code); | |
} | |
fn execute(&mut self, S: Vec<usize>, writer: &mut Writer) -> Result<(), Box<dyn Error>> { | |
self.reset(); | |
while self.λ < (S.len() as isize) { | |
let α = self.sep(S[self.λ as usize]); | |
match α.0 { | |
2 => {self.χ = self.con(α.1) - 1;}, | |
3 => {self.χ += self.con(α.1);}, | |
5 => {self.χ -= self.con(α.1);}, | |
7 => {self.M[self.χ] = (self.con(α.1) - 1) as isize;}, | |
11 => {self.M[self.χ] += self.con(α.1) as isize;}, | |
13 => {self.M[self.χ] -= self.con(α.1) as isize;}, | |
17 => {self.M[self.χ] *= self.con(α.1) as isize;}, | |
19 => {self.M[self.χ] /= self.con(α.1) as isize;}, | |
23 => {self.M[self.χ] += self.con(α.1) as isize;}, | |
29 => {self.regs.r1 = self.M[self.χ];}, | |
31 => {self.regs.r2 = self.M[self.χ];}, | |
37 => {self.regs.r3 = self.M[self.χ];}, | |
41 => {self.M[self.con(α.1) - 1] = self.M[self.χ];}, | |
43 => { | |
let aux = self.M[self.χ]; | |
self.M[self.χ] = 0; | |
self.regs.r1 = aux; | |
}, | |
47 => { | |
let aux = self.M[self.χ]; | |
self.M[self.χ] = 0; | |
self.regs.r2 = aux; | |
}, | |
53 => { | |
let aux = self.M[self.χ]; | |
self.M[self.χ] = 0; | |
self.regs.r3 = aux; | |
}, | |
59 => { | |
let aux = self.M[self.χ]; | |
self.M[self.χ] = 0; | |
self.M[self.con(α.1) - 1] = aux; | |
}, | |
61 => {(self.M[self.χ], self.regs.r1) = (self.regs.r1, self.M[self.χ]);}, | |
67 => {(self.M[self.χ], self.regs.r2) = (self.regs.r2, self.M[self.χ]);}, | |
71 => {(self.M[self.χ], self.regs.r3) = (self.regs.r3, self.M[self.χ]);}, | |
73 => {(self.M[self.χ], self.M[self.con(α.1) - 1]) = (self.M[self.con(α.1) - 1], self.M[self.χ]);}, | |
79 => {writer.print(format!("{}", std::char::from_u32(self.con(α.1) as u32).unwrap_or('X')))?;}, | |
83 => {writer.print(format!("{}", self.con(α.1)))?;}, | |
89 => { | |
if self.M[self.χ] != (self.con(α.1)-1).try_into().unwrap() { | |
if self.debug { | |
writer.println(format!("\n{}, {}", self.M[self.χ], self.con(α.1)-1))?; | |
} | |
self.λ += 1; | |
} | |
}, | |
97 => { | |
if self.M[self.χ] == (self.con(α.1)-1).try_into().unwrap() { | |
if self.debug { | |
writer.println(format!("\n{}, {}", self.M[self.χ], self.con(α.1)-1))?; | |
} | |
self.λ += 1; | |
} | |
}, | |
101 => {self.λ = self.con(α.1) as isize - 2;}, | |
103 => {self.λ += (self.con(α.1)) as isize;}, | |
107 => {self.λ -= (self.con(α.1)) as isize;}, | |
109 => {}, | |
113 => {self.quit(0)}, | |
_ => { Err(UndefinedInstructionError)?; } | |
} | |
self.λ += 1; | |
} | |
Ok(()) | |
} | |
} | |
fn main() -> Result<(), Box<dyn Error>> { | |
let mut writer = Writer::new(); | |
let mut interp = Interpreter::new(matches!(args().collect::<Vec<String>>()[0] | |
.as_str(), "debug")); | |
interp.execute((args().collect::<Vec<String>>())[2..] | |
.iter() | |
.cloned() | |
.map(|x| x.parse::<usize>() | |
.unwrap_or(109)) | |
.collect(), | |
&mut writer)?; | |
Ok(()) | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment