Fork of daniellemaywood.uk/gleam — Wasm codegen work
2

Configure Feed

Select the types of activity you want to include in your feed.

some fixed in echo's displayed dicts and bit arrays

+533 -53
+2
compiler-cli/src/integration.rs
··· 1 + #[cfg(test)] 2 + mod echo;
+185
compiler-cli/src/integration/echo.rs
··· 1 + use std::{env, io::Read, process::Stdio}; 2 + 3 + use camino::{Utf8Path, Utf8PathBuf}; 4 + use gleam_core::{ 5 + build::{Runtime, Target}, 6 + io::Command, 7 + paths::ProjectPaths, 8 + }; 9 + 10 + use crate::{ 11 + fs, 12 + run::{self, Which}, 13 + }; 14 + 15 + fn run_and_produce_pretty_snapshot( 16 + target: Option<Target>, 17 + runtime: Option<Runtime>, 18 + project_directory: Utf8PathBuf, 19 + ) -> String { 20 + let paths = fs::get_project_root(project_directory) 21 + .map(ProjectPaths::new) 22 + .expect("project paths"); 23 + 24 + let output = run_and_capture_output(&paths, "main", target, runtime); 25 + let main_module_content = 26 + fs::read(paths.src_directory().join("main.gleam")).expect("read main module"); 27 + 28 + format!( 29 + "--- main.gleam ---------------------- 30 + {main_module_content} 31 + 32 + --- gleam run output ---------------- 33 + {output} 34 + " 35 + ) 36 + } 37 + 38 + fn run_and_capture_output( 39 + paths: &ProjectPaths, 40 + main_module: &str, 41 + target: Option<Target>, 42 + runtime: Option<Runtime>, 43 + ) -> String { 44 + println!("{}", paths.build_directory()); 45 + let _ = fs::delete_directory(&paths.build_directory()).expect("delete build directory content"); 46 + 47 + let Command { 48 + program, 49 + args, 50 + env, 51 + cwd: _, 52 + stdio: _, 53 + } = run::setup( 54 + &paths, 55 + vec![], 56 + target, 57 + runtime, 58 + Some(main_module.into()), 59 + Which::Src, 60 + true, 61 + ) 62 + .expect("run setup"); 63 + 64 + let mut process = std::process::Command::new(&program) 65 + .args(args) 66 + .stdin(Stdio::null()) 67 + .stdout(Stdio::null()) 68 + .stderr(Stdio::piped()) 69 + .envs(env.iter().map(|pair| (&pair.0, &pair.1))) 70 + .current_dir(paths.root()) 71 + .spawn() 72 + .expect("spawn run process"); 73 + 74 + let mut stderr = process.stderr.take().expect("take stderr"); 75 + let mut output = String::new(); 76 + let _ = stderr.read_to_string(&mut output).expect("read stderr"); 77 + let _ = process.wait().expect("run with no errors"); 78 + output 79 + } 80 + 81 + macro_rules! assert_echo { 82 + ($project_name: expr) => { 83 + let snapshot_name = snapshot_name(None, None, $project_name); 84 + insta::allow_duplicates! { 85 + assert_echo!(&snapshot_name, Some(Target::Erlang), None, $project_name); 86 + assert_echo!(&snapshot_name, Some(Target::JavaScript), Some(Runtime::Bun), $project_name); 87 + assert_echo!(&snapshot_name, Some(Target::JavaScript), Some(Runtime::Deno), $project_name); 88 + assert_echo!(&snapshot_name, Some(Target::JavaScript), Some(Runtime::NodeJs), $project_name); 89 + } 90 + }; 91 + 92 + ($target: expr, $project_name: expr) => { 93 + let snapshot_name = snapshot_name(Some($target), None, $project_name); 94 + match $target { 95 + Target::JavaScript => insta::allow_duplicates! { 96 + assert_echo!(&snapshot_name, Some($target), Some(Runtime::Bun), $project_name); 97 + assert_echo!(&snapshot_name, Some($target), Some(Runtime::Deno), $project_name); 98 + assert_echo!(&snapshot_name, Some($target), Some(Runtime::NodeJs), $project_name); 99 + }, 100 + Target::Erlang => { 101 + assert_echo!(&snapshot_name, Some($target), None, $project_name); 102 + } 103 + } 104 + }; 105 + 106 + ($snapshot_name: expr, $target: expr, $runtime: expr, $project_name: expr) => { 107 + let path = fs::canonicalise(&Utf8Path::new("../test-output/cases").join($project_name)) 108 + .expect("canonicalise path"); 109 + let output = run_and_produce_pretty_snapshot($target, $runtime, path); 110 + insta::assert_snapshot!($snapshot_name.to_string(), output); 111 + }; 112 + } 113 + 114 + fn snapshot_name(target: Option<Target>, runtime: Option<Runtime>, suffix: &str) -> String { 115 + let prefix = match (target, runtime) { 116 + (None, None) => "".into(), 117 + (None, Some(runtime)) => format!("{runtime}-"), 118 + (Some(target), None) => format!("{target}-"), 119 + (Some(target), Some(runtime)) => format!("{target}-{runtime}-"), 120 + }; 121 + format!("{prefix}{suffix}") 122 + } 123 + 124 + #[test] 125 + fn echo_bitarray() { 126 + assert_echo!(Target::JavaScript, "echo_bitarray"); 127 + assert_echo!(Target::Erlang, "echo_bitarray"); 128 + } 129 + 130 + #[test] 131 + fn echo_bool() { 132 + assert_echo!("echo_bool"); 133 + } 134 + 135 + #[test] 136 + fn echo_custom_type() { 137 + assert_echo!(Target::Erlang, "echo_custom_type"); 138 + assert_echo!(Target::JavaScript, "echo_custom_type"); 139 + } 140 + 141 + #[test] 142 + fn echo_dict() { 143 + assert_echo!("echo_dict"); 144 + } 145 + 146 + #[test] 147 + fn echo_float() { 148 + assert_echo!(Target::Erlang, "echo_float"); 149 + assert_echo!(Target::JavaScript, "echo_float"); 150 + } 151 + 152 + #[test] 153 + fn echo_function() { 154 + assert_echo!("echo_function"); 155 + } 156 + 157 + #[test] 158 + fn echo_importing_module_named_inspect() { 159 + assert_echo!("echo_importing_module_named_inspect"); 160 + } 161 + 162 + #[test] 163 + fn echo_int() { 164 + assert_echo!("echo_int"); 165 + } 166 + 167 + #[test] 168 + fn echo_list() { 169 + assert_echo!("echo_list"); 170 + } 171 + 172 + #[test] 173 + fn echo_nil() { 174 + assert_echo!("echo_nil"); 175 + } 176 + 177 + #[test] 178 + fn echo_string() { 179 + assert_echo!("echo_string"); 180 + } 181 + 182 + #[test] 183 + fn echo_tuple() { 184 + assert_echo!("echo_tuple"); 185 + }
+16
compiler-cli/src/integration/snapshots/gleam__integration__echo__echo_bool.snap
··· 1 + --- 2 + source: compiler-cli/src/integration/echo.rs 3 + expression: output 4 + --- 5 + --- main.gleam ---------------------- 6 + pub fn main() { 7 + echo True 8 + echo False 9 + } 10 + 11 + 12 + --- gleam run output ---------------- 13 + src/main.gleam:2 14 + True 15 + src/main.gleam:3 16 + False
+18
compiler-cli/src/integration/snapshots/gleam__integration__echo__echo_dict.snap
··· 1 + --- 2 + source: compiler-cli/src/integration/echo.rs 3 + expression: output 4 + --- 5 + --- main.gleam ---------------------- 6 + import gleam/dict 7 + 8 + pub fn main() { 9 + echo dict.new() 10 + echo dict.from_list([#(1, "hello"), #(2, "world!")]) 11 + } 12 + 13 + 14 + --- gleam run output ---------------- 15 + src/main.gleam:4 16 + dict.from_list([]) 17 + src/main.gleam:5 18 + dict.from_list([#(1, "hello"), #(2, "world!")])
+20
compiler-cli/src/integration/snapshots/gleam__integration__echo__echo_function.snap
··· 1 + --- 2 + source: compiler-cli/src/integration/echo.rs 3 + expression: output 4 + --- 5 + --- main.gleam ---------------------- 6 + pub fn main() { 7 + echo fn(n) { n + 1 } 8 + echo private 9 + } 10 + 11 + fn private() { 12 + 1 13 + } 14 + 15 + 16 + --- gleam run output ---------------- 17 + src/main.gleam:2 18 + //fn(a) { ... } 19 + src/main.gleam:3 20 + //fn() { ... }
+15
compiler-cli/src/integration/snapshots/gleam__integration__echo__echo_importing_module_named_inspect.snap
··· 1 + --- 2 + source: compiler-cli/src/integration/echo.rs 3 + expression: output 4 + --- 5 + --- main.gleam ---------------------- 6 + import inspect 7 + 8 + pub fn main() { 9 + echo inspect.x 10 + } 11 + 12 + 13 + --- gleam run output ---------------- 14 + src/main.gleam:4 15 + Nil
+19
compiler-cli/src/integration/snapshots/gleam__integration__echo__echo_int.snap
··· 1 + --- 2 + source: compiler-cli/src/integration/echo.rs 3 + expression: output 4 + --- 5 + --- main.gleam ---------------------- 6 + pub fn main() { 7 + echo 1 8 + echo 2 9 + echo 100_000 10 + } 11 + 12 + 13 + --- gleam run output ---------------- 14 + src/main.gleam:2 15 + 1 16 + src/main.gleam:3 17 + 2 18 + src/main.gleam:4 19 + 100000
+16
compiler-cli/src/integration/snapshots/gleam__integration__echo__echo_list.snap
··· 1 + --- 2 + source: compiler-cli/src/integration/echo.rs 3 + expression: output 4 + --- 5 + --- main.gleam ---------------------- 6 + pub fn main() { 7 + echo [] 8 + echo [1, 2, 3] 9 + } 10 + 11 + 12 + --- gleam run output ---------------- 13 + src/main.gleam:2 14 + [] 15 + src/main.gleam:3 16 + [1, 2, 3]
+13
compiler-cli/src/integration/snapshots/gleam__integration__echo__echo_nil.snap
··· 1 + --- 2 + source: compiler-cli/src/integration/echo.rs 3 + expression: output 4 + --- 5 + --- main.gleam ---------------------- 6 + pub fn main() { 7 + echo Nil 8 + } 9 + 10 + 11 + --- gleam run output ---------------- 12 + src/main.gleam:2 13 + Nil
+20
compiler-cli/src/integration/snapshots/gleam__integration__echo__echo_string.snap
··· 1 + --- 2 + source: compiler-cli/src/integration/echo.rs 3 + expression: output 4 + --- 5 + --- main.gleam ---------------------- 6 + pub fn main() { 7 + echo "hello world" 8 + echo "multiline 9 + string" 10 + echo "string with\t\r\nescaped chars" 11 + } 12 + 13 + 14 + --- gleam run output ---------------- 15 + src/main.gleam:2 16 + "hello world" 17 + src/main.gleam:3 18 + "multiline\nstring" 19 + src/main.gleam:5 20 + "string with\t\r\nescaped chars"
+16
compiler-cli/src/integration/snapshots/gleam__integration__echo__echo_tuple.snap
··· 1 + --- 2 + source: compiler-cli/src/integration/echo.rs 3 + expression: output 4 + --- 5 + --- main.gleam ---------------------- 6 + pub fn main() { 7 + echo #() 8 + echo #(True, 1, "hello") 9 + } 10 + 11 + 12 + --- gleam run output ---------------- 13 + src/main.gleam:2 14 + #() 15 + src/main.gleam:3 16 + #(True, 1, "hello")
+19
compiler-cli/src/integration/snapshots/gleam__integration__echo__erlang-echo_bitarray.snap
··· 1 + --- 2 + source: compiler-cli/src/integration/echo.rs 3 + expression: output 4 + --- 5 + --- main.gleam ---------------------- 6 + pub fn main() { 7 + echo <<>> 8 + echo <<1, 2, 3>> 9 + echo <<1, 2, 3:2>> 10 + } 11 + 12 + 13 + --- gleam run output ---------------- 14 + src/main.gleam:2 15 + "" 16 + src/main.gleam:3 17 + "\u{0001}\u{0002}\u{0003}" 18 + src/main.gleam:4 19 + <<1, 2, 3:size(2)>>
+25
compiler-cli/src/integration/snapshots/gleam__integration__echo__erlang-echo_custom_type.snap
··· 1 + --- 2 + source: compiler-cli/src/integration/echo.rs 3 + expression: output 4 + --- 5 + --- main.gleam ---------------------- 6 + pub type Wibble { 7 + Wibble(a: Int, b: String) 8 + Wobble(a: List(Float)) 9 + Woo 10 + } 11 + 12 + pub fn main() { 13 + echo Wibble(1, "hello") 14 + echo Wobble([1.0, 1.1]) 15 + echo Woo 16 + } 17 + 18 + 19 + --- gleam run output ---------------- 20 + src/main.gleam:8 21 + Wibble(1, "hello") 22 + src/main.gleam:9 23 + Wobble([1.0, 1.1]) 24 + src/main.gleam:10 25 + Woo
+19
compiler-cli/src/integration/snapshots/gleam__integration__echo__erlang-echo_float.snap
··· 1 + --- 2 + source: compiler-cli/src/integration/echo.rs 3 + expression: output 4 + --- 5 + --- main.gleam ---------------------- 6 + pub fn main() { 7 + echo 1.0 8 + echo 2.1 9 + echo 11.11 10 + } 11 + 12 + 13 + --- gleam run output ---------------- 14 + src/main.gleam:2 15 + 1.0 16 + src/main.gleam:3 17 + 2.1 18 + src/main.gleam:4 19 + 11.11
+19
compiler-cli/src/integration/snapshots/gleam__integration__echo__javascript-echo_bitarray.snap
··· 1 + --- 2 + source: compiler-cli/src/integration/echo.rs 3 + expression: output 4 + --- 5 + --- main.gleam ---------------------- 6 + pub fn main() { 7 + echo <<>> 8 + echo <<1, 2, 3>> 9 + echo <<1, 2, 3:2>> 10 + } 11 + 12 + 13 + --- gleam run output ---------------- 14 + src/main.gleam:2 15 + <<>> 16 + src/main.gleam:3 17 + <<1, 2, 3>> 18 + src/main.gleam:4 19 + <<1, 2, 3:size(2)>>
+25
compiler-cli/src/integration/snapshots/gleam__integration__echo__javascript-echo_custom_type.snap
··· 1 + --- 2 + source: compiler-cli/src/integration/echo.rs 3 + expression: output 4 + --- 5 + --- main.gleam ---------------------- 6 + pub type Wibble { 7 + Wibble(a: Int, b: String) 8 + Wobble(a: List(Float)) 9 + Woo 10 + } 11 + 12 + pub fn main() { 13 + echo Wibble(1, "hello") 14 + echo Wobble([1.0, 1.1]) 15 + echo Woo 16 + } 17 + 18 + 19 + --- gleam run output ---------------- 20 + src/main.gleam:8 21 + Wibble(a: 1, b: "hello") 22 + src/main.gleam:9 23 + Wobble(a: [1, 1.1]) 24 + src/main.gleam:10 25 + Woo
+19
compiler-cli/src/integration/snapshots/gleam__integration__echo__javascript-echo_float.snap
··· 1 + --- 2 + source: compiler-cli/src/integration/echo.rs 3 + expression: output 4 + --- 5 + --- main.gleam ---------------------- 6 + pub fn main() { 7 + echo 1.0 8 + echo 2.1 9 + echo 11.11 10 + } 11 + 12 + 13 + --- gleam run output ---------------- 14 + src/main.gleam:2 15 + 1 16 + src/main.gleam:3 17 + 2.1 18 + src/main.gleam:4 19 + 11.11
+2
compiler-cli/src/main.rs
··· 67 67 mod fs; 68 68 mod hex; 69 69 mod http; 70 + #[cfg(test)] 71 + mod integration; 70 72 mod lsp; 71 73 mod new; 72 74 mod panic;
+3 -4
compiler-cli/src/run.rs
··· 30 30 which: Which, 31 31 no_print_progress: bool, 32 32 ) -> Result<(), Error> { 33 + // Don't exit on ctrl+c as it is used by child erlang shell 34 + ctrlc::set_handler(move || {}).expect("Error setting Ctrl-C handler"); 33 35 let command = setup( 34 36 paths, 35 37 arguments, ··· 43 45 std::process::exit(status); 44 46 } 45 47 46 - fn setup( 48 + pub(crate) fn setup( 47 49 paths: &ProjectPaths, 48 50 arguments: Vec<String>, 49 51 target: Option<Target>, ··· 122 124 123 125 // A module can not be run if it does not exist or does not have a public main function. 124 126 let main_function = get_or_suggest_main_function(built, &module, target)?; 125 - 126 - // Don't exit on ctrl+c as it is used by child erlang shell 127 - ctrlc::set_handler(move || {}).expect("Error setting Ctrl-C handler"); 128 127 129 128 telemetry.running(&format!("{module}.main")); 130 129
+3 -10
compiler-core/src/javascript.rs
··· 135 135 self.register_prelude_usage(&mut imports, "prepend", Some("listPrepend")); 136 136 }; 137 137 138 - if self.tracker.custom_type_used { 138 + if self.tracker.custom_type_used || self.tracker.echo_used { 139 139 self.register_prelude_usage(&mut imports, "CustomType", Some("$CustomType")); 140 140 }; 141 141 ··· 163 163 self.register_prelude_usage(&mut imports, "toBitArray", None); 164 164 } 165 165 166 - if self.tracker.bit_array_slice_used { 166 + if self.tracker.bit_array_slice_used || self.tracker.echo_used { 167 167 self.register_prelude_usage(&mut imports, "bitArraySlice", None); 168 168 } 169 169 ··· 171 171 self.register_prelude_usage(&mut imports, "bitArraySliceToFloat", None); 172 172 } 173 173 174 - if self.tracker.bit_array_slice_to_int_used { 174 + if self.tracker.bit_array_slice_to_int_used || self.tracker.echo_used { 175 175 self.register_prelude_usage(&mut imports, "bitArraySliceToInt", None); 176 176 } 177 177 ··· 207 207 self.register_prelude_usage(&mut imports, "BitArray", Some("$BitArray")); 208 208 self.register_prelude_usage(&mut imports, "List", Some("$List")); 209 209 self.register_prelude_usage(&mut imports, "UtfCodepoint", Some("$UtfCodepoint")); 210 - 211 - // If a custom type was used then this prelude usage will have 212 - // already been registered. So we have to add it only when no custom 213 - // type was used. 214 - if !self.tracker.custom_type_used { 215 - self.register_prelude_usage(&mut imports, "CustomType", Some("$CustomType")); 216 - } 217 210 docvec![line(), std::include_str!("../templates/echo.mjs"), line()] 218 211 } else { 219 212 nil()
+3 -1
compiler-core/src/javascript/tests/snapshots/gleam_core__javascript__tests__echo__echo_in_a_pipeline.snap
··· 17 17 import * as $stdlib$dict from "../../gleam_stdlib/dict.mjs"; 18 18 import { 19 19 toList, 20 + CustomType as $CustomType, 21 + bitArraySlice, 22 + bitArraySliceToInt, 20 23 BitArray as $BitArray, 21 24 List as $List, 22 25 UtfCodepoint as $UtfCodepoint, 23 - CustomType as $CustomType, 24 26 } from "../gleam.mjs"; 25 27 26 28 export function wibble(n) {
+3 -1
compiler-core/src/javascript/tests/snapshots/gleam_core__javascript__tests__echo__echo_with_a_block.snap
··· 15 15 ----- COMPILED JAVASCRIPT 16 16 import * as $stdlib$dict from "../../gleam_stdlib/dict.mjs"; 17 17 import { 18 + CustomType as $CustomType, 19 + bitArraySlice, 20 + bitArraySliceToInt, 18 21 BitArray as $BitArray, 19 22 List as $List, 20 23 UtfCodepoint as $UtfCodepoint, 21 - CustomType as $CustomType, 22 24 } from "../gleam.mjs"; 23 25 24 26 export function main() {
+3 -1
compiler-core/src/javascript/tests/snapshots/gleam_core__javascript__tests__echo__echo_with_a_case_expression.snap
··· 14 14 ----- COMPILED JAVASCRIPT 15 15 import * as $stdlib$dict from "../../gleam_stdlib/dict.mjs"; 16 16 import { 17 + CustomType as $CustomType, 18 + bitArraySlice, 19 + bitArraySliceToInt, 17 20 BitArray as $BitArray, 18 21 List as $List, 19 22 UtfCodepoint as $UtfCodepoint, 20 - CustomType as $CustomType, 21 23 } from "../gleam.mjs"; 22 24 23 25 export function main() {
+3 -1
compiler-core/src/javascript/tests/snapshots/gleam_core__javascript__tests__echo__echo_with_a_function_call.snap
··· 14 14 ----- COMPILED JAVASCRIPT 15 15 import * as $stdlib$dict from "../../gleam_stdlib/dict.mjs"; 16 16 import { 17 + CustomType as $CustomType, 18 + bitArraySlice, 19 + bitArraySliceToInt, 17 20 BitArray as $BitArray, 18 21 List as $List, 19 22 UtfCodepoint as $UtfCodepoint, 20 - CustomType as $CustomType, 21 23 } from "../gleam.mjs"; 22 24 23 25 function wibble(n, m) {
+3 -1
compiler-core/src/javascript/tests/snapshots/gleam_core__javascript__tests__echo__echo_with_a_panic.snap
··· 12 12 ----- COMPILED JAVASCRIPT 13 13 import * as $stdlib$dict from "../../gleam_stdlib/dict.mjs"; 14 14 import { 15 + CustomType as $CustomType, 15 16 makeError, 17 + bitArraySlice, 18 + bitArraySliceToInt, 16 19 BitArray as $BitArray, 17 20 List as $List, 18 21 UtfCodepoint as $UtfCodepoint, 19 - CustomType as $CustomType, 20 22 } from "../gleam.mjs"; 21 23 22 24 export function main() {
+3 -1
compiler-core/src/javascript/tests/snapshots/gleam_core__javascript__tests__echo__echo_with_a_simple_expression.snap
··· 12 12 ----- COMPILED JAVASCRIPT 13 13 import * as $stdlib$dict from "../../gleam_stdlib/dict.mjs"; 14 14 import { 15 + CustomType as $CustomType, 16 + bitArraySlice, 17 + bitArraySliceToInt, 15 18 BitArray as $BitArray, 16 19 List as $List, 17 20 UtfCodepoint as $UtfCodepoint, 18 - CustomType as $CustomType, 19 21 } from "../gleam.mjs"; 20 22 21 23 export function main() {
+3 -1
compiler-core/src/javascript/tests/snapshots/gleam_core__javascript__tests__echo__module_named_inspect.snap
··· 15 15 import * as $stdlib$dict from "../../gleam_stdlib/dict.mjs"; 16 16 import * as $inspect from "../../other/other/inspect.mjs"; 17 17 import { 18 + CustomType as $CustomType, 19 + bitArraySlice, 20 + bitArraySliceToInt, 18 21 BitArray as $BitArray, 19 22 List as $List, 20 23 UtfCodepoint as $UtfCodepoint, 21 - CustomType as $CustomType, 22 24 } from "../gleam.mjs"; 23 25 24 26 export function main() {
+3 -1
compiler-core/src/javascript/tests/snapshots/gleam_core__javascript__tests__echo__multiple_echos_in_a_pipeline.snap
··· 20 20 import * as $stdlib$dict from "../../gleam_stdlib/dict.mjs"; 21 21 import { 22 22 toList, 23 + CustomType as $CustomType, 24 + bitArraySlice, 25 + bitArraySliceToInt, 23 26 BitArray as $BitArray, 24 27 List as $List, 25 28 UtfCodepoint as $UtfCodepoint, 26 - CustomType as $CustomType, 27 29 } from "../gleam.mjs"; 28 30 29 31 export function wibble(n) {
+3 -1
compiler-core/src/javascript/tests/snapshots/gleam_core__javascript__tests__echo__multiple_echos_inside_expression.snap
··· 13 13 ----- COMPILED JAVASCRIPT 14 14 import * as $stdlib$dict from "../../gleam_stdlib/dict.mjs"; 15 15 import { 16 + CustomType as $CustomType, 17 + bitArraySlice, 18 + bitArraySliceToInt, 16 19 BitArray as $BitArray, 17 20 List as $List, 18 21 UtfCodepoint as $UtfCodepoint, 19 - CustomType as $CustomType, 20 22 } from "../gleam.mjs"; 21 23 22 24 export function main() {
+30 -1
compiler-core/templates/echo.mjs
··· 45 45 function echo$inspectDict(map) { 46 46 let body = "dict.from_list(["; 47 47 let first = true; 48 + 49 + let key_value_pairs = []; 48 50 map.forEach((value, key) => { 51 + key_value_pairs.push([key, value]); 52 + }); 53 + key_value_pairs.sort(); 54 + key_value_pairs.forEach(([key, value]) => { 49 55 if (!first) body = body + ", "; 50 56 body = body + "#(" + echo$inspect(key) + ", " + echo$inspect(value) + ")"; 51 57 first = false; ··· 85 91 if (Array.isArray(v)) return `#(${v.map(echo$inspect).join(", ")})`; 86 92 if (v instanceof $List) return `[${v.toArray().map(echo$inspect).join(", ")}]`; 87 93 if (v instanceof $UtfCodepoint) return `//utfcodepoint(${String.fromCodePoint(v.value)})`; 88 - if (v instanceof $BitArray) return `<<${Array.from(v.buffer).join(", ")}>>`; 94 + if (v instanceof $BitArray) return echo$inspectBitArray(v); 89 95 if (v instanceof $CustomType) return echo$inspectCustomType(v); 90 96 if (echo$isDict(v)) return echo$inspectDict(v); 91 97 if (v instanceof Set) return `//js(Set(${[...v].map(echo$inspect).join(", ")}))`; ··· 97 103 return `//fn(${args.join(", ")}) { ... }`; 98 104 } 99 105 return echo$inspectObject(v); 106 + } 107 + 108 + function echo$inspectBitArray(bitArray) { 109 + // We take all the aligned bytes of the bit array starting from `bitOffset` 110 + // up to the end of the section containing all the aligned bytes. 111 + let endOfAlignedBytes = bitArray.bitOffset + 8 * Math.trunc(bitArray.bitSize / 8); 112 + let alignedBytes = bitArraySlice(bitArray, bitArray.bitOffset, endOfAlignedBytes); 113 + 114 + // Now we need to get the remaining unaligned bits at the end of the bit array. 115 + // They will start after `endOfAlignedBytes` and end at `bitArray.bitSize` 116 + let remainingUnalignedBits = bitArray.bitSize % 8; 117 + if (remainingUnalignedBits > 0) { 118 + let remainingBits = bitArraySliceToInt(bitArray, endOfAlignedBytes, bitArray.bitSize, false, false); 119 + let alignedBytesArray = Array.from(alignedBytes.rawBuffer); 120 + let suffix = `${remainingBits}:size(${remainingUnalignedBits})`; 121 + if (alignedBytesArray.length === 0) { 122 + return `<<${suffix}>>`; 123 + } else { 124 + return `<<${Array.from(alignedBytes.rawBuffer).join(", ")}, ${suffix}>>`; 125 + } 126 + } else { 127 + return `<<${Array.from(alignedBytes.rawBuffer).join(", ")}>>`; 128 + } 100 129 } 101 130 102 131 function echo$isDict(value) {
+2
test-output/cases/.gitignore
··· 1 + **/build 2 + **/manifest.toml
-11
test-output/cases/echo_bitarray/src/main.gleam
··· 1 1 pub fn main() { 2 2 echo <<>> 3 3 echo <<1, 2, 3>> 4 - target_specific() 5 - } 6 - 7 - @target(erlang) 8 - pub fn target_specific() { 9 - // On erlang we also check non byte aligned bit arrays 10 4 echo <<1, 2, 3:2>> 11 5 } 12 - 13 - @target(javascript) 14 - pub fn target_specific() { 15 - Nil 16 - }
-18
test-output/cases/echo_tuple/src/main.gleam
··· 1 1 pub fn main() { 2 2 echo #() 3 3 echo #(True, 1, "hello") 4 - target_specific() 5 - } 6 - 7 - @target(erlang) 8 - pub type Wibble { 9 - Wibble 10 - } 11 - 12 - @target(erlang) 13 - pub fn target_specific() { 14 - // On erlang a tuple with an enum variant as the first item is printed as a 15 - // type with fields. 16 - echo #(Wibble, 1, "hello") 17 - } 18 - 19 - @target(javascript) 20 - pub fn target_specific() { 21 - Nil 22 4 }