mirror of
https://github.com/azur1s/bobbylisp.git
synced 2024-10-16 02:37:40 -05:00
Compare commits
No commits in common. "0a6e04ae5fedc251de3c0d940af23c882fc994d3" and "cef5e00f3a7db5193b6339b1281c83c64fc48612" have entirely different histories.
0a6e04ae5f
...
cef5e00f3a
10
a.hlm
10
a.hlm
|
@ -1,9 +1,5 @@
|
||||||
func add x: num -> num = x + 1;
|
println({
|
||||||
|
|
||||||
println(
|
|
||||||
{
|
|
||||||
println("Hello");
|
println("Hello");
|
||||||
return let x: num = 17 * 2 in
|
return let x: num = 17 * 2 in
|
||||||
add(x);
|
x + 1;
|
||||||
} + 34
|
} + 34);
|
||||||
);
|
|
|
@ -1,3 +0,0 @@
|
||||||
pub mod past;
|
|
||||||
pub mod ast;
|
|
||||||
pub mod js;
|
|
13
src/main.rs
13
src/main.rs
|
@ -1,5 +1,4 @@
|
||||||
#![feature(trait_alias)]
|
#![feature(trait_alias)]
|
||||||
pub mod asts;
|
|
||||||
pub mod read;
|
pub mod read;
|
||||||
pub mod trans;
|
pub mod trans;
|
||||||
pub mod args;
|
pub mod args;
|
||||||
|
@ -8,7 +7,7 @@ use std::io::Write;
|
||||||
use args::Options;
|
use args::Options;
|
||||||
use read::parse::{lex, parse};
|
use read::parse::{lex, parse};
|
||||||
use structopt::StructOpt;
|
use structopt::StructOpt;
|
||||||
use trans::low::{translate_stmt, translate_js_stmt};
|
use trans::low::{translate_expr, translate_js};
|
||||||
|
|
||||||
fn main() {
|
fn main() {
|
||||||
let opt = Options::from_args();
|
let opt = Options::from_args();
|
||||||
|
@ -17,15 +16,15 @@ fn main() {
|
||||||
let (tokens, lex_errs) = lex(src.to_owned());
|
let (tokens, lex_errs) = lex(src.to_owned());
|
||||||
|
|
||||||
let parse_errs = if let Some(tokens) = tokens {
|
let parse_errs = if let Some(tokens) = tokens {
|
||||||
let (past, parse_errs) = parse(tokens, src.len());
|
let (ast, parse_errs) = parse(tokens, src.len());
|
||||||
|
|
||||||
if let Some(past) = past {
|
if let Some(ast) = ast {
|
||||||
let ast = past.into_iter().map(|(e, _)| translate_stmt(e)).collect::<Vec<_>>();
|
let nexprs = ast.into_iter().map(|(e, _)| translate_expr(e)).collect::<Vec<_>>();
|
||||||
let js = ast.into_iter().map(translate_js_stmt).collect::<Vec<_>>();
|
let jsexprs = nexprs.into_iter().map(translate_js).collect::<Vec<_>>();
|
||||||
|
|
||||||
let mut file = std::fs::File::create(opt.output.unwrap_or("out.js".into()))
|
let mut file = std::fs::File::create(opt.output.unwrap_or("out.js".into()))
|
||||||
.expect("Failed to create file");
|
.expect("Failed to create file");
|
||||||
let s = js
|
let s = jsexprs
|
||||||
.into_iter()
|
.into_iter()
|
||||||
.map(|e| {
|
.map(|e| {
|
||||||
let s = format!("{}", e);
|
let s = format!("{}", e);
|
||||||
|
|
|
@ -1 +1,2 @@
|
||||||
pub mod parse;
|
pub mod parse;
|
||||||
|
pub mod past;
|
|
@ -3,7 +3,7 @@ use chumsky::{prelude::*, Stream};
|
||||||
use std::fmt::{Display, Formatter, Result as FmtResult};
|
use std::fmt::{Display, Formatter, Result as FmtResult};
|
||||||
use crate::trans::ty::Type;
|
use crate::trans::ty::Type;
|
||||||
|
|
||||||
use crate::asts::past::*;
|
use super::past::*;
|
||||||
|
|
||||||
#[derive(Clone, Copy, Debug, Eq, Hash, PartialEq)]
|
#[derive(Clone, Copy, Debug, Eq, Hash, PartialEq)]
|
||||||
pub enum Delim { Paren, Brack, Brace }
|
pub enum Delim { Paren, Brack, Brace }
|
||||||
|
@ -442,44 +442,11 @@ pub fn exprs_parser() -> impl P<Vec<Spanned<PExpr>>> {
|
||||||
.repeated()
|
.repeated()
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn stmt_parser() -> impl P<Spanned<PStmt>> {
|
|
||||||
let func = just(Token::Func)
|
|
||||||
.ignore_then(symbol_parser())
|
|
||||||
.then(
|
|
||||||
symbol_parser()
|
|
||||||
.then_ignore(just(Token::Colon))
|
|
||||||
.then(type_parser())
|
|
||||||
.separated_by(just(Token::Comma))
|
|
||||||
)
|
|
||||||
.then_ignore(just(Token::Arrow))
|
|
||||||
.then(type_parser())
|
|
||||||
.then_ignore(just(Token::Assign))
|
|
||||||
.then(expr_parser().map(Box::new))
|
|
||||||
.map(|(((name, args), ret), body)| PStmt::Func {
|
|
||||||
name,
|
|
||||||
args,
|
|
||||||
ret,
|
|
||||||
body,
|
|
||||||
});
|
|
||||||
|
|
||||||
let expr = expr_parser().map(PStmt::Expr);
|
|
||||||
|
|
||||||
func
|
|
||||||
.or(expr)
|
|
||||||
.map_with_span(|s, span| (s, span))
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn stmts_parser() -> impl P<Vec<Spanned<PStmt>>> {
|
|
||||||
stmt_parser()
|
|
||||||
.then_ignore(just(Token::Semicolon))
|
|
||||||
.repeated()
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn parse(
|
pub fn parse(
|
||||||
tokens: Vec<Spanned<Token>>,
|
tokens: Vec<Spanned<Token>>,
|
||||||
len: usize,
|
len: usize,
|
||||||
) -> (Option<Vec<Spanned<PStmt>>>, Vec<Simple<Token>>) {
|
) -> (Option<Vec<Spanned<PExpr>>>, Vec<Simple<Token>>) {
|
||||||
let (ast, parse_error) = stmts_parser()
|
let (ast, parse_error) = exprs_parser()
|
||||||
.then_ignore(end())
|
.then_ignore(end())
|
||||||
.parse_recovery(Stream::from_iter(len..len + 1, tokens.into_iter()));
|
.parse_recovery(Stream::from_iter(len..len + 1, tokens.into_iter()));
|
||||||
|
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
use crate::trans::ty::*;
|
use crate::trans::ty::*;
|
||||||
|
|
||||||
use crate::read::parse::Spanned;
|
use super::parse::Spanned;
|
||||||
|
|
||||||
#[derive(Clone, Debug)]
|
#[derive(Clone, Debug)]
|
||||||
pub enum PUnaryOp {
|
pub enum PUnaryOp {
|
||||||
|
@ -49,7 +49,6 @@ pub enum PStmt {
|
||||||
Func {
|
Func {
|
||||||
name: String,
|
name: String,
|
||||||
args: Vec<(String, Type)>,
|
args: Vec<(String, Type)>,
|
||||||
ret: Type,
|
|
||||||
body: Box<Spanned<PExpr>>,
|
body: Box<Spanned<PExpr>>,
|
||||||
},
|
},
|
||||||
}
|
}
|
|
@ -1,5 +1,5 @@
|
||||||
use std::fmt::{Display, Formatter, Result as FmtResult};
|
use std::fmt::{Display, Formatter, Result as FmtResult};
|
||||||
use crate::trans::ty::Type;
|
use super::ty::Type;
|
||||||
|
|
||||||
#[derive(Clone, Debug)]
|
#[derive(Clone, Debug)]
|
||||||
pub enum UnaryOp {
|
pub enum UnaryOp {
|
||||||
|
@ -37,18 +37,6 @@ pub enum Expr {
|
||||||
Return(Box<Self>),
|
Return(Box<Self>),
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Clone, Debug)]
|
|
||||||
pub enum Stmt {
|
|
||||||
Expr(Expr),
|
|
||||||
Let(Vec<(String, Type, Expr)>),
|
|
||||||
Func {
|
|
||||||
name: String,
|
|
||||||
args: Vec<(String, Type)>,
|
|
||||||
ret: Type,
|
|
||||||
body: Expr,
|
|
||||||
},
|
|
||||||
}
|
|
||||||
|
|
||||||
impl Display for Expr {
|
impl Display for Expr {
|
||||||
fn fmt(&self, f: &mut Formatter) -> FmtResult {
|
fn fmt(&self, f: &mut Formatter) -> FmtResult {
|
||||||
match self {
|
match self {
|
||||||
|
@ -96,25 +84,3 @@ impl Display for Expr {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Display for Stmt {
|
|
||||||
fn fmt(&self, f: &mut Formatter) -> FmtResult {
|
|
||||||
match self {
|
|
||||||
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 } => {
|
|
||||||
write!(f, "(defn {} [", name)?;
|
|
||||||
for (name, ty) in args {
|
|
||||||
write!(f, "[{} {}]", name, ty)?;
|
|
||||||
}
|
|
||||||
write!(f, "] {} {})", ret, body)
|
|
||||||
},
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,5 +1,5 @@
|
||||||
use std::fmt::{Display, Formatter, Result as FmtResult};
|
use std::fmt::{Display, Formatter, Result as FmtResult};
|
||||||
use crate::trans::ty::Type;
|
use super::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) }
|
||||||
|
@ -22,18 +22,6 @@ pub enum JSExpr {
|
||||||
Return(Box<Self>),
|
Return(Box<Self>),
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Clone, Debug)]
|
|
||||||
pub enum JSStmt {
|
|
||||||
Expr(JSExpr),
|
|
||||||
Let(Vec<(String, Type, JSExpr)>),
|
|
||||||
Func {
|
|
||||||
name: String,
|
|
||||||
args: Vec<(String, Type)>,
|
|
||||||
ret: Type,
|
|
||||||
body: JSExpr,
|
|
||||||
},
|
|
||||||
}
|
|
||||||
|
|
||||||
impl Display for JSExpr {
|
impl Display for JSExpr {
|
||||||
fn fmt(&self, f: &mut Formatter) -> FmtResult {
|
fn fmt(&self, f: &mut Formatter) -> FmtResult {
|
||||||
match self {
|
match self {
|
||||||
|
@ -102,32 +90,3 @@ impl Display for JSExpr {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Display for JSStmt {
|
|
||||||
fn fmt(&self, f: &mut Formatter) -> FmtResult {
|
|
||||||
match self {
|
|
||||||
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 } => {
|
|
||||||
// const name = (args) => body;
|
|
||||||
write!(f, "const {} = (", name)?;
|
|
||||||
for (i, (name, _ty)) in args.iter().enumerate() {
|
|
||||||
if i > 0 {
|
|
||||||
write!(f, ", ")?;
|
|
||||||
}
|
|
||||||
write!(f, "{}", name)?;
|
|
||||||
}
|
|
||||||
write!(f, ") => {};", body)
|
|
||||||
},
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,22 +1,9 @@
|
||||||
use crate::asts::{
|
use crate::read::past::{PExpr, PLiteral, PBinaryOp, PUnaryOp};
|
||||||
past::*,
|
use super::{
|
||||||
ast::*,
|
ast::{Expr, Literal, BinaryOp, UnaryOp},
|
||||||
js::*,
|
js::{JSExpr, JSLiteral},
|
||||||
};
|
};
|
||||||
|
|
||||||
pub fn translate_stmt(stmt: PStmt) -> Stmt {
|
|
||||||
match stmt {
|
|
||||||
PStmt::Expr(e) => Stmt::Expr(translate_expr(e.0)),
|
|
||||||
PStmt::Let(vars) => todo!(),
|
|
||||||
PStmt::Func { name, args, ret, body } => Stmt::Func {
|
|
||||||
name,
|
|
||||||
args,
|
|
||||||
ret,
|
|
||||||
body: translate_expr(body.0),
|
|
||||||
},
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
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!"),
|
||||||
|
@ -90,20 +77,7 @@ pub fn translate_expr(expr: PExpr) -> Expr {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn translate_js_stmt(stmt: Stmt) -> JSStmt {
|
pub fn translate_js(expr: Expr) -> JSExpr {
|
||||||
match stmt {
|
|
||||||
Stmt::Expr(e) => JSStmt::Expr(translate_js_expr(e)),
|
|
||||||
Stmt::Let(vars) => todo!(),
|
|
||||||
Stmt::Func { name, args, ret, body } => JSStmt::Func {
|
|
||||||
name,
|
|
||||||
args,
|
|
||||||
ret,
|
|
||||||
body: translate_js_expr(body),
|
|
||||||
},
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn translate_js_expr(expr: Expr) -> JSExpr {
|
|
||||||
match expr {
|
match expr {
|
||||||
Expr::Lit(l) => match l {
|
Expr::Lit(l) => match l {
|
||||||
Literal::Num(n) => JSExpr::Lit(JSLiteral::Num(n)),
|
Literal::Num(n) => JSExpr::Lit(JSLiteral::Num(n)),
|
||||||
|
@ -111,12 +85,12 @@ pub fn translate_js_expr(expr: Expr) -> JSExpr {
|
||||||
Literal::Bool(b) => JSExpr::Lit(JSLiteral::Bool(b)),
|
Literal::Bool(b) => JSExpr::Lit(JSLiteral::Bool(b)),
|
||||||
},
|
},
|
||||||
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).collect()),
|
||||||
|
|
||||||
Expr::UnaryOp(op, e) => JSExpr::Op(match op {
|
Expr::UnaryOp(op, e) => JSExpr::Op(match op {
|
||||||
UnaryOp::Neg => "-",
|
UnaryOp::Neg => "-",
|
||||||
UnaryOp::Not => "!",
|
UnaryOp::Not => "!",
|
||||||
}, Box::new(translate_js_expr(*e)), None),
|
}, Box::new(translate_js(*e)), None),
|
||||||
Expr::BinaryOp(op, e1, e2) => JSExpr::Op(match op {
|
Expr::BinaryOp(op, e1, e2) => JSExpr::Op(match op {
|
||||||
BinaryOp::Add => "+",
|
BinaryOp::Add => "+",
|
||||||
BinaryOp::Sub => "-",
|
BinaryOp::Sub => "-",
|
||||||
|
@ -133,7 +107,7 @@ pub fn translate_js_expr(expr: Expr) -> JSExpr {
|
||||||
|
|
||||||
BinaryOp::And => "&&",
|
BinaryOp::And => "&&",
|
||||||
BinaryOp::Or => "||",
|
BinaryOp::Or => "||",
|
||||||
}, Box::new(translate_js_expr(*e1)), Some(Box::new(translate_js_expr(*e2)))),
|
}, Box::new(translate_js(*e1)), Some(Box::new(translate_js(*e2)))),
|
||||||
|
|
||||||
Expr::Call(f, args) => {
|
Expr::Call(f, args) => {
|
||||||
match *f {
|
match *f {
|
||||||
|
@ -143,25 +117,25 @@ pub fn translate_js_expr(expr: Expr) -> JSExpr {
|
||||||
JSExpr::Method(
|
JSExpr::Method(
|
||||||
Box::new(JSExpr::Sym("console".to_string())),
|
Box::new(JSExpr::Sym("console".to_string())),
|
||||||
"log".to_string(),
|
"log".to_string(),
|
||||||
args.into_iter().map(translate_js_expr).collect(),
|
args.into_iter().map(translate_js).collect(),
|
||||||
)
|
)
|
||||||
},
|
},
|
||||||
_ => JSExpr::Call(
|
_ => JSExpr::Call(
|
||||||
Box::new(translate_js_expr(*f)),
|
Box::new(translate_js(*f)),
|
||||||
args.into_iter().map(translate_js_expr).collect(),
|
args.into_iter().map(translate_js).collect(),
|
||||||
),
|
),
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
_ => JSExpr::Call(
|
_ => JSExpr::Call(
|
||||||
Box::new(translate_js_expr(*f)),
|
Box::new(translate_js(*f)),
|
||||||
args.into_iter().map(translate_js_expr).collect(),
|
args.into_iter().map(translate_js).collect(),
|
||||||
),
|
),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Expr::Lambda { args, body } => JSExpr::Lambda {
|
Expr::Lambda { args, body } => JSExpr::Lambda {
|
||||||
args,
|
args,
|
||||||
body: body.into_iter().map(translate_js_expr).collect(),
|
body: body.into_iter().map(translate_js).collect(),
|
||||||
},
|
},
|
||||||
Expr::Return(e) => JSExpr::Return(Box::new(translate_js_expr(*e))),
|
Expr::Return(e) => JSExpr::Return(Box::new(translate_js(*e))),
|
||||||
}
|
}
|
||||||
}
|
}
|
|
@ -1,2 +1,4 @@
|
||||||
pub mod ty;
|
pub mod ty;
|
||||||
|
pub mod ast;
|
||||||
|
pub mod js;
|
||||||
pub mod low;
|
pub mod low;
|
Loading…
Reference in a new issue