Prepare optimizer

pull/4/head
azur 2022-12-20 21:21:21 +07:00
parent 6ebe1bc7ae
commit cfca9828f6
9 changed files with 48 additions and 13 deletions

1
Cargo.lock generated
View File

@ -76,6 +76,7 @@ name = "entry"
version = "0.1.0"
dependencies = [
"compiler",
"lower",
"parser",
"vm",
]

View File

@ -157,9 +157,9 @@ impl Compiler {
}
}
pub fn compile_program(&mut self, stmts: Vec<(Stmt, Span)>) -> Vec<Instr> {
pub fn compile_program(&mut self, stmts: Vec<Stmt>) -> Vec<Instr> {
let mut instrs = vec![];
for (stmt, _) in stmts {
for stmt in stmts {
instrs.extend(self.compile_stmt(stmt));
}
instrs

View File

@ -5,6 +5,7 @@ edition = "2021"
[dependencies]
parser = { path = "../parser" }
lower = { path = "../lower" }
compiler = { path = "../compiler" }
vm = { path = "../vm" }

View File

@ -1,4 +1,5 @@
use compiler::Compiler;
use lower::Lower;
use parser::{lex, parse, report};
use vm::exec::Executor;
@ -11,8 +12,10 @@ fn main() {
let (ast, parse_errors) = parse(tokens, src.len());
if let Some(ast) = ast {
let mut lower = Lower::new();
let last = lower.opt_stmts(ast.iter().map(|(s, _)| s.clone()).collect());
let mut compiler = Compiler::new();
let instrs = compiler.compile_program(ast);
let instrs = compiler.compile_program(last);
// instrs.iter().for_each(|i| println!("{:?}", i));
let mut executor = Executor::new(instrs);
match executor.run() {

View File

@ -8,6 +8,5 @@ end
fun double x = x * 2
fun main = do
let add = \x y -> x + y in
print(add(double(17), succ(34)))
x |> \a -> println(a)
end

View File

@ -1,12 +1,15 @@
// This is just proof of concept on what the language
// might look like in the future
import http from "http"
-- Define a custom type to represent a user
// Define a custom type to represent a user
type User =
id: number,
name: string,
end
-- Define a function to handle incoming HTTP requests
// Define a function to handle incoming HTTP requests
fun handle_request
req: http.IncomingMessage,
res: http.ServerResponse,

View File

@ -1,6 +1,8 @@
#![allow(clippy::new_without_default)]
use parser::*;
type SExpr = (Expr, std::ops::Range<usize>);
pub struct Lower {}
impl Lower {
@ -8,13 +10,39 @@ impl Lower {
Self {}
}
fn fold_pipe(&self, e: Expr) -> Vec<Expr> {
if let Expr::Binary((BinaryOp::Pipe, _), left, right) = e {
vec![Expr::Call(right, vec![*left])]
} else {
unreachable!()
pub fn opt_stmts(&self, ss: Vec<Stmt>) -> Vec<Stmt> {
ss.into_iter()
.flat_map(|s| self.opt_stmt(s.clone()).unwrap_or_else(|| vec![s]))
.collect()
}
pub fn opt_stmt(&self, s: Stmt) -> Option<Vec<Stmt>> {
match s {
// Stmt::Fun(name, args, body) => Some(vec![Stmt::Fun(
// name,
// args,
// self.opt_expr(body.0).unwrap_or_else(|| vec![body.0]),
// )]),
_ => None,
}
}
pub fn opt_exprs(&self, es: Vec<Expr>) -> Vec<Expr> {
es.into_iter()
.flat_map(|e| self.opt_expr(e.clone()).unwrap_or_else(|| vec![e]))
.collect()
}
pub fn opt_expr(&self, e: Expr) -> Option<Vec<Expr>> {
match e {
Expr::Binary((BinaryOp::Pipe, _), left, right) => Some(self.fold_pipe(*left, *right)),
_ => None,
}
}
fn fold_pipe(&self, left: SExpr, right: SExpr) -> Vec<Expr> {
vec![Expr::Call(Box::new(right), vec![left])]
}
}
#[cfg(test)]
@ -35,7 +63,7 @@ mod test {
let ex = ex.unwrap();
let l = Lower::new();
let ex = l.fold_pipe(ex.0);
let ex = l.opt_expr(ex.0).unwrap();
println!("{:?}", ex);
}
}