Skip to content

Commit

Permalink
fix: Inline functions that are re-exports
Browse files Browse the repository at this point in the history
  • Loading branch information
Marwes committed Aug 11, 2020
1 parent 51e266e commit bcf8783
Show file tree
Hide file tree
Showing 12 changed files with 748 additions and 170 deletions.
1 change: 0 additions & 1 deletion Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

166 changes: 166 additions & 0 deletions tests/inline.rs
Original file line number Diff line number Diff line change
Expand Up @@ -33,3 +33,169 @@ async fn inline_cross_module() {
"#;
check_expr_eq(core_expr.value.expr(), expected_str);
}

#[test]
fn inline_with_record_pattern_in_module() {
let _ = env_logger::try_init();

let thread = make_vm();
thread.get_database_mut().set_implicit_prelude(false);

thread
.load_script(
"test",
r#"
let f x = x
let m1 = {
f,
}
let m2 =
let { f } = m1
let num = {
(+) = \l -> l,
}
{
f,
num,
}
let { num } = m2
num.(+) 3
"#,
)
.unwrap_or_else(|err| panic!("{}", err));

let db = thread.get_database();
let core_expr = db
.core_expr("test".into())
.unwrap_or_else(|err| panic!("{}", err));
let expected_str = r#"
3
"#;
check_expr_eq(core_expr.value.expr(), expected_str);
}

#[test]
fn inline_across_two_modules() {
let _ = env_logger::try_init();

let thread = make_vm();
thread.get_database_mut().set_implicit_prelude(false);

thread
.load_script(
"test",
r#"
let { (+) } = import! tests.optimize.inline_through_module
let { ? } = import! tests.optimize.inline_through_module2
1 + 2
"#,
)
.unwrap_or_else(|err| panic!("{}", err));

let db = thread.get_database();
let core_expr = db
.core_expr("test".into())
.unwrap_or_else(|err| panic!("{}", err));
let expected_str = r#"
3
"#;
check_expr_eq(core_expr.value.expr(), expected_str);
}

#[test]
fn prune_prelude() {
let _ = env_logger::try_init();

let thread = make_vm();
thread.get_database_mut().set_implicit_prelude(false);

thread
.load_script(
"test",
r#"
let { (+) } = import! std.prelude
let { ? } = import! std.int
in 1 + 2
"#,
)
.unwrap_or_else(|err| panic!("{}", err));

let db = thread.get_database();
let core_expr = db
.core_expr("test".into())
.unwrap_or_else(|err| panic!("{}", err));
let expected_str = r#"
3
"#;
check_expr_eq(core_expr.value.expr(), expected_str);
}

#[test]
fn prune_factorial() {
let _ = env_logger::try_init();

let thread = make_vm();
thread.get_database_mut().set_implicit_prelude(false);

thread
.load_script(
"test",
r#"
let { (-), (*), (<) } = import! std.prelude
let { ? } = import! std.int
let factorial n =
if n < 2
then 1
else n * factorial (n - 1)
factorial
"#,
)
.unwrap_or_else(|err| panic!("{}", err));

let db = thread.get_database();
let core_expr = db
.core_expr("test".into())
.unwrap_or_else(|err| panic!("{}", err));
let expected_str = r#"
rec let factorial n =
match (#Int<) n 2 with
| True -> 1
| False -> (#Int*) n (factorial ( (#Int-) n 1))
end
in
factorial
"#;
check_expr_eq(core_expr.value.expr(), expected_str);
}

#[test]
fn inline_num() {
let _ = env_logger::try_init();

let thread = make_vm();
thread.get_database_mut().set_implicit_prelude(false);

thread
.load_script(
"test",
r#"
let mod = import! tests.optimize.inline_num
let no_inline x = if x #Int== 0 then no_inline x else x
mod.(+) (no_inline 1) 2
"#,
)
.unwrap_or_else(|err| panic!("{}", err));

let db = thread.get_database();
let core_expr = db
.core_expr("test".into())
.unwrap_or_else(|err| panic!("{}", err));
let expected_str = r#"
3
"#;
check_expr_eq(core_expr.value.expr(), expected_str);
}
12 changes: 12 additions & 0 deletions tests/optimize/inline_num.glu
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
let additive =
let semigroup = {
append = \x y -> x #Int+ y
}

{ semigroup }


{
(+) = additive.semigroup.append,
additive,
}
9 changes: 9 additions & 0 deletions tests/optimize/inline_through_module.glu
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
//@NO-IMPLICIT-PRELUDE
//! Definitions which gets implicit re-export in every file.

let { Num, (+), (-), (*), (/) } = import! tests.optimize.inline_through_module2

{
Num,
(+), (-), (*), (/),
}
39 changes: 39 additions & 0 deletions tests/optimize/inline_through_module2.glu
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
//@NO-IMPLICIT-PRELUDE

#[implicit]
type Num a = {
/// The addition operator
(+) : a -> a -> a,
/// The subtraction operator
(-) : a -> a -> a,
/// The multiplication operator
(*) : a -> a -> a,
/// The division operator
(/) : a -> a -> a,
}

let num : Num Int = {
(+) = \l r -> l #Int+ r,
(-) = \l r -> l #Int- r,
(*) = \l r -> l #Int* r,
(/) = \l r -> l #Int/ r,
}


#[infix(left, 6)]
let (+) ?num : [Num a] -> a -> a -> a = num.(+)
#[infix(left, 6)]
let (-) ?num : [Num a] -> a -> a -> a = num.(-)
#[infix(left, 7)]
let (*) ?num : [Num a] -> a -> a -> a = num.(*)
#[infix(left, 7)]
let (/) ?num : [Num a] -> a -> a -> a = num.(/)

{
Num,

(+), (-), (*), (/),

num,
}

2 changes: 1 addition & 1 deletion vm/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -61,7 +61,7 @@ pretty_assertions = "0.6"

# HACK Trick crates.io into letting letting this be published with a dependency on gluon
# (which requires gluon_vm to be published)
gluon = { path = "..", version = ">=0.9" }
# gluon = { path = "..", version = ">=0.9" }

lalrpop-util = "0.19"
regex = "1"
Expand Down
2 changes: 1 addition & 1 deletion vm/src/core/grammar.lalrpop
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ Comma<Rule>: Vec<Rule> =

Identifier: Symbol = {
<r"@?[A-Za-z_][A-Za-z0-9_]*"> => symbols.symbol(SymbolData::<&Name>::from(<>)),
<r"\(#?[A-Za-z_]+[+\-*/]\)"> => symbols.simple_symbol(&<>[1..<>.len() - 1]),
<r"\(#?[A-Za-z_]+[+\-*/<]\)"> => symbols.simple_symbol(&<>[1..<>.len() - 1]),
<r"\([&\|=*><+]+\)"> => symbols.simple_symbol(&<>[1..<>.len() - 1]),
};

Expand Down
Loading

0 comments on commit bcf8783

Please sign in to comment.