1
1
Fork 0
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.

10 changed files with 36 additions and 176 deletions

14
a.hlm
View file

@ -1,9 +1,5 @@
func add x: num -> num = x + 1; println({
println("Hello");
println( return let x: num = 17 * 2 in
{ x + 1;
println("Hello"); } + 34);
return let x: num = 17 * 2 in
add(x);
} + 34
);

View file

@ -1,3 +0,0 @@
pub mod past;
pub mod ast;
pub mod js;

View file

@ -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);

View file

@ -1 +1,2 @@
pub mod parse; pub mod parse;
pub mod past;

View file

@ -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()));

View file

@ -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>>,
}, },
} }

View file

@ -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 {
@ -95,26 +83,4 @@ impl Display for Expr {
Expr::Return(e) => write!(f, "(return {})", e), Expr::Return(e) => write!(f, "(return {})", e),
} }
} }
}
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)
},
}
}
} }

View file

@ -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 {
@ -101,33 +89,4 @@ impl Display for JSExpr {
JSExpr::Return(e) => write!(f, "return {}", e), JSExpr::Return(e) => write!(f, "return {}", e),
} }
} }
}
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)
},
}
}
} }

View file

@ -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))),
} }
} }

View file

@ -1,2 +1,4 @@
pub mod ty; pub mod ty;
pub mod ast;
pub mod js;
pub mod low; pub mod low;