diff --git a/CHANGELOG.md b/CHANGELOG.md index 88fee573..232beff7 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -86,6 +86,7 @@ _unreleased_ - Add `input(prompt) string` function _[JS]_ - Add `exists_dir(path)` that checks if path exists and is a directory _[JS]_ - Fix js error with `mkdir()` and `mkdir_all()` if path already exists +- strings: JS implementation of the string builder ### General Fixes - `parser`: Fix precedence of PrefixExpr @@ -223,7 +224,7 @@ _16 July 2023_ - Add `user_os()` function - Fix `cp()` for directories - builtin: New `toI32()` string method -- Add `strings` package containing a simple string builder _(C backend only)_ +- _[C]_ Add `strings` package containing a simple string builder ### C Backend (experimental) - Properly implement backend selection diff --git a/lib/bait/gen/js/fun.bt b/lib/bait/gen/js/fun.bt index db4a183d..00759822 100644 --- a/lib/bait/gen/js/fun.bt +++ b/lib/bait/gen/js/fun.bt @@ -85,8 +85,9 @@ fun (mut g Gen) call_expr(node ast.CallExpr) { } sym := g.table.get_sym(node.left_type) - if sym.kind == .array and ['push', 'push_many', 'push_many_with_len'].contains(node.name) { - g.gen_array_method(node.name, node, sym) + final_sym := g.table.get_final_sym(node.left_type) + if final_sym.kind == .array and ['push', 'push_many', 'push_many_with_len'].contains(node.name) { + g.gen_array_method(node.name, node, final_sym) return } diff --git a/lib/builtin/string.js.bt b/lib/builtin/string.js.bt index 8e2e0c9c..f3a83e45 100644 --- a/lib/builtin/string.js.bt +++ b/lib/builtin/string.js.bt @@ -3,7 +3,7 @@ package builtin struct string { -pub: +pub mut: str #JS.String length i32 } diff --git a/lib/strings/builder.js.bt b/lib/strings/builder.js.bt new file mode 100644 index 00000000..e4acb6ad --- /dev/null +++ b/lib/strings/builder.js.bt @@ -0,0 +1,31 @@ +// SPDX-FileCopyrightText: 2023-present Lukas Neubert +// SPDX-License-Identifier: MPL-2.0 +package strings + +type Builder := []u8 + +pub fun new_builder(initial_size i32) Builder { + return []u8 as Builder +} + +pub fun (mut b Builder) clear() { + #JS.'b.data = [] + b.length = 0' +} + +pub fun (mut b Builder) write(data []u8) { + b.push_many(data) +} + +pub fun (mut b Builder) write_str(s string) { + for c in s { + b.push(c) + } +} + +pub fun (b Builder) str() string { + return string{ + str = #JS.'String.fromCharCode(...b.data)' as #JS.String + length = b.length + } +} diff --git a/lib/strings/builder_test.bt b/lib/strings/builder_test.bt new file mode 100644 index 00000000..da376890 --- /dev/null +++ b/lib/strings/builder_test.bt @@ -0,0 +1,19 @@ +// SPDX-FileCopyrightText: 2023-present Lukas Neubert +// SPDX-License-Identifier: MPL-2.0 +import strings + +fun test_builder() { + mut b := strings.new_builder(50) + + b.write([104 as u8, 101 as u8]) // FIXME second u8 cast should not be needed + assert b.str() == 'he' + + b.write_str('llo') + assert b.str() == 'hello' + + b.clear() + assert b.str().length == 0 + + b.write_str('foo') + assert b.str() == 'foo' +}