Skip to content

Commit 600e1ab

Browse files
committed
use trait object to reduce compile time. fix #78
1 parent 05d5671 commit 600e1ab

File tree

7 files changed

+73
-78
lines changed

7 files changed

+73
-78
lines changed

src/ast/case_simplify.rs

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -785,14 +785,14 @@ impl Transform<Type> for WildcardToVariable {
785785
}
786786

787787
use crate::pass::Pass;
788-
impl<'a> Pass<TypedCoreContext, TypeError<'a>> for CaseSimplify {
788+
impl Pass<TypedCoreContext, TypeError> for CaseSimplify {
789789
type Target = TypedCoreContext;
790790

791-
fn trans<'b>(
792-
&'b mut self,
791+
fn trans(
792+
&mut self,
793793
Context(symbol_table, ast): TypedCoreContext,
794794
_: &Config,
795-
) -> Result<'a, Self::Target> {
795+
) -> Result<Self::Target> {
796796
let mut pass = self.generate_pass(symbol_table);
797797
let ast = pass.wildcard_to_variable(ast);
798798
let ast = pass.transform_ast(ast);

src/ast/mod.rs

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -418,21 +418,21 @@ impl SymbolTable {
418418
}
419419

420420
#[derive(Debug)]
421-
pub enum TypeError<'a> {
421+
pub enum TypeError {
422422
MisMatch { expected: Type, actual: Type },
423423
CannotInfer,
424424
FreeVar,
425425
NotFunction(ast::Expr<Type>),
426-
ParseError(nom::Err<(&'a str, nom::error::ErrorKind)>),
426+
ParseError(nom::Err<(String, nom::error::ErrorKind)>),
427427
}
428428

429-
impl<'a> fmt::Display for TypeError<'a> {
429+
impl fmt::Display for TypeError {
430430
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
431431
fmt::Debug::fmt(self, f)
432432
}
433433
}
434434

435-
impl<'a> Error for TypeError<'a> {
435+
impl Error for TypeError {
436436
fn description(&self) -> &str {
437437
use self::TypeError::*;
438438
match self {
@@ -445,8 +445,8 @@ impl<'a> Error for TypeError<'a> {
445445
}
446446
}
447447

448-
impl<'a> From<nom::Err<(&'a str, nom::error::ErrorKind)>> for TypeError<'a> {
449-
fn from(e: nom::Err<(&'a str, nom::error::ErrorKind)>) -> Self {
448+
impl From<nom::Err<(String, nom::error::ErrorKind)>> for TypeError {
449+
fn from(e: nom::Err<(String, nom::error::ErrorKind)>) -> Self {
450450
// fn conv<'b>(e: nom::Err<&'b [u8]>) -> nom::Err<&'b str> {
451451
// use std::str::from_utf8;
452452
// use nom::Err::*;
@@ -464,4 +464,4 @@ impl<'a> From<nom::Err<(&'a str, nom::error::ErrorKind)>> for TypeError<'a> {
464464
}
465465
}
466466

467-
pub type Result<'a, T> = ::std::result::Result<T, TypeError<'a>>;
467+
pub type Result<T> = ::std::result::Result<T, TypeError>;

src/ast/typing.rs

Lines changed: 24 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -57,11 +57,7 @@ fn conv_ty(pool: &UnificationPool<Typing>, ty: Typing) -> Type {
5757
}
5858
}
5959

60-
fn try_unify<'b, 'r>(
61-
pool: &'b mut UnificationPool<Typing>,
62-
t1: Typing,
63-
t2: Typing,
64-
) -> Result<'r, Typing> {
60+
fn try_unify<'b>(pool: &'b mut UnificationPool<Typing>, t1: Typing, t2: Typing) -> Result<Typing> {
6561
use Typing::*;
6662
match (t1, t2) {
6763
(t1, t2) if t1 == t2 => Ok(t1),
@@ -90,7 +86,7 @@ fn try_unify<'b, 'r>(
9086
.into_iter()
9187
.zip(tu2)
9288
.map(|(t1, t2)| pool.try_unify_with(t1, t2, try_unify))
93-
.collect::<Result<'_, Vec<_>>>()?;
89+
.collect::<Result<Vec<_>>>()?;
9490
Ok(Tuple(tu))
9591
}
9692
}
@@ -180,12 +176,12 @@ impl TypePool {
180176
node_id
181177
}
182178

183-
fn try_unify_with<'r>(
179+
fn try_unify_with(
184180
&mut self,
185181
id1: NodeId,
186182
id2: NodeId,
187-
try_unify: impl FnOnce(&mut UnificationPool<Typing>, Typing, Typing) -> Result<'r, Typing>,
188-
) -> Result<'r, NodeId> {
183+
try_unify: impl FnOnce(&mut UnificationPool<Typing>, Typing, Typing) -> Result<Typing>,
184+
) -> Result<NodeId> {
189185
self.pool.try_unify_with(id1, id2, try_unify)
190186
}
191187
}
@@ -234,7 +230,7 @@ impl TyEnv {
234230
}
235231
}
236232

237-
pub fn infer<'a, 'b>(&'a mut self, ast: &mut ast::Core<NodeId>) -> Result<'b, ()> {
233+
pub fn infer(&mut self, ast: &mut ast::Core<NodeId>) -> Result<()> {
238234
self.infer_ast(ast)?;
239235
Ok(())
240236
}
@@ -281,14 +277,14 @@ impl TyEnv {
281277
}
282278

283279
impl TyEnv {
284-
fn infer_ast<'b, 'r>(&'b mut self, ast: &Core<NodeId>) -> Result<'r, ()> {
280+
fn infer_ast(&mut self, ast: &Core<NodeId>) -> Result<()> {
285281
for decl in ast.0.iter() {
286282
self.infer_statement(&decl)?;
287283
}
288284
Ok(())
289285
}
290286

291-
fn infer_statement<'b, 'r>(&'b mut self, decl: &CoreDeclaration<NodeId>) -> Result<'r, ()> {
287+
fn infer_statement(&mut self, decl: &CoreDeclaration<NodeId>) -> Result<()> {
292288
use Declaration::*;
293289
match decl {
294290
Datatype { .. } => Ok(()),
@@ -313,7 +309,7 @@ impl TyEnv {
313309
}
314310
}
315311

316-
fn infer_expr<'b, 'r>(&'b mut self, expr: &CoreExpr<NodeId>) -> Result<'r, ()> {
312+
fn infer_expr(&mut self, expr: &CoreExpr<NodeId>) -> Result<()> {
317313
use crate::ast::ExprKind::*;
318314
let int = self.pool.ty_int();
319315
let real = self.pool.ty_real();
@@ -438,12 +434,12 @@ impl TyEnv {
438434
}
439435
}
440436

441-
fn infer_constructor<'b, 'r>(
442-
&'b mut self,
437+
fn infer_constructor(
438+
&mut self,
443439
sym: &Symbol,
444440
arg: &Option<Box<CoreExpr<NodeId>>>,
445441
given: NodeId,
446-
) -> Result<'r, ()> {
442+
) -> Result<()> {
447443
match self.get(&sym) {
448444
Some(ty) => {
449445
self.unify(ty, given)?;
@@ -460,14 +456,14 @@ impl TyEnv {
460456
}
461457
}
462458

463-
fn infer_symbol<'b, 'r>(&'b mut self, sym: &Symbol, given: NodeId) -> Result<'r, ()> {
459+
fn infer_symbol(&mut self, sym: &Symbol, given: NodeId) -> Result<()> {
464460
match self.get(&sym) {
465461
Some(t) => self.unify(t, given),
466462
None => Err(TypeError::FreeVar),
467463
}
468464
}
469465

470-
fn infer_literal<'b, 'r>(&'b mut self, lit: &Literal, given: NodeId) -> Result<'r, ()> {
466+
fn infer_literal(&mut self, lit: &Literal, given: NodeId) -> Result<()> {
471467
use crate::prim::Literal::*;
472468
let ty = match lit {
473469
Int(_) => self.pool.ty_int(),
@@ -478,19 +474,19 @@ impl TyEnv {
478474
Ok(())
479475
}
480476

481-
fn infer_constant<'b, 'r>(&'b mut self, _: &i64, given: NodeId) -> Result<'r, ()> {
477+
fn infer_constant(&mut self, _: &i64, given: NodeId) -> Result<()> {
482478
let ty = self.pool.ty_int();
483479
self.unify(given, ty)?;
484480
Ok(())
485481
}
486482

487-
fn infer_char<'b, 'r>(&'b mut self, _: &u32, given: NodeId) -> Result<'r, ()> {
483+
fn infer_char(&mut self, _: &u32, given: NodeId) -> Result<()> {
488484
let ty = self.pool.ty_char();
489485
self.unify(given, ty)?;
490486
Ok(())
491487
}
492488

493-
fn infer_pat<'b, 'r>(&'b mut self, pat: &Pattern<NodeId>) -> Result<'r, ()> {
489+
fn infer_pat(&mut self, pat: &Pattern<NodeId>) -> Result<()> {
494490
use self::PatternKind::*;
495491
let ty = &pat.ty();
496492
match &pat.inner {
@@ -541,11 +537,7 @@ impl TyEnv {
541537
Ok(())
542538
}
543539

544-
fn infer_tuple<'b, 'r>(
545-
&'b mut self,
546-
tuple: &Vec<CoreExpr<NodeId>>,
547-
given: NodeId,
548-
) -> Result<'r, ()> {
540+
fn infer_tuple(&mut self, tuple: &Vec<CoreExpr<NodeId>>, given: NodeId) -> Result<()> {
549541
use std::iter;
550542
let tys = iter::repeat_with(|| self.pool.tyvar())
551543
.take(tuple.len())
@@ -560,25 +552,25 @@ impl TyEnv {
560552
Ok(())
561553
}
562554

563-
fn unify<'b, 'r>(&'b mut self, id1: NodeId, id2: NodeId) -> Result<'r, ()> {
555+
fn unify(&mut self, id1: NodeId, id2: NodeId) -> Result<()> {
564556
self.pool.try_unify_with(id1, id2, try_unify).map(|_| ())
565557
}
566558

567-
fn give<'b, 'r>(&'b mut self, id1: NodeId, ty: Typing) -> Result<'r, ()> {
559+
fn give(&mut self, id1: NodeId, ty: Typing) -> Result<()> {
568560
let id2 = self.pool.node_new(ty);
569561
self.unify(id1, id2)
570562
}
571563
}
572564

573565
use crate::pass::Pass;
574-
impl<'a> Pass<UntypedCoreContext, TypeError<'a>> for Typer {
566+
impl Pass<UntypedCoreContext, TypeError> for Typer {
575567
type Target = TypedCoreContext;
576568

577-
fn trans<'b>(
578-
&'b mut self,
569+
fn trans(
570+
&mut self,
579571
Context(symbol_table, ast): UntypedCoreContext,
580572
_: &Config,
581-
) -> Result<'a, Self::Target> {
573+
) -> Result<Self::Target> {
582574
let mut pass = self.generate_pass(symbol_table);
583575
let mut typing_ast = pass.pool.typing_ast(ast);
584576
pass.infer(&mut typing_ast)?;

src/lib.rs

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -14,19 +14,18 @@ mod unification_pool;
1414

1515
pub use crate::ast::TypeError;
1616
pub use crate::config::Config;
17-
pub use crate::parser::parse;
1817
pub use crate::pass::{Chain, Pass};
1918
#[cfg(target_arch = "wasm32")]
2019
use wasm_bindgen::prelude::*;
2120

22-
pub fn compile_str<'a>(input: &'a str, config: &Config) -> Result<Vec<u8>, TypeError<'a>> {
23-
use crate::pass::{ConvError, PrintablePass};
21+
pub fn compile_string(input: String, config: &Config) -> Result<Vec<u8>, TypeError> {
22+
use crate::pass::PrintablePass;
2423
use wasm::Dump;
2524

2625
let id = id::Id::new();
2726

2827
let mut passes = compile_pass![
29-
parse: ConvError::new(parse),
28+
parse: parser::Parser::new(),
3029
desugar: ast::Desugar::new(id.clone()),
3130
rename: ast::Rename::new(id.clone()),
3231
var_to_constructor: ast::VarToConstructor::new(id.clone()),

src/main.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@ use std::collections::HashSet;
33
use std::fs;
44
use std::io::{self, prelude::*};
55
use std::path::Path;
6-
use webml::{compile_str, Config};
6+
use webml::{compile_string, Config};
77

88
fn read_and_append_to_string(path: impl AsRef<Path>, buf: &mut String) -> io::Result<usize> {
99
let file = fs::File::open(path)?;
@@ -47,6 +47,6 @@ fn main() {
4747
let prelude = include_str!("../ml_src/prelude.sml").to_string();
4848
let mut input = prelude;
4949
read_and_append_to_string(filename, &mut input).expect("failed to load file");
50-
let code = compile_str(&input, &config).expect("failed to compile file");
50+
let code = compile_string(input, &config).expect("failed to compile file");
5151
fs::write("out.wasm", &code).unwrap()
5252
}

src/parser.rs

Lines changed: 15 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
1-
use crate::ast::*;
1+
use crate::pass::Pass;
22
use crate::prim::*;
3+
use crate::{ast::*, Config};
34
use nom::branch::alt;
45
use nom::bytes::complete::tag;
56
use nom::character::complete::{alphanumeric1, digit1, multispace1};
@@ -18,12 +19,12 @@ static KEYWORDS: &[&str] = &[
1819

1920
static RESERVED: &[&str] = &["|", "=", "#"];
2021

21-
struct Parser {
22+
pub struct Parser {
2223
infixes: RefCell<Vec<BTreeMap<u8, Vec<Symbol>>>>,
2324
}
2425

2526
impl Parser {
26-
fn new() -> Self {
27+
pub fn new() -> Self {
2728
Self {
2829
infixes: RefCell::new(vec![BTreeMap::new()]),
2930
}
@@ -1094,10 +1095,15 @@ fn test_expr_infix_and_app2() {
10941095
)
10951096
}
10961097

1097-
pub fn parse(
1098-
input: &str,
1099-
) -> ::std::result::Result<UntypedAst, nom::Err<(&str, nom::error::ErrorKind)>> {
1100-
let parser = Parser::new();
1101-
let (_, iresult) = all_consuming(parser.top())(input)?;
1102-
Ok(iresult)
1098+
impl Pass<String, TypeError> for Parser {
1099+
type Target = UntypedAst;
1100+
1101+
fn trans(&mut self, input: String, _: &Config) -> std::result::Result<Self::Target, TypeError> {
1102+
match all_consuming(self.top())(&input) {
1103+
Ok((_, iresult)) => Ok(iresult),
1104+
Err(nom::Err::Incomplete(e)) => Err(nom::Err::Incomplete(e).into()),
1105+
Err(nom::Err::Error((s, kind))) => Err(nom::Err::Error((s.into(), kind)).into()),
1106+
Err(nom::Err::Failure((s, kind))) => Err(nom::Err::Error((s.into(), kind)).into()),
1107+
}
1108+
}
11031109
}

src/pass.rs

Lines changed: 18 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -88,27 +88,22 @@ where
8888
}
8989
}
9090

91-
pub struct Chain<F, FO, S, SO> {
92-
pub fst: F,
93-
pub snd: S,
94-
phantom: PhantomData<(FO, SO)>,
91+
pub struct Chain<In, Mid, Out, E> {
92+
pub fst: Box<dyn Pass<In, E, Target = Mid>>,
93+
pub snd: Box<dyn Pass<Mid, E, Target = Out>>,
9594
}
9695

97-
impl<F, FO, S, SO> Chain<F, FO, S, SO> {
98-
pub fn new(fst: F, snd: S) -> Self {
99-
Chain {
100-
fst,
101-
snd,
102-
phantom: PhantomData,
103-
}
104-
}
105-
}
106-
107-
impl<F, E, S, T, In, Out> Pass<In, E> for Chain<F, T, S, Out>
108-
where
109-
F: Pass<In, E, Target = T>,
110-
S: Pass<T, E, Target = Out>,
111-
{
96+
// impl<F, FO, S, SO> Chain<F, FO, S, SO> {
97+
// pub fn new(fst: F, snd: S) -> Self {
98+
// Chain {
99+
// fst,
100+
// snd,
101+
// phantom: PhantomData,
102+
// }
103+
// }
104+
// }
105+
106+
impl<In, Mid, Out, E> Pass<In, E> for Chain<In, Mid, Out, E> {
112107
type Target = Out;
113108

114109
fn trans(&mut self, i: In, config: &Config) -> Result<Self::Target, E> {
@@ -155,7 +150,10 @@ macro_rules! compile_pass {
155150
compile_pass!($($labels: $passes),*)
156151
};
157152
($label: ident : $pass: expr, $($labels: ident : $passes: expr),*) => {
158-
Chain::new(PrintablePass($pass, stringify!($label)), compile_pass!($($labels: $passes),*))
153+
Chain{
154+
fst:Box::new(PrintablePass($pass, stringify!($label))),
155+
snd: Box::new(compile_pass!($($labels: $passes),*)),
156+
}
159157
};
160158
($label: ident : $pass: expr) => {
161159
PrintablePass($pass, stringify!($label))

0 commit comments

Comments
 (0)