Skip to content

Commit

Permalink
port js fix for nested string prefixes
Browse files Browse the repository at this point in the history
Should not generate 'prefix = "w".wobble.whatever._0.else' but rather
'prefix = "w"'
  • Loading branch information
PgBiel committed Jan 20, 2025
1 parent aa1a109 commit b32765a
Show file tree
Hide file tree
Showing 6 changed files with 228 additions and 3 deletions.
16 changes: 13 additions & 3 deletions compiler-core/src/nix/pattern.rs
Original file line number Diff line number Diff line change
Expand Up @@ -553,9 +553,19 @@ impl<'module_ctx, 'expression_gen, 'a> Generator<'module_ctx, 'expression_gen, '
// let prefix = "wibble";
// ^^^^^^^^^^^^^^^^^^^^^ we're adding this assignment inside the if clause
// the case branch gets translated into.
let left_side_string =
expression::string(left_side_string, self.expression_generator.tracker);
self.push_assignment(left_side_string, left);
//
// We also want to push this assignment without using push_assignment, since we
// do _not_ want to access the current path on the static string!
let var = self.next_local_var(left);
self.assignments.push(Assignment {
subject: expression::string(
left_side_string,
self.expression_generator.tracker,
),
path: SubjectPath::new(),
name: left,
var,
});
}
Ok(())
}
Expand Down
17 changes: 17 additions & 0 deletions compiler-core/src/nix/tests/assignments.rs
Original file line number Diff line number Diff line change
Expand Up @@ -180,6 +180,23 @@ pub fn main(x) {
);
}

// https://github.com/gleam-lang/gleam/issues/3894
#[test]
fn let_assert_nested_string_prefix() {
assert_nix!(
r#"
type Wibble {
Wibble(wibble: String)
}
pub fn main() {
let assert Wibble(wibble: "w" as prefix <> rest) = Wibble("wibble")
prefix <> rest
}
"#
);
}

// Inspired by https://github.com/gleam-lang/gleam/issues/2931
#[test]
fn keyword_assignment() {
Expand Down
45 changes: 45 additions & 0 deletions compiler-core/src/nix/tests/case.rs
Original file line number Diff line number Diff line change
Expand Up @@ -287,3 +287,48 @@ pub fn main() {
"#
)
}

// https://github.com/gleam-lang/gleam/issues/3894
#[test]
fn nested_string_prefix_assignment() {
assert_nix!(
r#"
type Wibble {
Wibble(wobble: String)
}
pub fn main() {
let tmp = Wibble(wobble: "wibble")
case tmp {
Wibble(wobble: "w" as wibble <> rest) -> wibble <> rest
_ -> panic
}
}
"#
)
}

#[test]
fn deeply_nested_string_prefix_assignment() {
assert_nix!(
r#"
type Wibble {
Wibble(Wobble)
}
type Wobble {
Wobble(wabble: Wabble)
}
type Wabble {
Wabble(tuple: #(Int, String))
}
pub fn main() {
let tmp = Wibble(Wobble(Wabble(#(42, "wibble"))))
case tmp {
Wibble(Wobble(Wabble(#(_int, "w" as wibble <> rest)))) -> wibble <> rest
_ -> panic
}
}
"#
)
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
---
source: compiler-core/src/nix/tests/assignments.rs
expression: "\ntype Wibble {\n Wibble(wibble: String)\n}\n\npub fn main() {\n let assert Wibble(wibble: \"w\" as prefix <> rest) = Wibble(\"wibble\")\n prefix <> rest\n}\n"
---
----- SOURCE CODE

type Wibble {
Wibble(wibble: String)
}

pub fn main() {
let assert Wibble(wibble: "w" as prefix <> rest) = Wibble("wibble")
prefix <> rest
}


----- COMPILED NIX
let
inherit (builtins.import ./../gleam.nix) strHasPrefix makeError;

Wibble = wibble: { __gleamTag = "Wibble"; inherit wibble; };

main =
{ }:
let
_pat' = (Wibble "wibble");
_assert' =
if _pat'.__gleamTag != "Wibble" || !(strHasPrefix "w" _pat'.wibble) then
builtins.throw
(makeError
"let_assert"
"my/mod"
7
"main"
"Pattern match failed, no pattern matched the value."
{ value = _pat'; })
else null;
rest = builtins.seq _assert' (builtins.substring 1 (-1) _pat'.wibble);
prefix = builtins.seq _assert' "w";
in
builtins.seq _assert' (prefix + rest);
in
{ inherit main; }
Original file line number Diff line number Diff line change
@@ -0,0 +1,63 @@
---
source: compiler-core/src/nix/tests/case.rs
expression: "\ntype Wibble {\n Wibble(Wobble)\n}\ntype Wobble {\n Wobble(wabble: Wabble)\n}\ntype Wabble {\n Wabble(tuple: #(Int, String))\n}\n\npub fn main() {\n let tmp = Wibble(Wobble(Wabble(#(42, \"wibble\"))))\n case tmp {\n Wibble(Wobble(Wabble(#(_int, \"w\" as wibble <> rest)))) -> wibble <> rest\n _ -> panic\n }\n}\n"
---
----- SOURCE CODE

type Wibble {
Wibble(Wobble)
}
type Wobble {
Wobble(wabble: Wabble)
}
type Wabble {
Wabble(tuple: #(Int, String))
}

pub fn main() {
let tmp = Wibble(Wobble(Wabble(#(42, "wibble"))))
case tmp {
Wibble(Wobble(Wabble(#(_int, "w" as wibble <> rest)))) -> wibble <> rest
_ -> panic
}
}


----- COMPILED NIX
let
inherit (builtins.import ./../gleam.nix) strHasPrefix makeError;

Wibble = x0: { __gleamTag = "Wibble"; _0 = x0; };

Wobble = wabble: { __gleamTag = "Wobble"; inherit wabble; };

Wabble = tuple: { __gleamTag = "Wabble"; inherit tuple; };

main =
{ }:
let
tmp = Wibble (Wobble (Wabble [ 42 "wibble" ]));
in
if
tmp.__gleamTag == "Wibble" &&
tmp._0.__gleamTag == "Wobble" &&
tmp._0.wabble.__gleamTag == "Wabble" &&
strHasPrefix "w" (builtins.elemAt tmp._0.wabble.tuple 1)
then
let
rest =
(builtins.substring 1 (-1) (builtins.elemAt tmp._0.wabble.tuple 1));
wibble = "w";
in
wibble + rest
else
builtins.throw
(makeError
"panic"
"my/mod"
16
"main"
"`panic` expression evaluated."
{ });
in
{ inherit main; }
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
---
source: compiler-core/src/nix/tests/case.rs
expression: "\ntype Wibble {\n Wibble(wobble: String)\n}\n\npub fn main() {\n let tmp = Wibble(wobble: \"wibble\")\n case tmp {\n Wibble(wobble: \"w\" as wibble <> rest) -> wibble <> rest\n _ -> panic\n }\n}\n"
---
----- SOURCE CODE

type Wibble {
Wibble(wobble: String)
}

pub fn main() {
let tmp = Wibble(wobble: "wibble")
case tmp {
Wibble(wobble: "w" as wibble <> rest) -> wibble <> rest
_ -> panic
}
}


----- COMPILED NIX
let
inherit (builtins.import ./../gleam.nix) strHasPrefix makeError;

Wibble = wobble: { __gleamTag = "Wibble"; inherit wobble; };

main =
{ }:
let
tmp = Wibble "wibble";
in
if tmp.__gleamTag == "Wibble" && strHasPrefix "w" tmp.wobble then
let
rest = (builtins.substring 1 (-1) tmp.wobble);
wibble = "w";
in
wibble + rest
else
builtins.throw
(makeError
"panic"
"my/mod"
10
"main"
"`panic` expression evaluated."
{ });
in
{ inherit main; }

0 comments on commit b32765a

Please sign in to comment.