#![allow(dead_code)]
#![allow(unused_variables)]
#![allow(unused_parens)]
#![allow(unused_imports)]
#![allow(unused_mut)]
#![allow(non_snake_case)]
#![allow(non_camel_case_types)]
#![allow(non_upper_case_globals)]
extern crate rustlr;
use rustlr::{Lextoken,Lexer,LBox,LRc};
extern crate basic_lexer;
pub use basic_lexer::*;
use std::cell::{RefCell,Ref,RefMut};
use std::rc::Rc;
use crate::abstmachine::Lamterm::*;
#[derive(Clone)]
enum Lamterm {
Var(String),
Iconst(i64),
Abs(String,LRc<Lamterm>),
App(LRc<Lamterm>,LRc<Lamterm>),
Nothing,
}
impl Default for Lamterm
{
fn default() -> Self { Nothing }
}
struct Closure
{
term:LRc<Lamterm>,
env:Bindings,
}
fn newclosure(t:LRc<Lamterm>, b:Bindings) -> Closure
{
Closure{term:t, env:b}
}
type Bindings = Option<Rc<Binding>>;
struct Binding
{
var: String,
cl : Rc<Closure>,
rest: Bindings,
}
fn bind(v:String,vcl:Rc<Closure>,cur:&Bindings) -> Binding
{
Binding {
var:v,
cl:vcl,
rest: match cur {
None => None,
Some(rcb) => Some(Rc::clone(rcb)),
},
}
}
fn get<'t>(v:&str,mut env:&'t Bindings) -> Option<&'t Rc<Closure>>
{
while let Some(rcb) = env {
if v==&rcb.var { return Some(&rcb.cl); }
env = &rcb.rest;
}
return None;
}
pub struct Machine {
stack: Vec<Rc<Closure>>,
counter: usize, }
impl Machine
{
fn new(t0:LRc<Lamterm>) -> Machine
{
Machine {
stack: vec![Rc::new(Closure { term:t0, env:None, })],
counter: 0,
}
}
fn substalpha(&mut self, term:&LRc<Lamterm>, ev:&Bindings) -> LRc<Lamterm>
{
match &**term {
Var(x) => {
match get(&x[..],ev) {
None => term.clone(),
Some(cl) => self.substalpha(&cl.term,&cl.env),
} },
App(a,b) => {
let a2 = self.substalpha(a,ev);
let b2 = self.substalpha(b,ev);
term.transfer(App(a2,b2))
},
Abs(x,b) => {
self.counter += 1;
let aconv = format!("{}_{}",x,self.counter); let newbindings = bind(x.clone(),
Rc::new(newclosure(term.transfer(Var(aconv.clone())),None)),
ev);
let b2 = self.substalpha(b,&Some(Rc::new(newbindings)));
term.transfer(Abs(aconv,b2))
},
_ => term.clone(),
} }
pub fn beta(&mut self) -> bool {
if self.stack.len()<1 {return false;}
let topclosure = self.stack.pop().unwrap();
match &*topclosure.term {
Var(x) => {
match get(&x[..],&topclosure.env) {
None => { self.stack.push(topclosure); return false; },
Some(xcl) => { self.stack.push(Rc::clone(xcl)); },
} },
App(a,b) => {
self.stack.push(Rc::new(newclosure(LRc::clone(a),topclosure.env.clone())));
self.stack.push(Rc::new(newclosure(LRc::clone(b),topclosure.env.clone())));
},
Abs(x,b) => {
if self.stack.len()<1 {self.stack.push(topclosure); return false;}
let cl = self.stack.pop().unwrap();
let newenv = Some(Rc::new(bind(x.clone(),cl,&topclosure.env)));
let newcl = newclosure(LRc::clone(b),newenv);
self.stack.push(Rc::new(newcl));
},
_ => {self.stack.push(topclosure); return false;},
} return true;
}
}
fn main(){}