Skip to content

Commit

Permalink
refact(all): remove slice syntax support for strings
Browse files Browse the repository at this point in the history
The `string.substr()` method is added and this is used instead,
thus leaving the slice syntax only for arrays and dynamic arrays.
  • Loading branch information
StunxFS committed Dec 5, 2023
1 parent cf85fb5 commit 89a0b5e
Show file tree
Hide file tree
Showing 24 changed files with 135 additions and 141 deletions.
2 changes: 1 addition & 1 deletion lib/core/src/DynArray.ri
Original file line number Diff line number Diff line change
Expand Up @@ -85,7 +85,7 @@ struct DynArray {
if i + size > self.len {
end_idx := if size == 1 { "..{}".fmt(i + size) } else { "" };
runtime_error(
"DynArray.delete(): index out of range (i: {}..{}, self.len: {})",
"DynArray.delete: index out of range (i: {}..{}, self.len: {})",
i, end_idx, self.len
);
}
Expand Down
4 changes: 2 additions & 2 deletions lib/core/src/TokenIterator.ri
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@ pub struct TokenIterator {
mut end := start;
while end < self.buffer.len and !self.is_split_byte(self.buffer[end])
: end += 1 {}
return self.buffer[start..end];
return self.buffer.substr(start, end);
}

/// Returns a slice of the remaining bytes. Does not affect iterator state.
Expand All @@ -38,7 +38,7 @@ pub struct TokenIterator {
mut index := self.index;
while index < self.buffer.len and self.is_split_byte(self.buffer[index])
: index += 1 {}
return self.buffer[index..];
return self.buffer.substr(index);
}

/// Resets the iterator to the initial token.
Expand Down
6 changes: 3 additions & 3 deletions lib/core/src/parse_int.ri
Original file line number Diff line number Diff line change
Expand Up @@ -134,10 +134,10 @@ extend string {
mut s0 := self;
mut neg := false;
if self[0] == b'+' {
s0 = self[1..];
s0 = self.substr(1);
} else if self[0] == b'-' {
neg = true;
s0 = self[1..];
s0 = self.substr(1);
}

// convert unsigned and check range.
Expand Down Expand Up @@ -173,7 +173,7 @@ func underscore_ok(s_: string) -> bool {

// optional sign.
if s.len >= 1 and (s[0] == b'-' or s[0] == b'+') {
s = s[1..];
s = s.substr(1);
}

// optional base prefix.
Expand Down
70 changes: 34 additions & 36 deletions lib/core/src/string.c.ri
Original file line number Diff line number Diff line change
Expand Up @@ -60,7 +60,7 @@ pub struct string < Stringable, Hashable, Throwable {
return Self(res, bytes.len);
}
pub func at(self, idx: uint) -> uint8 {
func at(self, idx: uint) -> uint8 {
if idx >= self.len {
runtime_error("string index out of range (index: {}, len: {})", idx, self.len);
}
Expand Down Expand Up @@ -116,7 +116,7 @@ pub struct string < Stringable, Hashable, Throwable {
continue;
}
if is_space and is_in_word {
res.push(self[word_start..word_start + word_len]);
res.push(self.substr(word_start, word_start + word_len));
is_in_word = false;
word_len = 0;
word_start = 0;
Expand All @@ -125,7 +125,7 @@ pub struct string < Stringable, Hashable, Throwable {
}
if is_in_word and word_len > 0 {
// collect the remainder word at the end
res.push(self[word_start..self.len]);
res.push(self.substr(word_start, self.len));
}
return res;
}
Expand Down Expand Up @@ -211,7 +211,7 @@ pub struct string < Stringable, Hashable, Throwable {
/// If the substring is not found, it returns the full input string.
pub func all_before_of(self, sub: Self) -> Self {
return if pos := self.index_of(sub) {
self[..pos]
self.substr(end: pos)
} else {
self
};
Expand All @@ -220,7 +220,7 @@ pub struct string < Stringable, Hashable, Throwable {
/// Returns the contents before the last occurrence of `sub` in the string.
pub func all_before_of_last(self, sub: Self) -> Self {
return if pos := self.last_index_of(sub) {
self[..pos]
self.substr(end: pos)
} else {
self
};
Expand All @@ -230,7 +230,7 @@ pub struct string < Stringable, Hashable, Throwable {
/// not found, it returns the full input string.
pub func all_after_of(self, sub: Self) -> Self {
return if pos := self.index_of(sub) {
self[pos + sub.len..]
self.substr(pos + sub.len)
} else {
self
};
Expand All @@ -240,7 +240,7 @@ pub struct string < Stringable, Hashable, Throwable {
/// If the substring is not found, it returns the full input string.
pub func all_after_of_last(self, sub: Self) -> Self {
return if pos := self.last_index_of(sub) {
self[pos + sub.len..]
self.substr(pos + sub.len)
} else {
self
};
Expand Down Expand Up @@ -348,9 +348,9 @@ pub struct string < Stringable, Hashable, Throwable {
/// Returns the string found between `start` string and `end` string.
pub func find_between(self, start: Self, end: Self) -> Self {
start_pos := self.index_of(start) ?? return emptyString;
val := self.slice(start_pos + start.len, self.len);
val := self.substr(start_pos + start.len, self.len);
end_pos := val.index_of(end) ?? return val;
return val.slice(0, end_pos);
return val.substr(0, end_pos);
}

/// Strips any of the characters given in `cutset` from the start and end of
Expand All @@ -360,7 +360,7 @@ pub struct string < Stringable, Hashable, Throwable {
return self;
}
(pos_left, pos_right) := self.trim_indexes(cutset);
return self.slice(pos_left, pos_right);
return self.substr(pos_left, pos_right);
}

/// Gets the new start and end indexes of a string when any of the characters
Expand Down Expand Up @@ -415,7 +415,7 @@ pub struct string < Stringable, Hashable, Throwable {
break;
}
}
return self.slice_from(pos);
return self.substr(pos);
}

/// Strips any of the characters given in `cutset` from the right of the
Expand All @@ -440,7 +440,7 @@ pub struct string < Stringable, Hashable, Throwable {
break;
}
}
return self.slice(0, pos + 1);
return self.substr(0, pos + 1);
}

/// Strips any of ` `, `\n`, `\t`, `\v`, `\f`, `\r` from the start and end of
Expand Down Expand Up @@ -519,7 +519,7 @@ pub struct string < Stringable, Hashable, Throwable {
} else {
self.len
};
r := self[i..end];
r := self.substr(i, end);
i += char_len - 1;
r.utf32_code()
} else {
Expand Down Expand Up @@ -547,7 +547,7 @@ pub struct string < Stringable, Hashable, Throwable {
i = 1;
for ch in self.as_bytes() {
if nth > 0 and i >= nth {
res.push(self[i..]);
res.push(self.substr(i));
break;
}
res.push(ch.to_ascii());
Expand All @@ -563,35 +563,34 @@ pub struct string < Stringable, Hashable, Throwable {
if nth > 0 and res.len == nth - 1 {
break;
}
res.push(self[start..i]);
res.push(self.substr(start, i));
start = i + delim.len;
i = start;
} else {
i += 1;
}
}
if nth < 1 or res.len < nth {
res.push(self[start..]);
res.push(self.substr(start));
}
return res;
},
else -> {
mut start: uint := 0;
while i <= self.len {
is_delim := i + delim.len <= self.len and self[i..i + delim.len] == delim;
if is_delim {
if i + delim.len <= self.len and self.substr(i, i + delim.len) == delim {
if nth > 0 and res.len == nth - 1 {
break;
}
res.push(self[start..i]);
res.push(self.substr(start, i));
start = i + delim.len;
i = start;
} else {
i += 1;
}
}
if nth < 1 or res.len < nth {
res.push(self[start..]);
res.push(self.substr(start));
}
return res;
}
Expand All @@ -612,14 +611,14 @@ pub struct string < Stringable, Hashable, Throwable {
for index, ch in self.as_bytes() {
for delim_ch in delim.as_bytes() {
if ch == delim_ch {
res.push(self[i..index]);
res.push(self.substr(i, index));
i = index + 1;
break;
}
}
}
if i < self.len {
res.push(self[i..]);
res.push(self.substr(i));
}
}
return res;
Expand All @@ -644,14 +643,14 @@ pub struct string < Stringable, Hashable, Throwable {
res.push(if line_start == i {
emptyString
} else {
self[line_start..i]
self.substr(line_start, i)
});
line_start = i + 1;
} else if unsafe { self.ptr[i] == cr } {
res.push(if line_start == i {
emptyString
} else {
self[line_start..i]
self.substr(line_start, i)
});
if i + 1 < self.len and unsafe { self.ptr[i + 1] == lf } {
line_start = i + 2;
Expand All @@ -662,7 +661,7 @@ pub struct string < Stringable, Hashable, Throwable {
}
}
if line_start < self.len {
res.push(self[line_start..]);
res.push(self.substr(line_start));
}
return res;
}
Expand Down Expand Up @@ -785,27 +784,26 @@ pub struct string < Stringable, Hashable, Throwable {
return true;
}

func slice(self, start: uint, end: uint) -> Self {
/// Returns a portion of the current string as a reference. This does not clone
/// the returned value.
pub func substr(self, start: ?uint := none, end: ?uint := none) -> Self {
unsafe {
if start > end or start > self.len or end > self.len {
start_ := start ?? 0;
end_ := end ?? self.len;
if start_ > end_ or start_ > self.len or end_ > self.len {
runtime_error(
"string slice index out of range (range: {}..{}, len: {})", start,
end, self.len
"substring index out of range (range: {}..{}, len: {})", start_,
end_, self.len
);
}
len := end - start;
len := end_ - start_;
if len == self.len {
return self;
}
return Self(@ptr_add(self.ptr, start), len, is_ref: true);
return Self(@ptr_add(self.ptr, start_), len, is_ref: true);
}
}

#[inline]
func slice_from(self, start: uint) -> Self {
return self.slice(start, self.len);
}

pub func clone(self) -> Self {
if self.len == 0 {
return emptyString;
Expand Down
8 changes: 8 additions & 0 deletions lib/core/tests/string_test.ri
Original file line number Diff line number Diff line change
Expand Up @@ -158,3 +158,11 @@ test "string.parse_int()" {
true
});
}

test "string.slice()" {
str := "hello world!";
@assert(str.substr() == str);
@assert(str.substr(5) == "world!");
@assert(str.substr(end: 4) == "hello");
@assert(str.substr(1, 8) == "llo wor");
}
8 changes: 4 additions & 4 deletions lib/rivet/src/ast/CHeader.ri
Original file line number Diff line number Diff line change
Expand Up @@ -9,8 +9,8 @@ import { Path } from std/fs;

import ../token;

// Useful functions to get system `#define`s.
// Will soon be used to implement `extern (C) import`.
// Useful functions to get system `#define`s. Will soon be used to
// implement `extern (C) import`.

pub enum CImportAction {
Report {
Expand Down Expand Up @@ -130,8 +130,8 @@ extend Table {
mut is_macro := true;
if has_value {
if paren_idx := name.index_of_byte(b'(') {
def_args := name[paren_idx + 1..].all_before_of(")");
name = name[..paren_idx];
def_args := name.substr(paren_idx + 1).all_before_of(")");
name = name.substr(end: paren_idx);
if def_args.len > 0 {
for arg_name in def_args.split(",") {
args.push(arg_name.trim_space());
Expand Down
2 changes: 0 additions & 2 deletions lib/rivet/src/ast/Decl.ri
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,6 @@
// Use of this source code is governed by an MIT license that can
// be found in the LICENSE file.

import std/strings;

import ../token;

pub enum Decl {
Expand Down
8 changes: 4 additions & 4 deletions lib/rivet/src/ast/Table.ri
Original file line number Diff line number Diff line change
Expand Up @@ -395,7 +395,7 @@ pub struct Table {
new_inputs.push(input);
continue;
}
exts := base_name_input[..base_name_input.len - 3].split(".")[1..];
exts := base_name_input.substr(end: base_name_input.len - 3).split(".")[1..];
mut already_exts := @dyn_array(string, exts.len);
mut should_compile := false;
for ext in exts {
Expand All @@ -405,9 +405,9 @@ pub struct Table {
already_exts.push(ext);
if ext.starts_with("d_") or ext.starts_with("notd_") {
should_compile = if ext.starts_with("d_") {
ext[2..] in self.prefs.flags
ext.substr(2) in self.prefs.flags
} else {
ext[2..] !in self.prefs.flags
ext.substr(4) !in self.prefs.flags
};
} else if os := sys.OS.from_string(ext) {
should_compile = self.prefs.target_os == os;
Expand Down Expand Up @@ -577,4 +577,4 @@ enum BuiltinFuncCheck {
arg_idx: uint;
type: BuiltinFuncType;
}
}
}
2 changes: 1 addition & 1 deletion lib/rivet/src/checker/decls.ri
Original file line number Diff line number Diff line change
Expand Up @@ -169,7 +169,7 @@ extend Checker {
func check_func(mut self, mut func_decl: ast.Decl.Func) {
if !func_decl.is_operator {
name := if func_decl.is_method and func_decl.is_special_method {
func_decl.name[2..func_decl.name.len - 2] // skip `__`
func_decl.name.substr(2, func_decl.name.len - 2) // skip `__`
} else {
func_decl.name
};
Expand Down
11 changes: 7 additions & 4 deletions lib/rivet/src/checker/exprs.ri
Original file line number Diff line number Diff line change
Expand Up @@ -451,10 +451,13 @@ extend Checker {
}
if index.left_type == self.table.string_t {
if index.index is .Range {
self.table.string_t
} else {
self.table.uint8_t
mut err := report.error_builder(
"`string` does not support slicing syntax", index.pos
);
err.add_help("use `.substr()` instead");
err.emit();
}
self.table.uint8_t
} else {
@as(ast.Type.Pointer, index.left_type).inner
}
Expand Down Expand Up @@ -887,4 +890,4 @@ extend Checker {
};
return .Void();
}
}
}
Loading

0 comments on commit 89a0b5e

Please sign in to comment.