Skip to content

Instantly share code, notes, and snippets.

@sjkillen
Created November 25, 2019 05:08
Show Gist options
  • Save sjkillen/367ef21fbe4bedc9267a988e1d414db0 to your computer and use it in GitHub Desktop.
Save sjkillen/367ef21fbe4bedc9267a988e1d414db0 to your computer and use it in GitHub Desktop.
#![feature(box_patterns)]
#[derive(Debug)]
#[derive(Clone)]
pub enum Syntax {
Param(usize),
Constant(i32),
SymbolicValue,
Add(Box<Syntax>, Box<Syntax>),
Mul(Box<Syntax>, Box<Syntax>),
Sub(Box<Syntax>, Box<Syntax>),
Lt(Box<Syntax>, Box<Syntax>),
Gt(Box<Syntax>, Box<Syntax>),
Eq(Box<Syntax>, Box<Syntax>),
Malformed,
}
use Syntax::*;
fn symbolic_semantics(p: &Syntax, params: &Vec<i32>) -> Syntax {
let reduced = match p {
Constant(integer) => return Constant(*integer),
Param(index) => return Param(*index),
SymbolicValue => return SymbolicValue,
Malformed => return Malformed,
Add(left, right) => Add(Box::new(symbolic_semantics(left, params)), Box::new(symbolic_semantics(right, params))),
other => other.clone(),
};
match p {
Param(integer) => Param(*integer),
Constant(integer) => Constant(*integer),
SymbolicValue => SymbolicValue,
Add(box Constant(left), box Constant(right)) => Constant(*left + *right),
Mul(box Constant(left), box Constant(right)) => Constant(*left * *right),
Sub(box Constant(left), box Constant(right)) => Constant(*left - *right),
Lt(box Constant(left), box Constant(right)) => Constant((*left < *right) as i32),
Gt(box Constant(left), box Constant(right)) => Constant((*left > *right) as i32),
Eq(box Constant(left), box Constant(right)) => Constant((*left == *right) as i32),
Malformed => panic!("Malformed program!"),
_ => Malformed,
}
}
fn split_slice(slice: &[i32]) -> (&[i32], &[i32]) {
let len = slice.len();
(&slice[0..len / 2], &slice[len / 2..len])
}
fn generate_program(instructions: &[i32]) -> Syntax {
if instructions.len() == 0 {
return Constant(0);
}
match instructions[0] {
0 => {
if instructions.len() > 1 {
Param(instructions[0] as usize)
} else {
Malformed
}
}
1 => {
if instructions.len() > 1 {
Constant(instructions[0])
} else {
Malformed
}
}
2 => SymbolicValue,
_ => {
let (head, tail) = split_slice(&instructions[1..instructions.len()]);
match instructions[0] {
3 => Add(
Box::new(generate_program(head)),
Box::new(generate_program(tail)),
),
4 => Mul(
Box::new(generate_program(head)),
Box::new(generate_program(tail)),
),
5 => Sub(
Box::new(generate_program(head)),
Box::new(generate_program(tail)),
),
6 => Lt(
Box::new(generate_program(head)),
Box::new(generate_program(tail)),
),
7 => Gt(
Box::new(generate_program(head)),
Box::new(generate_program(tail)),
),
8 => Eq(
Box::new(generate_program(head)),
Box::new(generate_program(tail)),
),
_ => Malformed,
}
}
}
}
fn main() {
let v: Vec<i32> = vec![3, 1, 2, 0, 0];
let v: &[i32] = &v;
let program = generate_program(&v);
println!("{:#?}", program);
let result = symbolic_semantics(&program, &vec![12]);
println!("{:#?}", result);
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment