Skip to content

Commit

Permalink
several bugs fixed, doc updated
Browse files Browse the repository at this point in the history
  • Loading branch information
ireina7 committed Jun 9, 2021
1 parent 62a68ff commit 2c37499
Show file tree
Hide file tree
Showing 4 changed files with 88 additions and 8 deletions.
31 changes: 31 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,37 @@ Rust implementation of Abyss programming language

![Made in abyss](./img/made-in-abyss.jpg)

## Getting started
- Download or compile source code.
- Run the program and enter repl automatically (default lazy mode).

### REPL functions
- `quit`: Quit repl
- `help`: Get help
- `eager`: Turn on eager mode (where strict evaluation is the default)
- `lazy`: Turn on lazy mode (where lazy evaluation is the default)
- `debug`: Turn on debug mode

### Expressions
- *Function application*: `(f x)`
- *Let bindings*: `(let ((x value) (y value) ...) expression)`
- *Lambda abstraction*: `(lambda (x y z ...) expression)`
- *If branches*: `(if expression true-branch false-branch)`
- *Pattern matching*: `(case expression ((case1 value) (case2 value) ...))`

### Declarations
- *Definition*: `(define x expression)` | `(define (f x y ...) expression)`
- *Data abstraction*: `(data x)` | `(data (cons x y ..))`

### Environment
- Integers
- Symbols
- Strings
- Real numbers
- `::`: List constructor
- `+-*/`: Arithmetic operators


## Features
- Typed dynamic programming language
- Highly configurable and scalable
Expand Down
49 changes: 46 additions & 3 deletions src/abyss/checker.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
use super::object::Object;
use super::object::Env;
use super::eval::Eval;

use std::rc::Rc;



Expand All @@ -13,7 +13,7 @@ pub struct Type {
val: Object
}

#[derive(Debug)]
#[derive(Debug, PartialEq)]
pub struct CheckerError {
msg: String
}
Expand All @@ -34,6 +34,34 @@ fn arrow(types: Vec<Object>) -> Object {
List(vec![Cons("->".into())].into_iter().chain(types.into_iter()).collect())
}

pub fn env() -> Env {
let f = |s: &str| Rc::new(s.parse::<Object>().unwrap()); // You need to make sure no panic!
let env = vec![
//("fix", "(lambda (f) ((lambda (x) (f (lambda (v) (x x v)))) (lambda (x) (f (lambda (v) (x x v))))))"),
//("fix", "(lambda (f) ((lambda (x) (f (x x))) (lambda (x) (f (x x)))))"),
//("lazy", "(lambda (x) (lazy x))"),
//("!", "(lambda (x) (! x))"),
("+", "(-> Int Int Int)"),
("-", "(-> Int Int Int)"),
("*", "(-> Int Int Int)"),
("/", "(-> Int Int Int)"),
("<", "(-> Int Int Bool)"),
(">", "(-> Int Int Bool)"),
("==", "(-> Int Int Bool)"),
("/=", "(-> Int Int Bool)"),
("<=", "(-> Int Int Bool)"),
(">=", "(-> Int Int Bool)"),
//("::", "(-> Int Int Bool)"),
//("head", "(lambda (xs) (head xs))"),
//("tail", "(lambda (xs) (tail xs))"),
];
Env::new_from(env.into_iter().map(|(str, src)| (str.to_string(), f(src))).collect())
}





fn check(expr: Object, env: &mut Env, tnv: &mut Env) -> Result<Object, CheckerError> {
use Object::*;
//println!("eval: {}", expr);
Expand Down Expand Up @@ -68,7 +96,22 @@ fn check(expr: Object, env: &mut Env, tnv: &mut Env) -> Result<Object, CheckerEr
Ok(arrow(pts))
},

_ => todo!()
[f, xs @ ..] => {
let ft = check(f.clone(), env, tnv)?;
let mut xt = vec![];
for x in xs {
xt.push(check(x.clone(), env, tnv)?);
}
if let List(ts) = ft {
for (ht, xt) in ts.into_iter().zip(xt.into_iter()) {
if ht == xt { continue }
else { return Err(CheckerError { msg: format!("Type error, expect: {}, found: {}", ht, xt) }) }
}
}
todo!()
}

//_ => todo!()
}
_ => Err(CheckerError { msg: format!("Unknow expression: {:?}", expr) })
}
Expand Down
7 changes: 4 additions & 3 deletions src/abyss/eval/lazy.rs
Original file line number Diff line number Diff line change
Expand Up @@ -218,13 +218,12 @@ fn apply(f: Object, x: Object, backtrace: &mut Backtrace) -> Result<Object> {
apply_env(f.clone(), name, wash_type(pat), &x, &mut env, backtrace)?;
evaluate(Object::clone(expr.borrow()), &mut env, backtrace)
},
[pat, ss @ ..] => {
/*
[pat, ss @ ..] => {/*
if let Some(name) = name {
backtrace.push(format!("Apply function: {}", name));
}*/
apply_env(f.clone(), name, wash_type(pat), &x, &mut env, backtrace)?;
Ok(Closure(None, Rc::new(List(ss.to_vec())), expr.clone(), env.clone()))
Ok(Closure(None, Rc::new(List(ss.to_vec())), Rc::clone(expr), env.clone()))
}
},
others => Err(EvalError::new(format!("Function parameters should be a list instead of {:?}", others), backtrace.clone()))
Expand All @@ -237,6 +236,7 @@ fn apply(f: Object, x: Object, backtrace: &mut Backtrace) -> Result<Object> {


/// Handle cons expression
#[inline]
fn eval_cons(x: Object, xs: Object, env: &mut Env) -> Result<Object> {
use Object::*;
//let xs = evaluate(xs, env)?;
Expand All @@ -246,6 +246,7 @@ fn eval_cons(x: Object, xs: Object, env: &mut Env) -> Result<Object> {
}

/// Handle list constructions
#[inline]
fn eval_list(xs: &[Object], env: &mut Env) -> Result<Object> {
let mut v = vec![];
for x in xs {
Expand Down
9 changes: 7 additions & 2 deletions src/abyss/object.rs
Original file line number Diff line number Diff line change
Expand Up @@ -40,11 +40,12 @@ impl EvalError {

impl fmt::Display for EvalError {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
let backtrace = match &self.backtrace {
let _backtrace = match &self.backtrace {
None => "None".to_string(),
Some(bt) => format!("{}", bt)
};
write!(f, "Error: {}\nBacktrace:\n{}", self.msg, backtrace)
//write!(f, "Error: {}\nBacktrace:\n{}", self.msg, backtrace)
write!(f, "Error: {}", self.msg)
}
}

Expand Down Expand Up @@ -126,15 +127,19 @@ pub enum Object {
}

impl Object {
#[inline]
pub fn closure(ps: Object, expr: Object, env: Env) -> Self {
Self::Closure(None, Rc::new(ps), Rc::new(expr), env.clone())
}
#[inline]
pub fn closure_of(name: Option<String>, ps: Object, expr: Object, env: Env) -> Self {
Self::Closure(name, Rc::new(ps), Rc::new(expr), env.clone())
}
#[inline]
pub fn thunk(expr: Object, env: Env) -> Self {
Self::Thunk(None, Rc::new(Thunker::new(expr)), env)
}
#[inline]
pub fn thunk_of(name: Option<String>, expr: Object, env: Env) -> Self {
Self::Thunk(name, Rc::new(Thunker::new(expr)), env)
}
Expand Down

0 comments on commit 2c37499

Please sign in to comment.