From 0c56405b4da55c8539b54f79cc4b720ad0243f0e Mon Sep 17 00:00:00 2001 From: Cassie Jones Date: Thu, 27 Feb 2020 14:19:40 +0100 Subject: [PATCH] An s-expression parser and an example program This is intended to be a slightly fancier lambda calculus with arithmetic support. The way I've written the example here suggests not making conditionals a builtin, and instead just using church encodings. This will probably be bad for displaying data purposes? I'm not sure how I want to handle I/O. Maybe do an ML and put impure I/O in here? --- .gitignore | 1 + Cargo.lock | 14 ++++++++++++++ Cargo.toml | 10 ++++++++++ README.md | 3 +++ program.vy | 11 +++++++++++ src/main.rs | 25 +++++++++++++++++++++++++ 6 files changed, 64 insertions(+) create mode 100644 .gitignore create mode 100644 Cargo.lock create mode 100644 Cargo.toml create mode 100644 README.md create mode 100644 program.vy create mode 100644 src/main.rs diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..ea8c4bf --- /dev/null +++ b/.gitignore @@ -0,0 +1 @@ +/target diff --git a/Cargo.lock b/Cargo.lock new file mode 100644 index 0000000..fb1b2ed --- /dev/null +++ b/Cargo.lock @@ -0,0 +1,14 @@ +# This file is automatically @generated by Cargo. +# It is not intended for manual editing. +[[package]] +name = "ess" +version = "0.4.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c70ece3a2affa9eda5d916d778fe80fe2b7357aeb2d7b38f35286cfa983571d0" + +[[package]] +name = "ivy" +version = "0.1.0" +dependencies = [ + "ess", +] diff --git a/Cargo.toml b/Cargo.toml new file mode 100644 index 0000000..e3a65aa --- /dev/null +++ b/Cargo.toml @@ -0,0 +1,10 @@ +[package] +name = "ivy" +version = "0.1.0" +authors = ["Cassie Jones "] +edition = "2018" + +# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html + +[dependencies] +ess = "0.4.2" diff --git a/README.md b/README.md new file mode 100644 index 0000000..97da433 --- /dev/null +++ b/README.md @@ -0,0 +1,3 @@ +# Ivy + +Little lambdas eat ivy. diff --git a/program.vy b/program.vy new file mode 100644 index 0000000..f226258 --- /dev/null +++ b/program.vy @@ -0,0 +1,11 @@ +(let ([nil (lam (c n) (n))] + [cons (lam (x y) (lam (c n) (c x y)))] + [fix (lam (f) (f f))] + [if (lam (c t f) ((c t f)))] + [true (lam (t f) t)] + [false (lam (t f) f)]) + ([fix (lam (recur a b l n) + (if (<= n 0) + [lam () l] + [lam () (recur b (+ a b) (cons a l) (- n 1))]))] + 0 1 nil 20)) diff --git a/src/main.rs b/src/main.rs new file mode 100644 index 0000000..4f09f59 --- /dev/null +++ b/src/main.rs @@ -0,0 +1,25 @@ +use ess::{self, Sexp, parser::ParseError}; +use std::io::{self, Read}; + +fn parse(input: &str) -> Result { + let (sexp, rest) = ess::parse_one(input)?; + if !rest.trim().is_empty() { + return Err(ParseError::Unexpected('\0', sexp.get_loc().1)); + } + Ok(sexp) +} + +fn main() -> io::Result<()> { + let stdin = std::io::stdin(); + let mut text = String::new(); + stdin.lock().read_to_string(&mut text)?; + let item = match parse(&text) { + Ok(item) => item, + Err(err) => { + println!("{:?}", err); + std::process::exit(1); + } + }; + println!("{:?}", item); + Ok(()) +} -- 2.43.2