From dfc24c5444d9bcf32d48d4ff4b8e9c25afd1bb7d Mon Sep 17 00:00:00 2001 From: azur Date: Fri, 16 Dec 2022 20:31:35 +0700 Subject: [PATCH] callable lambda --- compiler/src/lib.rs | 19 ++++++++++++++----- entry/Cargo.toml | 6 +++++- entry/src/main.rs | 5 +---- examples/a.sial | 5 ++++- examples/sim.sial | 17 +---------------- parser/src/lib.rs | 14 ++++++++++---- vm/src/model.rs | 4 ++-- 7 files changed, 37 insertions(+), 33 deletions(-) diff --git a/compiler/src/lib.rs b/compiler/src/lib.rs index cba8dbd..8af7aa4 100644 --- a/compiler/src/lib.rs +++ b/compiler/src/lib.rs @@ -1,6 +1,7 @@ #![allow(clippy::new_without_default)] +#![allow(clippy::only_used_in_recursion)] use parser::{Expr, Literal, Span, Stmt}; -use vm::model::{Instr, Value}; +use vm::model::Instr; pub struct Compiler {} @@ -11,7 +12,10 @@ impl Compiler { pub fn compile_expr(&mut self, expr: Expr) -> Vec { match expr { - Expr::Error => unreachable!(), + Expr::Error => { + println!("{:?}", expr); + unreachable!() + } Expr::Literal(x) => match x { Literal::Num(x) => vec![Instr::NumPush(x)], Literal::Bool(x) => vec![Instr::BoolPush(x)], @@ -63,16 +67,21 @@ impl Compiler { for x in xs { instrs.extend(self.compile_expr(x.0)); } - if let Expr::Sym(fname) = &f.0 { - match fname.as_str() { + match &f.0 { + Expr::Sym(fname) => match fname.as_str() { "print" => instrs.push(Instr::Print), "println" => instrs.push(Instr::PrintLn), _ => { instrs.extend(self.compile_expr(f.0)); instrs.push(Instr::FuncApply); } + }, + Expr::Lambda(_, _) => { + instrs.extend(self.compile_expr(f.0)); + instrs.push(Instr::FuncApply); } - }; + _ => todo!(), + } instrs } Expr::Let(binds, body) => { diff --git a/entry/Cargo.toml b/entry/Cargo.toml index 1f39170..1aeac1e 100644 --- a/entry/Cargo.toml +++ b/entry/Cargo.toml @@ -6,4 +6,8 @@ edition = "2021" [dependencies] parser = { path = "../parser" } compiler = { path = "../compiler" } -vm = { path = "../vm" } \ No newline at end of file +vm = { path = "../vm" } + +[[bin]] +name = "hmc" +path = "src/main.rs" \ No newline at end of file diff --git a/entry/src/main.rs b/entry/src/main.rs index 064295b..147db60 100644 --- a/entry/src/main.rs +++ b/entry/src/main.rs @@ -15,10 +15,7 @@ fn main() { let instrs = compiler.compile_program(ast); // instrs.iter().for_each(|i| println!("{:?}", i)); let mut executor = Executor::new(instrs); - match executor.run_with(|exec| { - // println!("{:?}", exec.stack); - Ok(()) - }) { + match executor.run() { Ok(_) => {} Err(e) => println!("Runtime error: {:?}", e), } diff --git a/examples/a.sial b/examples/a.sial index 48564bc..1f643d4 100644 --- a/examples/a.sial +++ b/examples/a.sial @@ -18,4 +18,7 @@ end fun main = do let add = \x y -> x + y in print(add(34, succ(34))) -end \ No newline at end of file +end + +// succ(34) |> \x -> add (34, x) +// (\x -> add(34, x))(succ(34)) \ No newline at end of file diff --git a/examples/sim.sial b/examples/sim.sial index fcf785b..c71fd03 100644 --- a/examples/sim.sial +++ b/examples/sim.sial @@ -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 - let succ = \x -> x + 1, - n = 34, - in - println(n + succ(n)) - - print("Hello ") - println("World!") - - println(foo(1)) - println(fac(5)) + println((\x -> x + 1)(9)) end \ No newline at end of file diff --git a/parser/src/lib.rs b/parser/src/lib.rs index f69128c..fa64b5c 100644 --- a/parser/src/lib.rs +++ b/parser/src/lib.rs @@ -1,4 +1,5 @@ #![feature(trait_alias)] +#![allow(clippy::type_complexity)] use ariadne::{Color, Fmt, Label, Report, ReportKind, Source}; use chumsky::{error, prelude::*, Stream}; @@ -323,6 +324,12 @@ pub fn expr_parser() -> impl P> { }) .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) .ignore_then(symbol_parser().repeated()) .then_ignore(just(Token::Arrow)) @@ -369,6 +376,7 @@ pub fn expr_parser() -> impl P> { let atom = lit .or(ident) .or(vec) + .or(paren_expr) .or(lam) .or(let_in) .or(let_def) @@ -481,7 +489,7 @@ pub fn expr_parser() -> impl P> { }) .boxed(); - let pipe = logical + logical .clone() .then( just(Token::Pipe) @@ -494,9 +502,7 @@ pub fn expr_parser() -> impl P> { let s = lhs.1.start()..rhs.1.end(); (Expr::Binary(op, Box::new(lhs), Box::new(rhs)), s) }) - .boxed(); - - pipe + .boxed() }) } diff --git a/vm/src/model.rs b/vm/src/model.rs index a367a9f..bc730ef 100644 --- a/vm/src/model.rs +++ b/vm/src/model.rs @@ -123,7 +123,7 @@ pub enum Instr { // where x is the enum (1 byte) // s is the string (n bytes) // 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 // └────────────────────────────────────────┼─╼ string // └─╼ null delimiter @@ -153,7 +153,7 @@ pub enum Instr { // ╴╴┴──────┴────┴╶╶ // i is the instructions (m bytes) // 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 // └───────┼───────┼────────────────┼─╼ number of arguments // └───────┼────────────────┼─╼ number of instructions