Skip to content

Instantly share code, notes, and snippets.

@mbillingr
Created July 23, 2020 20:44
Show Gist options
  • Select an option

  • Save mbillingr/7113b49dec609835fd0942f11af58ef7 to your computer and use it in GitHub Desktop.

Select an option

Save mbillingr/7113b49dec609835fd0942f11af58ef7 to your computer and use it in GitHub Desktop.
Scheme->Rust compiler prototype
(define (meaning e r)
(if (atom? e)
(if (symbol? e) (meaning-reference e r)
(meaning-quotation e r))
(case (car e)
((quote) (meaning-quotation (cadr e) r))
((set!) (meaning-assignment (cadr e) (caddr e) r))
((begin) (meaning-sequence (cdr e) r))
((if) (meaning-alternative (cadr e) (caddr e) (cadddr e) r))
((lambda) (meaning-abstraction (cadr e) (cddr e) r))
(else (meaning-application (car e) (cdr e) r)))))
(define (meaning-quotation v r)
(display "Scm::from(")
(write v)
(display ")"))
(define (meaning-reference v r)
(case v
((*) (display "mul"))
(else (write v))
))
(define (meaning-assignment n e r)
(write n)
(display " = ")
(meaning e r)
(display "; Scm::Nil")
)
(define (meaning-sequence e* r)
(display "{")
(meaning-sequence-next e* r)
(display "}")
)
(define (meaning-sequence-next e* r)
(if (null? e*)
'ok
(begin (meaning (car e*) r)
(if (not (null? (cdr e*))) (display ";"))
(meaning-sequence-next (cdr e*) r)
)))
(define (meaning-alternative e1 e2 e3 r)
(display "if ")
(meaning e1 r)
(display ".is_true() ")
(display "{")
(meaning e2 r)
(display "} else {")
(meaning e3 r)
(display "}")
)
(define (meaning-abstraction params body r)
(display "(|")
(meaning-params params)
(display "|")
(meaning-sequence body r)
(display ")")
)
(define (meaning-params params)
(if (null? params)
'ok
(begin (display "mut ")
(write (car params))
(display ": Scm, ")
(meaning-params (cdr params))))
)
(define (meaning-application e e* r)
(meaning e r)
(display "(")
(meaning-args e* r)
(display ")"))
(define (meaning-args e* r)
(if (null? e*)
'ok
(begin (meaning (car e*) r)
(display ".clone(), ")
(meaning-args (cdr e*) r))))
(define (atom? x) (not (pair? x)))
(define r.init '())
(define prog '((lambda (x) (if (not x) (begin (set! x 3) x) (cons x x))) 5))
(meaning prog r.init)
mod runtime {
use std::rc::Rc;
pub fn mul(x: Scm, y: Scm) -> Scm {
match (x, y) {
(Scm::Int(a), Scm::Int(b)) => Scm::Int(a * b),
_ => panic!("type error"),
}
}
pub fn not(x: Scm) -> Scm {
if x.is_true() {
Scm::False
} else {
Scm::True
}
}
pub fn cons(a: Scm, d: Scm) -> Scm {
Scm::Pair(Rc::new((a, d)))
}
#[derive(Clone, Debug)]
pub enum Scm {
Nil,
True,
False,
Int(i64),
Pair(Rc<(Scm, Scm)>),
}
impl Scm {
pub fn is_true(&self) -> bool {
match self {
Scm::Nil | Scm::False => false,
_ => true,
}
}
}
impl From<i64> for Scm {
fn from(i: i64) -> Self {
Scm::Int(i)
}
}
impl From<(Scm, Scm)> for Scm {
fn from((car, cdr): (Scm, Scm)) -> Self {
Scm::Pair(Rc::new((car, cdr)))
}
}
}
fn main() {
use runtime::*;
println!(
"{:?}",
(|mut x: Scm| {
if not(x.clone()).is_true() {
{
x = Scm::from(3);
Scm::Nil;
x
}
} else {
cons(x.clone(), x.clone())
}
})(Scm::from(5).clone(),)
);
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment