Fork of daniellemaywood.uk/gleam — Wasm codegen work
Something went wrong. Try again.
9.6 kB · 626 lines
Rust
at wasm
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627// SPDX-License-Identifier: Apache-2.0// SPDX-FileCopyrightText: 2021 The Gleam contributors
use crate::{assert_js, assert_ts_def};
#[test]fn exported_functions() { assert_js!( r#"pub fn add(x, y) { x + y}"#, );}
#[test]fn calling_functions() { assert_js!( r#"pub fn twice(f: fn(t) -> t, x: t) -> t { f(f(x))}pub fn add_one(x: Int) -> Int { x + 1}pub fn add_two(x: Int) -> Int { twice(add_one, x)}
pub fn take_two(x: Int) -> Int { twice(fn(y) {y - 1}, x)}"#, );}
#[test]fn function_formatting() { assert_js!( r#"pub fn add(the_first_variable_that_should_be_added, the_second_variable_that_should_be_added) { the_first_variable_that_should_be_added + the_second_variable_that_should_be_added}"#, );}
#[test]fn function_formatting1() { assert_js!( r#"pub fn this_function_really_does_have_a_ludicrously_unfeasibly_long_name_for_a_function(x, y) {x + y}"#, );}
#[test]fn function_formatting2() { assert_js!( r#"pub fn add(x, y) {x + y}
pub fn long() { add(1, add(1, add(1, add(1, add(1, add(1, add(1, add(1, add(1, add(1, add(1, add(1, add(1, add(1, add(1, 1)))))))))))))))}"#, );}
#[test]fn function_formatting3() { assert_js!( r#"pub fn math(x, y) { fn() { x + y x - y 2 * x }}"#, );}
#[test]fn function_formatting_typescript() { assert_ts_def!( r#"pub fn add(the_first_variable_that_should_be_added, the_second_variable_that_should_be_added) { the_first_variable_that_should_be_added + the_second_variable_that_should_be_added}"#, );}
#[test]fn function_formatting_typescript1() { assert_ts_def!( r#"pub fn this_function_really_does_have_a_ludicrously_unfeasibly_long_name_for_a_function(x, y) {x + y}"#, );}
#[test]fn tail_call() { assert_js!( r#"pub fn count(xs, n) { case xs { [] -> n [_, ..xs] -> count(xs, n + 1) }}"#, );}
#[test]fn tail_call_doesnt_clobber_tail_position_tracking() { assert_js!( r#"pub fn loop(indentation) { case indentation > 0 { True -> loop(indentation - 1) False -> Nil }}"#, );}
#[test]fn pipe_last() { assert_js!( r#"fn id(x) { x }pub fn main() { 1 |> id}"#, );}
#[test]fn calling_fn_literal() { assert_js!( r#"pub fn main() { fn(x) { x }(1)}"#, );}
// Don't mistake calling a function with the same name as the current function// as tail recursion#[test]fn shadowing_current() { assert_js!( r#"pub fn main() { let main = fn() { 0 } main()}"#, );}
#[test]fn recursion_with_discards() { assert_js!( r#"pub fn main(f, _) { f() main(f, 1)}"#, );}
#[test]fn no_recur_in_anon_fn() { assert_js!( r#"pub fn main() { fn() { main() } 1}"#, );}
#[test]fn case_in_call() { assert_js!( r#"pub fn main(f, x) { f(case x { 1 -> 2 _ -> 0 })}"#, );}
#[test]fn reserved_word_fn() { assert_js!( r#"pub fn class() { Nil}"#, );}
#[test]fn reserved_word_imported() { assert_js!( ("for", "pub fn class() { 1 }"), r#"import for.{class}
pub fn export() { class()}"#, );}
#[test]fn reserved_word_imported_alias() { assert_js!( ("for", "pub fn class() { 1 }"), r#"import for.{class as while} as function
pub fn export() { let delete = function.class while()}"#, );}
#[test]fn reserved_word_const() { assert_js!( r#"const in = 1
pub fn export() { in}"#, );}
// https://github.com/gleam-lang/gleam/issues/1208#[test]fn reserved_word_argument() { assert_js!( r#"pub fn main(with) { with}"#, );}
// https://github.com/gleam-lang/gleam/issues/1186#[test]fn multiple_discard() { assert_js!( r#"pub fn main(_, _, _) { 1}"#, );}
#[test]fn keyword_in_recursive_function() { assert_js!( r#"pub fn main(with: Int) -> Nil { main(with - 1)}"#, );}
#[test]fn reserved_word_in_function_arguments() { assert_js!( r#"pub fn main(arguments, eval) { #(arguments, eval)}"#, );}
#[test]fn let_last() { assert_js!( r#"pub fn main() { let x = 1}"#, );}
#[test]fn assert_last() { assert_js!( r#"pub fn main() { let assert x = 1}"#, );}
#[test]fn fn_return_fn_typescript() { assert_ts_def!( r#"pub fn main(f: fn(Int) -> Int) { let func = fn(x, y) { f(x) + f(y) } func}"#, );}
// https://github.com/gleam-lang/gleam/issues/1637#[test]fn variable_rewriting_in_anon_fn_with_matching_parameter() { assert_js!( r#"pub fn bad() { fn(state) { let state = state state }}"#, );}
// https://github.com/gleam-lang/gleam/issues/1637#[test]fn variable_rewriting_in_anon_fn_with_matching_parameter_in_case() { assert_js!( r#"pub fn bad() { fn(state) { let state = case Nil { _ -> state } state }}"#, );}
// https://github.com/gleam-lang/gleam/issues/1508#[test]fn pipe_variable_rebinding() { assert_js!( "pub fn main() { let version = 1 |> version() version}
pub fn version(n) { Ok(1)}" )}
#[test]fn pipe_shadow_import() { assert_js!( ("wibble", "pub fn println(x: String) { }"), r#" import wibble.{println} pub fn main() { let println = "oh dear" |> println println }"# );}
#[test]fn module_const_fn() { assert_js!( r#"pub fn int_identity(i: Int) -> Int { i }pub const int_identity_alias: fn(Int) -> Int = int_identitypub fn use_int_identity_alias() { int_identity_alias(42) }
pub const compound: #(fn(Int) -> Int, fn(Int) -> Int) = #(int_identity, int_identity_alias)pub fn use_compound() { compound.0(compound.1(42)) }"# );}
#[test]fn module_const_fn1() { assert_ts_def!( r#"pub fn int_identity(i: Int) -> Int { i }pub const int_identity_alias: fn(Int) -> Int = int_identitypub const compound: #(fn(Int) -> Int, fn(Int) -> Int) = #(int_identity, int_identity_alias)"# )}
// https://github.com/gleam-lang/gleam/issues/2399#[test]fn bad_comma() { assert_js!( r#"fn function_with_a_long_name_that_is_intended_to_sit_right_on_the_limit() { Nil}
fn identity(x) { x}
pub fn main() { function_with_a_long_name_that_is_intended_to_sit_right_on_the_limit() |> identity}"# )}
// https://github.com/gleam-lang/gleam/issues/2518#[test]fn function_literals_get_properly_wrapped_1() { assert_js!( r#"pub fn main() { fn(n) { n + 1 }(10)}"# );}
// https://github.com/gleam-lang/gleam/issues/2518#[test]fn function_literals_get_properly_wrapped_2() { assert_js!( r#"pub fn main() { { fn(n) { n + 1 } }(10)}"# );}
// https://github.com/gleam-lang/gleam/issues/2518#[test]fn function_literals_get_properly_wrapped_3() { assert_js!( r#"pub fn main() { { let a = fn(n) { n + 1 } }(10)}"# );}
#[test]fn labelled_argument_ordering() { // https://github.com/gleam-lang/gleam/issues/3671 assert_js!( "type A { A }type B { B }type C { C }type D { D }
fn wibble(a a: A, b b: B, c c: C, d d: D) { Nil}
pub fn main() { wibble(A, C, D, b: B) wibble(A, C, D, b: B) wibble(B, C, D, a: A) wibble(B, C, a: A, d: D) wibble(B, C, d: D, a: A) wibble(B, D, a: A, c: C) wibble(B, D, c: C, a: A) wibble(C, D, b: B, a: A)}" );}
// During the implementation of https://github.com/gleam-lang/gleam/pull/4337,// a bug was found where this code would compile incorrectly.#[test]fn two_pipes_in_a_row() { assert_js!( "pub type Function(a) { Function(fn() -> a)}
pub fn main() { [fn() { 1 } |> Function, fn() { 2 } |> Function]}" );}
// https://github.com/gleam-lang/gleam/issues/4472#[test]fn pipe_into_block() { assert_js!( "fn side_effects(x) { x }
pub fn main() { 1 |> side_effects |> { side_effects(2) side_effects }}" );}
// https://github.com/gleam-lang/gleam/issues/4472#[test]fn pipe_with_block_in_the_middle() { assert_js!( "fn side_effects(x) { x }
pub fn main() { 1 |> side_effects |> { side_effects(2) side_effects } |> side_effects}" );}
// https://github.com/gleam-lang/gleam/issues/4533#[test]fn immediately_invoked_function_expressions_include_statement_level() { assert_js!( "fn identity(x) { x }
pub type Wibble { Wibble(a: Int, b: Int)}
pub fn main() { let w = Wibble(1, 2) identity(Wibble(..w |> identity, b: 4)) |> identity}" );}
#[test]fn public_function_gets_jsdoc() { assert_js!( "/// Hello! This is the documentation of the `main`/// function.///pub fn main() { 1 }" );}
#[test]fn internal_function_gets_ignored_jsdoc() { assert_js!( "/// Hello! This is the documentation of the `main`/// function, which is internal!///@internalpub fn main() { 1 }" );}
#[test]fn star_slash_in_jsdoc() { assert_js!( "/// *////pub fn main() { 1 }" );}
// https://github.com/gleam-lang/gleam/issues/5488#[test]fn pipeline_has_correct_semicolons() { assert_js!( "pub fn main() { 1 |> echo |> fn(x) { { x + 1 } * 2 } { 1 + 2 } * 3}" );}
#[test]fn pipeline_with_final_has_correct_semicolon() { assert_js!( "pub fn main() { 1 |> echo { 1 + 2 } * 3}" );}