1
1
Fork 0
mirror of https://github.com/azur1s/bobbylisp.git synced 2024-10-16 02:37:40 -05:00

callable lambda

This commit is contained in:
azur 2022-12-16 20:31:35 +07:00
parent b5856a35e7
commit dfc24c5444
7 changed files with 37 additions and 33 deletions

View file

@ -1,6 +1,7 @@
#![allow(clippy::new_without_default)] #![allow(clippy::new_without_default)]
#![allow(clippy::only_used_in_recursion)]
use parser::{Expr, Literal, Span, Stmt}; use parser::{Expr, Literal, Span, Stmt};
use vm::model::{Instr, Value}; use vm::model::Instr;
pub struct Compiler {} pub struct Compiler {}
@ -11,7 +12,10 @@ impl Compiler {
pub fn compile_expr(&mut self, expr: Expr) -> Vec<Instr> { pub fn compile_expr(&mut self, expr: Expr) -> Vec<Instr> {
match expr { match expr {
Expr::Error => unreachable!(), Expr::Error => {
println!("{:?}", expr);
unreachable!()
}
Expr::Literal(x) => match x { Expr::Literal(x) => match x {
Literal::Num(x) => vec![Instr::NumPush(x)], Literal::Num(x) => vec![Instr::NumPush(x)],
Literal::Bool(x) => vec![Instr::BoolPush(x)], Literal::Bool(x) => vec![Instr::BoolPush(x)],
@ -63,16 +67,21 @@ impl Compiler {
for x in xs { for x in xs {
instrs.extend(self.compile_expr(x.0)); instrs.extend(self.compile_expr(x.0));
} }
if let Expr::Sym(fname) = &f.0 { match &f.0 {
match fname.as_str() { Expr::Sym(fname) => match fname.as_str() {
"print" => instrs.push(Instr::Print), "print" => instrs.push(Instr::Print),
"println" => instrs.push(Instr::PrintLn), "println" => instrs.push(Instr::PrintLn),
_ => { _ => {
instrs.extend(self.compile_expr(f.0)); instrs.extend(self.compile_expr(f.0));
instrs.push(Instr::FuncApply); instrs.push(Instr::FuncApply);
} }
},
Expr::Lambda(_, _) => {
instrs.extend(self.compile_expr(f.0));
instrs.push(Instr::FuncApply);
}
_ => todo!(),
} }
};
instrs instrs
} }
Expr::Let(binds, body) => { Expr::Let(binds, body) => {

View file

@ -7,3 +7,7 @@ edition = "2021"
parser = { path = "../parser" } parser = { path = "../parser" }
compiler = { path = "../compiler" } compiler = { path = "../compiler" }
vm = { path = "../vm" } vm = { path = "../vm" }
[[bin]]
name = "hmc"
path = "src/main.rs"

View file

@ -15,10 +15,7 @@ fn main() {
let instrs = compiler.compile_program(ast); let instrs = compiler.compile_program(ast);
// instrs.iter().for_each(|i| println!("{:?}", i)); // instrs.iter().for_each(|i| println!("{:?}", i));
let mut executor = Executor::new(instrs); let mut executor = Executor::new(instrs);
match executor.run_with(|exec| { match executor.run() {
// println!("{:?}", exec.stack);
Ok(())
}) {
Ok(_) => {} Ok(_) => {}
Err(e) => println!("Runtime error: {:?}", e), Err(e) => println!("Runtime error: {:?}", e),
} }

View file

@ -19,3 +19,6 @@ fun main = do
let add = \x y -> x + y in let add = \x y -> x + y in
print(add(34, succ(34))) print(add(34, succ(34)))
end end
// succ(34) |> \x -> add (34, x)
// (\x -> add(34, x))(succ(34))

View file

@ -1,18 +1,3 @@
fun foo x = do
x
end
fun fac n = if n == 0 then 1 else n * fac(n - 1)
fun main = do fun main = do
let succ = \x -> x + 1, println((\x -> x + 1)(9))
n = 34,
in
println(n + succ(n))
print("Hello ")
println("World!")
println(foo(1))
println(fac(5))
end end

View file

@ -1,4 +1,5 @@
#![feature(trait_alias)] #![feature(trait_alias)]
#![allow(clippy::type_complexity)]
use ariadne::{Color, Fmt, Label, Report, ReportKind, Source}; use ariadne::{Color, Fmt, Label, Report, ReportKind, Source};
use chumsky::{error, prelude::*, Stream}; use chumsky::{error, prelude::*, Stream};
@ -323,6 +324,12 @@ pub fn expr_parser() -> impl P<Spanned<Expr>> {
}) })
.labelled("vector"); .labelled("vector");
let paren_expr = just(Token::Open(Delimiter::Paren))
.ignore_then(expr.clone())
.then_ignore(just(Token::Close(Delimiter::Paren)))
.map(|e| e.0)
.labelled("parenthesized expression");
let lam = just(Token::Backslash) let lam = just(Token::Backslash)
.ignore_then(symbol_parser().repeated()) .ignore_then(symbol_parser().repeated())
.then_ignore(just(Token::Arrow)) .then_ignore(just(Token::Arrow))
@ -369,6 +376,7 @@ pub fn expr_parser() -> impl P<Spanned<Expr>> {
let atom = lit let atom = lit
.or(ident) .or(ident)
.or(vec) .or(vec)
.or(paren_expr)
.or(lam) .or(lam)
.or(let_in) .or(let_in)
.or(let_def) .or(let_def)
@ -481,7 +489,7 @@ pub fn expr_parser() -> impl P<Spanned<Expr>> {
}) })
.boxed(); .boxed();
let pipe = logical logical
.clone() .clone()
.then( .then(
just(Token::Pipe) just(Token::Pipe)
@ -494,9 +502,7 @@ pub fn expr_parser() -> impl P<Spanned<Expr>> {
let s = lhs.1.start()..rhs.1.end(); let s = lhs.1.start()..rhs.1.end();
(Expr::Binary(op, Box::new(lhs), Box::new(rhs)), s) (Expr::Binary(op, Box::new(lhs), Box::new(rhs)), s)
}) })
.boxed(); .boxed()
pipe
}) })
} }

View file

@ -123,7 +123,7 @@ pub enum Instr {
// where x is the enum (1 byte) // where x is the enum (1 byte)
// s is the string (n bytes) // s is the string (n bytes)
// Example: StrPush "Hello, World!" // Example: StrPush "Hello, World!"
// [05] [48 65 6c 6c 6f 2c 20 57 6f 72 6c 64 21] [00] // [XX] [48 65 6c 6c 6f 2c 20 57 6f 72 6c 64 21] [00]
// └────┼────────────────────────────────────────┼─╼ enum // └────┼────────────────────────────────────────┼─╼ enum
// └────────────────────────────────────────┼─╼ string // └────────────────────────────────────────┼─╼ string
// └─╼ null delimiter // └─╼ null delimiter
@ -153,7 +153,7 @@ pub enum Instr {
// ╴╴┴──────┴────┴╶╶ // ╴╴┴──────┴────┴╶╶
// i is the instructions (m bytes) // i is the instructions (m bytes)
// Example: FuncMake ["x", "y"] [Get "x", Get "yz", NumAdd] // Example: FuncMake ["x", "y"] [Get "x", Get "yz", NumAdd]
// [0d] [02 ..] [03 ..] [78 00 79 7a 00] [16 78 00 16 79 7a 00 01] // [XX] [02 ..] [03 ..] [78 00 79 7a 00] [16 78 00 16 79 7a 00 01]
// └────┼───────┼───────┼────────────────┼─╼ enum // └────┼───────┼───────┼────────────────┼─╼ enum
// └───────┼───────┼────────────────┼─╼ number of arguments // └───────┼───────┼────────────────┼─╼ number of arguments
// └───────┼────────────────┼─╼ number of instructions // └───────┼────────────────┼─╼ number of instructions