Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

str.pad_startとstr.pad_endを追加 #653

Merged
merged 3 commits into from
May 12, 2024
Merged
Show file tree
Hide file tree
Changes from 2 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
# 未リリース分
- `Date:year`系の関数に0を渡すと現在時刻になる問題を修正
- シンタックスエラーなどの位置情報を修正
- `str.pad_start`,`str.pad_end`を追加

# 0.18.0
- `Core:abort`でプログラムを緊急停止できるように
Expand Down
10 changes: 10 additions & 0 deletions docs/primitive-props.md
Original file line number Diff line number Diff line change
Expand Up @@ -78,6 +78,16 @@ _fromIndex_が指定されていれば、その位置から検索を開始しま
_fromIndex_が負値の時は末尾からの位置(文字列の長さ+_fromIndex_)が使用されます。
該当が無ければ-1を返します。

### @(_v_: str).pad_start(_width_: num, _pad_?: str): str
文字列の長さがが _width_ になるように、先頭を _pad_ の繰り返しで埋めた新しい文字列を返します。\
_pad_ を省略した場合、空白`' '`で埋められます。\
_pad_ が長すぎる場合、_pad_ の末尾が切り捨てられます。

### @(_v_: str).pad_end(_width_: num, _pad_?: str): str
文字列の長さがが _width_ になるように、末尾を _pad_ の繰り返しで埋めた新しい文字列を返します。\
_pad_ を省略した場合、空白`' '`で埋められます。\
_pad_ が長すぎる場合、_pad_ の末尾が切り捨てられます。

### @(_v_: str).trim(): str
文字列の前後の空白を取り除いたものを返します。

Expand Down
14 changes: 14 additions & 0 deletions src/interpreter/primitive-props.ts
Original file line number Diff line number Diff line change
Expand Up @@ -86,7 +86,7 @@
split: (target: VStr): VFn => FN_NATIVE(async ([splitter], _opts) => {
if (splitter) assertString(splitter);
if (splitter) {
return ARR(target.value.split(splitter ? splitter.value : '').map(s => STR(s)));

Check warning on line 89 in src/interpreter/primitive-props.ts

View workflow job for this annotation

GitHub Actions / lint

Unnecessary conditional, value is always truthy
} else {
return ARR(toArray(target.value).map(s => STR(s)));
}
Expand Down Expand Up @@ -119,6 +119,20 @@
const res = target.value.codePointAt(i.value) ?? target.value.charCodeAt(i.value);
return Number.isNaN(res) ? NULL : NUM(res);
}),

pad_start: (target: VStr): VFn => FN_NATIVE(([width, pad], _) => {
assertNumber(width);
const s = (pad) ? (assertString(pad), pad.value) : ' ';

return STR(target.value.padStart(width.value, s));
}),

pad_end: (target: VStr): VFn => FN_NATIVE(([width, pad], _) => {
assertNumber(width);
const s = (pad) ? (assertString(pad), pad.value) : ' ';

return STR(target.value.padEnd(width.value, s));
}),
},

arr: {
Expand Down
32 changes: 32 additions & 0 deletions test/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2626,6 +2626,38 @@ describe('primitive props', () => {
ARR([NUM(97), NUM(98), NUM(99), NUM(240), NUM(169), NUM(184), NUM(189), NUM(240), NUM(159), NUM(145), NUM(137), NUM(240), NUM(159), NUM(143), NUM(191), NUM(240), NUM(159), NUM(145), NUM(168), NUM(226), NUM(128), NUM(141), NUM(240), NUM(159), NUM(145), NUM(166), NUM(100), NUM(101), NUM(102)])
);
});

test.concurrent("pad_start", async () => {
const res = await exe(`
let str = "abc"
<: [
str.pad_start(0), str.pad_start(1), str.pad_start(2), str.pad_start(3), str.pad_start(4), str.pad_start(5),
str.pad_start(0, "0"), str.pad_start(1, "0"), str.pad_start(2, "0"), str.pad_start(3, "0"), str.pad_start(4, "0"), str.pad_start(5, "0"),
str.pad_start(0, "01"), str.pad_start(1, "01"), str.pad_start(2, "01"), str.pad_start(3, "01"), str.pad_start(4, "01"), str.pad_start(5, "01"),
]
`);
eq(res, ARR([
STR("abc"), STR("abc"), STR("abc"), STR("abc"), STR(" abc"), STR(" abc"),
STR("abc"), STR("abc"), STR("abc"), STR("abc"), STR("0abc"), STR("00abc"),
STR("abc"), STR("abc"), STR("abc"), STR("abc"), STR("0abc"), STR("01abc"),
]));
});

test.concurrent("pad_end", async () => {
const res = await exe(`
let str = "abc"
<: [
str.pad_end(0), str.pad_end(1), str.pad_end(2), str.pad_end(3), str.pad_end(4), str.pad_end(5),
str.pad_end(0, "0"), str.pad_end(1, "0"), str.pad_end(2, "0"), str.pad_end(3, "0"), str.pad_end(4, "0"), str.pad_end(5, "0"),
str.pad_end(0, "01"), str.pad_end(1, "01"), str.pad_end(2, "01"), str.pad_end(3, "01"), str.pad_end(4, "01"), str.pad_end(5, "01"),
]
`);
eq(res, ARR([
STR("abc"), STR("abc"), STR("abc"), STR("abc"), STR("abc "), STR("abc "),
STR("abc"), STR("abc"), STR("abc"), STR("abc"), STR("abc0"), STR("abc00"),
STR("abc"), STR("abc"), STR("abc"), STR("abc"), STR("abc0"), STR("abc01"),
]));
});
});

describe('arr', () => {
Expand Down
Loading