Last active
December 17, 2024 13:42
-
-
Save FranchuFranchu/b453b01c8453ddb877593e510073107b to your computer and use it in GitHub Desktop.
Tree calculus interpreter in Vine
This file contains hidden or 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
use std::option::Option; | |
use Option::{Some, None}; | |
enum Program { | |
Leaf, | |
Stem(Program), | |
Fork(Program, Program), | |
} | |
mod Program { | |
pub fn graft(self: Program, other: Program) -> Program { | |
use Program::{Leaf, Stem, Fork}; | |
match self { | |
Leaf => Stem(other), | |
Stem(self) => Fork(self, other), | |
Fork(first, snd) => { | |
match first { | |
Leaf => snd, | |
Stem(x) => snd.graft(other).graft(x.graft(other)), | |
Fork(w, x) => other.graft(w).graft(x) | |
} | |
} | |
} | |
} | |
pub fn to_string(self: Program) -> String { | |
use Program::{Leaf, Stem, Fork}; | |
match self { | |
Leaf => "()", | |
Stem(self) => "(()" ++ self.to_string() ++ ")", | |
Fork(first, snd) => "(()" ++ first.to_string() ++ snd.to_string() ++ ")" | |
} | |
} | |
} | |
/// Syntax: | |
/// () is a leaf | |
/// ab grafts b into a. This operation is left associative | |
/// this means that ()a is a stem of A and ()ab is a fork of a and b | |
struct Parser(String); | |
mod Parser { | |
pub fn new(s: String) -> Parser { | |
Parser(s) | |
} | |
pub fn pop_front(&Parser(s): &Parser) -> Option[Char] { | |
s.pop_front() | |
} | |
pub fn push_front(&Parser(s): &Parser, c: Char) { | |
s.push_front(c) | |
} | |
pub fn expect(&state: &Parser, c: Char) -> Bool { | |
if state.pop_front() is Some(i) { | |
if i == c { | |
true | |
} else { | |
state.push_front(i); | |
false | |
} | |
} else { | |
false | |
} | |
} | |
pub fn parse_program_paren(&state: &Parser) -> Option[Program] { | |
if state.expect('(') { | |
let program = state.parse_program() | |
if state.expect(')') { | |
Some(program) | |
} else { | |
None | |
} | |
} else { | |
None | |
} | |
} | |
pub fn parse_program(&state: &Parser) -> Program { | |
if state.parse_program_paren() is Some(program) { | |
while state.parse_program_paren() is Some(graft) { | |
program = program.graft(graft) | |
} | |
program | |
} else { | |
Program::Leaf | |
} | |
} | |
} | |
pub fn main(&io: &IO) { | |
// K = (()()) | |
// I = (()(()())(()())) | |
// the program below is (K I () (()())) = (false () (()())) | |
// example program: (()())(()(()())(()()))(())(()()) | |
let s = Parser::new(io.full_input()); | |
let t = s.parse_program().to_string(); | |
io.println(t) | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Example usage: