Skip to content

Instantly share code, notes, and snippets.

@h3nry-d1az

h3nry-d1az/pirho Secret

Last active November 19, 2023 05:27
Show Gist options
  • Save h3nry-d1az/3e58f58c690ec7f52fcda4b0f55825ca to your computer and use it in GitHub Desktop.
Save h3nry-d1az/3e58f58c690ec7f52fcda4b0f55825ca to your computer and use it in GitHub Desktop.
Todo lo relacionado con mi lenguaje de programación esotérico 𝚷ᵨ
Un lenguaje de programación esotérico basado en el teorema fundamental de la aritmética.
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}')
#![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