mirror of
https://github.com/azur1s/bobbylisp.git
synced 2024-10-16 02:37:40 -05:00
callable lambda
This commit is contained in:
parent
b5856a35e7
commit
dfc24c5444
|
@ -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) => {
|
||||||
|
|
|
@ -6,4 +6,8 @@ edition = "2021"
|
||||||
[dependencies]
|
[dependencies]
|
||||||
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"
|
|
@ -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),
|
||||||
}
|
}
|
||||||
|
|
|
@ -18,4 +18,7 @@ end
|
||||||
fun main = do
|
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))
|
|
@ -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
|
|
@ -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
|
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -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
|
||||||
|
|
Loading…
Reference in a new issue