diff --git a/cmd/src/tools/cmd_fmt.ri b/cmd/src/tools/cmd_fmt.ri index c6d531651..960dd9cf2 100644 --- a/cmd/src/tools/cmd_fmt.ri +++ b/cmd/src/tools/cmd_fmt.ri @@ -1,5 +1,5 @@ -// Copyright (C) 2023-present Jose Mendoza - All rights reserved. Use of this -// source code is governed by an MIT license that can be found in the LICENSE +// Copyright (C) 2023-present Jose Mendoza - All rights reserved. Use of this +// source code is governed by an MIT license that can be found in the LICENSE // file. import std/flag; @@ -15,7 +15,7 @@ import rivet/parser; var fmt_desc := "Formats the given Rivet source files or recursively formats all files in the directory, then prints their formatted source to stdout."; -pub func cmd_fmt(args: []string) -> ! { +pub func cmd_fmt(args: [:]string) -> ! { mut fp := flag.FlagParser.new(args); fp.set_application_name("rivet fmt"); fp.set_arguments_description("[FILES|DIRECTORIES]"); diff --git a/cmd/src/tools/cmd_new.ri b/cmd/src/tools/cmd_new.ri index 71e99846a..c640f61c3 100644 --- a/cmd/src/tools/cmd_new.ri +++ b/cmd/src/tools/cmd_new.ri @@ -29,7 +29,7 @@ var available_templates := "Available templates: bin A simple binary project (default). lib A simple library project."; -pub func cmd_new(args: []string, is_init: bool) -> ! { +pub func cmd_new(args: [:]string, is_init: bool) -> ! { mut template := ""; mut fp := flag.FlagParser.new(args); if is_init { diff --git a/lib/core/src/Slice.ri b/lib/core/src/Slice.ri new file mode 100644 index 000000000..8e2028949 --- /dev/null +++ b/lib/core/src/Slice.ri @@ -0,0 +1,71 @@ +// Copyright (C) 2023-present Jose Mendoza - All rights reserved. Use of this +// source code is governed by an MIT license that can be found in the LICENSE +// file. + +struct Slice { + ptr: rawptr; + elem_size: uint; + len: uint; + + func get(&self, idx: uint) -> rawptr { + if idx >= self.len { + runtime_error("dynamic array index out of range (index: {}, len: {})", idx, self.len); + } + return unsafe { @ptr_add(@as([&]mut uint8, self.ptr), idx * self.elem_size) }; + } + + func set(&self, idx: uint, val: rawptr) { + if idx >= self.len { + runtime_error("dynamic array index out of range (index: {}, len: {})", idx, self.len); + } + unsafe { + mem_copy( + @ptr_add(@as([&]mut uint8, self.ptr), self.elem_size * idx), + val, self.elem_size + ); + } + } + + #[inline] + func is_empty(&self) -> bool { + return self.len == 0; + } + + func slice(self, start: uint, end: uint) -> Self { + if start > end || end > self.len { + runtime_error( + "slice index [{}:{}] out of range (len: {})", start, end, self.len + ); + } + len := end - start; + if len == self.len { + return Self(self.ptr, self.elem_size, self.len); + } + return Self( + unsafe { @ptr_add(@as([&]mut uint8, self.ptr), start * self.elem_size) }, + self.elem_size, len + ); + } + + #[inline] + func slice_from(self, start: uint) -> Self { + return self.slice(start, self.len); + } + + #[inline] + func to_dynamic_array(&self) -> DynArray { + return unsafe { DynArray.from_array(self.ptr, self.elem_size, self.len) }; + } + + func ==(&self, rhs: &Self) -> bool { + if self.len != rhs.len { + return false; + } + return mem_cmp(self.ptr, rhs.ptr, self.len) == 0; + } + + #[inline] + func !=(&self, rhs: &Self) -> bool { + return !(self == rhs); + } +} diff --git a/lib/core/src/StringBuilder.c.ri b/lib/core/src/StringBuilder.c.ri index 4055843b9..060b94865 100644 --- a/lib/core/src/StringBuilder.c.ri +++ b/lib/core/src/StringBuilder.c.ri @@ -1,5 +1,5 @@ -// Copyright (C) 2023-present Jose Mendoza - All rights reserved. Use of this -// source code is governed by an MIT license that can be found in the LICENSE +// Copyright (C) 2023-present Jose Mendoza - All rights reserved. Use of this +// source code is governed by an MIT license that can be found in the LICENSE // file. import c/libc; @@ -65,7 +65,7 @@ pub struct StringBuilder < Stringable { self.write_byte('\n'); } - pub func write_join(mut self, ss: []string, sep: string := "") { + pub func write_join(mut self, ss: [:]string, sep: string := "") { if ss.len == 1 { self.write_string(ss[0]); } else { diff --git a/lib/rivet/src/ast/Env.ri b/lib/rivet/src/ast/Env.ri index 6703a0d09..1123c6e8e 100644 --- a/lib/rivet/src/ast/Env.ri +++ b/lib/rivet/src/ast/Env.ri @@ -5,7 +5,6 @@ import std/sys; import std/fs.Path; -import ../token; import ../prefs; import ../report; import ../utils; diff --git a/lib/rivet/src/builder/mod.ri b/lib/rivet/src/builder/mod.ri index 5b6753f4d..155348dc2 100644 --- a/lib/rivet/src/builder/mod.ri +++ b/lib/rivet/src/builder/mod.ri @@ -238,12 +238,12 @@ pub struct Builder { "/" ); full_name = if "src" in names { - src_idx := utils.index_of(names, "src"); + src_idx := utils.index_of(names[:], "src"); utils.join(names[:src_idx], ".").concat( ".", utils.join(names[src_idx + 1:], ".") ) } else { - utils.join(names, ".") + utils.join(names[:], ".") }; } if found { diff --git a/lib/rivet/src/checker/call_expr.ri b/lib/rivet/src/checker/call_expr.ri index 17cc1b073..92735488c 100644 --- a/lib/rivet/src/checker/call_expr.ri +++ b/lib/rivet/src/checker/call_expr.ri @@ -1,5 +1,5 @@ -// Copyright (C) 2023-present Jose Mendoza - All rights reserved. Use of this -// source code is governed by an MIT license that can be found in the LICENSE +// Copyright (C) 2023-present Jose Mendoza - All rights reserved. Use of this +// source code is governed by an MIT license that can be found in the LICENSE // file. import ../ast; @@ -422,7 +422,7 @@ extend Checker { // check default expressions if func_.has_named_args { args_len := call_expr.pure_args_count(); - mut args := call_expr.args[:args_len]; + mut args := call_expr.args[:args_len].to_dynamic_array(); mut i: uint := args_len; while i < func_args_len : i += 1 { arg := func_.args[i]; diff --git a/lib/rivet/src/checker/exprs.ri b/lib/rivet/src/checker/exprs.ri index 0179276e8..e6ec6becb 100644 --- a/lib/rivet/src/checker/exprs.ri +++ b/lib/rivet/src/checker/exprs.ri @@ -276,8 +276,8 @@ extend Checker { } self.inside_unsafe_block = false; } - block.defer_stmts = self.defer_stmts[self.defer_stmts_start:]; - self.defer_stmts = self.defer_stmts[:self.defer_stmts_start]; + block.defer_stmts = self.defer_stmts[self.defer_stmts_start:].to_dynamic_array(); + self.defer_stmts = self.defer_stmts[:self.defer_stmts_start].to_dynamic_array(); block.type }, .Unary(mut unary) -> self.check_unary(unary), diff --git a/lib/rivet/src/checker/match_expr.ri b/lib/rivet/src/checker/match_expr.ri index 8c598f505..10cce1eb0 100644 --- a/lib/rivet/src/checker/match_expr.ri +++ b/lib/rivet/src/checker/match_expr.ri @@ -1,5 +1,5 @@ -// Copyright (C) 2023-present Jose Mendoza - All rights reserved. Use of this -// source code is governed by an MIT license that can be found in the LICENSE +// Copyright (C) 2023-present Jose Mendoza - All rights reserved. Use of this +// source code is governed by an MIT license that can be found in the LICENSE // file. import ../ast; @@ -198,7 +198,7 @@ extend Checker { if unhandled.len > 0 { mut err_details := "add `match` branches for: "; if unhandled.len < MATCH_EXHAUSTIVE_CUTOFF_LIMIT { - err_details = err_details.concat(utils.join(unhandled, ", ")); + err_details = err_details.concat(utils.join(unhandled[:], ", ")); } else { err_details = err_details.concat( utils.join(unhandled[:MATCH_EXHAUSTIVE_CUTOFF_LIMIT], ", ") diff --git a/lib/rivet/src/depgraph/mod.ri b/lib/rivet/src/depgraph/mod.ri index d65939325..6216948bb 100644 --- a/lib/rivet/src/depgraph/mod.ri +++ b/lib/rivet/src/depgraph/mod.ri @@ -1,5 +1,5 @@ -// Copyright (C) 2023-present Jose Mendoza - All rights reserved. Use of this -// source code is governed by an MIT license that can be found in the LICENSE +// Copyright (C) 2023-present Jose Mendoza - All rights reserved. Use of this +// source code is governed by an MIT license that can be found in the LICENSE // file. import std/strings; @@ -89,7 +89,7 @@ pub struct DepGraph { } (seen, cycle_names) = nn.is_part_of_cycle(k.key, cycle_names); if seen { - out.writeln_fmt(" * `{}`", utils.join(cycle_names, "` -> `")); + out.writeln_fmt(" * `{}`", utils.join(cycle_names[:], "` -> `")); nn.is_cycle = maps.MapStringBool(); } } diff --git a/lib/rivet/src/prefs/mod.ri b/lib/rivet/src/prefs/mod.ri index 9f3da1de8..5b4c7eeb6 100644 --- a/lib/rivet/src/prefs/mod.ri +++ b/lib/rivet/src/prefs/mod.ri @@ -1,5 +1,5 @@ -// Copyright (C) 2023-present Jose Mendoza - All rights reserved. Use of this -// source code is governed by an MIT license that can be found in the LICENSE +// Copyright (C) 2023-present Jose Mendoza - All rights reserved. Use of this +// source code is governed by an MIT license that can be found in the LICENSE // file. import std/env; @@ -82,7 +82,7 @@ pub struct Prefs { pub mut run_output: bool; pub mut run_output_args: []string; - pub func from_args(args: []string, is_test: bool, run_output: bool, is_check: bool) -> !Self { + pub func from_args(args: [:]string, is_test: bool, run_output: bool, is_check: bool) -> !Self { mut prefs := Prefs(is_test: is_test, run_output: run_output, check: is_check); mut fp := flag.FlagParser.new(args); fp.set_application_name(if is_test { diff --git a/lib/rivet/src/tokenizer/mod.ri b/lib/rivet/src/tokenizer/mod.ri index b111f1796..869395f50 100644 --- a/lib/rivet/src/tokenizer/mod.ri +++ b/lib/rivet/src/tokenizer/mod.ri @@ -252,7 +252,7 @@ pub struct Tokenizer { s.substr(end_idx) }); } - return utils.join(ss, ""); + return utils.join(ss[:], ""); } #[inline] @@ -298,7 +298,7 @@ func decode_o_escapes(s: string, start: uint, escapes_pos: []uint) -> string { s.substr(end_idx) }); } - return utils.join(ss, ""); + return utils.join(ss[:], ""); } func decode_u_escape_single(str: string, idx: uint) -> (uint, string) { @@ -316,7 +316,7 @@ func decode_unicode_escaped_rune(str: string) -> string { mut ss := []string(cap: 2); ss.push(segment); ss.push(str.substr(end_idx)); - utils.join(ss, "") + utils.join(ss[:], "") }; } diff --git a/lib/rivet/src/tokenizer/next.ri b/lib/rivet/src/tokenizer/next.ri index b3271acd2..e566e81d2 100644 --- a/lib/rivet/src/tokenizer/next.ri +++ b/lib/rivet/src/tokenizer/next.ri @@ -766,7 +766,7 @@ extend Tokenizer { if segment_idx < lit.len { str_segments.push(lit.substr(segment_idx)); } - lit = utils.join(str_segments, ""); + lit = utils.join(str_segments[:], ""); } if n_cr_chars > 0 { lit = lit.replace("\r", ""); diff --git a/lib/rivet/src/utils/array.ri b/lib/rivet/src/utils/array.ri index 82b92d62f..315fcff28 100644 --- a/lib/rivet/src/utils/array.ri +++ b/lib/rivet/src/utils/array.ri @@ -1,21 +1,21 @@ -// Copyright (C) 2023-present Jose Mendoza - All rights reserved. Use of this -// source code is governed by an MIT license that can be found in the LICENSE +// Copyright (C) 2023-present Jose Mendoza - All rights reserved. Use of this +// source code is governed by an MIT license that can be found in the LICENSE // file. import std/strings; -pub func join(vec: []string, s: string) -> string { - return if vec.is_empty() { +pub func join(slice: [:]string, s: string) -> string { + return if slice.is_empty() { "" } else { mut sb := strings.Builder.new(); - sb.write_join(vec, s); + sb.write_join(slice, s); sb.to_string() }; } -pub func index_of(vec: []string, value: string) -> uint { - for i, val in vec { +pub func index_of(slice: [:]string, value: string) -> uint { + for i, val in slice { if val == value { return i; } diff --git a/lib/rivet/src/utils/file.ri b/lib/rivet/src/utils/file.ri index 6b90664fe..1302df30d 100644 --- a/lib/rivet/src/utils/file.ri +++ b/lib/rivet/src/utils/file.ri @@ -1,5 +1,5 @@ -// Copyright (C) 2023-present Jose Mendoza - All rights reserved. Use of this -// source code is governed by an MIT license that can be found in the LICENSE +// Copyright (C) 2023-present Jose Mendoza - All rights reserved. Use of this +// source code is governed by an MIT license that can be found in the LICENSE // file. import std/env; @@ -57,7 +57,7 @@ struct SourceCache { }; } - pub func find_lines_between(mut self, path_: string, line: uint, end_line: uint) -> ?[]string { + pub func find_lines_between(mut self, path_: string, line: uint, end_line: uint) -> ?[:]string { return if lines := self.find_lines(path_) { if lines.len > 0 && lines.len >= end_line { lines[line:end_line] diff --git a/lib/std/src/flag/mod.ri b/lib/std/src/flag/mod.ri index 14a936fc4..23069cfc6 100644 --- a/lib/std/src/flag/mod.ri +++ b/lib/std/src/flag/mod.ri @@ -1,5 +1,5 @@ -// Copyright (C) 2023-present Jose Mendoza - All rights reserved. Use of this -// source code is governed by an MIT license that can be found in the LICENSE +// Copyright (C) 2023-present Jose Mendoza - All rights reserved. Use of this +// source code is governed by an MIT license that can be found in the LICENSE // file. import ../traits; @@ -42,7 +42,7 @@ pub struct Flag < traits.Stringable { #[boxed] pub struct FlagParser { /// The original arguments to be parsed. - original_args: []string; + original_args: [:]string; /// The index of a `--`, `none` if there is not any. idx_dashdash: ?uint; /// All options after `--` are ignored, and will be passed to the application unmodified. @@ -71,19 +71,18 @@ pub struct FlagParser { mut footers: []string; /// Create a new flag parser for the given args. - pub func new(args: []string) -> Self { - original_args := args.clone(); - mut all_before_dashdash := args.clone(); + pub func new(args: [:]string) -> Self { + mut all_before_dashdash := args.to_dynamic_array(); mut all_after_dashdash := []string(); idx_dashdash := index_of(args, "--"); if v := idx_dashdash { all_before_dashdash.trim(v); - if v < original_args.len { - all_after_dashdash = original_args[v + 1:]; + if v < args.len { + all_after_dashdash = args[v + 1:].to_dynamic_array(); } } return Self( - original_args: original_args, + original_args: args, idx_dashdash: idx_dashdash, all_after_dashdash: all_after_dashdash, args: all_before_dashdash, @@ -487,8 +486,8 @@ pub struct FlagParser { } } -pub func index_of(vec: []string, value: string) -> ?uint { - for i, val in vec { +pub func index_of(slice: [:]string, value: string) -> ?uint { + for i, val in slice { if val == value { return i; } diff --git a/rivetc/src/codegen/__init__.py b/rivetc/src/codegen/__init__.py index e7c87b016..c4478a7b0 100644 --- a/rivetc/src/codegen/__init__.py +++ b/rivetc/src/codegen/__init__.py @@ -1630,18 +1630,20 @@ def gen_expr(self, expr, custom_tmp = None): else: end = None tmp = self.cur_func.local_name() - if s.kind == TypeKind.DynArray: + if s.kind in (TypeKind.DynArray, TypeKind.Slice): if end == None: + method_name = "_R4core5Slice10slice_fromM" if s.kind==TypeKind.Slice else "_R4core8DynArray10slice_fromM" inst = ir.Inst( ir.InstKind.Call, [ - ir.Name("_R4core8DynArray10slice_fromM"), left, + ir.Name(method_name), left, start ] ) else: + method_name = "_R4core5Slice5sliceM" if s.kind==TypeKind.Slice else "_R4core8DynArray5sliceM" inst = ir.Inst( ir.InstKind.Call, [ - ir.Name("_R4core8DynArray5sliceM"), left, start, + ir.Name(method_name), left, start, end ] ) diff --git a/rivetc/src/type.py b/rivetc/src/type.py index 37542327b..55ab50d13 100644 --- a/rivetc/src/type.py +++ b/rivetc/src/type.py @@ -167,7 +167,7 @@ def qualstr(self): return f"[:]{self.typ.qualstr()}" def __eq__(self, other): - if not isinstance(other, DynArray): + if not isinstance(other, Slice): return False return self.typ == other.typ and self.is_mut == other.is_mut