compiler/vlib: replace substr/left/right with `[start..end]` everywhere

pull/2562/head
joe-conigliaro 2019-10-27 18:03:15 +11:00 committed by Alexander Medvednikov
parent ed55826686
commit 59378dce46
49 changed files with 308 additions and 306 deletions

View File

@ -9,7 +9,7 @@ fn main() {
break break
} }
end := html.index_after('"', pos) end := html.index_after('"', pos)
println(html.substr(pos, end)) println(html[pos..end])
} }
} }

View File

@ -69,5 +69,5 @@ fn filter_word(word string) string {
i++ i++
} }
end := i end := i
return word.substr(start, end) return word[start..end]
} }

View File

@ -249,7 +249,7 @@ fn (gen_vc mut GenVC) generate() {
// last commit hash in v repo // last commit hash in v repo
last_commit_hash_v := git_log_v.find_between('commit', '\n').trim_space() last_commit_hash_v := git_log_v.find_between('commit', '\n').trim_space()
last_commit_hash_v_short := last_commit_hash_v.left(7) last_commit_hash_v_short := last_commit_hash_v[..7]
// log some info // log some info
gen_vc.logger.debug('last commit time ($git_repo_v): ' + last_commit_time_v.format_ss()) gen_vc.logger.debug('last commit time ($git_repo_v): ' + last_commit_time_v.format_ss())
@ -270,7 +270,7 @@ fn (gen_vc mut GenVC) generate() {
// build v.c for each os // build v.c for each os
for os_name in vc_build_oses { for os_name in vc_build_oses {
vc_suffix := if os_name == 'unix' { '' } else { '_${os_name.left(3)}' } vc_suffix := if os_name == 'unix' { '' } else { '_${os_name[..3]}' }
v_os_arg := if os_name == 'unix' { '' } else { '-os $os_name' } v_os_arg := if os_name == 'unix' { '' } else { '-os $os_name' }
c_file := 'v${vc_suffix}.c' c_file := 'v${vc_suffix}.c'
// try generate .c file // try generate .c file

View File

@ -116,7 +116,7 @@ fn test_repeat() {
fn test_right() { fn test_right() {
a := [1, 2, 3, 4] a := [1, 2, 3, 4]
b := a.right(1) b := a[1..]
c := a[1..a.len] c := a[1..a.len]
d := a[1..] d := a[1..]
assert b[0] == 2 assert b[0] == 2
@ -129,6 +129,9 @@ fn test_right() {
fn test_right_with_n_bigger_than_array_size() { fn test_right_with_n_bigger_than_array_size() {
a := [1, 2, 3, 4] a := [1, 2, 3, 4]
// NOTE: slice syntax wont return empty array
// instead will give index out of bounds
// mut b := a[10..]
mut b := a.right(10) mut b := a.right(10)
assert b.len == 0 assert b.len == 0
@ -143,7 +146,7 @@ fn test_right_with_n_bigger_than_array_size() {
fn test_left() { fn test_left() {
a := [1, 2, 3] a := [1, 2, 3]
b := a.left(2) b := a[..2]
c := a[0..2] c := a[0..2]
d := a[..2] d := a[..2]
assert b[0] == 1 assert b[0] == 1
@ -207,9 +210,9 @@ fn modify (numbers mut []int) {
fn test_mut_slice() { fn test_mut_slice() {
mut n := [1,2,3] mut n := [1,2,3]
modify(mut n.left(2)) modify(mut n[..2])
assert n[0] == 777 assert n[0] == 777
modify(mut n.right(2)) modify(mut n[2..])
assert n[2] == 777 assert n[2] == 777
println(n) println(n)
} }

View File

@ -148,12 +148,12 @@ pub fn (s string) find_between(start, end string) string {
return '' return ''
} }
// First get everything to the right of 'start' // First get everything to the right of 'start'
val := s.right(start_pos + start.len) val := s[start_pos + start.len..]
end_pos := val.index(end) end_pos := val.index(end)
if end_pos == -1 { if end_pos == -1 {
return val return val
} }
return val.left(end_pos) return val[..end_pos]
} }
// TODO generic // TODO generic
@ -258,7 +258,7 @@ pub fn (s string) all_before(dot string) string {
if pos == -1 { if pos == -1 {
return s return s
} }
return s.left(pos) return s[..pos]
} }
pub fn (s string) all_before_last(dot string) string { pub fn (s string) all_before_last(dot string) string {
@ -266,7 +266,7 @@ pub fn (s string) all_before_last(dot string) string {
if pos == -1 { if pos == -1 {
return s return s
} }
return s.left(pos) return s[..pos]
} }
pub fn (s string) all_after(dot string) string { pub fn (s string) all_after(dot string) string {
@ -274,7 +274,7 @@ pub fn (s string) all_after(dot string) string {
if pos == -1 { if pos == -1 {
return s return s
} }
return s.right(pos + dot.len) return s[pos + dot.len..]
} }
// fn (s []string) substr(a, b int) string { // fn (s []string) substr(a, b int) string {

View File

@ -260,7 +260,7 @@ fn test_upper() {
fn test_left_right() { fn test_left_right() {
s := 'ALOHA' s := 'ALOHA'
assert s.left(3) == 'ALO' assert s.left(3) == 'ALO'
assert s.right(3) == 'HA' assert s[3..] == 'HA'
u := s.ustring() u := s.ustring()
assert u.left(3) == 'ALO' assert u.left(3) == 'ALO'
assert u.right(3) == 'HA' assert u.right(3) == 'HA'

View File

@ -85,8 +85,8 @@ fn (table mut Table) parse_cflag(cflag string, mod string) ?bool {
mut name := '' mut name := ''
if flag.starts_with('linux') || flag.starts_with('darwin') || flag.starts_with('freebsd') || flag.starts_with('windows') { if flag.starts_with('linux') || flag.starts_with('darwin') || flag.starts_with('freebsd') || flag.starts_with('windows') {
pos := flag.index(' ') pos := flag.index(' ')
fos = flag.left(pos).trim_space() fos = flag[..pos].trim_space()
flag = flag.right(pos).trim_space() flag = flag[pos..].trim_space()
} }
for { for {
mut index := -1 mut index := -1
@ -94,9 +94,9 @@ fn (table mut Table) parse_cflag(cflag string, mod string) ?bool {
if flag[0] == `-` { if flag[0] == `-` {
for f in allowed_flags { for f in allowed_flags {
i := 1+f.len i := 1+f.len
if i <= flag.len && f == flag.substr(1,i) { if i <= flag.len && f == flag[1..i] {
name = flag.left(i).trim_space() name = flag[..i].trim_space()
flag = flag.right(i).trim_space() flag = flag[i..].trim_space()
break break
} }
} }
@ -109,17 +109,17 @@ fn (table mut Table) parse_cflag(cflag string, mod string) ?bool {
if index != -1 && flag[index] == ` ` && flag[index+1] == `-` { if index != -1 && flag[index] == ` ` && flag[index+1] == `-` {
for f in allowed_flags { for f in allowed_flags {
i := index+f.len i := index+f.len
if i < flag.len && f == flag.substr(index, i) { if i < flag.len && f == flag[index..i] {
index = i index = i
break break
} }
} }
value = flag.left(index).trim_space() value = flag[..index].trim_space()
flag = flag.right(index).trim_space() flag = flag[index..].trim_space()
} }
else if index != -1 && index < flag.len-2 && flag[index] == `,` { else if index != -1 && index < flag.len-2 && flag[index] == `,` {
value = flag.left(index).trim_space() value = flag[..index].trim_space()
flag = flag.right(index+1).trim_space() flag = flag[index+1..].trim_space()
} }
else { else {
value = flag.trim_space() value = flag.trim_space()

View File

@ -136,12 +136,12 @@ fn (g mut CGen) cut() string {
pos := g.cut_pos pos := g.cut_pos
g.cut_pos = 0 g.cut_pos = 0
if g.is_tmp { if g.is_tmp {
res := g.tmp_line.right(pos) res := g.tmp_line[pos..]
g.tmp_line = g.tmp_line.left(pos) g.tmp_line = g.tmp_line[..pos]
return res return res
} }
res := g.cur_line.right(pos) res := g.cur_line[pos..]
g.cur_line = g.cur_line.left(pos) g.cur_line = g.cur_line[..pos]
return res return res
} }
@ -151,13 +151,13 @@ fn (g mut CGen) set_placeholder(pos int, val string) {
} }
// g.lines.set(pos, val) // g.lines.set(pos, val)
if g.is_tmp { if g.is_tmp {
left := g.tmp_line.left(pos) left := g.tmp_line[..pos]
right := g.tmp_line.right(pos) right := g.tmp_line[pos..]
g.tmp_line = '${left}${val}${right}' g.tmp_line = '${left}${val}${right}'
return return
} }
left := g.cur_line.left(pos) left := g.cur_line[..pos]
right := g.cur_line.right(pos) right := g.cur_line[pos..]
g.cur_line = '${left}${val}${right}' g.cur_line = '${left}${val}${right}'
// g.genln('') // g.genln('')
} }

View File

@ -167,9 +167,9 @@ fn (p mut Parser) comp_time() {
pp.v.add_parser(pp) pp.v.add_parser(pp)
tmpl_fn_body := p.cgen.lines.slice(pos + 2, p.cgen.lines.len).join('\n').clone() tmpl_fn_body := p.cgen.lines.slice(pos + 2, p.cgen.lines.len).join('\n').clone()
end_pos := tmpl_fn_body.last_index('Builder_str( sb )') + 19 // TODO end_pos := tmpl_fn_body.last_index('Builder_str( sb )') + 19 // TODO
p.cgen.lines = p.cgen.lines.left(pos) p.cgen.lines = p.cgen.lines[..pos]
p.genln('/////////////////// tmpl start') p.genln('/////////////////// tmpl start')
p.genln(tmpl_fn_body.left(end_pos)) p.genln(tmpl_fn_body[..end_pos])
p.genln('/////////////////// tmpl end') p.genln('/////////////////// tmpl end')
// `app.vweb.html(index_view())` // `app.vweb.html(index_view())`
receiver := p.cur_fn.args[0] receiver := p.cur_fn.args[0]
@ -188,7 +188,7 @@ fn (p mut Parser) chash() {
p.next() p.next()
if hash.starts_with('flag ') { if hash.starts_with('flag ') {
if p.first_pass() { if p.first_pass() {
mut flag := hash.right(5) mut flag := hash[5..]
// expand `@VROOT` `@VMOD` to absolute path // expand `@VROOT` `@VMOD` to absolute path
flag = flag.replace('@VROOT', p.vroot) flag = flag.replace('@VROOT', p.vroot)
flag = flag.replace('@VMOD', v_modules_path) flag = flag.replace('@VMOD', v_modules_path)
@ -214,7 +214,7 @@ fn (p mut Parser) chash() {
// TODO remove after ui_mac.m is removed // TODO remove after ui_mac.m is removed
else if hash.contains('embed') { else if hash.contains('embed') {
pos := hash.index('embed') + 5 pos := hash.index('embed') + 5
file := hash.right(pos) file := hash[pos..]
if p.pref.build_mode != .default_mode { if p.pref.build_mode != .default_mode {
p.genln('#include $file') p.genln('#include $file')
} }
@ -283,7 +283,7 @@ fn (p mut Parser) gen_array_str(typ Type) {
is_public: true is_public: true
receiver_typ: typ.name receiver_typ: typ.name
}) })
elm_type := typ.name.right(6) elm_type := typ.name[6..]
elm_type2 := p.table.find_type(elm_type) elm_type2 := p.table.find_type(elm_type)
is_array := elm_type.starts_with('array_') is_array := elm_type.starts_with('array_')
if is_array { if is_array {
@ -350,7 +350,7 @@ fn (p mut Parser) gen_array_filter(str_typ string, method_ph int) {
} }
array_int b = tmp2; array_int b = tmp2;
*/ */
val_type:=str_typ.right(6) val_type:=str_typ[6..]
p.open_scope() p.open_scope()
p.register_var(Var{ p.register_var(Var{
name: 'it' name: 'it'
@ -390,7 +390,7 @@ fn (p mut Parser) gen_array_map(str_typ string, method_ph int) string {
} }
array_int b = tmp2; array_int b = tmp2;
*/ */
val_type:=str_typ.right(6) val_type:=str_typ[6..]
p.open_scope() p.open_scope()
p.register_var(Var{ p.register_var(Var{
name: 'it' name: 'it'

View File

@ -1099,11 +1099,11 @@ fn (p mut Parser) extract_type_inst(f &Fn, args_ []string) TypeInst {
tp := f.type_pars[i] tp := f.type_pars[i]
mut ti := e mut ti := e
if ti.starts_with('fn (') { if ti.starts_with('fn (') {
fn_args := ti.right(4).all_before(') ').split(',') fn_args := ti[4..].all_before(') ').split(',')
mut found := false mut found := false
for fa_ in fn_args { for fa_ in fn_args {
mut fa := fa_ mut fa := fa_
for fa.starts_with('array_') { fa = fa.right(6) } for fa.starts_with('array_') { fa = fa[6..] }
if fa == tp { if fa == tp {
r.inst[tp] = fa r.inst[tp] = fa
found = true found = true
@ -1114,7 +1114,7 @@ fn (p mut Parser) extract_type_inst(f &Fn, args_ []string) TypeInst {
if found { continue } if found { continue }
ti = ti.all_after(') ') ti = ti.all_after(') ')
} }
for ti.starts_with('array_') { ti = ti.right(6) } for ti.starts_with('array_') { ti = ti[6..] }
if r.inst[tp] != '' { if r.inst[tp] != '' {
if r.inst[tp] != ti { if r.inst[tp] != ti {
p.error('type parameter `$tp` has type ${r.inst[tp]}, not `$ti`') p.error('type parameter `$tp` has type ${r.inst[tp]}, not `$ti`')
@ -1150,12 +1150,12 @@ fn (p mut Parser) replace_type_params(f &Fn, ti TypeInst) []string {
mut fr := '' mut fr := ''
if fi.starts_with('fn (') { if fi.starts_with('fn (') {
fr += 'fn (' fr += 'fn ('
mut fn_args := fi.right(4).all_before(') ').split(',') mut fn_args := fi[4..].all_before(') ').split(',')
fn_args << fi.all_after(') ') fn_args << fi.all_after(') ')
for i, fa_ in fn_args { for i, fa_ in fn_args {
mut fna := fa_.trim_space() mut fna := fa_.trim_space()
for fna.starts_with('array_') { for fna.starts_with('array_') {
fna = fna.right(6) fna = fna[6..]
fr += 'array_' fr += 'array_'
} }
if fna in ti.inst.keys() { if fna in ti.inst.keys() {
@ -1173,11 +1173,11 @@ fn (p mut Parser) replace_type_params(f &Fn, ti TypeInst) []string {
continue continue
} }
for fi.starts_with('array_') { for fi.starts_with('array_') {
fi = fi.right(6) fi = fi[6..]
fr += 'array_' fr += 'array_'
} }
is_varg := fi.starts_with('...') is_varg := fi.starts_with('...')
if is_varg { fi = fi.right(3) } if is_varg { fi = fi[3..] }
if fi in ti.inst.keys() { if fi in ti.inst.keys() {
mut t := ti.inst[fi] mut t := ti.inst[fi]
if is_varg { t = '...$t' } if is_varg { t = '...$t' }
@ -1214,7 +1214,7 @@ fn (p mut Parser) fn_call_vargs(f Fn) (string, []string) {
return '', []string return '', []string
} }
last_arg := f.args.last() last_arg := f.args.last()
mut varg_def_type := last_arg.typ.right(3) mut varg_def_type := last_arg.typ[3..]
mut types := []string mut types := []string
mut values := []string mut values := []string
for p.tok != .rpar { for p.tok != .rpar {
@ -1428,7 +1428,7 @@ fn (f &Fn) str_args(table &Table) string {
for method in interface_type.methods { for method in interface_type.methods {
s += ', $method.typ (*${arg.typ}_${method.name})(void*' s += ', $method.typ (*${arg.typ}_${method.name})(void*'
if method.args.len > 1 { if method.args.len > 1 {
for a in method.args.right(1) { for a in method.args[1..] {
s += ', $a.typ' s += ', $a.typ'
} }
} }

View File

@ -17,7 +17,7 @@ fn (p mut Parser) gen_var_decl(name string, is_static bool) string {
// `[typ] [name] = bool_expression();` // `[typ] [name] = bool_expression();`
pos := p.cgen.add_placeholder() pos := p.cgen.add_placeholder()
mut typ := p.bool_expression() mut typ := p.bool_expression()
if typ.starts_with('...') { typ = typ.right(3) } if typ.starts_with('...') { typ = typ[3..] }
//p.gen('/*after expr*/') //p.gen('/*after expr*/')
// Option check ? or { // Option check ? or {
or_else := p.tok == .key_orelse or_else := p.tok == .key_orelse
@ -66,7 +66,7 @@ fn (p mut Parser) gen_var_decl(name string, is_static bool) string {
} else if typ.starts_with('[') && typ[ typ.len-1 ] != `*` { } else if typ.starts_with('[') && typ[ typ.len-1 ] != `*` {
// a fixed_array initializer, like `v := [1.1, 2.2]!!` // a fixed_array initializer, like `v := [1.1, 2.2]!!`
// ... should translate to the following in C `f32 v[2] = {1.1, 2.2};` // ... should translate to the following in C `f32 v[2] = {1.1, 2.2};`
initializer := p.cgen.cur_line.right(pos) initializer := p.cgen.cur_line[pos..]
if initializer.len > 0 { if initializer.len > 0 {
p.cgen.resetln(' = {' + initializer.all_after('{') ) p.cgen.resetln(' = {' + initializer.all_after('{') )
} else if initializer.len == 0 { } else if initializer.len == 0 {
@ -175,11 +175,11 @@ fn (p mut Parser) index_get(typ string, fn_ph int, cfg IndexConfig) {
// "m, 0" is an index expression, save it before deleting and insert later in map_get() // "m, 0" is an index expression, save it before deleting and insert later in map_get()
mut index_expr := '' mut index_expr := ''
if p.cgen.is_tmp { if p.cgen.is_tmp {
index_expr = p.cgen.tmp_line.right(fn_ph) index_expr = p.cgen.tmp_line[fn_ph..]
p.cgen.resetln(p.cgen.tmp_line.left(fn_ph)) p.cgen.resetln(p.cgen.tmp_line[..fn_ph])
} else { } else {
index_expr = p.cgen.cur_line.right(fn_ph) index_expr = p.cgen.cur_line[fn_ph..]
p.cgen.resetln(p.cgen.cur_line.left(fn_ph)) p.cgen.resetln(p.cgen.cur_line[..fn_ph])
} }
// Can't pass integer literal, because map_get() requires a void* // Can't pass integer literal, because map_get() requires a void*
tmp := p.get_tmp() tmp := p.get_tmp()
@ -301,9 +301,9 @@ fn (p mut Parser) gen_array_at(typ_ string, is_arr0 bool, fn_ph int) {
// array_int a; a[0] // array_int a; a[0]
// type is "array_int", need "int" // type is "array_int", need "int"
// typ = typ.replace('array_', '') // typ = typ.replace('array_', '')
if is_arr0 { // if is_arr0 {
typ = typ.right(6) // typ = typ.right(6)
} // }
// array a; a.first() voidptr // array a; a.first() voidptr
// type is "array", need "void*" // type is "array", need "void*"
if typ == 'array' { if typ == 'array' {
@ -377,8 +377,8 @@ fn (p mut Parser) gen_array_init(typ string, no_alloc bool, new_arr_ph int, nr_e
fn (p mut Parser) gen_array_set(typ string, is_ptr, is_map bool,fn_ph, assign_pos int, is_cao bool) { fn (p mut Parser) gen_array_set(typ string, is_ptr, is_map bool,fn_ph, assign_pos int, is_cao bool) {
// `a[0] = 7` // `a[0] = 7`
// curline right now: `a , 0 = 7` // curline right now: `a , 0 = 7`
mut val := p.cgen.cur_line.right(assign_pos) mut val := p.cgen.cur_line[assign_pos..]
p.cgen.resetln(p.cgen.cur_line.left(assign_pos)) p.cgen.resetln(p.cgen.cur_line[..assign_pos])
mut cao_tmp := p.cgen.cur_line mut cao_tmp := p.cgen.cur_line
mut func := '' mut func := ''
if is_map { if is_map {
@ -522,7 +522,7 @@ fn (p mut Parser) cast(typ string) {
fn type_default(typ string) string { fn type_default(typ string) string {
if typ.starts_with('array_') { if typ.starts_with('array_') {
return 'new_array(0, 1, sizeof( ${typ.right(6)} ))' return 'new_array(0, 1, sizeof( ${typ[6..]} ))'
} }
// Always set pointers to 0 // Always set pointers to 0
if typ.ends_with('*') { if typ.ends_with('*') {
@ -567,7 +567,7 @@ fn (p mut Parser) gen_array_push(ph int, typ, expr_type, tmp, elm_type string) {
push_call := if typ.contains('*'){'_PUSH('} else { '_PUSH(&'} push_call := if typ.contains('*'){'_PUSH('} else { '_PUSH(&'}
p.cgen.set_placeholder(ph, push_call) p.cgen.set_placeholder(ph, push_call)
if elm_type.ends_with('*') { if elm_type.ends_with('*') {
p.gen('), $tmp, ${elm_type.left(elm_type.len - 1)})') p.gen('), $tmp, ${elm_type[..elm_type.len - 1]})')
} else { } else {
p.gen('), $tmp, $elm_type)') p.gen('), $tmp, $elm_type)')
} }

View File

@ -9,7 +9,7 @@ const (
fn (p mut Parser) gen_var_decl(name string, is_static bool) string { fn (p mut Parser) gen_var_decl(name string, is_static bool) string {
p.gen('var $name /* typ */ = ') p.gen('var $name /* typ */ = ')
mut typ := p.bool_expression() mut typ := p.bool_expression()
if typ.starts_with('...') { typ = typ.right(3) } if typ.starts_with('...') { typ = typ[3..] }
or_else := p.tok == .key_orelse or_else := p.tok == .key_orelse
//tmp := p.get_tmp() //tmp := p.get_tmp()
if or_else { if or_else {
@ -149,8 +149,8 @@ fn (p mut Parser) gen_array_init(typ string, no_alloc bool, new_arr_ph int, nr_e
} }
fn (p mut Parser) gen_array_set(typ string, is_ptr, is_map bool,fn_ph, assign_pos int, is_cao bool) { fn (p mut Parser) gen_array_set(typ string, is_ptr, is_map bool,fn_ph, assign_pos int, is_cao bool) {
mut val := p.cgen.cur_line.right(assign_pos) mut val := p.cgen.cur_line[assign_pos..]
p.cgen.resetln(p.cgen.cur_line.left(assign_pos)) p.cgen.resetln(p.cgen.cur_line[..assign_pos])
p.gen('] =') p.gen('] =')
cao_tmp := p.cgen.cur_line cao_tmp := p.cgen.cur_line
if is_cao { if is_cao {

View File

@ -86,7 +86,7 @@ string res = tos2("");
continue continue
} }
name := if field.attr.starts_with('json:') { name := if field.attr.starts_with('json:') {
field.attr.right(5) field.attr[5..]
} else { } else {
field.name field.name
} }

View File

@ -493,7 +493,7 @@ pub fn (v V) run_compiled_executable_and_exit() {
if i == 0 { continue } if i == 0 { continue }
if a.starts_with('-') { continue } if a.starts_with('-') { continue }
if a in ['run','test'] { if a in ['run','test'] {
args_after += args.right(i+2).join(' ') args_after += args[i+2..].join(' ')
break break
} }
} }
@ -660,7 +660,7 @@ pub fn (v &V) get_user_files() []string {
if is_test_with_imports { if is_test_with_imports {
user_files << dir user_files << dir
pos := dir.last_index(os.path_separator) pos := dir.last_index(os.path_separator)
dir = dir.left(pos) + os.path_separator// TODO why is this needed dir = dir[..pos] + os.path_separator// TODO why is this needed
} }
if dir.ends_with('.v') || dir.ends_with('.vsh') { if dir.ends_with('.v') || dir.ends_with('.vsh') {
// Just compile one file and get parent dir // Just compile one file and get parent dir
@ -743,7 +743,7 @@ pub fn get_param_after(joined_args, arg, def string) string {
if space == -1 { if space == -1 {
space = joined_args.len space = joined_args.len
} }
res := joined_args.substr(pos, space) res := joined_args[pos..space]
return res return res
} }
@ -777,7 +777,7 @@ pub fn new_v(args[]string) &V {
dir = dir.all_before_last(os.path_separator) dir = dir.all_before_last(os.path_separator)
} }
if dir.starts_with('.$os.path_separator') { if dir.starts_with('.$os.path_separator') {
dir = dir.right(2) dir = dir[2..]
} }
if args.len < 2 { if args.len < 2 {
dir = '' dir = ''
@ -792,7 +792,7 @@ pub fn new_v(args[]string) &V {
dir.all_after('vlib'+os.path_separator) dir.all_after('vlib'+os.path_separator)
} }
else if dir.starts_with('.\\') || dir.starts_with('./') { else if dir.starts_with('.\\') || dir.starts_with('./') {
dir.right(2) dir[2..]
} }
else if dir.starts_with(os.path_separator) { else if dir.starts_with(os.path_separator) {
dir.all_after(os.path_separator) dir.all_after(os.path_separator)
@ -821,7 +821,7 @@ pub fn new_v(args[]string) &V {
} }
// No -o provided? foo.v => foo // No -o provided? foo.v => foo
if out_name == 'a.out' && dir.ends_with('.v') && dir != '.v' { if out_name == 'a.out' && dir.ends_with('.v') && dir != '.v' {
out_name = dir.left(dir.len - 2) out_name = dir[..dir.len - 2]
// Building V? Use v2, since we can't overwrite a running // Building V? Use v2, since we can't overwrite a running
// executable on Windows + the precompiled V is more // executable on Windows + the precompiled V is more
// optimized. // optimized.
@ -957,7 +957,7 @@ pub fn env_vflags_and_os_args() []string {
args << os.args[0] args << os.args[0]
args << vflags.split(' ') args << vflags.split(' ')
if os.args.len > 1 { if os.args.len > 1 {
args << os.args.right(1) args << os.args[1..]
} }
} else{ } else{
args << os.args args << os.args

View File

@ -158,7 +158,7 @@ fn find_vs(vswhere_dir string, host_arch string) ?VsInstallation {
// println('version: $version') // println('version: $version')
v := if version.ends_with('\n') { v := if version.ends_with('\n') {
version.left(version.len - 2) version[..version.len - 2]
} else { } else {
version version
} }

View File

@ -8,7 +8,7 @@ fn (p mut Parser) in_optimization(typ string, ph int) {
p.check(.lsbr) p.check(.lsbr)
mut i := 0 mut i := 0
// Get `a` expr value (can be a string literal, not a variable) // Get `a` expr value (can be a string literal, not a variable)
expr := p.cgen.cur_line.right(ph) expr := p.cgen.cur_line[ph..]
is_str := typ == 'string' is_str := typ == 'string'
//println('!! $p.expr_var.name => $name ($typ)') //println('!! $p.expr_var.name => $name ($typ)')
for p.tok != .rsbr && p.tok != .eof { for p.tok != .rsbr && p.tok != .eof {

View File

@ -1030,7 +1030,7 @@ fn (p mut Parser) close_scope() {
//p.cur_fn.defer_text[f] = '' //p.cur_fn.defer_text[f] = ''
} }
p.cur_fn.scope_level-- p.cur_fn.scope_level--
p.cur_fn.defer_text = p.cur_fn.defer_text.left(p.cur_fn.scope_level + 1) p.cur_fn.defer_text = p.cur_fn.defer_text[..p.cur_fn.scope_level + 1]
p.var_idx = i + 1 p.var_idx = i + 1
// println('close_scope new var_idx=$f.var_idx\n') // println('close_scope new var_idx=$f.var_idx\n')
} }
@ -1235,17 +1235,17 @@ fn ($v.name mut $v.typ) $p.cur_fn.name (...) {
//} //}
// Allow `num = 4` where `num` is an `?int` // Allow `num = 4` where `num` is an `?int`
if p.assigned_type.starts_with('Option_') && if p.assigned_type.starts_with('Option_') &&
expr_type == p.assigned_type.right('Option_'.len) { expr_type == p.assigned_type['Option_'.len..] {
expr := p.cgen.cur_line.right(pos) expr := p.cgen.cur_line[pos..]
left := p.cgen.cur_line.left(pos) left := p.cgen.cur_line[..pos]
typ := expr_type.replace('Option_', '') typ := expr_type.replace('Option_', '')
p.cgen.resetln(left + 'opt_ok($expr, sizeof($typ))') p.cgen.resetln(left + 'opt_ok($expr, sizeof($typ))')
} }
else if expr_type[0]==`[` { else if expr_type[0]==`[` {
// assignment to a fixed_array `mut a:=[3]int a=[1,2,3]!!` // assignment to a fixed_array `mut a:=[3]int a=[1,2,3]!!`
expr := p.cgen.cur_line.right(pos).all_after('{').all_before('}') expr := p.cgen.cur_line[pos..].all_after('{').all_before('}')
left := p.cgen.cur_line.left(pos).all_before('=') left := p.cgen.cur_line[..pos].all_before('=')
cline_pos := p.cgen.cur_line.right(pos) cline_pos := p.cgen.cur_line[pos..]
etype := cline_pos.all_before(' {') etype := cline_pos.all_before(' {')
if p.assigned_type != p.expected_type { if p.assigned_type != p.expected_type {
p.error_with_token_index( 'incompatible types: $p.assigned_type != $p.expected_type', errtok) p.error_with_token_index( 'incompatible types: $p.assigned_type != $p.expected_type', errtok)
@ -1933,7 +1933,7 @@ fn (p mut Parser) dot(str_typ_ string, method_ph int) string {
mut str_typ := str_typ_ mut str_typ := str_typ_
p.check(.dot) p.check(.dot)
is_variadic_arg := str_typ.starts_with('...') is_variadic_arg := str_typ.starts_with('...')
if is_variadic_arg { str_typ = str_typ.right(3) } if is_variadic_arg { str_typ = str_typ[3..] }
mut typ := p.find_type(str_typ) mut typ := p.find_type(str_typ)
if typ.name.len == 0 { if typ.name.len == 0 {
p.error('dot(): cannot find type `$str_typ`') p.error('dot(): cannot find type `$str_typ`')
@ -1971,7 +1971,7 @@ fn (p mut Parser) dot(str_typ_ string, method_ph int) string {
} }
if !typ.is_c && !p.is_c_fn_call && !has_field && !has_method && !p.first_pass() { if !typ.is_c && !p.is_c_fn_call && !has_field && !has_method && !p.first_pass() {
if typ.name.starts_with('Option_') { if typ.name.starts_with('Option_') {
opt_type := typ.name.right(7) opt_type := typ.name[7..]
p.error('unhandled option type: `?$opt_type`') p.error('unhandled option type: `?$opt_type`')
} }
//println('error in dot():') //println('error in dot():')
@ -2044,7 +2044,7 @@ struct $typ.name {
} }
// Array methods returning `voidptr` (like `last()`) should return element type // Array methods returning `voidptr` (like `last()`) should return element type
if method.typ == 'void*' && typ.name.starts_with('array_') { if method.typ == 'void*' && typ.name.starts_with('array_') {
return typ.name.right(6) return typ.name[6..]
} }
//if false && p.tok == .lsbr { //if false && p.tok == .lsbr {
// if is_indexer { // if is_indexer {
@ -2119,7 +2119,7 @@ fn (p mut Parser) index_expr(typ_ string, fn_ph int) string {
// `[10]int` => `int`, `[10][3]int` => `[3]int` // `[10]int` => `int`, `[10][3]int` => `[3]int`
if typ.contains('][') { if typ.contains('][') {
pos := typ.index_after('[', 1) pos := typ.index_after('[', 1)
typ = typ.right(pos) typ = typ[pos..]
} }
else { else {
typ = typ.all_after(']') typ = typ.all_after(']')
@ -2138,7 +2138,7 @@ fn (p mut Parser) index_expr(typ_ string, fn_ph int) string {
} }
if is_arr { if is_arr {
if is_arr0 { if is_arr0 {
typ = typ.right(6) typ = typ[6..]
} }
p.gen_array_at(typ, is_arr0, fn_ph) p.gen_array_at(typ, is_arr0, fn_ph)
} }
@ -2163,7 +2163,7 @@ fn (p mut Parser) index_expr(typ_ string, fn_ph int) string {
if T.parent != 'int' && T.parent != 'u32' { if T.parent != 'int' && T.parent != 'u32' {
p.check_types(T.name, 'int') p.check_types(T.name, 'int')
} }
if p.cgen.cur_line.right(index_pos).replace(' ', '').int() < 0 { if p.cgen.cur_line[index_pos..].replace(' ', '').int() < 0 {
p.error('cannot access negative array index') p.error('cannot access negative array index')
} }
} }
@ -2216,7 +2216,7 @@ fn (p mut Parser) index_expr(typ_ string, fn_ph int) string {
if is_indexer { if is_indexer {
l := p.cgen.cur_line.trim_space() l := p.cgen.cur_line.trim_space()
index_val := l.right(l.last_index(' ')).trim_space() index_val := l.right(l.last_index(' ')).trim_space()
p.cgen.resetln(l.left(fn_ph)) p.cgen.resetln(l[..fn_ph])
p.table.varg_access << VargAccess{ p.table.varg_access << VargAccess{
fn_name: p.cur_fn.name, fn_name: p.cur_fn.name,
tok_idx: index_error_tok_pos, tok_idx: index_error_tok_pos,
@ -2337,7 +2337,7 @@ fn (p mut Parser) expression() string {
// a << 7 => int tmp = 7; array_push(&a, &tmp); // a << 7 => int tmp = 7; array_push(&a, &tmp);
// _PUSH(&a, expression(), tmp, string) // _PUSH(&a, expression(), tmp, string)
tmp := p.get_tmp() tmp := p.get_tmp()
tmp_typ := typ.right(6)// skip "array_" tmp_typ := typ[6..]// skip "array_"
p.check_space(.left_shift) p.check_space(.left_shift)
// Get the value we are pushing // Get the value we are pushing
p.gen(', (') p.gen(', (')
@ -2989,8 +2989,8 @@ fn (p mut Parser) array_init() string {
if i == 1 && p.tok == .semicolon { if i == 1 && p.tok == .semicolon {
p.warn('`[0 ; len]` syntax was removed. Use `[0].repeat(len)` instead') p.warn('`[0 ; len]` syntax was removed. Use `[0].repeat(len)` instead')
p.check_space(.semicolon) p.check_space(.semicolon)
val := p.cgen.cur_line.right(pos) val := p.cgen.cur_line[pos..]
p.cgen.resetln(p.cgen.cur_line.left(pos)) p.cgen.resetln(p.cgen.cur_line[..pos])
p.gen('array_repeat_old(& ($typ[]){ $val }, ') p.gen('array_repeat_old(& ($typ[]){ $val }, ')
p.check_types(p.bool_expression(), 'int') p.check_types(p.bool_expression(), 'int')
p.gen(', sizeof($typ) )') p.gen(', sizeof($typ) )')
@ -3080,7 +3080,7 @@ fn (p mut Parser) if_st(is_expr bool, elif_depth int) string {
p.next() p.next()
p.check(.decl_assign) p.check(.decl_assign)
option_type, expr := p.tmp_expr()// := p.bool_expression() option_type, expr := p.tmp_expr()// := p.bool_expression()
typ := option_type.right(7) typ := option_type[7..]
// Option_User tmp = get_user(1); // Option_User tmp = get_user(1);
// if (tmp.ok) { // if (tmp.ok) {
// User user = *(User*)tmp.data; // User user = *(User*)tmp.data;
@ -3236,7 +3236,7 @@ fn (p mut Parser) for_st() {
is_map := typ.starts_with('map_') is_map := typ.starts_with('map_')
is_str := typ == 'string' is_str := typ == 'string'
is_variadic_arg := typ.starts_with('...') is_variadic_arg := typ.starts_with('...')
if is_variadic_arg { typ = typ.right(3) } if is_variadic_arg { typ = typ[3..] }
if !is_arr && !is_str && !is_map && !is_variadic_arg { if !is_arr && !is_str && !is_map && !is_variadic_arg {
p.error('cannot range over type `$typ`') p.error('cannot range over type `$typ`')
} }
@ -3251,7 +3251,7 @@ fn (p mut Parser) for_st() {
pad := if is_arr { 6 } else { 4 } pad := if is_arr { 6 } else { 4 }
var_typ := if is_str { 'byte' } var_typ := if is_str { 'byte' }
else if is_variadic_arg { typ } else if is_variadic_arg { typ }
else { typ.right(pad) } else { typ[pad..] }
// typ = strings.Replace(typ, "_ptr", "*", -1) // typ = strings.Replace(typ, "_ptr", "*", -1)
mut i_var_type := 'int' mut i_var_type := 'int'
if is_variadic_arg { if is_variadic_arg {
@ -3297,7 +3297,7 @@ fn (p mut Parser) for_st() {
expr := p.cgen.end_tmp() expr := p.cgen.end_tmp()
is_range := p.tok == .dotdot is_range := p.tok == .dotdot
is_variadic_arg := typ.starts_with('...') is_variadic_arg := typ.starts_with('...')
if is_variadic_arg { typ = typ.right(3) } if is_variadic_arg { typ = typ[3..] }
mut range_end := '' mut range_end := ''
if is_range { if is_range {
p.check_types(typ, 'int') p.check_types(typ, 'int')
@ -3329,7 +3329,7 @@ fn (p mut Parser) for_st() {
p.gen_for_range_header(i, range_end, tmp, var_type, val) p.gen_for_range_header(i, range_end, tmp, var_type, val)
} }
else if is_arr { else if is_arr {
var_type = typ.right(6)// all after `array_` var_type = typ[6..]// all after `array_`
p.gen_for_header(i, tmp, var_type, val) p.gen_for_header(i, tmp, var_type, val)
} }
else if is_str { else if is_str {
@ -3686,7 +3686,7 @@ fn (p mut Parser) return_st() {
mut expr_type := p.bool_expression() mut expr_type := p.bool_expression()
// println('$p.cur_fn.name returns type $expr_type, should be $p.cur_fn.typ') // println('$p.cur_fn.name returns type $expr_type, should be $p.cur_fn.typ')
mut types := []string mut types := []string
mut mr_values := [p.cgen.cur_line.right(ph).trim_space()] mut mr_values := [p.cgen.cur_line[ph..].trim_space()]
types << expr_type types << expr_type
for p.tok == .comma { for p.tok == .comma {
p.check(.comma) p.check(.comma)
@ -3715,14 +3715,14 @@ fn (p mut Parser) return_st() {
if p.cur_fn.typ.ends_with(expr_type) && !is_none && if p.cur_fn.typ.ends_with(expr_type) && !is_none &&
p.cur_fn.typ.starts_with('Option_') { p.cur_fn.typ.starts_with('Option_') {
tmp := p.get_tmp() tmp := p.get_tmp()
ret := p.cgen.cur_line.right(ph) ret := p.cgen.cur_line[ph..]
typ := expr_type.replace('Option_', '') typ := expr_type.replace('Option_', '')
p.cgen.resetln('$expr_type $tmp = OPTION_CAST($expr_type)($ret);') p.cgen.resetln('$expr_type $tmp = OPTION_CAST($expr_type)($ret);')
p.genln(deferred_text) p.genln(deferred_text)
p.gen('return opt_ok(&$tmp, sizeof($typ))') p.gen('return opt_ok(&$tmp, sizeof($typ))')
} }
else { else {
ret := p.cgen.cur_line.right(ph) ret := p.cgen.cur_line[ph..]
if deferred_text == '' || expr_type == 'void*' { if deferred_text == '' || expr_type == 'void*' {
// no defer{} necessary? // no defer{} necessary?
@ -3928,17 +3928,17 @@ fn (p mut Parser) defer_st() {
p.genln('{') p.genln('{')
p.statements() p.statements()
p.cur_fn.defer_text.last() = p.cgen.lines.right(pos).join('\n') + p.cur_fn.defer_text.last() p.cur_fn.defer_text.last() = p.cgen.lines[pos..].join('\n') + p.cur_fn.defer_text.last()
// Rollback p.cgen.lines // Rollback p.cgen.lines
p.cgen.lines = p.cgen.lines.left(pos) p.cgen.lines = p.cgen.lines[..pos]
p.cgen.resetln('') p.cgen.resetln('')
} }
fn (p mut Parser) check_and_register_used_imported_type(typ_name string) { fn (p mut Parser) check_and_register_used_imported_type(typ_name string) {
us_idx := typ_name.index('__') us_idx := typ_name.index('__')
if us_idx != -1 { if us_idx != -1 {
arg_mod := typ_name.left(us_idx) arg_mod := typ_name[..us_idx]
if p.import_table.known_alias(arg_mod) { if p.import_table.known_alias(arg_mod) {
p.import_table.register_used_import(arg_mod) p.import_table.register_used_import(arg_mod)
} }

View File

@ -28,13 +28,13 @@ fn (r mut Repl) checks() bool {
in_string = !in_string in_string = !in_string
} }
if r.line[i] == `{` && !in_string { if r.line[i] == `{` && !in_string {
r.line = r.line.left(i + 1) + '\n' + r.line.right(i + 1) r.line = r.line[..i + 1] + '\n' + r.line[i + 1..]
is_cut = true is_cut = true
i++ i++
r.indent++ r.indent++
} }
if r.line[i] == `}` && !in_string { if r.line[i] == `}` && !in_string {
r.line = r.line.left(i) + '\n' + r.line.right(i) r.line = r.line[..i] + '\n' + r.line[i..]
is_cut = true is_cut = true
i++ i++
r.indent-- r.indent--
@ -77,8 +77,8 @@ pub fn run_repl() []string {
defer { defer {
os.rm(file) os.rm(file)
os.rm(temp_file) os.rm(temp_file)
os.rm(file.left(file.len - 2)) os.rm(file[..file.len - 2])
os.rm(temp_file.left(temp_file.len - 2)) os.rm(temp_file[..temp_file.len - 2])
} }
mut r := Repl{} mut r := Repl{}
vexe := os.args[0] vexe := os.args[0]

View File

@ -106,7 +106,7 @@ fn (s mut Scanner) ident_name() string {
break break
} }
} }
name := s.text.substr(start, s.pos) name := s.text[start..s.pos]
s.pos-- s.pos--
return name return name
} }
@ -124,7 +124,7 @@ fn (s mut Scanner) ident_hex_number() string {
} }
s.pos++ s.pos++
} }
number := s.text.substr(start_pos, s.pos) number := s.text[start_pos..s.pos]
s.pos-- s.pos--
return number return number
} }
@ -145,7 +145,7 @@ fn (s mut Scanner) ident_oct_number() string {
} }
s.pos++ s.pos++
} }
number := s.text.substr(start_pos, s.pos) number := s.text[start_pos..s.pos]
s.pos-- s.pos--
return number return number
} }
@ -161,7 +161,7 @@ fn (s mut Scanner) ident_dec_number() string {
// e.g. 1..9 // e.g. 1..9
// we just return '1' and don't scan '..9' // we just return '1' and don't scan '..9'
if s.expect('..', s.pos) { if s.expect('..', s.pos) {
number := s.text.substr(start_pos, s.pos) number := s.text[start_pos..s.pos]
s.pos-- s.pos--
return number return number
} }
@ -200,7 +200,7 @@ fn (s mut Scanner) ident_dec_number() string {
} }
} }
number := s.text.substr(start_pos, s.pos) number := s.text[start_pos..s.pos]
s.pos-- s.pos--
return number return number
} }
@ -474,11 +474,11 @@ fn (s mut Scanner) scan() ScanRes {
s.ignore_line() s.ignore_line()
if nextc == `!` { if nextc == `!` {
// treat shebang line (#!) as a comment // treat shebang line (#!) as a comment
s.line_comment = s.text.substr(start + 1, s.pos).trim_space() s.line_comment = s.text[start + 1..s.pos].trim_space()
s.fgenln('// shebang line "$s.line_comment"') s.fgenln('// shebang line "$s.line_comment"')
return s.scan() return s.scan()
} }
hash := s.text.substr(start, s.pos) hash := s.text[start..s.pos]
return scan_res(.hash, hash.trim_space()) return scan_res(.hash, hash.trim_space())
} }
`>` { `>` {
@ -577,7 +577,7 @@ fn (s mut Scanner) scan() ScanRes {
if nextc == `/` { if nextc == `/` {
start := s.pos + 1 start := s.pos + 1
s.ignore_line() s.ignore_line()
s.line_comment = s.text.substr(start + 1, s.pos) s.line_comment = s.text[start + 1..s.pos]
s.line_comment = s.line_comment.trim_space() s.line_comment = s.line_comment.trim_space()
s.fgenln('// ${s.prev_tok.str()} "$s.line_comment"') s.fgenln('// ${s.prev_tok.str()} "$s.line_comment"')
// Skip the comment (return the next token) // Skip the comment (return the next token)
@ -608,7 +608,7 @@ fn (s mut Scanner) scan() ScanRes {
} }
s.pos++ s.pos++
end := s.pos + 1 end := s.pos + 1
comm := s.text.substr(start, end) comm := s.text[start..end]
s.fgenln(comm) s.fgenln(comm)
// Skip if not in fmt mode // Skip if not in fmt mode
return s.scan() return s.scan()
@ -706,7 +706,7 @@ fn (s mut Scanner) ident_string() string {
} }
if start > s.pos{} if start > s.pos{}
else { else {
lit = s.text.substr(start, end) lit = s.text[start..end]
} }
return lit return lit
} }
@ -732,7 +732,7 @@ fn (s mut Scanner) ident_char() string {
} }
} }
len-- len--
c := s.text.substr(start + 1, s.pos) c := s.text[start + 1..s.pos]
if len != 1 { if len != 1 {
u := c.ustring() u := c.ustring()
if u.len != 1 { if u.len != 1 {
@ -814,7 +814,7 @@ fn (s Scanner) line(n int) string {
nline_start := if n == 0 { 0 } else { s.line_ends[ n - 1 ] } nline_start := if n == 0 { 0 } else { s.line_ends[ n - 1 ] }
nline_end := s.line_ends[n] nline_end := s.line_ends[n]
if nline_start <= nline_end { if nline_start <= nline_end {
res = s.text.substr( nline_start, nline_end ) res = s.text[nline_start..nline_end]
} }
} }
return res.trim_right('\r\n').trim_left('\r\n') return res.trim_right('\r\n').trim_left('\r\n')

View File

@ -13,7 +13,7 @@ fn (p mut Parser) struct_decl() {
// V can generate Objective C for integration with Cocoa // V can generate Objective C for integration with Cocoa
// `[objc_interface:ParentInterface]` // `[objc_interface:ParentInterface]`
is_objc := p.attr.starts_with('objc_interface') is_objc := p.attr.starts_with('objc_interface')
objc_parent := if is_objc { p.attr.right(15) } else { '' } objc_parent := if is_objc { p.attr[15..] } else { '' }
// interface, union, struct // interface, union, struct
is_interface := p.tok == .key_interface is_interface := p.tok == .key_interface
is_union := p.tok == .key_union is_union := p.tok == .key_union
@ -288,7 +288,7 @@ fn (p mut Parser) struct_init(typ string) string {
// init map fields // init map fields
if field_typ.starts_with('map_') { if field_typ.starts_with('map_') {
p.gen_struct_field_init(sanitized_name) p.gen_struct_field_init(sanitized_name)
p.gen_empty_map(field_typ.right(4)) p.gen_empty_map(field_typ[4..])
inited_fields << sanitized_name inited_fields << sanitized_name
if i != t.fields.len - 1 { if i != t.fields.len - 1 {
p.gen(',') p.gen(',')

View File

@ -330,11 +330,11 @@ fn (table &Table) known_type(typ_ string) bool {
mut typ := typ_ mut typ := typ_
// vararg // vararg
if typ.starts_with('...') && typ.len > 3 { if typ.starts_with('...') && typ.len > 3 {
typ = typ.right(3) typ = typ[3..]
} }
// 'byte*' => look up 'byte', but don't mess up fns // 'byte*' => look up 'byte', but don't mess up fns
if typ.ends_with('*') && !typ.contains(' ') { if typ.ends_with('*') && !typ.contains(' ') {
typ = typ.left(typ.len - 1) typ = typ[..typ.len - 1]
} }
t := table.typesmap[typ] t := table.typesmap[typ]
return t.name.len > 0 && !t.is_placeholder return t.name.len > 0 && !t.is_placeholder
@ -560,7 +560,7 @@ fn (p &Parser) find_type(name string) Type {
fn (t &Table) find_type(name_ string) Type { fn (t &Table) find_type(name_ string) Type {
mut name := name_ mut name := name_
if name.ends_with('*') && !name.contains(' ') { if name.ends_with('*') && !name.contains(' ') {
name = name.left(name.len - 1) name = name[..name.len - 1]
} }
if !(name in t.typesmap) { if !(name in t.typesmap) {
//println('ret Type') //println('ret Type')
@ -585,10 +585,10 @@ fn (p mut Parser) check_types2(got_, expected_ string, throw bool) bool {
// variadic // variadic
if expected.starts_with('...') { if expected.starts_with('...') {
expected = expected.right(3) expected = expected[3..]
} }
if got.starts_with('...') { if got.starts_with('...') {
got = got.right(3) got = got[3..]
} }
// Allow ints to be used as floats // Allow ints to be used as floats
if got == 'int' && expected == 'f32' { if got == 'int' && expected == 'f32' {
@ -906,7 +906,7 @@ fn (p &Parser) identify_typo(name string) string {
fn (table &Table) find_misspelled_fn(name string, p &Parser, min_match f32) string { fn (table &Table) find_misspelled_fn(name string, p &Parser, min_match f32) string {
mut closest := f32(0) mut closest := f32(0)
mut closest_fn := '' mut closest_fn := ''
n1 := if name.starts_with('main__') { name.right(6) } else { name } n1 := if name.starts_with('main__') { name[6..] } else { name }
for _, f in table.fns { for _, f in table.fns {
if n1.len - f.name.len > 2 || f.name.len - n1.len > 2 { continue } if n1.len - f.name.len > 2 || f.name.len - n1.len > 2 { continue }
if !(f.mod in ['', 'main', 'builtin']) { if !(f.mod in ['', 'main', 'builtin']) {
@ -933,7 +933,7 @@ fn (table &Table) find_misspelled_fn(name string, p &Parser, min_match f32) stri
fn (table &Table) find_misspelled_imported_mod(name string, p &Parser, min_match f32) string { fn (table &Table) find_misspelled_imported_mod(name string, p &Parser, min_match f32) string {
mut closest := f32(0) mut closest := f32(0)
mut closest_mod := '' mut closest_mod := ''
n1 := if name.starts_with('main.') { name.right(5) } else { name } n1 := if name.starts_with('main.') { name[5..] } else { name }
for alias, mod in p.import_table.imports { for alias, mod in p.import_table.imports {
if n1.len - alias.len > 2 || alias.len - n1.len > 2 { continue } if n1.len - alias.len > 2 || alias.len - n1.len > 2 { continue }
mod_alias := if alias == mod { alias } else { '$alias ($mod)' } mod_alias := if alias == mod { alias } else { '$alias ($mod)' }

View File

@ -13,8 +13,8 @@ fn test_flag_parsing() {
mut base := rest mut base := rest
fl := if rest.starts_with('-') { fl := if rest.starts_with('-') {
base = rest.right(2).trim_space() base = rest[2..].trim_space()
rest.left(2) rest[..2]
} else { } else {
'' ''
} }
@ -28,8 +28,8 @@ fn test_flag_parsing() {
} }
} }
arg := if lowest != -1 { arg := if lowest != -1 {
rest = base.right(lowest).trim_space().trim(',') rest = base[lowest..].trim_space().trim(',')
base.left(lowest).trim_space().trim(',') base[..lowest].trim_space().trim(',')
} else { } else {
rest = '' rest = ''
base.trim_space() base.trim_space()

View File

@ -80,7 +80,7 @@ pub fn new_options() RunnerOptions {
vexec := full_path_to_v() vexec := full_path_to_v()
mut files := []string mut files := []string
if os.args.len > 1 { if os.args.len > 1 {
files = os.args.right(1) files = os.args[1..]
} else { } else {
files = os.walk_ext('.', '.repl') files = os.walk_ext('.', '.repl')
} }

View File

@ -39,7 +39,7 @@ pub fn test_v() {
return return
} }
args_string := args.right(1).join(' ') args_string := args[1..].join(' ')
args_before := args_string.all_before('test ') args_before := args_string.all_before('test ')
args_after := args_string.all_after('test ') args_after := args_string.all_after('test ')

View File

@ -49,7 +49,7 @@ pub fn (c &AesCipher) encrypt(dst, src []byte) {
panic('crypto.aes: output not full block') panic('crypto.aes: output not full block')
} }
// if subtle.inexact_overlap(dst[:block_size], src[:block_size]) { // if subtle.inexact_overlap(dst[:block_size], src[:block_size]) {
if subtle.inexact_overlap(dst.left(block_size), src.left(block_size)) { if subtle.inexact_overlap(dst[..block_size], src[..block_size]) {
panic('crypto.aes: invalid buffer overlap') panic('crypto.aes: invalid buffer overlap')
} }
// for now use generic version // for now use generic version
@ -63,7 +63,7 @@ pub fn (c &AesCipher) decrypt(dst, src []byte) {
if dst.len < block_size { if dst.len < block_size {
panic('crypto.aes: output not full block') panic('crypto.aes: output not full block')
} }
if subtle.inexact_overlap(dst.left(block_size), src.left(block_size)) { if subtle.inexact_overlap(dst[..block_size], src[..block_size]) {
panic('crypto.aes: invalid buffer overlap') panic('crypto.aes: invalid buffer overlap')
} }
// for now use generic version // for now use generic version

View File

@ -56,7 +56,7 @@ pub fn (x mut AesCbc) encrypt_blocks(dst mut []byte, src_ []byte) {
if dst.len < src.len { if dst.len < src.len {
panic('crypto.cipher: output smaller than input') panic('crypto.cipher: output smaller than input')
} }
if subtle.inexact_overlap(dst.left(src.len), src) { if subtle.inexact_overlap(dst[..src.len], src) {
panic('crypto.cipher: invalid buffer overlap') panic('crypto.cipher: invalid buffer overlap')
} }
@ -64,17 +64,17 @@ pub fn (x mut AesCbc) encrypt_blocks(dst mut []byte, src_ []byte) {
for src.len > 0 { for src.len > 0 {
// Write the xor to dst, then encrypt in place. // Write the xor to dst, then encrypt in place.
cipher.xor_bytes(mut dst.left(x.block_size), src.left(x.block_size), iv) cipher.xor_bytes(mut dst[..x.block_size], src[..x.block_size], iv)
x.b.encrypt(dst.left(x.block_size), dst.left(x.block_size)) x.b.encrypt(dst[..x.block_size], dst[..x.block_size])
// Move to the next block with this block as the next iv. // Move to the next block with this block as the next iv.
iv = dst.left(x.block_size) iv = dst[..x.block_size]
if x.block_size >= src.len { if x.block_size >= src.len {
src = []byte src = []byte
} else { } else {
src = src.right(x.block_size) src = src[x.block_size..]
} }
*dst = dst.right(x.block_size) *dst = dst[x.block_size..]
} }
// Save the iv for the next crypt_blocks call. // Save the iv for the next crypt_blocks call.
@ -88,7 +88,7 @@ pub fn (x mut AesCbc) decrypt_blocks(dst mut []byte, src []byte) {
if dst.len < src.len { if dst.len < src.len {
panic('crypto.cipher: output smaller than input') panic('crypto.cipher: output smaller than input')
} }
if subtle.inexact_overlap(dst.left(src.len), src) { if subtle.inexact_overlap(dst[..src.len], src) {
panic('crypto.cipher: invalid buffer overlap') panic('crypto.cipher: invalid buffer overlap')
} }
if src.len == 0 { if src.len == 0 {

View File

@ -14,8 +14,8 @@ fn test_crypto_aes() {
if ciphertext.len < aes.block_size { if ciphertext.len < aes.block_size {
panic('ciphertext too short') panic('ciphertext too short')
} }
iv := ciphertext.left(aes.block_size) iv := ciphertext[..aes.block_size]
ciphertext = ciphertext.right(aes.block_size) ciphertext = ciphertext[aes.block_size..]
// CBC mode always works in whole blocks. // CBC mode always works in whole blocks.
if ciphertext.len%aes.block_size != 0 { if ciphertext.len%aes.block_size != 0 {
panic('ciphertext is not a multiple of the block size') panic('ciphertext is not a multiple of the block size')

View File

@ -44,7 +44,7 @@ import (
// Encrypt one block from src into dst, using the expanded key xk. // Encrypt one block from src into dst, using the expanded key xk.
fn encrypt_block_generic(xk []u32, dst, src []byte) { fn encrypt_block_generic(xk []u32, dst, src []byte) {
_ = src[15] // early bounds check _ = src[15] // early bounds check
mut s0 := binary.big_endian_u32(src.left(4)) mut s0 := binary.big_endian_u32(src[..4])
mut s1 := binary.big_endian_u32(src.slice(4, 8)) mut s1 := binary.big_endian_u32(src.slice(4, 8))
mut s2 := binary.big_endian_u32(src.slice(8, 12)) mut s2 := binary.big_endian_u32(src.slice(8, 12))
mut s3 := binary.big_endian_u32(src.slice(12, 16)) mut s3 := binary.big_endian_u32(src.slice(12, 16))
@ -87,7 +87,7 @@ fn encrypt_block_generic(xk []u32, dst, src []byte) {
s3 ^= xk[k+3] s3 ^= xk[k+3]
_ = dst[15] // early bounds check _ = dst[15] // early bounds check
binary.big_endian_put_u32(mut dst.left(4), s0) binary.big_endian_put_u32(mut dst[..4], s0)
binary.big_endian_put_u32(mut dst.slice(4, 8), s1) binary.big_endian_put_u32(mut dst.slice(4, 8), s1)
binary.big_endian_put_u32(mut dst.slice(8, 12), s2) binary.big_endian_put_u32(mut dst.slice(8, 12), s2)
binary.big_endian_put_u32(mut dst.slice(12, 16), s3) binary.big_endian_put_u32(mut dst.slice(12, 16), s3)
@ -96,7 +96,7 @@ fn encrypt_block_generic(xk []u32, dst, src []byte) {
// Decrypt one block from src into dst, using the expanded key xk. // Decrypt one block from src into dst, using the expanded key xk.
fn decrypt_block_generic(xk []u32, dst, src []byte) { fn decrypt_block_generic(xk []u32, dst, src []byte) {
_ = src[15] // early bounds check _ = src[15] // early bounds check
mut s0 := binary.big_endian_u32(src.left(4)) mut s0 := binary.big_endian_u32(src[..4])
mut s1 := binary.big_endian_u32(src.slice(4, 8)) mut s1 := binary.big_endian_u32(src.slice(4, 8))
mut s2 := binary.big_endian_u32(src.slice(8, 12)) mut s2 := binary.big_endian_u32(src.slice(8, 12))
mut s3 := binary.big_endian_u32(src.slice(12, 16)) mut s3 := binary.big_endian_u32(src.slice(12, 16))
@ -139,7 +139,7 @@ fn decrypt_block_generic(xk []u32, dst, src []byte) {
s3 ^= xk[k+3] s3 ^= xk[k+3]
_ = dst[15] // early bounds check _ = dst[15] // early bounds check
binary.big_endian_put_u32(mut dst.left(4), s0) binary.big_endian_put_u32(mut dst[..4], s0)
binary.big_endian_put_u32(mut dst.slice(4, 8), s1) binary.big_endian_put_u32(mut dst.slice(4, 8), s1)
binary.big_endian_put_u32(mut dst.slice(8, 12), s2) binary.big_endian_put_u32(mut dst.slice(8, 12), s2)
binary.big_endian_put_u32(mut dst.slice(12, 16), s3) binary.big_endian_put_u32(mut dst.slice(12, 16), s3)
@ -166,7 +166,7 @@ fn expand_key_generic(key []byte, enc mut []u32, dec mut []u32) {
if 4*i >= key.len { if 4*i >= key.len {
break break
} }
enc[i] = binary.big_endian_u32(key.right(4*i)) enc[i] = binary.big_endian_u32(key[4*i..])
} }
for i < enc.len { for i < enc.len {

View File

@ -60,7 +60,7 @@ pub fn (d mut Digest) write(p_ []byte) ?int {
nn := p.len nn := p.len
d.len += u64(nn) d.len += u64(nn)
if d.nx > 0 { if d.nx > 0 {
n := copy(d.x.right(d.nx), p) n := copy(d.x[d.nx..], p)
d.nx += n d.nx += n
if d.nx == block_size { if d.nx == block_size {
block(mut d, d.x) block(mut d, d.x)
@ -69,16 +69,16 @@ pub fn (d mut Digest) write(p_ []byte) ?int {
if n >= p.len { if n >= p.len {
p = []byte p = []byte
} else { } else {
p = p.right(n) p = p[n..]
} }
} }
if p.len >= block_size { if p.len >= block_size {
n := p.len &~ (block_size - 1) n := p.len &~ (block_size - 1)
block(mut d, p.left(n)) block(mut d, p[..n])
if n >= p.len { if n >= p.len {
p = []byte p = []byte
} else { } else {
p = p.right(n) p = p[n..]
} }
} }
if p.len > 0 { if p.len > 0 {
@ -108,8 +108,8 @@ pub fn (d mut Digest) checksum() []byte {
mut tmp := [byte(0)].repeat(1 + 63 + 8) mut tmp := [byte(0)].repeat(1 + 63 + 8)
tmp[0] = 0x80 tmp[0] = 0x80
pad := int((55 - int(d.len)) % u64(64)) // calculate number of padding bytes pad := int((55 - int(d.len)) % u64(64)) // calculate number of padding bytes
binary.little_endian_put_u64(mut tmp.right(1+pad), d.len<<u64(3)) // append length in bits binary.little_endian_put_u64(mut tmp[1+pad..], d.len<<u64(3)) // append length in bits
d.write(tmp.left(1+pad+8)) d.write(tmp[..1+pad+8])
// The previous write ensures that a whole number of // The previous write ensures that a whole number of
// blocks (i.e. a multiple of 64 bytes) have been hashed. // blocks (i.e. a multiple of 64 bytes) have been hashed.
@ -120,9 +120,9 @@ pub fn (d mut Digest) checksum() []byte {
digest := [byte(0)].repeat(size) digest := [byte(0)].repeat(size)
binary.little_endian_put_u32(mut digest, d.s[0]) binary.little_endian_put_u32(mut digest, d.s[0])
binary.little_endian_put_u32(mut digest.right(4), d.s[1]) binary.little_endian_put_u32(mut digest[4..], d.s[1])
binary.little_endian_put_u32(mut digest.right(8), d.s[2]) binary.little_endian_put_u32(mut digest[8..], d.s[2])
binary.little_endian_put_u32(mut digest.right(12), d.s[3]) binary.little_endian_put_u32(mut digest[12..], d.s[3])
return digest return digest
} }

View File

@ -21,8 +21,8 @@ fn block_generic(dig mut Digest, p []byte) {
mut d := dig.s[3] mut d := dig.s[3]
for i := 0; i <= p.len-block_size; i += block_size { for i := 0; i <= p.len-block_size; i += block_size {
mut q := p.right(i) mut q := p[i..]
q = q.left(block_size) q = q[..block_size]
// save current state // save current state
aa := a aa := a
bb := b bb := b
@ -30,22 +30,22 @@ fn block_generic(dig mut Digest, p []byte) {
dd := d dd := d
// load input block // load input block
x0 := binary.little_endian_u32(q.right(4*0x0)) x0 := binary.little_endian_u32(q[4*0x0..])
x1 := binary.little_endian_u32(q.right(4*0x1)) x1 := binary.little_endian_u32(q[4*0x1..])
x2 := binary.little_endian_u32(q.right(4*0x2)) x2 := binary.little_endian_u32(q[4*0x2..])
x3 := binary.little_endian_u32(q.right(4*0x3)) x3 := binary.little_endian_u32(q[4*0x3..])
x4 := binary.little_endian_u32(q.right(4*0x4)) x4 := binary.little_endian_u32(q[4*0x4..])
x5 := binary.little_endian_u32(q.right(4*0x5)) x5 := binary.little_endian_u32(q[4*0x5..])
x6 := binary.little_endian_u32(q.right(4*0x6)) x6 := binary.little_endian_u32(q[4*0x6..])
x7 := binary.little_endian_u32(q.right(4*0x7)) x7 := binary.little_endian_u32(q[4*0x7..])
x8 := binary.little_endian_u32(q.right(4*0x8)) x8 := binary.little_endian_u32(q[4*0x8..])
x9 := binary.little_endian_u32(q.right(4*0x9)) x9 := binary.little_endian_u32(q[4*0x9..])
xa := binary.little_endian_u32(q.right(4*0xa)) xa := binary.little_endian_u32(q[4*0xa..])
xb := binary.little_endian_u32(q.right(4*0xb)) xb := binary.little_endian_u32(q[4*0xb..])
xc := binary.little_endian_u32(q.right(4*0xc)) xc := binary.little_endian_u32(q[4*0xc..])
xd := binary.little_endian_u32(q.right(4*0xd)) xd := binary.little_endian_u32(q[4*0xd..])
xe := binary.little_endian_u32(q.right(4*0xe)) xe := binary.little_endian_u32(q[4*0xe..])
xf := binary.little_endian_u32(q.right(4*0xf)) xf := binary.little_endian_u32(q[4*0xf..])
// round 1 // round 1
a = b + bits.rotate_left_32((((c^d)&b)^d)+a+x0+u32(0xd76aa478), 7) a = b + bits.rotate_left_32((((c^d)&b)^d)+a+x0+u32(0xd76aa478), 7)

View File

@ -63,13 +63,13 @@ pub fn (c mut Cipher) xor_key_stream(dst mut []byte, src []byte) {
if src.len == 0 { if src.len == 0 {
return return
} }
if subtle.inexact_overlap(dst.left(src.len), src) { if subtle.inexact_overlap(dst[..src.len], src) {
panic('crypto.rc4: invalid buffer overlap') panic('crypto.rc4: invalid buffer overlap')
} }
mut i := c.i mut i := c.i
mut j := c.j mut j := c.j
_ = dst[src.len-1] _ = dst[src.len-1]
*dst = dst.left(src.len) // eliminate bounds check from loop *dst = dst[..src.len] // eliminate bounds check from loop
for k, v in src { for k, v in src {
i += byte(1) i += byte(1)
x := c.s[i] x := c.s[i]

View File

@ -64,7 +64,7 @@ pub fn (d mut Digest) write(p_ []byte) ?int {
d.len += u64(nn) d.len += u64(nn)
if d.nx > 0 { if d.nx > 0 {
n := copy(d.x.right(d.nx), p) n := copy(d.x[d.nx..], p)
d.nx += n d.nx += n
if d.nx == chunk { if d.nx == chunk {
block(d, d.x) block(d, d.x)
@ -73,16 +73,16 @@ pub fn (d mut Digest) write(p_ []byte) ?int {
if n >= p.len { if n >= p.len {
p = []byte p = []byte
} else { } else {
p = p.right(n) p = p[n..]
} }
} }
if p.len >= chunk { if p.len >= chunk {
n := p.len &~ (chunk - 1) n := p.len &~ (chunk - 1)
block(d, p.left(n)) block(d, p[..n])
if n >= p.len { if n >= p.len {
p = []byte p = []byte
} else { } else {
p = p.right(n) p = p[n..]
} }
} }
if p.len > 0 { if p.len > 0 {
@ -110,23 +110,23 @@ fn (d mut Digest) checksum() []byte {
tmp[0] = 0x80 tmp[0] = 0x80
if int(len)%64 < 56 { if int(len)%64 < 56 {
d.write(tmp.left(56-int(len)%64)) d.write(tmp[..56-int(len)%64])
} else { } else {
d.write(tmp.left(64+56-int(len)%64)) d.write(tmp[..64+56-int(len)%64])
} }
// Length in bits. // Length in bits.
len <<= 3 len <<= 3
binary.big_endian_put_u64(mut tmp, len) binary.big_endian_put_u64(mut tmp, len)
d.write(tmp.left(8)) d.write(tmp[..8])
mut digest := [byte(0)].repeat(size) mut digest := [byte(0)].repeat(size)
binary.big_endian_put_u32(mut digest, d.h[0]) binary.big_endian_put_u32(mut digest, d.h[0])
binary.big_endian_put_u32(mut digest.right(4), d.h[1]) binary.big_endian_put_u32(mut digest[4..], d.h[1])
binary.big_endian_put_u32(mut digest.right(8), d.h[2]) binary.big_endian_put_u32(mut digest[8..], d.h[2])
binary.big_endian_put_u32(mut digest.right(12), d.h[3]) binary.big_endian_put_u32(mut digest[12..], d.h[3])
binary.big_endian_put_u32(mut digest.right(16), d.h[4]) binary.big_endian_put_u32(mut digest[16..], d.h[4])
return digest return digest
} }

View File

@ -111,7 +111,7 @@ fn block_generic(dig mut Digest, p_ []byte) {
if chunk >= p.len { if chunk >= p.len {
p = []byte p = []byte
} else { } else {
p = p.right(chunk) p = p[chunk..]
} }
} }

View File

@ -97,7 +97,7 @@ fn (d mut Digest) write(p_ []byte) ?int {
nn := p.len nn := p.len
d.len += u64(nn) d.len += u64(nn)
if d.nx > 0 { if d.nx > 0 {
n := copy(d.x.right(d.nx), p) n := copy(d.x[d.nx..], p)
d.nx += n d.nx += n
if d.nx == chunk { if d.nx == chunk {
block(mut d, d.x) block(mut d, d.x)
@ -106,16 +106,16 @@ fn (d mut Digest) write(p_ []byte) ?int {
if n >= p.len { if n >= p.len {
p = []byte p = []byte
} else { } else {
p = p.right(n) p = p[n..]
} }
} }
if p.len >= chunk { if p.len >= chunk {
n := p.len &~ (chunk - 1) n := p.len &~ (chunk - 1)
block(mut d, p.left(n)) block(mut d, p[..n])
if n >= p.len { if n >= p.len {
p = []byte p = []byte
} else { } else {
p = p.right(n) p = p[n..]
} }
} }
if p.len > 0 { if p.len > 0 {
@ -130,7 +130,7 @@ fn (d &Digest) sum(b_in []byte) []byte {
hash := d0.checksum() hash := d0.checksum()
mut b_out := b_in.clone() mut b_out := b_in.clone()
if d0.is224 { if d0.is224 {
for b in hash.left(size224) { for b in hash[..size224] {
b_out << b b_out << b
} }
} else { } else {
@ -147,15 +147,15 @@ fn (d mut Digest) checksum() []byte {
mut tmp := [byte(0)].repeat(64) mut tmp := [byte(0)].repeat(64)
tmp[0] = 0x80 tmp[0] = 0x80
if int(len)%64 < 56 { if int(len)%64 < 56 {
d.write(tmp.left(56-int(len)%64)) d.write(tmp[..56-int(len)%64])
} else { } else {
d.write(tmp.left(64+56-int(len)%64)) d.write(tmp[..64+56-int(len)%64])
} }
// Length in bits. // Length in bits.
len <<= u64(3) len <<= u64(3)
binary.big_endian_put_u64(mut tmp, len) binary.big_endian_put_u64(mut tmp, len)
d.write(tmp.left(8)) d.write(tmp[..8])
if d.nx != 0 { if d.nx != 0 {
panic('d.nx != 0') panic('d.nx != 0')
@ -164,14 +164,14 @@ fn (d mut Digest) checksum() []byte {
digest := [byte(0)].repeat(size) digest := [byte(0)].repeat(size)
binary.big_endian_put_u32(mut digest, d.h[0]) binary.big_endian_put_u32(mut digest, d.h[0])
binary.big_endian_put_u32(mut digest.right(4), d.h[1]) binary.big_endian_put_u32(mut digest[4..], d.h[1])
binary.big_endian_put_u32(mut digest.right(8), d.h[2]) binary.big_endian_put_u32(mut digest[8..], d.h[2])
binary.big_endian_put_u32(mut digest.right(12), d.h[3]) binary.big_endian_put_u32(mut digest[12..], d.h[3])
binary.big_endian_put_u32(mut digest.right(16), d.h[4]) binary.big_endian_put_u32(mut digest[16..], d.h[4])
binary.big_endian_put_u32(mut digest.right(20), d.h[5]) binary.big_endian_put_u32(mut digest[20..], d.h[5])
binary.big_endian_put_u32(mut digest.right(24), d.h[6]) binary.big_endian_put_u32(mut digest[24..], d.h[6])
if !d.is224 { if !d.is224 {
binary.big_endian_put_u32(mut digest.right(28), d.h[7]) binary.big_endian_put_u32(mut digest[28..], d.h[7])
} }
return digest return digest
@ -195,7 +195,7 @@ pub fn sum224(data []byte) []byte {
d.write(data) d.write(data)
sum := d.checksum() sum := d.checksum()
mut sum224 := [byte(0)].repeat(size224) mut sum224 := [byte(0)].repeat(size224)
copy(sum224, sum.left(size224)) copy(sum224, sum[..size224])
return sum224 return sum224
} }

View File

@ -144,7 +144,7 @@ fn block_generic(dig mut Digest, p_ []byte) {
if chunk >= p.len { if chunk >= p.len {
p = []byte p = []byte
} else { } else {
p = p.right(chunk) p = p[chunk..]
} }
} }

View File

@ -152,7 +152,7 @@ fn (d mut Digest) write(p_ []byte) ?int {
nn := p.len nn := p.len
d.len += u64(nn) d.len += u64(nn)
if d.nx > 0 { if d.nx > 0 {
n := copy(d.x.right(d.nx), p) n := copy(d.x[d.nx..], p)
d.nx += n d.nx += n
if d.nx == Chunk { if d.nx == Chunk {
block(mut d, d.x) block(mut d, d.x)
@ -161,16 +161,16 @@ fn (d mut Digest) write(p_ []byte) ?int {
if n >= p.len { if n >= p.len {
p = []byte p = []byte
} else { } else {
p = p.right(n) p = p[n..]
} }
} }
if p.len >= Chunk { if p.len >= Chunk {
n := p.len &~ (Chunk - 1) n := p.len &~ (Chunk - 1)
block(mut d, p.left(n)) block(mut d, p[..n])
if n >= p.len { if n >= p.len {
p = []byte p = []byte
} else { } else {
p = p.right(n) p = p[n..]
} }
} }
if p.len > 0 { if p.len > 0 {
@ -186,15 +186,15 @@ fn (d mut Digest) sum(b_in []byte) []byte {
mut b_out := b_in.clone() mut b_out := b_in.clone()
switch d0.function { switch d0.function {
case crypto.Hash.sha384: case crypto.Hash.sha384:
for b in hash.left(size384) { for b in hash[..size384] {
b_out << b b_out << b
} }
case crypto.Hash.sha512_224: case crypto.Hash.sha512_224:
for b in hash.left(size224) { for b in hash[..size224] {
b_out << b b_out << b
} }
case crypto.Hash.sha512_256: case crypto.Hash.sha512_256:
for b in hash.left(size256) { for b in hash[..size256] {
b_out << b b_out << b
} }
default: default:
@ -212,17 +212,17 @@ fn (d mut Digest) checksum() []byte {
tmp[0] = 0x80 tmp[0] = 0x80
if int(len)%128 < 112 { if int(len)%128 < 112 {
d.write(tmp.left(112-int(len)%128)) d.write(tmp[..112-int(len)%128])
} else { } else {
d.write(tmp.left(128+112-int(len)%128)) d.write(tmp[..128+112-int(len)%128])
} }
// Length in bits. // Length in bits.
len <<= u64(3) len <<= u64(3)
binary.big_endian_put_u64(mut tmp, u64(0)) // upper 64 bits are always zero, because len variable has type u64 binary.big_endian_put_u64(mut tmp, u64(0)) // upper 64 bits are always zero, because len variable has type u64
binary.big_endian_put_u64(mut tmp.right(8), len) binary.big_endian_put_u64(mut tmp[8..], len)
d.write(tmp.left(16)) d.write(tmp[..16])
if d.nx != 0 { if d.nx != 0 {
panic('d.nx != 0') panic('d.nx != 0')
@ -231,14 +231,14 @@ fn (d mut Digest) checksum() []byte {
mut digest := [byte(0)].repeat(size) mut digest := [byte(0)].repeat(size)
binary.big_endian_put_u64(mut digest, d.h[0]) binary.big_endian_put_u64(mut digest, d.h[0])
binary.big_endian_put_u64(mut digest.right(8), d.h[1]) binary.big_endian_put_u64(mut digest[8..], d.h[1])
binary.big_endian_put_u64(mut digest.right(16), d.h[2]) binary.big_endian_put_u64(mut digest[16..], d.h[2])
binary.big_endian_put_u64(mut digest.right(24), d.h[3]) binary.big_endian_put_u64(mut digest[24..], d.h[3])
binary.big_endian_put_u64(mut digest.right(32), d.h[4]) binary.big_endian_put_u64(mut digest[32..], d.h[4])
binary.big_endian_put_u64(mut digest.right(40), d.h[5]) binary.big_endian_put_u64(mut digest[40..], d.h[5])
if d.function != crypto.Hash.sha384 { if d.function != crypto.Hash.sha384 {
binary.big_endian_put_u64(mut digest.right(48), d.h[6]) binary.big_endian_put_u64(mut digest[48..], d.h[6])
binary.big_endian_put_u64(mut digest.right(56), d.h[7]) binary.big_endian_put_u64(mut digest[56..], d.h[7])
} }
return digest return digest
@ -257,7 +257,7 @@ pub fn sum384(data []byte) []byte {
d.write(data) d.write(data)
sum := d.checksum() sum := d.checksum()
mut sum384 := [byte(0)].repeat(size384) mut sum384 := [byte(0)].repeat(size384)
copy(sum384, sum.left(size384)) copy(sum384, sum[..size384])
return sum384 return sum384
} }
@ -267,7 +267,7 @@ pub fn sum512_224(data []byte) []byte {
d.write(data) d.write(data)
sum := d.checksum() sum := d.checksum()
mut sum224 := [byte(0)].repeat(size224) mut sum224 := [byte(0)].repeat(size224)
copy(sum224, sum.left(size224)) copy(sum224, sum[..size224])
return sum224 return sum224
} }
@ -277,7 +277,7 @@ pub fn sum512_256(data []byte) []byte {
d.write(data) d.write(data)
sum := d.checksum() sum := d.checksum()
mut sum256 := [byte(0)].repeat(size256) mut sum256 := [byte(0)].repeat(size256)
copy(sum256, sum.left(size256)) copy(sum256, sum[..size256])
return sum256 return sum256
} }

View File

@ -160,7 +160,7 @@ fn block_generic(dig mut Digest, p_ []byte) {
if Chunk >= p.len { if Chunk >= p.len {
p = []byte p = []byte
} else { } else {
p = p.right(Chunk) p = p[Chunk..]
} }
} }

View File

@ -80,11 +80,11 @@ fn (r mut Reader) read_line() ?string {
} }
} }
} }
mut line := r.data.substr(r.row_pos, i) mut line := r.data[r.row_pos..i]
r.row_pos = i+1 r.row_pos = i+1
// normalize win line endings (remove extra \r) // normalize win line endings (remove extra \r)
if !r.is_mac_pre_osx_le && (line.len >= 1 && line[line.len-1] == `\r`) { if !r.is_mac_pre_osx_le && (line.len >= 1 && line[line.len-1] == `\r`) {
line = line.left(line.len-1) line = line[..line.len-1]
} }
return line return line
} }
@ -118,28 +118,28 @@ fn (r mut Reader) read_record() ?[]string {
// last // last
break break
} }
fields << line.left(i) fields << line[..i]
line = line.right(i+1) line = line[i+1..]
continue continue
} }
// quoted // quoted
else { else {
line = line.right(1) line = line[1..]
i = line.index('"') i = line.index('"')
if i != -1 { if i != -1 {
if i+1 == line.len { if i+1 == line.len {
// last record // last record
fields << line.left(i) fields << line[..i]
break break
} }
next := line[i+1] next := line[i+1]
if next == r.delimiter { if next == r.delimiter {
fields << line.left(i) fields << line[..i]
line = line.right(i) line = line[i..]
continue continue
} }
} }
line = line.right(1) line = line[1..]
} }
if i <= -1 && fields.len == 0 { if i <= -1 && fields.len == 0 {
return err_invalid_delim return err_invalid_delim

View File

@ -46,8 +46,8 @@ pub fn (w mut Writer) write(record []string) ?bool {
i = field.len i = field.len
} }
w.sb.write(field.left(i)) w.sb.write(field[..i])
field = field.right(i) field = field[i..]
if field.len > 0 { if field.len > 0 {
z := field[0] z := field[0]
@ -57,7 +57,7 @@ pub fn (w mut Writer) write(record []string) ?bool {
case `\r` || `\n`: case `\r` || `\n`:
w.sb.write(le) w.sb.write(le)
} }
field = field.right(1) field = field[1..]
} }
} }
w.sb.write('"') w.sb.write('"')

View File

@ -133,8 +133,8 @@ fn (fs mut FlagParser) parse_value(n string, ab byte) ?string {
} else { } else {
panic('Missing argument for \'$n\'') panic('Missing argument for \'$n\'')
} }
} else if a.len > c.len && c == a.left(c.len) && a.substr(c.len, c.len+1) == '=' { } else if a.len > c.len && c == a[..c.len] && a[c.len..c.len+1] == '=' {
val := a.right(c.len+1) val := a[c.len+1..]
fs.args.delete(i) fs.args.delete(i)
return val return val
} }
@ -162,8 +162,8 @@ fn (fs mut FlagParser) parse_bool_value(n string, ab byte) ?string {
fs.args.delete(i) fs.args.delete(i)
return val return val
} }
} else if a.len > c.len && c == a.left(c.len) && a.substr(c.len, c.len+1) == '=' { } else if a.len > c.len && c == a[..c.len] && a[c.len..c.len+1] == '=' {
val := a.right(c.len+1) val := a[c.len+1..]
fs.args.delete(i) fs.args.delete(i)
return val return val
} }
@ -349,7 +349,7 @@ pub fn (fs FlagParser) usage() string {
space := if flag_desc.len > SPACE.len-2 { space := if flag_desc.len > SPACE.len-2 {
'\n$SPACE' '\n$SPACE'
} else { } else {
SPACE.right(flag_desc.len) SPACE[flag_desc.len..]
} }
abbr_desc := if f.abbr == `\0` { '' } else { ' -${tos(f.abbr, 1)}\n' } abbr_desc := if f.abbr == `\0` { '' } else { ' -${tos(f.abbr, 1)}\n' }
use += '${abbr_desc}${flag_desc}${space}${f.usage}\n' use += '${abbr_desc}${flag_desc}${space}${f.usage}\n'
@ -368,8 +368,8 @@ pub fn (fs FlagParser) usage() string {
// error handling is up to the application developer // error handling is up to the application developer
pub fn (fs FlagParser) finalize() ?[]string { pub fn (fs FlagParser) finalize() ?[]string {
for a in fs.args { for a in fs.args {
if a.left(2) == '--' { if a.len >= 2 && a[..2] == '--' {
return error('Unknown argument \'${a.right(2)}\'') return error('Unknown argument \'${a[2..]}\'')
} }
} }
if fs.args.len < fs.min_free_args && fs.min_free_args > 0 { if fs.args.len < fs.min_free_args && fs.min_free_args > 0 {

View File

@ -42,7 +42,7 @@ fn (s mut ChunkScanner) skip_crlf() {
fn (s mut ChunkScanner) read_chunk(chunksize int) string { fn (s mut ChunkScanner) read_chunk(chunksize int) string {
startpos := s.pos startpos := s.pos
s.pos += chunksize s.pos += chunksize
return s.text.substr(startpos, s.pos) return s.text[startpos..s.pos]
} }
pub fn decode(text string) string { pub fn decode(text string) string {

View File

@ -188,10 +188,10 @@ fn parse_response(resp string) Response {
if nl_pos == -1 { if nl_pos == -1 {
break break
} }
h := resp.substr(old_pos + 1, nl_pos) h := resp[old_pos + 1..nl_pos]
// End of headers // End of headers
if h.len <= 1 { if h.len <= 1 {
text = resp.right(nl_pos + 1) text = resp[nl_pos + 1..]
break break
} }
i++ i++
@ -202,8 +202,8 @@ fn parse_response(resp string) Response {
//if h.contains('Content-Type') { //if h.contains('Content-Type') {
//continue //continue
//} //}
key := h.left(pos) key := h[..pos]
val := h.right(pos + 2) val := h[pos + 2..]
headers[key] = val.trim_space() headers[key] = val.trim_space()
} }

View File

@ -161,9 +161,9 @@ fn unescape(s_ string, mode EncodingMode) ?string {
} }
n++ n++
if i+2 >= s.len || !ishex(s[i+1]) || !ishex(s[i+2]) { if i+2 >= s.len || !ishex(s[i+1]) || !ishex(s[i+2]) {
s = s.right(i) s = s[i..]
if s.len > 3 { if s.len > 3 {
s = s.left(3) s = s[..3]
} }
return error(error_msg(err_msg_escape, s)) return error(error_msg(err_msg_escape, s))
} }
@ -173,8 +173,8 @@ fn unescape(s_ string, mode EncodingMode) ?string {
// But https://tools.ietf.org/html/rfc6874#section-2 // But https://tools.ietf.org/html/rfc6874#section-2
// introduces %25 being allowed to escape a percent sign // introduces %25 being allowed to escape a percent sign
// in IPv6 scoped-address literals. Yay. // in IPv6 scoped-address literals. Yay.
if mode == .encode_host && unhex(s[i+1]) < 8 && s.substr(i, i+3) != '%25' { if mode == .encode_host && unhex(s[i+1]) < 8 && s[i..i+3] != '%25' {
return error(error_msg(err_msg_escape, s.substr(i, i+3))) return error(error_msg(err_msg_escape, s[i..i+3]))
} }
if mode == .encode_zone { if mode == .encode_zone {
// RFC 6874 says basically 'anything goes' for zone identifiers // RFC 6874 says basically 'anything goes' for zone identifiers
@ -185,19 +185,18 @@ fn unescape(s_ string, mode EncodingMode) ?string {
// to introduce bytes you couldn't just write directly. // to introduce bytes you couldn't just write directly.
// But Windows puts spaces here! Yay. // But Windows puts spaces here! Yay.
v := byte(unhex(s[i+1])<<byte(4) | unhex(s[i+2])) v := byte(unhex(s[i+1])<<byte(4) | unhex(s[i+2]))
if s.substr(i, i+3) != '%25' && v != ` ` && should_escape(v, .encode_host) { if s[i..i+3] != '%25' && v != ` ` && should_escape(v, .encode_host) {
error(error_msg(err_msg_escape, s.substr(i, i+3))) error(error_msg(err_msg_escape, s[i..i+3]))
} }
} }
i += 3 i += 3
} }
`+`{ `+`{
has_plus = mode == .encode_query_component has_plus = mode == .encode_query_component
i++ i++
} else { } else {
if (mode == .encode_host || mode == .encode_zone) && s[i] < 0x80 && should_escape(s[i], mode) { if (mode == .encode_host || mode == .encode_zone) && s[i] < 0x80 && should_escape(s[i], mode) {
error(error_msg('invalid character in host name', s.substr(i, i+1))) error(error_msg('invalid character in host name', s[i..i+1]))
} }
i++ i++
} }
@ -266,7 +265,7 @@ fn escape(s string, mode EncodingMode) string {
required := s.len + 2*hex_count required := s.len + 2*hex_count
if required <= buf.len { if required <= buf.len {
t = buf.left(required) t = buf[..required]
} else { } else {
t = [byte(0)].repeat(required) t = [byte(0)].repeat(required)
} }
@ -400,7 +399,7 @@ fn split_by_scheme(rawurl string) ?[]string {
if i == 0 { if i == 0 {
return error(error_msg('missing protocol scheme', '')) return error(error_msg('missing protocol scheme', ''))
} }
return [rawurl.left(i), rawurl.right(i+1)] return [rawurl[..i], rawurl[i+1..]]
} }
else { else {
// we have encountered an invalid character, // we have encountered an invalid character,
@ -427,9 +426,9 @@ fn split(s string, sep byte, cutc bool) (string, string) {
return s, '' return s, ''
} }
if cutc { if cutc {
return s.left(i), s.right(i+1) return s[..i], s[i+1..]
} }
return s.left(i), s.right(i) return s[..i], s[i..]
} }
// parse parses rawurl into a URL structure. // parse parses rawurl into a URL structure.
@ -492,9 +491,9 @@ fn parse_url(rawurl string, via_request bool) ?URL {
url.scheme = url.scheme.to_lower() url.scheme = url.scheme.to_lower()
// if rest.ends_with('?') && strings.count(rest, '?') == 1 { // if rest.ends_with('?') && strings.count(rest, '?') == 1 {
if rest.ends_with('?') && !rest.left(1).contains('?') { if rest.ends_with('?') && !rest[..1].contains('?') {
url.force_query = true url.force_query = true
rest = rest.left(rest.len-1) rest = rest[..rest.len-1]
} else { } else {
r, raw_query := split(rest, `?`, true) r, raw_query := split(rest, `?`, true)
rest = r rest = r
@ -526,7 +525,7 @@ fn parse_url(rawurl string, via_request bool) ?URL {
} }
if ((url.scheme != '' || !via_request) && !rest.starts_with('///')) && rest.starts_with('//') { if ((url.scheme != '' || !via_request) && !rest.starts_with('///')) && rest.starts_with('//') {
authority, r := split(rest.right(2), `/`, false) authority, r := split(rest[2..], `/`, false)
rest = r rest = r
a := parse_authority(authority) or { a := parse_authority(authority) or {
return error(err) return error(err)
@ -559,7 +558,7 @@ fn parse_authority(authority string) ?ParseAuthorityRes {
} }
host = h host = h
} else { } else {
h := parse_host(authority.right(i+1)) or { h := parse_host(authority[i+1..]) or {
return error(err) return error(err)
} }
host = h host = h
@ -567,7 +566,7 @@ fn parse_authority(authority string) ?ParseAuthorityRes {
if i < 0 { if i < 0 {
return ParseAuthorityRes{host: host} return ParseAuthorityRes{host: host}
} }
mut userinfo := authority.left(i) mut userinfo := authority[..i]
if !valid_userinfo(userinfo) { if !valid_userinfo(userinfo) {
return error(error_msg('invalid userinfo', '')) return error(error_msg('invalid userinfo', ''))
} }
@ -605,7 +604,7 @@ fn parse_host(host string) ?string {
if i < 0 { if i < 0 {
return error(error_msg('missing \']\' in host', '')) return error(error_msg('missing \']\' in host', ''))
} }
mut colon_port := host.right(i+1) mut colon_port := host[i+1..]
if !valid_optional_port(colon_port) { if !valid_optional_port(colon_port) {
return error(error_msg('invalid port $colon_port after host ', '')) return error(error_msg('invalid port $colon_port after host ', ''))
} }
@ -616,22 +615,22 @@ fn parse_host(host string) ?string {
// can only %-encode non-ASCII bytes. // can only %-encode non-ASCII bytes.
// We do impose some restrictions on the zone, to avoid stupidity // We do impose some restrictions on the zone, to avoid stupidity
// like newlines. // like newlines.
zone := host.left(i).index('%25') zone := host[..i].index('%25')
if zone >= 0 { if zone >= 0 {
host1 := unescape(host.left(zone), .encode_host) or { host1 := unescape(host[..zone], .encode_host) or {
return err return err
} }
host2 := unescape(host.substr(zone, i), .encode_zone) or { host2 := unescape(host[zone..i], .encode_zone) or {
return err return err
} }
host3 := unescape(host.right(i), .encode_host) or { host3 := unescape(host[i..], .encode_host) or {
return err return err
} }
return host1 + host2 + host3 return host1 + host2 + host3
} else { } else {
i = host.last_index(':') i = host.last_index(':')
if i != -1 { if i != -1 {
colon_port = host.right(i) colon_port = host[i..]
if !valid_optional_port(colon_port) { if !valid_optional_port(colon_port) {
return error(error_msg('invalid port $colon_port after host ', '')) return error(error_msg('invalid port $colon_port after host ', ''))
} }
@ -728,7 +727,7 @@ fn valid_optional_port(port string) bool {
if port[0] != `:` { if port[0] != `:` {
return false return false
} }
for b in port.right(1) { for b in port[1..] {
if b < `0` || b > `9` { if b < `0` || b > `9` {
return false return false
} }
@ -790,7 +789,7 @@ pub fn (u &URL) str() string {
// preceded by a dot-segment (e.g., './this:that') to make a relative- // preceded by a dot-segment (e.g., './this:that') to make a relative-
// path reference. // path reference.
i := path.index_byte(`:`) i := path.index_byte(`:`)
if i > -1 && path.left(i).index_byte(`/`) == -1 { if i > -1 && path[..i].index_byte(`/`) == -1 {
buf.write('./') buf.write('./')
} }
} }
@ -845,8 +844,8 @@ fn parse_query_values(m mut Values, query string) ?bool {
mut key := q mut key := q
mut i := key.index_any('&;') mut i := key.index_any('&;')
if i >= 0 { if i >= 0 {
q = key.right(i+1) q = key[i+1..]
key = key.left(i) key = key[..i]
} else { } else {
q = '' q = ''
} }
@ -856,8 +855,8 @@ fn parse_query_values(m mut Values, query string) ?bool {
mut value := '' mut value := ''
i = key.index('=') i = key.index('=')
if i >= 0 { if i >= 0 {
value = key.right(i+1) value = key[i+1..]
key = key.left(i) key = key[..i]
} }
k := query_unescape(key) or { k := query_unescape(key) or {
had_error = true had_error = true
@ -913,7 +912,7 @@ fn resolve_path(base, ref string) string {
full = base full = base
} else if ref[0] != `/` { } else if ref[0] != `/` {
i := base.last_index('/') i := base.last_index('/')
full = base.left(i+1) + ref full = base[..i+1] + ref
} else { } else {
full = ref full = ref
} }
@ -929,7 +928,7 @@ fn resolve_path(base, ref string) string {
} }
'..' { '..' {
if dst.len > 0 { if dst.len > 0 {
dst = dst.left(dst.len-1) dst = dst[..dst.len-1]
} }
} else { } else {
dst << elem dst << elem
@ -1049,13 +1048,13 @@ fn split_host_port(hostport string) (string, string) {
mut port := '' mut port := ''
colon := host.last_index_byte(`:`) colon := host.last_index_byte(`:`)
if colon != -1 && valid_optional_port(host.right(colon)) { if colon != -1 && valid_optional_port(host[colon..]) {
port = host.right(colon+1) port = host[colon+1..]
host = host.left(colon) host = host[..colon]
} }
if host.starts_with('[') && host.ends_with(']') { if host.starts_with('[') && host.ends_with(']') {
host = host.substr(1, host.len-1) host = host[1..host.len-1]
} }
return host, port return host, port

View File

@ -495,7 +495,7 @@ pub fn ext(path string) string {
if pos == -1 { if pos == -1 {
return '' return ''
} }
return path.right(pos) return path[pos..]
} }
@ -508,7 +508,7 @@ pub fn dir(path string) string {
if pos == -1 { if pos == -1 {
return '.' return '.'
} }
return path.left(pos) return path[..pos]
} }
fn path_sans_ext(path string) string { fn path_sans_ext(path string) string {
@ -516,7 +516,7 @@ fn path_sans_ext(path string) string {
if pos == -1 { if pos == -1 {
return path return path
} }
return path.left(pos) return path[..pos]
} }
@ -525,7 +525,7 @@ pub fn basedir(path string) string {
if pos == -1 { if pos == -1 {
return path return path
} }
return path.left(pos + 1) return path[..pos + 1]
} }
pub fn filename(path string) string { pub fn filename(path string) string {

View File

@ -141,10 +141,10 @@ pub fn parse_int(_s string, base int, _bit_size int) i64 {
// Pick off leading sign. // Pick off leading sign.
mut neg := false mut neg := false
if s[0] == `+` { if s[0] == `+` {
s = s.right(1) s = s[1..]
} else if s[0] == `-` { } else if s[0] == `-` {
neg = true neg = true
s = s.right(1) s = s[1..]
} }
// Convert unsigned and check range. // Convert unsigned and check range.

View File

@ -44,13 +44,13 @@ pub fn dice_coefficient(s1, s2 string) f32 {
b := if a == s1 { s2 } else { s1 } b := if a == s1 { s2 } else { s1 }
mut first_bigrams := map[string]int mut first_bigrams := map[string]int
for i := 0; i < a.len-1; i++ { for i := 0; i < a.len-1; i++ {
bigram := a.substr(i, i+2) bigram := a[i..i+2]
q := if bigram in first_bigrams { first_bigrams[bigram]+1 } else { 1 } q := if bigram in first_bigrams { first_bigrams[bigram]+1 } else { 1 }
first_bigrams[bigram] = q first_bigrams[bigram] = q
} }
mut intersection_size := 0 mut intersection_size := 0
for i := 0; i < b.len-1; i++ { for i := 0; i < b.len-1; i++ {
bigram := b.substr(i, i+2) bigram := b[i..i+2]
count := if bigram in first_bigrams { first_bigrams[bigram] } else { 0 } count := if bigram in first_bigrams { first_bigrams[bigram] } else { 0 }
if count > 0 { if count > 0 {
first_bigrams[bigram] = count - 1 first_bigrams[bigram] = count - 1

View File

@ -185,7 +185,7 @@ pub fn (t Time) format() string {
pub fn (t Time) smonth() string { pub fn (t Time) smonth() string {
i := t.month - 1 i := t.month - 1
return months_string.substr(i * 3, (i + 1) * 3) return months_string[i * 3..(i + 1) * 3]
} }
// 21:04 // 21:04
@ -287,13 +287,13 @@ pub fn parse(s string) Time {
println('bad time format') println('bad time format')
return now() return now()
} }
symd := s.left(pos) symd := s[..pos]
ymd := symd.split('-') ymd := symd.split('-')
if ymd.len != 3 { if ymd.len != 3 {
println('bad time format') println('bad time format')
return now() return now()
} }
shms := s.right(pos) shms := s[pos..]
hms := shms.split(':') hms := shms.split(':')
hour := hms[0] hour := hms[0]
minute := hms[1] minute := hms[1]
@ -382,7 +382,7 @@ pub fn (t Time) day_of_week() int {
// weekday_str() returns the current day in string (upto 3 characters) // weekday_str() returns the current day in string (upto 3 characters)
pub fn (t Time) weekday_str() string { pub fn (t Time) weekday_str() string {
i := t.day_of_week() - 1 i := t.day_of_week() - 1
return days_string.substr(i * 3, (i + 1) * 3) return days_string[i * 3..(i + 1) * 3]
} }
struct C.timeval { struct C.timeval {

View File

@ -47,7 +47,7 @@ _ = header
if line.contains('@if ') { if line.contains('@if ') {
s.writeln(STR_END) s.writeln(STR_END)
pos := line.index('@if') pos := line.index('@if')
s.writeln('if ' + line.right(pos + 4) + '{') s.writeln('if ' + line[pos + 4..] + '{')
s.writeln(STR_START) s.writeln(STR_START)
} }
else if line.contains('@end') { else if line.contains('@end') {
@ -63,7 +63,7 @@ _ = header
else if line.contains('@for') { else if line.contains('@for') {
s.writeln(STR_END) s.writeln(STR_END)
pos := line.index('@for') pos := line.index('@for')
s.writeln('for ' + line.right(pos + 4) + '{') s.writeln('for ' + line[pos + 4..] + '{')
s.writeln(STR_START) s.writeln(STR_START)
} }
else if !in_css && line.contains('.') && line.ends_with('{') { else if !in_css && line.contains('.') && line.ends_with('{') {

View File

@ -116,7 +116,7 @@ pub fn run<T>(app T, port int) {
conn.close() conn.close()
return return
} }
mut action := vals[1].right(1).all_before('/') mut action := vals[1][1..].all_before('/')
if action.contains('?') { if action.contains('?') {
action = action.all_before('?') action = action.all_before('?')
} }
@ -177,7 +177,7 @@ fn (ctx mut Context) parse_form(s string) {
} }
pos := s.index('\r\n\r\n') pos := s.index('\r\n\r\n')
if pos > -1 { if pos > -1 {
mut str_form := s.substr(pos, s.len) mut str_form := s[pos..s.len]
str_form = str_form.replace('+', ' ') str_form = str_form.replace('+', ' ')
words := str_form.split('&') words := str_form.split('&')
for word in words { for word in words {
@ -208,9 +208,9 @@ fn (ctx mut Context) scan_static_directory(directory_path, mount_path string) {
for i > 0 { for i > 0 {
i-- i--
if flag { if flag {
ext = file.substr(i, i + 1) + ext ext = file[i..i + 1] + ext
} }
if file.substr(i, i + 1) == '.' { if file[i..i + 1] == '.' {
flag = false flag = false
} }
} }