mirror of
https://github.com/azur1s/bobbylisp.git
synced 2024-10-16 02:37:40 -05:00
allow let without body
This commit is contained in:
parent
b72121e256
commit
c061c6d038
313
Cargo.lock
generated
Normal file
313
Cargo.lock
generated
Normal file
|
@ -0,0 +1,313 @@
|
||||||
|
# This file is automatically @generated by Cargo.
|
||||||
|
# It is not intended for manual editing.
|
||||||
|
version = 3
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "ahash"
|
||||||
|
version = "0.7.6"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "fcb51a0695d8f838b1ee009b3fbf66bda078cd64590202a864a8f3e8c4315c47"
|
||||||
|
dependencies = [
|
||||||
|
"getrandom",
|
||||||
|
"once_cell",
|
||||||
|
"version_check",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "ansi_term"
|
||||||
|
version = "0.12.1"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "d52a9bb7ec0cf484c551830a7ce27bd20d67eac647e1befb56b0be4ee39a55d2"
|
||||||
|
dependencies = [
|
||||||
|
"winapi",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "atty"
|
||||||
|
version = "0.2.14"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "d9b39be18770d11421cdb1b9947a45dd3f37e93092cbf377614828a319d5fee8"
|
||||||
|
dependencies = [
|
||||||
|
"hermit-abi",
|
||||||
|
"libc",
|
||||||
|
"winapi",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "bitflags"
|
||||||
|
version = "1.3.2"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "bef38d45163c2f1dde094a7dfd33ccf595c92905c8f8f4fdc18d06fb1037718a"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "cc"
|
||||||
|
version = "1.0.79"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "50d30906286121d95be3d479533b458f87493b30a4b5f79a607db8f5d11aa91f"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "cfg-if"
|
||||||
|
version = "1.0.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "chumsky"
|
||||||
|
version = "0.9.2"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "23170228b96236b5a7299057ac284a321457700bc8c41a4476052f0f4ba5349d"
|
||||||
|
dependencies = [
|
||||||
|
"hashbrown",
|
||||||
|
"stacker",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "clap"
|
||||||
|
version = "2.34.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "a0610544180c38b88101fecf2dd634b174a62eef6946f84dfc6a7127512b381c"
|
||||||
|
dependencies = [
|
||||||
|
"ansi_term",
|
||||||
|
"atty",
|
||||||
|
"bitflags",
|
||||||
|
"strsim",
|
||||||
|
"textwrap",
|
||||||
|
"unicode-width",
|
||||||
|
"vec_map",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "getrandom"
|
||||||
|
version = "0.2.8"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "c05aeb6a22b8f62540c194aac980f2115af067bfe15a0734d7277a768d396b31"
|
||||||
|
dependencies = [
|
||||||
|
"cfg-if",
|
||||||
|
"libc",
|
||||||
|
"wasi",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "hashbrown"
|
||||||
|
version = "0.12.3"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "8a9ee70c43aaf417c914396645a0fa852624801b24ebb7ae78fe8272889ac888"
|
||||||
|
dependencies = [
|
||||||
|
"ahash",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "heck"
|
||||||
|
version = "0.3.3"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "6d621efb26863f0e9924c6ac577e8275e5e6b77455db64ffa6c65c904e9e132c"
|
||||||
|
dependencies = [
|
||||||
|
"unicode-segmentation",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "hermit-abi"
|
||||||
|
version = "0.1.19"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "62b467343b94ba476dcb2500d242dadbb39557df889310ac77c5d99100aaac33"
|
||||||
|
dependencies = [
|
||||||
|
"libc",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "lazy_static"
|
||||||
|
version = "1.4.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "e2abad23fbc42b3700f2f279844dc832adb2b2eb069b2df918f455c4e18cc646"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "libc"
|
||||||
|
version = "0.2.139"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "201de327520df007757c1f0adce6e827fe8562fbc28bfd9c15571c66ca1f5f79"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "once_cell"
|
||||||
|
version = "1.17.1"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "b7e5500299e16ebb147ae15a00a942af264cf3688f47923b8fc2cd5858f23ad3"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "proc-macro-error"
|
||||||
|
version = "1.0.4"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "da25490ff9892aab3fcf7c36f08cfb902dd3e71ca0f9f9517bea02a73a5ce38c"
|
||||||
|
dependencies = [
|
||||||
|
"proc-macro-error-attr",
|
||||||
|
"proc-macro2",
|
||||||
|
"quote",
|
||||||
|
"syn",
|
||||||
|
"version_check",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "proc-macro-error-attr"
|
||||||
|
version = "1.0.4"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "a1be40180e52ecc98ad80b184934baf3d0d29f979574e439af5a55274b35f869"
|
||||||
|
dependencies = [
|
||||||
|
"proc-macro2",
|
||||||
|
"quote",
|
||||||
|
"version_check",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "proc-macro2"
|
||||||
|
version = "1.0.51"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "5d727cae5b39d21da60fa540906919ad737832fe0b1c165da3a34d6548c849d6"
|
||||||
|
dependencies = [
|
||||||
|
"unicode-ident",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "psm"
|
||||||
|
version = "0.1.21"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "5787f7cda34e3033a72192c018bc5883100330f362ef279a8cbccfce8bb4e874"
|
||||||
|
dependencies = [
|
||||||
|
"cc",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "quote"
|
||||||
|
version = "1.0.23"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "8856d8364d252a14d474036ea1358d63c9e6965c8e5c1885c18f73d70bff9c7b"
|
||||||
|
dependencies = [
|
||||||
|
"proc-macro2",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "renxi"
|
||||||
|
version = "0.1.0"
|
||||||
|
dependencies = [
|
||||||
|
"chumsky",
|
||||||
|
"structopt",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "stacker"
|
||||||
|
version = "0.1.15"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "c886bd4480155fd3ef527d45e9ac8dd7118a898a46530b7b94c3e21866259fce"
|
||||||
|
dependencies = [
|
||||||
|
"cc",
|
||||||
|
"cfg-if",
|
||||||
|
"libc",
|
||||||
|
"psm",
|
||||||
|
"winapi",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "strsim"
|
||||||
|
version = "0.8.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "8ea5119cdb4c55b55d432abb513a0429384878c15dde60cc77b1c99de1a95a6a"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "structopt"
|
||||||
|
version = "0.3.26"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "0c6b5c64445ba8094a6ab0c3cd2ad323e07171012d9c98b0b15651daf1787a10"
|
||||||
|
dependencies = [
|
||||||
|
"clap",
|
||||||
|
"lazy_static",
|
||||||
|
"structopt-derive",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "structopt-derive"
|
||||||
|
version = "0.4.18"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "dcb5ae327f9cc13b68763b5749770cb9e048a99bd9dfdfa58d0cf05d5f64afe0"
|
||||||
|
dependencies = [
|
||||||
|
"heck",
|
||||||
|
"proc-macro-error",
|
||||||
|
"proc-macro2",
|
||||||
|
"quote",
|
||||||
|
"syn",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "syn"
|
||||||
|
version = "1.0.109"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "72b64191b275b66ffe2469e8af2c1cfe3bafa67b529ead792a6d0160888b4237"
|
||||||
|
dependencies = [
|
||||||
|
"proc-macro2",
|
||||||
|
"quote",
|
||||||
|
"unicode-ident",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "textwrap"
|
||||||
|
version = "0.11.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "d326610f408c7a4eb6f51c37c330e496b08506c9457c9d34287ecc38809fb060"
|
||||||
|
dependencies = [
|
||||||
|
"unicode-width",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "unicode-ident"
|
||||||
|
version = "1.0.7"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "775c11906edafc97bc378816b94585fbd9a054eabaf86fdd0ced94af449efab7"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "unicode-segmentation"
|
||||||
|
version = "1.10.1"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "1dd624098567895118886609431a7c3b8f516e41d30e0643f03d94592a147e36"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "unicode-width"
|
||||||
|
version = "0.1.10"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "c0edd1e5b14653f783770bce4a4dabb4a5108a5370a5f5d8cfe8710c361f6c8b"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "vec_map"
|
||||||
|
version = "0.8.2"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "f1bddf1187be692e79c5ffeab891132dfb0f236ed36a43c7ed39f1165ee20191"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "version_check"
|
||||||
|
version = "0.9.4"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "49874b5167b65d7193b8aba1567f5c7d93d001cafc34600cee003eda787e483f"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "wasi"
|
||||||
|
version = "0.11.0+wasi-snapshot-preview1"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "9c8d87e72b64a3b4db28d11ce29237c246188f4f51057d65a7eab63b7987e423"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "winapi"
|
||||||
|
version = "0.3.9"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "5c839a674fcd7a98952e593242ea400abe93992746761e38641405d28b00f419"
|
||||||
|
dependencies = [
|
||||||
|
"winapi-i686-pc-windows-gnu",
|
||||||
|
"winapi-x86_64-pc-windows-gnu",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "winapi-i686-pc-windows-gnu"
|
||||||
|
version = "0.4.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "ac3b87c63620426dd9b991e5ce0329eff545bccbbb34f3be09ff6fb6ab51b7b6"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "winapi-x86_64-pc-windows-gnu"
|
||||||
|
version = "0.4.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f"
|
14
a.hlm
14
a.hlm
|
@ -1,9 +1,7 @@
|
||||||
func add (x: num) num = (\a: num -> a + 1)(x);
|
let x: num = 34,
|
||||||
|
y: num = 35
|
||||||
|
in
|
||||||
|
println(x + y);
|
||||||
|
|
||||||
println(
|
let foo: num = 69;
|
||||||
{
|
println(foo);
|
||||||
println("Hello");
|
|
||||||
return let x: num = 17 * 2 in
|
|
||||||
add(x);
|
|
||||||
} + 34
|
|
||||||
);
|
|
|
@ -16,7 +16,7 @@ pub enum BinaryOp {
|
||||||
|
|
||||||
#[derive(Clone, Debug)]
|
#[derive(Clone, Debug)]
|
||||||
pub enum Literal {
|
pub enum Literal {
|
||||||
Num(i64), Str(String), Bool(bool),
|
Num(i64), Str(String), Bool(bool), Unit,
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Enum to represent internal expression
|
/// Enum to represent internal expression
|
||||||
|
@ -31,19 +31,19 @@ pub enum Expr {
|
||||||
|
|
||||||
Call(Box<Self>, Vec<Self>),
|
Call(Box<Self>, Vec<Self>),
|
||||||
Lambda {
|
Lambda {
|
||||||
args: Vec<(String, Type)>,
|
args: Vec<String>,
|
||||||
body: Vec<Self>,
|
body: Vec<Self>,
|
||||||
},
|
},
|
||||||
|
Defines(Vec<(String, Self)>),
|
||||||
Return(Box<Self>),
|
Return(Box<Self>),
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Clone, Debug)]
|
#[derive(Clone, Debug)]
|
||||||
pub enum Stmt {
|
pub enum Stmt {
|
||||||
Expr(Expr),
|
Expr(Expr),
|
||||||
Let(Vec<(String, Type, Expr)>),
|
|
||||||
Func {
|
Func {
|
||||||
name: String,
|
name: String,
|
||||||
args: Vec<(String, Type)>,
|
args: Vec<String>,
|
||||||
ret: Type,
|
ret: Type,
|
||||||
body: Expr,
|
body: Expr,
|
||||||
},
|
},
|
||||||
|
@ -56,6 +56,7 @@ impl Display for Expr {
|
||||||
Literal::Num(n) => write!(f, "{}", n),
|
Literal::Num(n) => write!(f, "{}", n),
|
||||||
Literal::Str(s) => write!(f, "\"{}\"", s),
|
Literal::Str(s) => write!(f, "\"{}\"", s),
|
||||||
Literal::Bool(b) => write!(f, "{}", b),
|
Literal::Bool(b) => write!(f, "{}", b),
|
||||||
|
Literal::Unit => write!(f, "()"),
|
||||||
},
|
},
|
||||||
Expr::Sym(s) => write!(f, "{}", s),
|
Expr::Sym(s) => write!(f, "{}", s),
|
||||||
Expr::Vec(v) => {
|
Expr::Vec(v) => {
|
||||||
|
@ -79,8 +80,8 @@ impl Display for Expr {
|
||||||
},
|
},
|
||||||
Expr::Lambda { args, body } => {
|
Expr::Lambda { args, body } => {
|
||||||
write!(f, "(lambda ")?;
|
write!(f, "(lambda ")?;
|
||||||
for (name, ty) in args {
|
for arg in args {
|
||||||
write!(f, "[{} {}]", name, ty)?;
|
write!(f, " {}", arg)?;
|
||||||
}
|
}
|
||||||
if body.len() == 1 {
|
if body.len() == 1 {
|
||||||
write!(f, " {})", body[0])
|
write!(f, " {})", body[0])
|
||||||
|
@ -92,6 +93,13 @@ impl Display for Expr {
|
||||||
write!(f, "))")
|
write!(f, "))")
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
Expr::Defines(defs) => {
|
||||||
|
write!(f, "(defs ")?;
|
||||||
|
for (name, expr) in defs {
|
||||||
|
write!(f, "({} {})", name, expr)?;
|
||||||
|
}
|
||||||
|
write!(f, ")")
|
||||||
|
},
|
||||||
Expr::Return(e) => write!(f, "(return {})", e),
|
Expr::Return(e) => write!(f, "(return {})", e),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -101,17 +109,10 @@ impl Display for Stmt {
|
||||||
fn fmt(&self, f: &mut Formatter) -> FmtResult {
|
fn fmt(&self, f: &mut Formatter) -> FmtResult {
|
||||||
match self {
|
match self {
|
||||||
Stmt::Expr(e) => write!(f, "{}", e),
|
Stmt::Expr(e) => write!(f, "{}", e),
|
||||||
Stmt::Let(vars) => {
|
|
||||||
write!(f, "(let")?;
|
|
||||||
for (name, ty, e) in vars {
|
|
||||||
write!(f, " [{} {} {}]", name, ty, e)?;
|
|
||||||
}
|
|
||||||
write!(f, ")")
|
|
||||||
},
|
|
||||||
Stmt::Func { name, args, ret, body } => {
|
Stmt::Func { name, args, ret, body } => {
|
||||||
write!(f, "(defn {} [", name)?;
|
write!(f, "(defn {} [", name)?;
|
||||||
for (name, ty) in args {
|
for name in args {
|
||||||
write!(f, "[{} {}]", name, ty)?;
|
write!(f, " {}", name)?;
|
||||||
}
|
}
|
||||||
write!(f, "] {} {})", ret, body)
|
write!(f, "] {} {})", ret, body)
|
||||||
},
|
},
|
||||||
|
|
|
@ -2,7 +2,7 @@ use std::fmt::{Display, Formatter, Result as FmtResult};
|
||||||
use crate::trans::ty::Type;
|
use crate::trans::ty::Type;
|
||||||
|
|
||||||
#[derive(Clone, Debug)]
|
#[derive(Clone, Debug)]
|
||||||
pub enum JSLiteral { Num(i64), Str(String), Bool(bool) }
|
pub enum JSLiteral { Num(i64), Str(String), Bool(bool), Undefined }
|
||||||
|
|
||||||
/// Enum to represent javascript expression
|
/// Enum to represent javascript expression
|
||||||
#[derive(Clone, Debug)]
|
#[derive(Clone, Debug)]
|
||||||
|
@ -16,19 +16,19 @@ pub enum JSExpr {
|
||||||
Call(Box<Self>, Vec<Self>),
|
Call(Box<Self>, Vec<Self>),
|
||||||
Method(Box<Self>, String, Vec<Self>),
|
Method(Box<Self>, String, Vec<Self>),
|
||||||
Lambda {
|
Lambda {
|
||||||
args: Vec<(String, Type)>,
|
args: Vec<String>,
|
||||||
body: Vec<Self>,
|
body: Vec<Self>,
|
||||||
},
|
},
|
||||||
|
Defines(Vec<(String, Self)>),
|
||||||
Return(Box<Self>),
|
Return(Box<Self>),
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Clone, Debug)]
|
#[derive(Clone, Debug)]
|
||||||
pub enum JSStmt {
|
pub enum JSStmt {
|
||||||
Expr(JSExpr),
|
Expr(JSExpr),
|
||||||
Let(Vec<(String, Type, JSExpr)>),
|
|
||||||
Func {
|
Func {
|
||||||
name: String,
|
name: String,
|
||||||
args: Vec<(String, Type)>,
|
args: Vec<String>,
|
||||||
ret: Type,
|
ret: Type,
|
||||||
body: JSExpr,
|
body: JSExpr,
|
||||||
},
|
},
|
||||||
|
@ -38,9 +38,10 @@ impl Display for JSExpr {
|
||||||
fn fmt(&self, f: &mut Formatter) -> FmtResult {
|
fn fmt(&self, f: &mut Formatter) -> FmtResult {
|
||||||
match self {
|
match self {
|
||||||
JSExpr::Lit(l) => match l {
|
JSExpr::Lit(l) => match l {
|
||||||
JSLiteral::Num(n) => write!(f, "{}", n),
|
JSLiteral::Num(n) => write!(f, "{}", n),
|
||||||
JSLiteral::Str(s) => write!(f, "'{}'", s),
|
JSLiteral::Str(s) => write!(f, "'{}'", s),
|
||||||
JSLiteral::Bool(b) => write!(f, "{}", b),
|
JSLiteral::Bool(b) => write!(f, "{}", b),
|
||||||
|
JSLiteral::Undefined => write!(f, "undefined"),
|
||||||
},
|
},
|
||||||
JSExpr::Sym(s) => write!(f, "{}", s),
|
JSExpr::Sym(s) => write!(f, "{}", s),
|
||||||
JSExpr::Array(v) => {
|
JSExpr::Array(v) => {
|
||||||
|
@ -81,7 +82,7 @@ impl Display for JSExpr {
|
||||||
},
|
},
|
||||||
JSExpr::Lambda { args, body } => {
|
JSExpr::Lambda { args, body } => {
|
||||||
write!(f, "((")?;
|
write!(f, "((")?;
|
||||||
for (i, (name, _ty)) in args.iter().enumerate() {
|
for (i, name) in args.iter().enumerate() {
|
||||||
if i > 0 {
|
if i > 0 {
|
||||||
write!(f, ", ")?;
|
write!(f, ", ")?;
|
||||||
}
|
}
|
||||||
|
@ -98,6 +99,23 @@ impl Display for JSExpr {
|
||||||
write!(f, "}})")
|
write!(f, "}})")
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
JSExpr::Defines(vs) => {
|
||||||
|
write!(f, "let [")?;
|
||||||
|
for (i, (name, _)) in vs.iter().enumerate() {
|
||||||
|
if i > 0 {
|
||||||
|
write!(f, ", ")?;
|
||||||
|
}
|
||||||
|
write!(f, "{}", name)?;
|
||||||
|
}
|
||||||
|
write!(f, "] = [")?;
|
||||||
|
for (i, (_, expr)) in vs.iter().enumerate() {
|
||||||
|
if i > 0 {
|
||||||
|
write!(f, ", ")?;
|
||||||
|
}
|
||||||
|
write!(f, "{}", expr)?;
|
||||||
|
}
|
||||||
|
write!(f, "]")
|
||||||
|
}
|
||||||
JSExpr::Return(e) => write!(f, "return {}", e),
|
JSExpr::Return(e) => write!(f, "return {}", e),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -107,20 +125,10 @@ impl Display for JSStmt {
|
||||||
fn fmt(&self, f: &mut Formatter) -> FmtResult {
|
fn fmt(&self, f: &mut Formatter) -> FmtResult {
|
||||||
match self {
|
match self {
|
||||||
JSStmt::Expr(e) => write!(f, "{}", e),
|
JSStmt::Expr(e) => write!(f, "{}", e),
|
||||||
JSStmt::Let(vars) => {
|
|
||||||
write!(f, "let ")?;
|
|
||||||
for (i, (name, _ty, e)) in vars.iter().enumerate() {
|
|
||||||
if i > 0 {
|
|
||||||
write!(f, ", ")?;
|
|
||||||
}
|
|
||||||
write!(f, "{} = {}", name, e)?;
|
|
||||||
}
|
|
||||||
write!(f, ";")
|
|
||||||
},
|
|
||||||
JSStmt::Func { name, args, ret: _, body } => {
|
JSStmt::Func { name, args, ret: _, body } => {
|
||||||
// const name = (args) => body;
|
// const name = (args) => body;
|
||||||
write!(f, "const {} = (", name)?;
|
write!(f, "const {} = (", name)?;
|
||||||
for (i, (name, _ty)) in args.iter().enumerate() {
|
for (i, name) in args.iter().enumerate() {
|
||||||
if i > 0 {
|
if i > 0 {
|
||||||
write!(f, ", ")?;
|
write!(f, ", ")?;
|
||||||
}
|
}
|
||||||
|
|
|
@ -16,7 +16,7 @@ pub enum PBinaryOp {
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Clone, Debug)]
|
#[derive(Clone, Debug)]
|
||||||
pub enum PLiteral { Num(i64), Str(String), Bool(bool) }
|
pub enum PLiteral { Num(i64), Str(String), Bool(bool), Unit }
|
||||||
|
|
||||||
#[derive(Clone, Debug)]
|
#[derive(Clone, Debug)]
|
||||||
pub enum PExpr {
|
pub enum PExpr {
|
||||||
|
@ -36,7 +36,7 @@ pub enum PExpr {
|
||||||
},
|
},
|
||||||
Let {
|
Let {
|
||||||
vars: Vec<(String, Type, Spanned<Self>)>,
|
vars: Vec<(String, Type, Spanned<Self>)>,
|
||||||
body: Box<Spanned<Self>>,
|
body: Option<Box<Spanned<Self>>>,
|
||||||
},
|
},
|
||||||
Block(Vec<Spanned<Self>>),
|
Block(Vec<Spanned<Self>>),
|
||||||
Return(Box<Spanned<Self>>),
|
Return(Box<Spanned<Self>>),
|
||||||
|
|
|
@ -295,10 +295,16 @@ pub fn expr_parser() -> impl P<Spanned<PExpr>> {
|
||||||
.then(expr.clone())
|
.then(expr.clone())
|
||||||
.map(|(vars, body)| PExpr::Let {
|
.map(|(vars, body)| PExpr::Let {
|
||||||
vars,
|
vars,
|
||||||
body: Box::new(body),
|
body: Some(Box::new(body)),
|
||||||
})
|
})
|
||||||
.boxed()
|
.boxed()
|
||||||
.labelled("let..in");
|
.labelled("let with expression");
|
||||||
|
|
||||||
|
let let_def = just(Token::Let)
|
||||||
|
.ignore_then(let_binds)
|
||||||
|
.map(|vars| PExpr::Let { vars, body: None })
|
||||||
|
.boxed()
|
||||||
|
.labelled("let definition");
|
||||||
|
|
||||||
let block = nested_parser(
|
let block = nested_parser(
|
||||||
expr.clone()
|
expr.clone()
|
||||||
|
@ -322,6 +328,7 @@ pub fn expr_parser() -> impl P<Spanned<PExpr>> {
|
||||||
.or(paren_expr)
|
.or(paren_expr)
|
||||||
.or(lam)
|
.or(lam)
|
||||||
.or(let_in)
|
.or(let_in)
|
||||||
|
.or(let_def)
|
||||||
.or(block)
|
.or(block)
|
||||||
.or(ret)
|
.or(ret)
|
||||||
.map_with_span(|e, s| (e, s))
|
.map_with_span(|e, s| (e, s))
|
||||||
|
|
|
@ -10,13 +10,21 @@ pub fn translate_stmt(stmt: PStmt) -> Stmt {
|
||||||
PStmt::Let(vars) => todo!(),
|
PStmt::Let(vars) => todo!(),
|
||||||
PStmt::Func { name, args, ret, body } => Stmt::Func {
|
PStmt::Func { name, args, ret, body } => Stmt::Func {
|
||||||
name,
|
name,
|
||||||
args,
|
args: args.into_iter().map(|(name, _ty)| name).collect(),
|
||||||
ret,
|
ret,
|
||||||
body: translate_expr(body.0),
|
body: translate_expr(body.0),
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn exprs_to_lam(es: Vec<PExpr>) -> Expr {
|
||||||
|
let lam = Expr::Lambda {
|
||||||
|
args: vec![],
|
||||||
|
body: es.into_iter().map(|e| translate_expr(e)).collect(),
|
||||||
|
};
|
||||||
|
Expr::Call(Box::new(lam), vec![])
|
||||||
|
}
|
||||||
|
|
||||||
pub fn translate_expr(expr: PExpr) -> Expr {
|
pub fn translate_expr(expr: PExpr) -> Expr {
|
||||||
match expr {
|
match expr {
|
||||||
PExpr::Error => panic!("Error in expression!"),
|
PExpr::Error => panic!("Error in expression!"),
|
||||||
|
@ -25,6 +33,7 @@ pub fn translate_expr(expr: PExpr) -> Expr {
|
||||||
PLiteral::Num(n) => Literal::Num(n),
|
PLiteral::Num(n) => Literal::Num(n),
|
||||||
PLiteral::Str(s) => Literal::Str(s),
|
PLiteral::Str(s) => Literal::Str(s),
|
||||||
PLiteral::Bool(b) => Literal::Bool(b),
|
PLiteral::Bool(b) => Literal::Bool(b),
|
||||||
|
PLiteral::Unit => Literal::Unit,
|
||||||
}),
|
}),
|
||||||
PExpr::Sym(s) => Expr::Sym(s),
|
PExpr::Sym(s) => Expr::Sym(s),
|
||||||
PExpr::Vec(v) => Expr::Vec(v.into_iter().map(|e| translate_expr(e.0)).collect()),
|
PExpr::Vec(v) => Expr::Vec(v.into_iter().map(|e| translate_expr(e.0)).collect()),
|
||||||
|
@ -61,30 +70,32 @@ pub fn translate_expr(expr: PExpr) -> Expr {
|
||||||
args.into_iter().map(|a| translate_expr(a.0)).collect(),
|
args.into_iter().map(|a| translate_expr(a.0)).collect(),
|
||||||
),
|
),
|
||||||
PExpr::Lambda { args, body } => Expr::Lambda {
|
PExpr::Lambda { args, body } => Expr::Lambda {
|
||||||
args,
|
args: args.into_iter().map(|(name, _ty)| name).collect(),
|
||||||
body: vec![translate_expr((*body).0)],
|
body: vec![translate_expr((*body).0)],
|
||||||
},
|
},
|
||||||
PExpr::Let { vars, body } => {
|
PExpr::Let { vars, body } => {
|
||||||
let mut expr: Expr = translate_expr(body.0); // The expression we're building up
|
if let Some(body) = body {
|
||||||
for (name, ty, val) in vars.into_iter().rev() { // Reverse so we can build up the lambda
|
let mut expr: Expr = translate_expr(body.0); // The expression we're building up
|
||||||
// e.g.: let x : t = e1 in e2; => (lambda (x : t) = e2)(e1)
|
for (name, _ty, val) in vars.into_iter().rev() { // Reverse so we can build up the lambda
|
||||||
// Build up the lambda
|
// e.g.: let x : t = e1 in e2; => (lambda (x : t) = e2)(e1)
|
||||||
expr = Expr::Lambda {
|
// Build up the lambda
|
||||||
args: vec![(name, ty)],
|
expr = Expr::Lambda {
|
||||||
body: vec![expr],
|
args: vec![name],
|
||||||
};
|
body: vec![expr],
|
||||||
// Call the lambda with the value
|
};
|
||||||
let val = translate_expr(val.0);
|
// Call the lambda with the value
|
||||||
expr = Expr::Call(Box::new(expr), vec![val]);
|
let val = translate_expr(val.0);
|
||||||
|
expr = Expr::Call(Box::new(expr), vec![val]);
|
||||||
|
}
|
||||||
|
expr
|
||||||
|
} else {
|
||||||
|
Expr::Defines(vars.into_iter().map(|(name, _ty, val)| {
|
||||||
|
(name, translate_expr(val.0))
|
||||||
|
}).collect())
|
||||||
}
|
}
|
||||||
expr
|
|
||||||
},
|
},
|
||||||
PExpr::Block(es) => {
|
PExpr::Block(es) => {
|
||||||
let lam = Expr::Lambda {
|
exprs_to_lam(es.into_iter().map(|e| e.0).collect())
|
||||||
args: vec![],
|
|
||||||
body: es.into_iter().map(|e| translate_expr(e.0)).collect(),
|
|
||||||
};
|
|
||||||
Expr::Call(Box::new(lam), vec![])
|
|
||||||
},
|
},
|
||||||
PExpr::Return(e) => Expr::Return(Box::new(translate_expr((*e).0))),
|
PExpr::Return(e) => Expr::Return(Box::new(translate_expr((*e).0))),
|
||||||
}
|
}
|
||||||
|
@ -93,7 +104,6 @@ pub fn translate_expr(expr: PExpr) -> Expr {
|
||||||
pub fn translate_js_stmt(stmt: Stmt) -> JSStmt {
|
pub fn translate_js_stmt(stmt: Stmt) -> JSStmt {
|
||||||
match stmt {
|
match stmt {
|
||||||
Stmt::Expr(e) => JSStmt::Expr(translate_js_expr(e)),
|
Stmt::Expr(e) => JSStmt::Expr(translate_js_expr(e)),
|
||||||
Stmt::Let(vars) => todo!(),
|
|
||||||
Stmt::Func { name, args, ret, body } => JSStmt::Func {
|
Stmt::Func { name, args, ret, body } => JSStmt::Func {
|
||||||
name,
|
name,
|
||||||
args,
|
args,
|
||||||
|
@ -109,6 +119,7 @@ pub fn translate_js_expr(expr: Expr) -> JSExpr {
|
||||||
Literal::Num(n) => JSExpr::Lit(JSLiteral::Num(n)),
|
Literal::Num(n) => JSExpr::Lit(JSLiteral::Num(n)),
|
||||||
Literal::Str(s) => JSExpr::Lit(JSLiteral::Str(s)),
|
Literal::Str(s) => JSExpr::Lit(JSLiteral::Str(s)),
|
||||||
Literal::Bool(b) => JSExpr::Lit(JSLiteral::Bool(b)),
|
Literal::Bool(b) => JSExpr::Lit(JSLiteral::Bool(b)),
|
||||||
|
Literal::Unit => JSExpr::Lit(JSLiteral::Undefined),
|
||||||
},
|
},
|
||||||
Expr::Sym(s) => JSExpr::Sym(s),
|
Expr::Sym(s) => JSExpr::Sym(s),
|
||||||
Expr::Vec(v) => JSExpr::Array(v.into_iter().map(translate_js_expr).collect()),
|
Expr::Vec(v) => JSExpr::Array(v.into_iter().map(translate_js_expr).collect()),
|
||||||
|
@ -162,6 +173,9 @@ pub fn translate_js_expr(expr: Expr) -> JSExpr {
|
||||||
args,
|
args,
|
||||||
body: body.into_iter().map(translate_js_expr).collect(),
|
body: body.into_iter().map(translate_js_expr).collect(),
|
||||||
},
|
},
|
||||||
|
Expr::Defines(defs) => JSExpr::Defines(defs.into_iter().map(|(name, val)| {
|
||||||
|
(name, translate_js_expr(val))
|
||||||
|
}).collect()),
|
||||||
Expr::Return(e) => JSExpr::Return(Box::new(translate_js_expr(*e))),
|
Expr::Return(e) => JSExpr::Return(Box::new(translate_js_expr(*e))),
|
||||||
}
|
}
|
||||||
}
|
}
|
Loading…
Reference in a new issue