all: switch to the new fn arg syntax everywhere; add lots of vfmt -verify tests

pull/6622/head
Alexander Medvednikov 2020-10-15 12:32:28 +02:00
parent 982056894e
commit 7da1afa140
37 changed files with 382 additions and 404 deletions

View File

@ -27,6 +27,29 @@ jobs:
./v fmt -verify vlib/v/gen/x64/gen.v ./v fmt -verify vlib/v/gen/x64/gen.v
./v fmt -verify vlib/v/table/table.v ./v fmt -verify vlib/v/table/table.v
./v fmt -verify vlib/v/fmt/fmt.v ./v fmt -verify vlib/v/fmt/fmt.v
./v fmt -verify vlib/builtin/array.v
./v fmt -verify vlib/os/file.v
./v fmt -verify vlib/v/util/errors.v
./v fmt -verify vlib/v/util/suggestions.v
./v fmt -verify vlib/v/util/util.v
./v fmt -verify vlib/v/builder/builder.v
./v fmt -verify vlib/v/builder/cc.v
./v fmt -verify vlib/v/builder/compile.v
./v fmt -verify vlib/v/builder/msvc.v
./v fmt -verify vlib/math/bits/bits.v
./v fmt -verify vlib/time/time.v
./v fmt -verify vlib/term/colors.v
./v fmt -verify vlib/term/term.v
./v fmt -verify vlib/v/ast/scope.v
./v fmt -verify vlib/v/checker/check_types.v
./v fmt -verify vlib/v/table/atypes.v
./v fmt -verify vlib/v/cflag/cflags.v
./v fmt -verify vlib/v/table/cflags.v
./v fmt -verify vlib/v/gen/auto_str_methods.v
./v fmt -verify vlib/v/parser/parse_type.v
./v fmt -verify vlib/v/gen/json.v
- name: v test-fmt - name: v test-fmt
run: ./v -silent test-fmt run: ./v -silent test-fmt

View File

@ -158,7 +158,7 @@ fn add(x int, y int) int {
return x + y return x + y
} }
fn sub(x, y int) int { fn sub(x int, y int) int {
return x - y return x - y
} }
``` ```
@ -644,7 +644,7 @@ fn main() {
println('Hello, $name!') println('Hello, $name!')
} }
``` ```
This program can use any public definitions from the `os` module, such This program can use any public definitions from the `os` module, such
as the `input` function. See the [standard library](https://modules.vlang.io/) as the `input` function. See the [standard library](https://modules.vlang.io/)
documentation for a list of common modules and their public symbols. documentation for a list of common modules and their public symbols.
@ -1466,7 +1466,7 @@ fn main() {
### `init` functions ### `init` functions
If you want a module to automatically call some setup/initialization code when it is imported, If you want a module to automatically call some setup/initialization code when it is imported,
you can use a module `init` function: you can use a module `init` function:
```v ```v
@ -1475,7 +1475,7 @@ fn init() {
} }
``` ```
The `init` function cannot be public - it will be called automatically. This feature is The `init` function cannot be public - it will be called automatically. This feature is
particularly useful for initializing a C library. particularly useful for initializing a C library.
## Types 2 ## Types 2
@ -2044,15 +2044,15 @@ performance.
### Asserts ### Asserts
```v ```v
mut v := 2 mut v := 2
foo(mut v) foo(mut v)
assert v < 4 assert v < 4
``` ```
An `assert` statement checks that its expression evaluates to `true`. If an assert fails, An `assert` statement checks that its expression evaluates to `true`. If an assert fails,
the program will abort. Asserts should only be used to detect programming errors. When an the program will abort. Asserts should only be used to detect programming errors. When an
assert fails it is reported to *stderr*, and the values on each side of a comparison operator assert fails it is reported to *stderr*, and the values on each side of a comparison operator
(such as `<`, `==`) will be printed when possible. This is useful to easily find an (such as `<`, `==`) will be printed when possible. This is useful to easily find an
unexpected value. Assert statements can be used in any function. unexpected value. Assert statements can be used in any function.
### Test files ### Test files
@ -2074,8 +2074,8 @@ fn test_hello() {
assert hello() == 'Hello world' assert hello() == 'Hello world'
} }
``` ```
To run the test above, use `v hello_test.v`. This will check that the function `hello` is To run the test above, use `v hello_test.v`. This will check that the function `hello` is
producing the correct output. V executes all test functions in the file. producing the correct output. V executes all test functions in the file.
* All test functions have to be inside a test file whose name ends in `_test.v`. * All test functions have to be inside a test file whose name ends in `_test.v`.
* Test function names must begin with `test_` to mark them for execution. * Test function names must begin with `test_` to mark them for execution.
@ -2084,15 +2084,15 @@ producing the correct output. V executes all test functions in the file.
* There are 2 kinds of tests: external and internal. * There are 2 kinds of tests: external and internal.
* The internal tests, have to *declare* their module, just like all other .v * The internal tests, have to *declare* their module, just like all other .v
files from the same module. Internal tests can call even private functions in files from the same module. Internal tests can call even private functions in
the same module. the same module.
* The external tests, have to *import* the modules which they test. They do not * The external tests, have to *import* the modules which they test. They do not
have access to the private functions/types of the modules. They can test only have access to the private functions/types of the modules. They can test only
the external/public API that a module provides. the external/public API that a module provides.
In the example above, `test_hello` is an internal test, that can call In the example above, `test_hello` is an internal test, that can call
the private function `hello()` because `hello_test.v` has `module main`, the private function `hello()` because `hello_test.v` has `module main`,
just like `hello.v`, i.e. both are part of the same module. Note also that just like `hello.v`, i.e. both are part of the same module. Note also that
since `module main` is a regular module like the others, internal tests can since `module main` is a regular module like the others, internal tests can
be used to test private functions in your main program .v files too. be used to test private functions in your main program .v files too.
You can also define special test functions in a test file: You can also define special test functions in a test file:
@ -2103,8 +2103,8 @@ You can also define special test functions in a test file:
To run test functions in an individual test file, use `v foo_test.v`. To run test functions in an individual test file, use `v foo_test.v`.
To test an entire module, use `v test mymodule`. You can also use `v test .` to test To test an entire module, use `v test mymodule`. You can also use `v test .` to test
everything inside your current folder (and subfolders). You can pass the `-stats` everything inside your current folder (and subfolders). You can pass the `-stats`
option to see more details about the individual tests run. option to see more details about the individual tests run.
## Memory management ## Memory management

View File

@ -9,8 +9,8 @@ pub struct array {
pub: pub:
element_size int element_size int
pub mut: pub mut:
data voidptr// Using a void pointer allows to implement arrays without generics and without generating data voidptr // Using a void pointer allows to implement arrays without generics and without generating
// extra code for every type. // extra code for every type.
len int len int
cap int cap int
} }
@ -36,10 +36,8 @@ fn __new_array_with_default(mylen int, cap int, elm_size int, val voidptr) array
cap: cap_ cap: cap_
} }
if val != 0 { if val != 0 {
for i in 0..arr.len { for i in 0 .. arr.len {
unsafe { unsafe {arr.set_unsafe(i, val)}
arr.set_unsafe(i, val)
}
} }
} }
return arr return arr
@ -53,19 +51,16 @@ fn __new_array_with_array_default(mylen int, cap int, elm_size int, val array) a
len: mylen len: mylen
cap: cap_ cap: cap_
} }
for i in 0..arr.len { for i in 0 .. arr.len {
val_clone := val.clone() val_clone := val.clone()
unsafe { unsafe {arr.set_unsafe(i, &val_clone)}
arr.set_unsafe(i, &val_clone)
}
} }
return arr return arr
} }
// Private function, used by V (`nums := [1, 2, 3]`) // Private function, used by V (`nums := [1, 2, 3]`)
fn new_array_from_c_array(len, cap, elm_size int, c_array voidptr) array { fn new_array_from_c_array(len int, cap int, elm_size int, c_array voidptr) array {
cap_ := if cap < len { len } else { cap } cap_ := if cap < len { len } else { cap }
arr := array{ arr := array{
element_size: elm_size element_size: elm_size
data: vcalloc(cap_ * elm_size) data: vcalloc(cap_ * elm_size)
@ -73,14 +68,12 @@ fn new_array_from_c_array(len, cap, elm_size int, c_array voidptr) array {
cap: cap_ cap: cap_
} }
// TODO Write all memory functions (like memcpy) in V // TODO Write all memory functions (like memcpy) in V
unsafe { unsafe {C.memcpy(arr.data, c_array, len * elm_size)}
C.memcpy(arr.data, c_array, len * elm_size)
}
return arr return arr
} }
// Private function, used by V (`nums := [1, 2, 3] !`) // Private function, used by V (`nums := [1, 2, 3] !`)
fn new_array_from_c_array_no_alloc(len, cap, elm_size int, c_array voidptr) array { fn new_array_from_c_array_no_alloc(len int, cap int, elm_size int, c_array voidptr) array {
arr := array{ arr := array{
element_size: elm_size element_size: elm_size
data: c_array data: c_array
@ -102,8 +95,7 @@ fn (mut a array) ensure_cap(required int) {
} }
if a.cap == 0 { if a.cap == 0 {
a.data = vcalloc(cap * a.element_size) a.data = vcalloc(cap * a.element_size)
} } else {
else {
a.data = v_realloc(a.data, u32(cap * a.element_size)) a.data = v_realloc(a.data, u32(cap * a.element_size))
} }
a.cap = cap a.cap = cap
@ -124,20 +116,14 @@ pub fn (a array) repeat(count int) array {
len: count * a.len len: count * a.len
cap: count * a.len cap: count * a.len
} }
for i in 0..count { for i in 0 .. count {
if a.len > 0 && a.element_size == sizeof(array) { if a.len > 0 && a.element_size == sizeof(array) {
ary := array{} ary := array{}
unsafe { unsafe {C.memcpy(&ary, a.data, sizeof(array))}
C.memcpy(&ary, a.data, sizeof(array))
}
ary_clone := ary.clone() ary_clone := ary.clone()
unsafe { unsafe {C.memcpy(arr.get_unsafe(i * a.len), &ary_clone, a.len * a.element_size)}
C.memcpy(arr.get_unsafe(i * a.len), &ary_clone, a.len * a.element_size)
}
} else { } else {
unsafe { unsafe {C.memcpy(arr.get_unsafe(i * a.len), byteptr(a.data), a.len * a.element_size)}
C.memcpy(arr.get_unsafe(i * a.len), byteptr(a.data), a.len * a.element_size)
}
} }
} }
return arr return arr
@ -150,7 +136,7 @@ pub fn (mut a array) sort_with_compare(compare voidptr) {
// array.insert // array.insert
pub fn (mut a array) insert(i int, val voidptr) { pub fn (mut a array) insert(i int, val voidptr) {
$if !no_bounds_checking? { $if !no_bounds_checking ? {
if i < 0 || i > a.len { if i < 0 || i > a.len {
panic('array.insert: index out of range (i == $i, a.len == $a.len)') panic('array.insert: index out of range (i == $i, a.len == $a.len)')
} }
@ -165,7 +151,7 @@ pub fn (mut a array) insert(i int, val voidptr) {
// array.insert_many // array.insert_many
pub fn (mut a array) insert_many(i int, val voidptr, size int) { pub fn (mut a array) insert_many(i int, val voidptr, size int) {
$if !no_bounds_checking? { $if !no_bounds_checking ? {
if i < 0 || i > a.len { if i < 0 || i > a.len {
panic('array.insert_many: index out of range (i == $i, a.len == $a.len)') panic('array.insert_many: index out of range (i == $i, a.len == $a.len)')
} }
@ -192,16 +178,14 @@ pub fn (mut a array) prepend_many(val voidptr, size int) {
// array.delete deletes array element at the given index // array.delete deletes array element at the given index
pub fn (mut a array) delete(i int) { pub fn (mut a array) delete(i int) {
$if !no_bounds_checking? { $if !no_bounds_checking ? {
if i < 0 || i >= a.len { if i < 0 || i >= a.len {
panic('array.delete: index out of range (i == $i, a.len == $a.len)') panic('array.delete: index out of range (i == $i, a.len == $a.len)')
} }
} }
// NB: if a is [12,34], a.len = 2, a.delete(0) // NB: if a is [12,34], a.len = 2, a.delete(0)
// should move (2-0-1) elements = 1 element (the 34) forward // should move (2-0-1) elements = 1 element (the 34) forward
unsafe { unsafe {C.memmove(a.get_unsafe(i), a.get_unsafe(i + 1), (a.len - i - 1) * a.element_size)}
C.memmove(a.get_unsafe(i), a.get_unsafe(i + 1), (a.len - i - 1) * a.element_size)
}
a.len-- a.len--
} }
@ -219,7 +203,8 @@ pub fn (mut a array) trim(index int) {
} }
// we manually inline this for single operations for performance without -prod // we manually inline this for single operations for performance without -prod
[inline] [unsafe] [inline]
[unsafe]
fn (a array) get_unsafe(i int) voidptr { fn (a array) get_unsafe(i int) voidptr {
unsafe { unsafe {
return byteptr(a.data) + i * a.element_size return byteptr(a.data) + i * a.element_size
@ -228,7 +213,7 @@ fn (a array) get_unsafe(i int) voidptr {
// Private function. Used to implement array[] operator // Private function. Used to implement array[] operator
fn (a array) get(i int) voidptr { fn (a array) get(i int) voidptr {
$if !no_bounds_checking? { $if !no_bounds_checking ? {
if i < 0 || i >= a.len { if i < 0 || i >= a.len {
panic('array.get: index out of range (i == $i, a.len == $a.len)') panic('array.get: index out of range (i == $i, a.len == $a.len)')
} }
@ -240,7 +225,7 @@ fn (a array) get(i int) voidptr {
// array.first returns the first element of the array // array.first returns the first element of the array
pub fn (a array) first() voidptr { pub fn (a array) first() voidptr {
$if !no_bounds_checking? { $if !no_bounds_checking ? {
if a.len == 0 { if a.len == 0 {
panic('array.first: array is empty') panic('array.first: array is empty')
} }
@ -250,7 +235,7 @@ pub fn (a array) first() voidptr {
// array.last returns the last element of the array // array.last returns the last element of the array
pub fn (a array) last() voidptr { pub fn (a array) last() voidptr {
$if !no_bounds_checking? { $if !no_bounds_checking ? {
if a.len == 0 { if a.len == 0 {
panic('array.last: array is empty') panic('array.last: array is empty')
} }
@ -263,13 +248,13 @@ pub fn (a array) last() voidptr {
// array.pop returns the last element of the array, and removes it // array.pop returns the last element of the array, and removes it
pub fn (mut a array) pop() voidptr { pub fn (mut a array) pop() voidptr {
// in a sense, this is the opposite of `a << x` // in a sense, this is the opposite of `a << x`
$if !no_bounds_checking? { $if !no_bounds_checking ? {
if a.len == 0 { if a.len == 0 {
panic('array.pop: array is empty') panic('array.pop: array is empty')
} }
} }
new_len := a.len - 1 new_len := a.len - 1
last_elem := unsafe { byteptr(a.data) + (new_len) * a.element_size } last_elem := unsafe {byteptr(a.data) + (new_len) * a.element_size}
a.len = new_len a.len = new_len
// NB: a.cap is not changed here *on purpose*, so that // NB: a.cap is not changed here *on purpose*, so that
// further << ops on that array will be more efficient. // further << ops on that array will be more efficient.
@ -280,9 +265,9 @@ pub fn (mut a array) pop() voidptr {
// but starting from the `start` element and ending with the element before // but starting from the `start` element and ending with the element before
// the `end` element of the original array with the length and capacity // the `end` element of the original array with the length and capacity
// set to the number of the elements in the slice. // set to the number of the elements in the slice.
fn (a array) slice(start, _end int) array { fn (a array) slice(start int, _end int) array {
mut end := _end mut end := _end
$if !no_bounds_checking? { $if !no_bounds_checking ? {
if start > end { if start > end {
panic('array.slice: invalid slice index ($start > $end)') panic('array.slice: invalid slice index ($start > $end)')
} }
@ -308,7 +293,7 @@ fn (a array) slice(start, _end int) array {
} }
// used internally for [2..4] // used internally for [2..4]
fn (a array) slice2(start, _end int, end_max bool) array { fn (a array) slice2(start int, _end int, end_max bool) array {
end := if end_max { a.len } else { _end } end := if end_max { a.len } else { _end }
return a.slice(start, end) return a.slice(start, end)
} }
@ -333,27 +318,21 @@ pub fn (a &array) clone() array {
} }
// Recursively clone-generated elements if array element is array type // Recursively clone-generated elements if array element is array type
if a.element_size == sizeof(array) { if a.element_size == sizeof(array) {
for i in 0..a.len { for i in 0 .. a.len {
ar := array{} ar := array{}
unsafe { unsafe {C.memcpy(&ar, a.get_unsafe(i), sizeof(array))}
C.memcpy(&ar, a.get_unsafe(i), sizeof(array))
}
ar_clone := ar.clone() ar_clone := ar.clone()
unsafe { unsafe {arr.set_unsafe(i, &ar_clone)}
arr.set_unsafe(i, &ar_clone)
}
} }
} else { } else {
unsafe { unsafe {C.memcpy(byteptr(arr.data), a.data, a.cap * a.element_size)}
C.memcpy(byteptr(arr.data), a.data, a.cap * a.element_size)
}
} }
return arr return arr
} }
fn (a &array) slice_clone(start, _end int) array { fn (a &array) slice_clone(start int, _end int) array {
mut end := _end mut end := _end
$if !no_bounds_checking? { $if !no_bounds_checking ? {
if start > end { if start > end {
panic('array.slice: invalid slice index ($start > $end)') panic('array.slice: invalid slice index ($start > $end)')
} }
@ -379,30 +358,25 @@ fn (a &array) slice_clone(start, _end int) array {
} }
// we manually inline this for single operations for performance without -prod // we manually inline this for single operations for performance without -prod
[inline] [unsafe] [inline]
[unsafe]
fn (mut a array) set_unsafe(i int, val voidptr) { fn (mut a array) set_unsafe(i int, val voidptr) {
unsafe { unsafe {C.memcpy(byteptr(a.data) + a.element_size * i, val, a.element_size)}
C.memcpy(byteptr(a.data) + a.element_size * i, val, a.element_size)
}
} }
// Private function. Used to implement assigment to the array element. // Private function. Used to implement assigment to the array element.
fn (mut a array) set(i int, val voidptr) { fn (mut a array) set(i int, val voidptr) {
$if !no_bounds_checking? { $if !no_bounds_checking ? {
if i < 0 || i >= a.len { if i < 0 || i >= a.len {
panic('array.set: index out of range (i == $i, a.len == $a.len)') panic('array.set: index out of range (i == $i, a.len == $a.len)')
} }
} }
unsafe { unsafe {C.memcpy(byteptr(a.data) + a.element_size * i, val, a.element_size)}
C.memcpy(byteptr(a.data) + a.element_size * i, val, a.element_size)
}
} }
fn (mut a array) push(val voidptr) { fn (mut a array) push(val voidptr) {
a.ensure_cap(a.len + 1) a.ensure_cap(a.len + 1)
unsafe { unsafe {C.memcpy(byteptr(a.data) + a.element_size * a.len, val, a.element_size)}
C.memcpy(byteptr(a.data) + a.element_size * a.len, val, a.element_size)
}
a.len++ a.len++
} }
@ -414,14 +388,12 @@ pub fn (mut a3 array) push_many(val voidptr, size int) {
copy := a3.clone() copy := a3.clone()
a3.ensure_cap(a3.len + size) a3.ensure_cap(a3.len + size)
unsafe { unsafe {
//C.memcpy(a.data, copy.data, copy.element_size * copy.len) // C.memcpy(a.data, copy.data, copy.element_size * copy.len)
C.memcpy(a3.get_unsafe(a3.len), copy.data, a3.element_size * size) C.memcpy(a3.get_unsafe(a3.len), copy.data, a3.element_size * size)
} }
} else { } else {
a3.ensure_cap(a3.len + size) a3.ensure_cap(a3.len + size)
unsafe { unsafe {C.memcpy(a3.get_unsafe(a3.len), val, a3.element_size * size)}
C.memcpy(a3.get_unsafe(a3.len), val, a3.element_size * size)
}
} }
a3.len += size a3.len += size
} }
@ -432,10 +404,11 @@ pub fn (mut a array) reverse_in_place() {
} }
unsafe { unsafe {
mut tmp_value := malloc(a.element_size) mut tmp_value := malloc(a.element_size)
for i in 0..a.len/2 { for i in 0 .. a.len / 2 {
C.memcpy(tmp_value, byteptr(a.data) + i * a.element_size, a.element_size) C.memcpy(tmp_value, byteptr(a.data) + i * a.element_size, a.element_size)
C.memcpy(byteptr(a.data) + i * a.element_size, byteptr(a.data) + (a.len-1-i) * a.element_size, a.element_size) C.memcpy(byteptr(a.data) + i * a.element_size, byteptr(a.data) + (a.len - 1 - i) *
C.memcpy(byteptr(a.data) + (a.len-1-i) * a.element_size, tmp_value, a.element_size) a.element_size, a.element_size)
C.memcpy(byteptr(a.data) + (a.len - 1 - i) * a.element_size, tmp_value, a.element_size)
} }
free(tmp_value) free(tmp_value)
} }
@ -453,10 +426,8 @@ pub fn (a array) reverse() array {
len: a.len len: a.len
cap: a.cap cap: a.cap
} }
for i in 0..a.len { for i in 0 .. a.len {
unsafe { unsafe {arr.set_unsafe(i, a.get_unsafe(a.len - 1 - i))}
arr.set_unsafe(i, a.get_unsafe(a.len - 1 - i))
}
} }
return arr return arr
} }
@ -478,7 +449,7 @@ pub fn (a &array) free() {
pub fn (a []string) str() string { pub fn (a []string) str() string {
mut sb := strings.new_builder(a.len * 3) mut sb := strings.new_builder(a.len * 3)
sb.write('[') sb.write('[')
for i in 0..a.len { for i in 0 .. a.len {
val := a[i] val := a[i]
sb.write("\'") sb.write("\'")
sb.write(val) sb.write(val)
@ -508,7 +479,7 @@ pub fn (b []byte) hex() string {
} }
unsafe { unsafe {
hex[dst_i] = `\0` hex[dst_i] = `\0`
return tos(hex,dst_i) return tos(hex, dst_i)
} }
} }
@ -516,20 +487,18 @@ pub fn (b []byte) hex() string {
// The number of the elements copied is the minimum of the length of both arrays. // The number of the elements copied is the minimum of the length of both arrays.
// Returns the number of elements copied. // Returns the number of elements copied.
// TODO: implement for all types // TODO: implement for all types
pub fn copy(dst, src []byte) int { pub fn copy(dst []byte, src []byte) int {
if dst.len > 0 && src.len > 0 { if dst.len > 0 && src.len > 0 {
mut min := 0 mut min := 0
min = if dst.len < src.len { dst.len } else { src.len } min = if dst.len < src.len { dst.len } else { src.len }
unsafe { unsafe {C.memcpy(byteptr(dst.data), src[..min].data, dst.element_size * min)}
C.memcpy(byteptr(dst.data), src[..min].data, dst.element_size * min)
}
return min return min
} }
return 0 return 0
} }
// Private function. Comparator for int type. // Private function. Comparator for int type.
fn compare_ints(a, b &int) int { fn compare_ints(a &int, b &int) int {
if *a < *b { if *a < *b {
return -1 return -1
} }
@ -539,7 +508,7 @@ fn compare_ints(a, b &int) int {
return 0 return 0
} }
fn compare_ints_reverse(a, b &int) int { fn compare_ints_reverse(a &int, b &int) int {
if *a > *b { if *a > *b {
return -1 return -1
} }
@ -549,7 +518,7 @@ fn compare_ints_reverse(a, b &int) int {
return 0 return 0
} }
fn compare_floats(a, b &f64) int { fn compare_floats(a &f64, b &f64) int {
if *a < *b { if *a < *b {
return -1 return -1
} }
@ -559,7 +528,7 @@ fn compare_floats(a, b &f64) int {
return 0 return 0
} }
fn compare_floats_reverse(a, b &f64) int { fn compare_floats_reverse(a &f64, b &f64) int {
if *a > *b { if *a > *b {
return -1 return -1
} }
@ -577,7 +546,7 @@ pub fn (mut a []int) sort() {
// []string.index returns the index of the first element equal to the given value, // []string.index returns the index of the first element equal to the given value,
// or -1 if the value is not found in the array. // or -1 if the value is not found in the array.
pub fn (a []string) index(v string) int { pub fn (a []string) index(v string) int {
for i in 0..a.len { for i in 0 .. a.len {
if a[i] == v { if a[i] == v {
return i return i
} }
@ -588,7 +557,7 @@ pub fn (a []string) index(v string) int {
// []int.index returns the index of the first element equal to the given value, // []int.index returns the index of the first element equal to the given value,
// or -1 if the value is not found in the array. // or -1 if the value is not found in the array.
pub fn (a []int) index(v int) int { pub fn (a []int) index(v int) int {
for i in 0..a.len { for i in 0 .. a.len {
if a[i] == v { if a[i] == v {
return i return i
} }
@ -599,7 +568,7 @@ pub fn (a []int) index(v int) int {
// []byte.index returns the index of the first element equal to the given value, // []byte.index returns the index of the first element equal to the given value,
// or -1 if the value is not found in the array. // or -1 if the value is not found in the array.
pub fn (a []byte) index(v byte) int { pub fn (a []byte) index(v byte) int {
for i in 0..a.len { for i in 0 .. a.len {
if a[i] == v { if a[i] == v {
return i return i
} }
@ -608,7 +577,7 @@ pub fn (a []byte) index(v byte) int {
} }
pub fn (a []rune) index(v rune) int { pub fn (a []rune) index(v rune) int {
for i in 0..a.len { for i in 0 .. a.len {
if a[i] == v { if a[i] == v {
return i return i
} }
@ -620,7 +589,7 @@ pub fn (a []rune) index(v rune) int {
// or -1 if the value is not found in the array. // or -1 if the value is not found in the array.
// TODO is `char` type yet in the language? // TODO is `char` type yet in the language?
pub fn (a []char) index(v char) int { pub fn (a []char) index(v char) int {
for i in 0..a.len { for i in 0 .. a.len {
if a[i] == v { if a[i] == v {
return i return i
} }
@ -630,12 +599,11 @@ pub fn (a []char) index(v char) int {
// []int.reduce executes a given reducer function on each element of the array, // []int.reduce executes a given reducer function on each element of the array,
// resulting in a single output value. // resulting in a single output value.
pub fn (a []int) reduce(iter fn(accum, curr int)int, accum_start int) int { pub fn (a []int) reduce(iter fn (int, int) int, accum_start int) int {
mut accum_ := accum_start mut accum_ := accum_start
for i in a { for i in a {
accum_ = iter(accum_, i) accum_ = iter(accum_, i)
} }
return accum_ return accum_
} }
@ -671,13 +639,12 @@ pub fn (a []f32) eq(a2 []f32) bool {
return array_eq(a, a2) return array_eq(a, a2)
} }
*/ */
pub fn (a1 []string) eq(a2 []string) bool { pub fn (a1 []string) eq(a2 []string) bool {
//return array_eq(a, a2) // return array_eq(a, a2)
if a1.len != a2.len { if a1.len != a2.len {
return false return false
} }
for i in 0..a1.len { for i in 0 .. a1.len {
if a1[i] != a2[i] { if a1[i] != a2[i] {
return false return false
} }
@ -693,7 +660,7 @@ pub fn (a1 []string) eq(a2 []string) bool {
// println(x) // Sorted i64 Array // println(x) // Sorted i64 Array
// output: // output:
// [10, 28, 70, 92, 100] // [10, 28, 70, 92, 100]
pub fn compare_i64(a, b &i64) int { pub fn compare_i64(a &i64, b &i64) int {
if *a < *b { if *a < *b {
return -1 return -1
} }
@ -705,7 +672,7 @@ pub fn compare_i64(a, b &i64) int {
// compare_f64 for []f64 sort_with_compare() // compare_f64 for []f64 sort_with_compare()
// ref. compare_i64(...) // ref. compare_i64(...)
pub fn compare_f64(a, b &f64) int { pub fn compare_f64(a &f64, b &f64) int {
if *a < *b { if *a < *b {
return -1 return -1
} }
@ -717,7 +684,7 @@ pub fn compare_f64(a, b &f64) int {
// compare_f32 for []f32 sort_with_compare() // compare_f32 for []f32 sort_with_compare()
// ref. compare_i64(...) // ref. compare_i64(...)
pub fn compare_f32(a, b &f32) int { pub fn compare_f32(a &f32, b &f32) int {
if *a < *b { if *a < *b {
return -1 return -1
} }
@ -731,10 +698,8 @@ pub fn compare_f32(a, b &f32) int {
// is the address of the corresponding element in a. // is the address of the corresponding element in a.
pub fn (a array) pointers() []voidptr { pub fn (a array) pointers() []voidptr {
mut res := []voidptr{} mut res := []voidptr{}
for i in 0..a.len { for i in 0 .. a.len {
unsafe { unsafe {res << a.get_unsafe(i)}
res << a.get_unsafe(i)
}
} }
return res return res
} }

View File

@ -36,7 +36,7 @@ pub fn print_backtrace() {
} }
// replaces panic when -debug arg is passed // replaces panic when -debug arg is passed
fn panic_debug(line_no int, file, mod, fn_name, s string) { fn panic_debug(line_no int, file string, mod string, fn_name string, s string) {
// NB: the order here is important for a stabler test output // NB: the order here is important for a stabler test output
// module is less likely to change than function, etc... // module is less likely to change than function, etc...
// During edits, the line number will change most frequently, // During edits, the line number will change most frequently,
@ -239,7 +239,7 @@ pub fn is_atty(fd int) int {
} }
} }
fn __as_cast(obj voidptr, obj_type, expected_type int) voidptr { fn __as_cast(obj voidptr, obj_type int, expected_type int) voidptr {
if obj_type != expected_type { if obj_type != expected_type {
panic('as cast: cannot cast $obj_type to $expected_type') panic('as cast: cannot cast $obj_type to $expected_type')
} }

View File

@ -91,7 +91,7 @@ fn f64_abs(a f64) f64 {
[inline] [inline]
pub fn f32_max(a, b f32) f32 { pub fn f32_max(a f32, b f32) f32 {
return if a > b { return if a > b {
a a
} else { } else {
@ -100,7 +100,7 @@ pub fn f32_max(a, b f32) f32 {
} }
[inline] [inline]
pub fn f32_min(a, b f32) f32 { pub fn f32_min(a f32, b f32) f32 {
return if a < b { return if a < b {
a a
} else { } else {
@ -109,7 +109,7 @@ pub fn f32_min(a, b f32) f32 {
} }
[inline] [inline]
pub fn f64_max(a, b f64) f64 { pub fn f64_max(a f64, b f64) f64 {
return if a > b { return if a > b {
a a
} else { } else {
@ -118,7 +118,7 @@ pub fn f64_max(a, b f64) f64 {
} }
[inline] [inline]
fn f64_min(a, b f64) f64 { fn f64_min(a f64, b f64) f64 {
return if a < b { return if a < b {
a a
} else { } else {

View File

@ -83,7 +83,7 @@ const (
// the strings are very likely to be equal // the strings are very likely to be equal
// TODO: add branch prediction hints // TODO: add branch prediction hints
[inline] [inline]
fn fast_string_eq(a, b string) bool { fn fast_string_eq(a string, b string) bool {
if a.len != b.len { if a.len != b.len {
return false return false
} }
@ -219,7 +219,7 @@ fn new_map_1(value_bytes int) map {
} }
} }
fn new_map_init(n, value_bytes int, keys &string, values voidptr) map { fn new_map_init(n int, value_bytes int, keys &string, values voidptr) map {
mut out := new_map_1(value_bytes) mut out := new_map_1(value_bytes)
for i in 0 .. n { for i in 0 .. n {
unsafe { unsafe {

View File

@ -37,7 +37,7 @@ mut:
values [11]voidptr // TODO: Should use `max_len` values [11]voidptr // TODO: Should use `max_len`
} }
fn new_sorted_map(n, value_bytes int) SortedMap { // TODO: Remove `n` fn new_sorted_map(n int, value_bytes int) SortedMap { // TODO: Remove `n`
return SortedMap { return SortedMap {
value_bytes: value_bytes value_bytes: value_bytes
root: new_node() root: new_node()
@ -45,7 +45,7 @@ fn new_sorted_map(n, value_bytes int) SortedMap { // TODO: Remove `n`
} }
} }
fn new_sorted_map_init(n, value_bytes int, keys &string, values voidptr) SortedMap { fn new_sorted_map_init(n int, value_bytes int, keys &string, values voidptr) SortedMap {
mut out := new_sorted_map(n, value_bytes) mut out := new_sorted_map(n, value_bytes)
for i in 0 .. n { for i in 0 .. n {
unsafe { unsafe {

View File

@ -169,14 +169,14 @@ pub fn cstring_to_vstring(cstr byteptr) string {
return tos_clone(cstr) return tos_clone(cstr)
} }
pub fn (s string) replace_once(rep, with string) string { pub fn (s string) replace_once(rep string, with string) string {
index := s.index(rep) or { index := s.index(rep) or {
return s.clone() return s.clone()
} }
return s.substr(0, index) + with + s.substr(index + rep.len, s.len) return s.substr(0, index) + with + s.substr(index + rep.len, s.len)
} }
pub fn (s string) replace(rep, with string) string { pub fn (s string) replace(rep string, with string) string {
if s.len == 0 || rep.len == 0 { if s.len == 0 || rep.len == 0 {
return s.clone() return s.clone()
} }
@ -239,7 +239,7 @@ struct RepIndex {
val_idx int val_idx int
} }
fn compare_rep_index(a, b &RepIndex) int { fn compare_rep_index(a &RepIndex, b &RepIndex) int {
if a.idx < b.idx { if a.idx < b.idx {
return -1 return -1
} }
@ -566,12 +566,12 @@ fn (s string) right(n int) string {
} }
// used internally for [2..4] // used internally for [2..4]
fn (s string) substr2(start, _end int, end_max bool) string { fn (s string) substr2(start int, _end int, end_max bool) string {
end := if end_max { s.len } else { _end } end := if end_max { s.len } else { _end }
return s.substr(start, end) return s.substr(start, end)
} }
pub fn (s string) substr(start, end int) string { pub fn (s string) substr(start int, end int) string {
$if !no_bounds_checking? { $if !no_bounds_checking? {
if start > end || start > s.len || end > s.len || start < 0 || end < 0 { if start > end || start > s.len || end > s.len || start < 0 || end < 0 {
panic('substr($start, $end) out of bounds (len=$s.len)') panic('substr($start, $end) out of bounds (len=$s.len)')
@ -898,7 +898,7 @@ pub fn (s string) is_title() bool {
// 'hey [man] how you doin' // 'hey [man] how you doin'
// find_between('[', ']') == 'man' // find_between('[', ']') == 'man'
pub fn (s string) find_between(start, end string) string { pub fn (s string) find_between(start string, end string) string {
start_pos := s.index(start) or { start_pos := s.index(start) or {
return '' return ''
} }
@ -1004,7 +1004,7 @@ pub fn (s string) trim_suffix(str string) string {
return s return s
} }
pub fn compare_strings(a, b &string) int { pub fn compare_strings(a &string, b &string) int {
if a.lt(b) { if a.lt(b) {
return -1 return -1
} }
@ -1014,7 +1014,7 @@ pub fn compare_strings(a, b &string) int {
return 0 return 0
} }
fn compare_strings_reverse(a, b &string) int { fn compare_strings_reverse(a &string, b &string) int {
if a.lt(b) { if a.lt(b) {
return 1 return 1
} }
@ -1024,7 +1024,7 @@ fn compare_strings_reverse(a, b &string) int {
return 0 return 0
} }
fn compare_strings_by_len(a, b &string) int { fn compare_strings_by_len(a &string, b &string) int {
if a.len < b.len { if a.len < b.len {
return -1 return -1
} }
@ -1034,7 +1034,7 @@ fn compare_strings_by_len(a, b &string) int {
return 0 return 0
} }
fn compare_lower_strings(a, b &string) int { fn compare_lower_strings(a &string, b &string) int {
aa := a.to_lower() aa := a.to_lower()
bb := b.to_lower() bb := b.to_lower()
return compare_strings(aa, bb) return compare_strings(aa, bb)
@ -1200,7 +1200,7 @@ pub fn (u ustring) count(substr ustring) int {
return 0 // TODO can never get here - v doesn't know that return 0 // TODO can never get here - v doesn't know that
} }
pub fn (u ustring) substr(_start, _end int) string { pub fn (u ustring) substr(_start int, _end int) string {
$if !no_bounds_checking? { $if !no_bounds_checking? {
if _start > _end || _start > u.len || _end > u.len || _start < 0 || _end < 0 { if _start > _end || _start > u.len || _end > u.len || _start < 0 || _end < 0 {
panic('substr($_start, $_end) out of bounds (len=$u.len)') panic('substr($_start, $_end) out of bounds (len=$u.len)')

View File

@ -29,7 +29,7 @@ const (
) )
[inline] [inline]
pub fn wyhash_c(key byteptr, len, seed u64) u64 { pub fn wyhash_c(key byteptr, len u64, seed u64) u64 {
return C.wyhash(key, len, seed) return C.wyhash(key, len, seed)
} }
@ -44,7 +44,7 @@ pub fn sum64(key []byte, seed u64) u64 {
} }
[inline] [inline]
fn wyhash64(key byteptr, len, seed_ u64) u64 { fn wyhash64(key byteptr, len u64, seed_ u64) u64 {
if len == 0 { if len == 0 {
return 0 return 0
} }
@ -96,7 +96,7 @@ fn wyrotr(v u64, k u32) u64 {
} }
[inline] [inline]
pub fn wymum(a, b u64) u64 { pub fn wymum(a u64, b u64) u64 {
/* /*
mut r := u128(a) mut r := u128(a)
r = r*b r = r*b

View File

@ -4,17 +4,14 @@
module bits module bits
const ( const (
// See http://supertech.csail.mit.edu/papers/debruijn.pdf // See http://supertech.csail.mit.edu/papers/debruijn.pdf
de_bruijn32 = u32(0x077CB531) de_bruijn32 = u32(0x077CB531)
de_bruijn32tab = [byte(0), 1, 28, 2, 29, 14, 24, 3, 30, 22, 20, 15, 25, 17, 4, 8, de_bruijn32tab = [byte(0), 1, 28, 2, 29, 14, 24, 3, 30, 22, 20, 15, 25, 17, 4, 8, 31, 27, 13,
31, 27, 13, 23, 21, 19, 16, 7, 26, 12, 18, 6, 11, 5, 10, 9, 23, 21, 19, 16, 7, 26, 12, 18, 6, 11, 5, 10, 9]
] de_bruijn64 = u64(0x03f79d71b4ca8b09)
de_bruijn64 = u64(0x03f79d71b4ca8b09) de_bruijn64tab = [byte(0), 1, 56, 2, 57, 49, 28, 3, 61, 58, 42, 50, 38, 29, 17, 4, 62, 47,
de_bruijn64tab = [byte(0), 1, 56, 2, 57, 49, 28, 3, 61, 58, 42, 50, 38, 29, 17, 4, 59, 36, 45, 43, 51, 22, 53, 39, 33, 30, 24, 18, 12, 5, 63, 55, 48, 27, 60, 41, 37, 16, 46, 35,
62, 47, 59, 36, 45, 43, 51, 22, 53, 39, 33, 30, 24, 18, 12, 5, 44, 21, 52, 32, 23, 11, 54, 26, 40, 15, 34, 20, 31, 10, 25, 14, 19, 9, 13, 8, 7, 6]
63, 55, 48, 27, 60, 41, 37, 16, 46, 35, 44, 21, 52, 32, 23, 11,
54, 26, 40, 15, 34, 20, 31, 10, 25, 14, 19, 9, 13, 8, 7, 6,
]
) )
const ( const (
@ -64,7 +61,7 @@ pub fn trailing_zeros_16(x u16) int {
return 16 return 16
} }
// see comment in trailing_zeros_64 // see comment in trailing_zeros_64
return int(de_bruijn32tab[u32(x & -x) * de_bruijn32>>(32 - 5)]) return int(de_bruijn32tab[u32(x & -x) * de_bruijn32 >> (32 - 5)])
} }
// trailing_zeros_32 returns the number of trailing zero bits in x; the result is 32 for x == 0. // trailing_zeros_32 returns the number of trailing zero bits in x; the result is 32 for x == 0.
@ -73,7 +70,7 @@ pub fn trailing_zeros_32(x u32) int {
return 32 return 32
} }
// see comment in trailing_zeros_64 // see comment in trailing_zeros_64
return int(de_bruijn32tab[(x & -x) * de_bruijn32>>(32 - 5)]) return int(de_bruijn32tab[(x & -x) * de_bruijn32 >> (32 - 5)])
} }
// trailing_zeros_64 returns the number of trailing zero bits in x; the result is 64 for x == 0. // trailing_zeros_64 returns the number of trailing zero bits in x; the result is 64 for x == 0.
@ -92,11 +89,10 @@ pub fn trailing_zeros_64(x u64) int {
// find by how many bits it was shifted by looking at which six bit // find by how many bits it was shifted by looking at which six bit
// substring ended up at the top of the word. // substring ended up at the top of the word.
// (Knuth, volume 4, section 7.3.1) // (Knuth, volume 4, section 7.3.1)
return int(de_bruijn64tab[(x & -x) * de_bruijn64>>(64 - 6)]) return int(de_bruijn64tab[(x & -x) * de_bruijn64 >> (64 - 6)])
} }
// --- OnesCount --- // --- OnesCount ---
// ones_count_8 returns the number of one bits ("population count") in x. // ones_count_8 returns the number of one bits ("population count") in x.
pub fn ones_count_8(x byte) int { pub fn ones_count_8(x byte) int {
return int(pop_8_tab[x]) return int(pop_8_tab[x])
@ -104,12 +100,13 @@ pub fn ones_count_8(x byte) int {
// ones_count_16 returns the number of one bits ("population count") in x. // ones_count_16 returns the number of one bits ("population count") in x.
pub fn ones_count_16(x u16) int { pub fn ones_count_16(x u16) int {
return int(pop_8_tab[x>>8] + pop_8_tab[x & u16(0xff)]) return int(pop_8_tab[x >> 8] + pop_8_tab[x & u16(0xff)])
} }
// ones_count_32 returns the number of one bits ("population count") in x. // ones_count_32 returns the number of one bits ("population count") in x.
pub fn ones_count_32(x u32) int { pub fn ones_count_32(x u32) int {
return int(pop_8_tab[x>>24] + pop_8_tab[x>>16 & 0xff] + pop_8_tab[x>>8 & 0xff] + pop_8_tab[x & u32(0xff)]) return int(pop_8_tab[x >> 24] + pop_8_tab[x >> 16 & 0xff] + pop_8_tab[x >> 8 & 0xff] + pop_8_tab[x &
u32(0xff)])
} }
// ones_count_64 returns the number of one bits ("population count") in x. // ones_count_64 returns the number of one bits ("population count") in x.
@ -133,17 +130,16 @@ pub fn ones_count_64(x u64) int {
// Per "Hacker's Delight", the first line can be simplified // Per "Hacker's Delight", the first line can be simplified
// more, but it saves at best one instruction, so we leave // more, but it saves at best one instruction, so we leave
// it alone for clarity. // it alone for clarity.
mut y := (x>>u64(1) & (m0 & max_u64)) + (x & (m0 & max_u64)) mut y := (x >> u64(1) & (m0 & max_u64)) + (x & (m0 & max_u64))
y = (y>>u64(2) & (m1 & max_u64)) + (y & (m1 & max_u64)) y = (y >> u64(2) & (m1 & max_u64)) + (y & (m1 & max_u64))
y = ((y>>4) + y) & (m2 & max_u64) y = ((y >> 4) + y) & (m2 & max_u64)
y += y>>8 y += y >> 8
y += y>>16 y += y >> 16
y += y>>32 y += y >> 32
return int(y) & ((1<<7) - 1) return int(y) & ((1 << 7) - 1)
} }
// --- RotateLeft --- // --- RotateLeft ---
// rotate_left_8 returns the value of x rotated left by (k mod 8) bits. // rotate_left_8 returns the value of x rotated left by (k mod 8) bits.
// To rotate x right by k bits, call rotate_left_8(x, -k). // To rotate x right by k bits, call rotate_left_8(x, -k).
// //
@ -152,7 +148,7 @@ pub fn ones_count_64(x u64) int {
pub fn rotate_left_8(x byte, k int) byte { pub fn rotate_left_8(x byte, k int) byte {
n := byte(8) n := byte(8)
s := byte(k) & (n - byte(1)) s := byte(k) & (n - byte(1))
return ((x<<s) | (x>>(n - s))) return ((x << s) | (x >> (n - s)))
} }
// rotate_left_16 returns the value of x rotated left by (k mod 16) bits. // rotate_left_16 returns the value of x rotated left by (k mod 16) bits.
@ -163,7 +159,7 @@ pub fn rotate_left_8(x byte, k int) byte {
pub fn rotate_left_16(x u16, k int) u16 { pub fn rotate_left_16(x u16, k int) u16 {
n := u16(16) n := u16(16)
s := u16(k) & (n - u16(1)) s := u16(k) & (n - u16(1))
return ((x<<s) | (x>>(n - s))) return ((x << s) | (x >> (n - s)))
} }
// rotate_left_32 returns the value of x rotated left by (k mod 32) bits. // rotate_left_32 returns the value of x rotated left by (k mod 32) bits.
@ -174,7 +170,7 @@ pub fn rotate_left_16(x u16, k int) u16 {
pub fn rotate_left_32(x u32, k int) u32 { pub fn rotate_left_32(x u32, k int) u32 {
n := u32(32) n := u32(32)
s := u32(k) & (n - u32(1)) s := u32(k) & (n - u32(1))
return ((x<<s) | (x>>(n - s))) return ((x << s) | (x >> (n - s)))
} }
// rotate_left_64 returns the value of x rotated left by (k mod 64) bits. // rotate_left_64 returns the value of x rotated left by (k mod 64) bits.
@ -185,11 +181,10 @@ pub fn rotate_left_32(x u32, k int) u32 {
pub fn rotate_left_64(x u64, k int) u64 { pub fn rotate_left_64(x u64, k int) u64 {
n := u64(64) n := u64(64)
s := u64(k) & (n - u64(1)) s := u64(k) & (n - u64(1))
return ((x<<s) | (x>>(n - s))) return ((x << s) | (x >> (n - s)))
} }
// --- Reverse --- // --- Reverse ---
// reverse_8 returns the value of x with its bits in reversed order. // reverse_8 returns the value of x with its bits in reversed order.
[inline] [inline]
pub fn reverse_8(x byte) byte { pub fn reverse_8(x byte) byte {
@ -199,35 +194,34 @@ pub fn reverse_8(x byte) byte {
// reverse_16 returns the value of x with its bits in reversed order. // reverse_16 returns the value of x with its bits in reversed order.
[inline] [inline]
pub fn reverse_16(x u16) u16 { pub fn reverse_16(x u16) u16 {
return u16(rev_8_tab[x>>8]) | (u16(rev_8_tab[x & u16(0xff)])<<8) return u16(rev_8_tab[x >> 8]) | (u16(rev_8_tab[x & u16(0xff)]) << 8)
} }
// reverse_32 returns the value of x with its bits in reversed order. // reverse_32 returns the value of x with its bits in reversed order.
[inline] [inline]
pub fn reverse_32(x u32) u32 { pub fn reverse_32(x u32) u32 {
mut y := ((x>>u32(1) & (m0 & max_u32)) | ((x & (m0 & max_u32))<<1)) mut y := ((x >> u32(1) & (m0 & max_u32)) | ((x & (m0 & max_u32)) << 1))
y = ((y>>u32(2) & (m1 & max_u32)) | ((y & (m1 & max_u32))<<u32(2))) y = ((y >> u32(2) & (m1 & max_u32)) | ((y & (m1 & max_u32)) << u32(2)))
y = ((y>>u32(4) & (m2 & max_u32)) | ((y & (m2 & max_u32))<<u32(4))) y = ((y >> u32(4) & (m2 & max_u32)) | ((y & (m2 & max_u32)) << u32(4)))
return reverse_bytes_32(u32(y)) return reverse_bytes_32(u32(y))
} }
// reverse_64 returns the value of x with its bits in reversed order. // reverse_64 returns the value of x with its bits in reversed order.
[inline] [inline]
pub fn reverse_64(x u64) u64 { pub fn reverse_64(x u64) u64 {
mut y := ((x>>u64(1) & (m0 & max_u64)) | ((x & (m0 & max_u64))<<1)) mut y := ((x >> u64(1) & (m0 & max_u64)) | ((x & (m0 & max_u64)) << 1))
y = ((y>>u64(2) & (m1 & max_u64)) | ((y & (m1 & max_u64))<<2)) y = ((y >> u64(2) & (m1 & max_u64)) | ((y & (m1 & max_u64)) << 2))
y = ((y>>u64(4) & (m2 & max_u64)) | ((y & (m2 & max_u64))<<4)) y = ((y >> u64(4) & (m2 & max_u64)) | ((y & (m2 & max_u64)) << 4))
return reverse_bytes_64(y) return reverse_bytes_64(y)
} }
// --- ReverseBytes --- // --- ReverseBytes ---
// reverse_bytes_16 returns the value of x with its bytes in reversed order. // reverse_bytes_16 returns the value of x with its bytes in reversed order.
// //
// This function's execution time does not depend on the inputs. // This function's execution time does not depend on the inputs.
[inline] [inline]
pub fn reverse_bytes_16(x u16) u16 { pub fn reverse_bytes_16(x u16) u16 {
return (x>>8) | (x<<8) return (x >> 8) | (x << 8)
} }
// reverse_bytes_32 returns the value of x with its bytes in reversed order. // reverse_bytes_32 returns the value of x with its bytes in reversed order.
@ -235,8 +229,8 @@ pub fn reverse_bytes_16(x u16) u16 {
// This function's execution time does not depend on the inputs. // This function's execution time does not depend on the inputs.
[inline] [inline]
pub fn reverse_bytes_32(x u32) u32 { pub fn reverse_bytes_32(x u32) u32 {
y := ((x>>u32(8) & (m3 & max_u32)) | ((x & (m3 & max_u32))<<u32(8))) y := ((x >> u32(8) & (m3 & max_u32)) | ((x & (m3 & max_u32)) << u32(8)))
return u32((y>>16) | (y<<16)) return u32((y >> 16) | (y << 16))
} }
// reverse_bytes_64 returns the value of x with its bytes in reversed order. // reverse_bytes_64 returns the value of x with its bytes in reversed order.
@ -244,13 +238,12 @@ pub fn reverse_bytes_32(x u32) u32 {
// This function's execution time does not depend on the inputs. // This function's execution time does not depend on the inputs.
[inline] [inline]
pub fn reverse_bytes_64(x u64) u64 { pub fn reverse_bytes_64(x u64) u64 {
mut y := ((x>>u64(8) & (m3 & max_u64)) | ((x & (m3 & max_u64))<<u64(8))) mut y := ((x >> u64(8) & (m3 & max_u64)) | ((x & (m3 & max_u64)) << u64(8)))
y = ((y>>u64(16) & (m4 & max_u64)) | ((y & (m4 & max_u64))<<u64(16))) y = ((y >> u64(16) & (m4 & max_u64)) | ((y & (m4 & max_u64)) << u64(16)))
return (y>>32) | (y<<32) return (y >> 32) | (y << 32)
} }
// --- Len --- // --- Len ---
// len_8 returns the minimum number of bits required to represent x; the result is 0 for x == 0. // len_8 returns the minimum number of bits required to represent x; the result is 0 for x == 0.
pub fn len_8(x byte) int { pub fn len_8(x byte) int {
return int(len_8_tab[x]) return int(len_8_tab[x])
@ -260,7 +253,7 @@ pub fn len_8(x byte) int {
pub fn len_16(x u16) int { pub fn len_16(x u16) int {
mut y := x mut y := x
mut n := 0 mut n := 0
if y >= 1<<8 { if y >= 1 << 8 {
y >>= 8 y >>= 8
n = 8 n = 8
} }
@ -271,11 +264,11 @@ pub fn len_16(x u16) int {
pub fn len_32(x u32) int { pub fn len_32(x u32) int {
mut y := x mut y := x
mut n := 0 mut n := 0
if y >= (1<<16) { if y >= (1 << 16) {
y >>= 16 y >>= 16
n = 16 n = 16
} }
if y >= (1<<8) { if y >= (1 << 8) {
y >>= 8 y >>= 8
n += 8 n += 8
} }
@ -286,15 +279,15 @@ pub fn len_32(x u32) int {
pub fn len_64(x u64) int { pub fn len_64(x u64) int {
mut y := x mut y := x
mut n := 0 mut n := 0
if y >= u64(1)<<u64(32) { if y >= u64(1) << u64(32) {
y >>= 32 y >>= 32
n = 32 n = 32
} }
if y >= u64(1)<<u64(16) { if y >= u64(1) << u64(16) {
y >>= 16 y >>= 16
n += 16 n += 16
} }
if y >= u64(1)<<u64(8) { if y >= u64(1) << u64(8) {
y >>= 8 y >>= 8
n += 8 n += 8
} }
@ -302,12 +295,10 @@ pub fn len_64(x u64) int {
} }
// --- Add with carry --- // --- Add with carry ---
// Add returns the sum with carry of x, y and carry: sum = x + y + carry. // Add returns the sum with carry of x, y and carry: sum = x + y + carry.
// The carry input must be 0 or 1; otherwise the behavior is undefined. // The carry input must be 0 or 1; otherwise the behavior is undefined.
// The carryOut output is guaranteed to be 0 or 1. // The carryOut output is guaranteed to be 0 or 1.
// //
// add_32 returns the sum with carry of x, y and carry: sum = x + y + carry. // add_32 returns the sum with carry of x, y and carry: sum = x + y + carry.
// The carry input must be 0 or 1; otherwise the behavior is undefined. // The carry input must be 0 or 1; otherwise the behavior is undefined.
// The carryOut output is guaranteed to be 0 or 1. // The carryOut output is guaranteed to be 0 or 1.
@ -316,7 +307,7 @@ pub fn len_64(x u64) int {
pub fn add_32(x u32, y u32, carry u32) (u32, u32) { pub fn add_32(x u32, y u32, carry u32) (u32, u32) {
sum64 := u64(x) + u64(y) + u64(carry) sum64 := u64(x) + u64(y) + u64(carry)
sum := u32(sum64) sum := u32(sum64)
carry_out := u32(sum64>>32) carry_out := u32(sum64 >> 32)
return sum, carry_out return sum, carry_out
} }
@ -330,17 +321,15 @@ pub fn add_64(x u64, y u64, carry u64) (u64, u64) {
// The sum will overflow if both top bits are set (x & y) or if one of them // The sum will overflow if both top bits are set (x & y) or if one of them
// is (x | y), and a carry from the lower place happened. If such a carry // is (x | y), and a carry from the lower place happened. If such a carry
// happens, the top bit will be 1 + 0 + 1 = 0 (&^ sum). // happens, the top bit will be 1 + 0 + 1 = 0 (&^ sum).
carry_out := ((x & y) | ((x | y) & ~sum ))>>63 carry_out := ((x & y) | ((x | y) & ~sum)) >> 63
return sum, carry_out return sum, carry_out
} }
// --- Subtract with borrow --- // --- Subtract with borrow ---
// Sub returns the difference of x, y and borrow: diff = x - y - borrow. // Sub returns the difference of x, y and borrow: diff = x - y - borrow.
// The borrow input must be 0 or 1; otherwise the behavior is undefined. // The borrow input must be 0 or 1; otherwise the behavior is undefined.
// The borrowOut output is guaranteed to be 0 or 1. // The borrowOut output is guaranteed to be 0 or 1.
// //
// sub_32 returns the difference of x, y and borrow, diff = x - y - borrow. // sub_32 returns the difference of x, y and borrow, diff = x - y - borrow.
// The borrow input must be 0 or 1; otherwise the behavior is undefined. // The borrow input must be 0 or 1; otherwise the behavior is undefined.
// The borrowOut output is guaranteed to be 0 or 1. // The borrowOut output is guaranteed to be 0 or 1.
@ -352,7 +341,7 @@ pub fn sub_32(x u32, y u32, borrow u32) (u32, u32) {
// bit of y is set (^x & y) or if they are the same (^(x ^ y)) and a borrow // bit of y is set (^x & y) or if they are the same (^(x ^ y)) and a borrow
// from the lower place happens. If that borrow happens, the result will be // from the lower place happens. If that borrow happens, the result will be
// 1 - 1 - 1 = 0 - 0 - 1 = 1 (& diff). // 1 - 1 - 1 = 0 - 0 - 1 = 1 (& diff).
borrow_out := ((~x & y) | (~(x ^ y) & diff))>>31 borrow_out := ((~x & y) | (~(x ^ y) & diff)) >> 31
return diff, borrow_out return diff, borrow_out
} }
@ -364,17 +353,16 @@ pub fn sub_32(x u32, y u32, borrow u32) (u32, u32) {
pub fn sub_64(x u64, y u64, borrow u64) (u64, u64) { pub fn sub_64(x u64, y u64, borrow u64) (u64, u64) {
diff := x - y - borrow diff := x - y - borrow
// See Sub32 for the bit logic. // See Sub32 for the bit logic.
borrow_out := ((~x & y) | (~(x ^ y) & diff))>>63 borrow_out := ((~x & y) | (~(x ^ y) & diff)) >> 63
return diff, borrow_out return diff, borrow_out
} }
// --- Full-width multiply --- // --- Full-width multiply ---
const ( const (
two32 = u64(0x1_0000_0000) two32 = u64(0x100000000)
mask32 = two32 - 1 mask32 = two32 - 1
overflow_error = "Overflow Error" overflow_error = 'Overflow Error'
divide_error = "Divide Error" divide_error = 'Divide Error'
) )
// mul_32 returns the 64-bit product of x and y: (hi, lo) = x * y // mul_32 returns the 64-bit product of x and y: (hi, lo) = x * y
@ -384,7 +372,7 @@ const (
// This function's execution time does not depend on the inputs. // This function's execution time does not depend on the inputs.
pub fn mul_32(x u32, y u32) (u32, u32) { pub fn mul_32(x u32, y u32) (u32, u32) {
tmp := u64(x) * u64(y) tmp := u64(x) * u64(y)
hi := u32(tmp>>32) hi := u32(tmp >> 32)
lo := u32(tmp) lo := u32(tmp)
return hi, lo return hi, lo
} }
@ -396,21 +384,20 @@ pub fn mul_32(x u32, y u32) (u32, u32) {
// This function's execution time does not depend on the inputs. // This function's execution time does not depend on the inputs.
pub fn mul_64(x u64, y u64) (u64, u64) { pub fn mul_64(x u64, y u64) (u64, u64) {
x0 := x & mask32 x0 := x & mask32
x1 := x>>32 x1 := x >> 32
y0 := y & mask32 y0 := y & mask32
y1 := y>>32 y1 := y >> 32
w0 := x0 * y0 w0 := x0 * y0
t := x1*y0 + (w0>>32) t := x1 * y0 + (w0 >> 32)
mut w1 := t & mask32 mut w1 := t & mask32
w2 := t>>32 w2 := t >> 32
w1 += x0 * y1 w1 += x0 * y1
hi := x1*y1 + w2 + (w1>>32) hi := x1 * y1 + w2 + (w1 >> 32)
lo := x * y lo := x * y
return hi, lo return hi, lo
} }
// --- Full-width divide --- // --- Full-width divide ---
// div_32 returns the quotient and remainder of (hi, lo) divided by y: // div_32 returns the quotient and remainder of (hi, lo) divided by y:
// quo = (hi, lo)/y, rem = (hi, lo)%y with the dividend bits' upper // quo = (hi, lo)/y, rem = (hi, lo)%y with the dividend bits' upper
// half in parameter hi and the lower half in parameter lo. // half in parameter hi and the lower half in parameter lo.
@ -419,9 +406,9 @@ pub fn div_32(hi u32, lo u32, y u32) (u32, u32) {
if y != 0 && y <= hi { if y != 0 && y <= hi {
panic(overflow_error) panic(overflow_error)
} }
z := (u64(hi)<<32) | u64(lo) z := (u64(hi) << 32) | u64(lo)
quo := u32(z/u64(y)) quo := u32(z / u64(y))
rem := u32(z%u64(y)) rem := u32(z % u64(y))
return quo, rem return quo, rem
} }
@ -437,59 +424,53 @@ pub fn div_64(hi u64, lo u64, y1 u64) (u64, u64) {
if y <= hi { if y <= hi {
panic(overflow_error) panic(overflow_error)
} }
s := u32(leading_zeros_64(y)) s := u32(leading_zeros_64(y))
y <<= s y <<= s
yn1 := y >> 32
yn1 := y>>32
yn0 := y & mask32 yn0 := y & mask32
un32 := (hi<<s) | (lo>>(64-s)) un32 := (hi << s) | (lo >> (64 - s))
un10 := lo<<s un10 := lo << s
un1 := un10>>32 un1 := un10 >> 32
un0 := un10 & mask32 un0 := un10 & mask32
mut q1 := un32 / yn1 mut q1 := un32 / yn1
mut rhat := un32 - q1*yn1 mut rhat := un32 - q1 * yn1
for q1 >= two32 || q1 * yn0 > two32 * rhat + un1 {
for q1 >= two32 || q1*yn0 > two32*rhat+un1 {
q1-- q1--
rhat += yn1 rhat += yn1
if rhat >= two32 { if rhat >= two32 {
break break
} }
} }
un21 := un32 * two32 + un1 - q1 * y
un21 := un32*two32 + un1 - q1*y
mut q0 := un21 / yn1 mut q0 := un21 / yn1
rhat = un21 - q0*yn1 rhat = un21 - q0 * yn1
for q0 >= two32 || q0 * yn0 > two32 * rhat + un0 {
for q0 >= two32 || q0*yn0 > two32*rhat+un0 {
q0-- q0--
rhat += yn1 rhat += yn1
if rhat >= two32 { if rhat >= two32 {
break break
} }
} }
return q1 * two32 + q0, (un21 * two32 + un0 - q0 * y) >> s
return q1*two32 + q0, (un21*two32 + un0 - q0*y)>>s
} }
// rem_32 returns the remainder of (hi, lo) divided by y. Rem32 panics // rem_32 returns the remainder of (hi, lo) divided by y. Rem32 panics
// for y == 0 (division by zero) but, unlike Div32, it doesn't panic // for y == 0 (division by zero) but, unlike Div32, it doesn't panic
// on a quotient overflow. // on a quotient overflow.
pub fn rem_32(hi u32, lo u32, y u32) u32 { pub fn rem_32(hi u32, lo u32, y u32) u32 {
return u32(((u64(hi)<<32) | u64(lo)) % u64(y)) return u32(((u64(hi) << 32) | u64(lo)) % u64(y))
} }
// rem_64 returns the remainder of (hi, lo) divided by y. Rem64 panics // rem_64 returns the remainder of (hi, lo) divided by y. Rem64 panics
// for y == 0 (division by zero) but, unlike div_64, it doesn't panic // for y == 0 (division by zero) but, unlike div_64, it doesn't panic
// on a quotient overflow. // on a quotient overflow.
pub fn rem_64(hi, lo, y u64) u64 { pub fn rem_64(hi u64, lo u64, y u64) u64 {
// We scale down hi so that hi < y, then use div_64 to compute the // We scale down hi so that hi < y, then use div_64 to compute the
// rem with the guarantee that it won't panic on quotient overflow. // rem with the guarantee that it won't panic on quotient overflow.
// Given that // Given that
// hi ≡ hi%y (mod y) // hi ≡ hi%y (mod y)
// we have // we have
// hi<<64 + lo ≡ (hi%y)<<64 + lo (mod y) // hi<<64 + lo ≡ (hi%y)<<64 + lo (mod y)
_, rem := div_64(hi%y, lo, y) _, rem := div_64(hi % y, lo, y)
return rem return rem
} }

View File

@ -70,7 +70,7 @@ pub fn (mut f File) write_bytes(data voidptr, size int) int {
return C.fwrite(data, 1, size, f.cfile) return C.fwrite(data, 1, size, f.cfile)
} }
pub fn (mut f File) write_bytes_at(data voidptr, size, pos int) int { pub fn (mut f File) write_bytes_at(data voidptr, size int, pos int) int {
C.fseek(f.cfile, pos, C.SEEK_SET) C.fseek(f.cfile, pos, C.SEEK_SET)
res := C.fwrite(data, 1, size, f.cfile) res := C.fwrite(data, 1, size, f.cfile)
C.fseek(f.cfile, 0, C.SEEK_END) C.fseek(f.cfile, 0, C.SEEK_END)
@ -84,7 +84,7 @@ pub fn (f &File) read_bytes(size int) []byte {
} }
// read_bytes_at reads bytes at the given position in the file // read_bytes_at reads bytes at the given position in the file
pub fn (f &File) read_bytes_at(size, pos int) []byte { pub fn (f &File) read_bytes_at(size int, pos int) []byte {
mut arr := []byte{len: size} mut arr := []byte{len: size}
nreadbytes := f.read_bytes_into(pos, mut arr) or { nreadbytes := f.read_bytes_into(pos, mut arr) or {
// return err // return err

View File

@ -57,7 +57,7 @@ pub fn read_file(path string) ?string {
} }
} }
/***************************** OS ops ************************/ //***************************** OS ops ************************
// file_size returns the size of the file located in `path`. // file_size returns the size of the file located in `path`.
pub fn file_size(path string) int { pub fn file_size(path string) int {
mut s := C.stat{} mut s := C.stat{}
@ -76,7 +76,7 @@ pub fn file_size(path string) int {
} }
// mv moves files or folders from `src` to `dst`. // mv moves files or folders from `src` to `dst`.
pub fn mv(src, dst string) { pub fn mv(src string, dst string) {
mut rdst := dst mut rdst := dst
if is_dir(rdst) { if is_dir(rdst) {
rdst = join_path(rdst.trim_right(path_separator),file_name(src.trim_right(path_separator))) rdst = join_path(rdst.trim_right(path_separator),file_name(src.trim_right(path_separator)))
@ -91,7 +91,7 @@ pub fn mv(src, dst string) {
} }
// cp copies files or folders from `src` to `dst`. // cp copies files or folders from `src` to `dst`.
pub fn cp(src, dst string) ? { pub fn cp(src string, dst string) ? {
$if windows { $if windows {
w_src := src.replace('/', '\\') w_src := src.replace('/', '\\')
w_dst := dst.replace('/', '\\') w_dst := dst.replace('/', '\\')
@ -135,14 +135,14 @@ pub fn cp(src, dst string) ? {
} }
[deprecated] [deprecated]
pub fn cp_r(osource_path, odest_path string, overwrite bool) ? { pub fn cp_r(osource_path string, odest_path string, overwrite bool) ? {
eprintln('warning: `os.cp_r` has been deprecated, use `os.cp_all` instead') eprintln('warning: `os.cp_r` has been deprecated, use `os.cp_all` instead')
return cp_all(osource_path, odest_path, overwrite) return cp_all(osource_path, odest_path, overwrite)
} }
// cp_all will recursively copy `src` to `dst`, // cp_all will recursively copy `src` to `dst`,
// optionally overwriting files or dirs in `dst`. // optionally overwriting files or dirs in `dst`.
pub fn cp_all(src, dst string, overwrite bool) ? { pub fn cp_all(src string, dst string, overwrite bool) ? {
source_path := os.real_path(src) source_path := os.real_path(src)
dest_path := os.real_path(dst) dest_path := os.real_path(dst)
if !os.exists(source_path) { if !os.exists(source_path) {
@ -190,7 +190,7 @@ pub fn mv_by_cp(source string, target string) ? {
// vfopen returns an opened C file, given its path and open mode. // vfopen returns an opened C file, given its path and open mode.
// NB: os.vfopen is useful for compatibility with C libraries, that expect `FILE *`. // NB: os.vfopen is useful for compatibility with C libraries, that expect `FILE *`.
// If you write pure V code, os.create or os.open are more convenient. // If you write pure V code, os.create or os.open are more convenient.
pub fn vfopen(path, mode string) ?&C.FILE { pub fn vfopen(path string, mode string) ?&C.FILE {
if path.len == 0 { if path.len == 0 {
return error('vfopen called with ""') return error('vfopen called with ""')
} }
@ -858,7 +858,7 @@ pub fn home_dir() string {
} }
// write_file writes `text` data to a file in `path`. // write_file writes `text` data to a file in `path`.
pub fn write_file(path, text string) ? { pub fn write_file(path string, text string) ? {
mut f := os.create(path)? mut f := os.create(path)?
f.write(text) f.write(text)
f.close() f.close()
@ -1164,7 +1164,7 @@ pub fn join_path(base string, dirs ...string) string {
} }
// walk_ext returns a recursive list of all files in `path` ending with `ext`. // walk_ext returns a recursive list of all files in `path` ending with `ext`.
pub fn walk_ext(path, ext string) []string { pub fn walk_ext(path string, ext string) []string {
if !os.is_dir(path) { if !os.is_dir(path) {
return [] return []
} }

View File

@ -159,7 +159,7 @@ pub fn exec(cmd string) ?Result {
} }
} }
pub fn symlink(origin, target string) ?bool { pub fn symlink(origin string, target string) ?bool {
res := C.symlink(charptr(origin.str), charptr(target.str)) res := C.symlink(charptr(origin.str), charptr(target.str))
if res == 0 { if res == 0 {
return true return true

View File

@ -846,7 +846,7 @@ pub fn v_sprintf(str string, pt ... voidptr) string{
} }
[inline] [inline]
fn v_sprintf_panic( idx, len int) { fn v_sprintf_panic(idx int, len int) {
if idx >= len { if idx >= len {
panic('${idx+1} % conversion specifiers, but given only ${len} args') panic('${idx+1} % conversion specifiers, but given only ${len} args')
} }

View File

@ -2,7 +2,7 @@ module strings
// #-js // #-js
// use levenshtein distance algorithm to calculate // use levenshtein distance algorithm to calculate
// the distance between between two strings (lower is closer) // the distance between between two strings (lower is closer)
pub fn levenshtein_distance(a, b string) int { pub fn levenshtein_distance(a string, b string) int {
mut f := [0].repeat(b.len + 1) mut f := [0].repeat(b.len + 1)
for j in 0..f.len { for j in 0..f.len {
f[j] = j f[j] = j
@ -29,7 +29,7 @@ pub fn levenshtein_distance(a, b string) int {
// use levenshtein distance algorithm to calculate // use levenshtein distance algorithm to calculate
// how similar two strings are as a percentage (higher is closer) // how similar two strings are as a percentage (higher is closer)
pub fn levenshtein_distance_percentage(a, b string) f32 { pub fn levenshtein_distance_percentage(a string, b string) f32 {
d := levenshtein_distance(a, b) d := levenshtein_distance(a, b)
l := if a.len >= b.len { a.len } else { b.len } l := if a.len >= b.len { a.len } else { b.len }
return (1.00 - f32(d) / f32(l)) * 100.00 return (1.00 - f32(d) / f32(l)) * 100.00
@ -38,7 +38,7 @@ pub fn levenshtein_distance_percentage(a, b string) f32 {
// implementation of SørensenDice coefficient. // implementation of SørensenDice coefficient.
// find the similarity between two strings. // find the similarity between two strings.
// returns coefficient between 0.0 (not similar) and 1.0 (exact match). // returns coefficient between 0.0 (not similar) and 1.0 (exact match).
pub fn dice_coefficient(s1, s2 string) f32 { pub fn dice_coefficient(s1 string, s2 string) f32 {
if s1.len == 0 || s2.len == 0 { if s1.len == 0 || s2.len == 0 {
return 0.0 return 0.0
} }

View File

@ -3,28 +3,29 @@
// that can be found in the LICENSE file. // that can be found in the LICENSE file.
module term module term
pub fn format(msg, open, close string) string { pub fn format(msg string, open string, close string) string {
return '\x1b[' + open + 'm' + msg + '\x1b[' + close + 'm' return '\x1b[' + open + 'm' + msg + '\x1b[' + close + 'm'
} }
pub fn format_rgb(r, g, b int, msg, open, close string) string { pub fn format_rgb(r int, g int, b int, msg string, open string, close string) string {
return '\x1b[' + open + ';2;' + r.str() + ';' + g.str() + ';' + b.str() + 'm' + msg + '\x1b[' + close + 'm' return '\x1b[' + open + ';2;' + r.str() + ';' + g.str() + ';' + b.str() + 'm' + msg + '\x1b[' +
close + 'm'
} }
pub fn rgb(r, g, b int, msg string) string { pub fn rgb(r int, g int, b int, msg string) string {
return format_rgb(r, g, b, msg, '38', '39') return format_rgb(r, g, b, msg, '38', '39')
} }
pub fn bg_rgb(r, g, b int, msg string) string { pub fn bg_rgb(r int, g int, b int, msg string) string {
return format_rgb(r, g, b, msg, '48', '49') return format_rgb(r, g, b, msg, '48', '49')
} }
pub fn hex(hex int, msg string) string { pub fn hex(hex int, msg string) string {
return format_rgb(hex>>16, hex>>8 & 0xFF, hex & 0xFF, msg, '38', '39') return format_rgb(hex >> 16, hex >> 8 & 0xFF, hex & 0xFF, msg, '38', '39')
} }
pub fn bg_hex(hex int, msg string) string { pub fn bg_hex(hex int, msg string) string {
return format_rgb(hex>>16, hex>>8 & 0xFF, hex & 0xFF, msg, '48', '49') return format_rgb(hex >> 16, hex >> 8 & 0xFF, hex & 0xFF, msg, '48', '49')
} }
pub fn bg_black(msg string) string { pub fn bg_black(msg string) string {
@ -190,4 +191,3 @@ pub fn yellow(msg string) string {
pub fn bright_yellow(msg string) string { pub fn bright_yellow(msg string) string {
return format(msg, '93', '39') return format(msg, '93', '39')
} }

View File

@ -4,7 +4,7 @@ import os
const ( const (
default_columns_size = 80 default_columns_size = 80
default_rows_size = 25 default_rows_size = 25
) )
// Coord - used by term.get_cursor_position and term.set_cursor_position // Coord - used by term.get_cursor_position and term.set_cursor_position
@ -29,51 +29,70 @@ pub fn can_show_color_on_stderr() bool {
// ok_message returns a colored string with green color. // ok_message returns a colored string with green color.
// If colors are not allowed, returns a given string. // If colors are not allowed, returns a given string.
pub fn ok_message(s string) string { pub fn ok_message(s string) string {
return if can_show_color_on_stdout() { green(s) } else { s } return if can_show_color_on_stdout() {
green(s)
} else {
s
}
} }
// fail_message returns a colored string with red color. // fail_message returns a colored string with red color.
// If colors are not allowed, returns a given string. // If colors are not allowed, returns a given string.
pub fn fail_message(s string) string { pub fn fail_message(s string) string {
return if can_show_color_on_stdout() { bold(bg_red(white(s))) } else { s } return if can_show_color_on_stdout() {
bold(bg_red(white(s)))
} else {
s
}
} }
// warn_message returns a colored string with yellow color. // warn_message returns a colored string with yellow color.
// If colors are not allowed, returns a given string. // If colors are not allowed, returns a given string.
pub fn warn_message(s string) string { pub fn warn_message(s string) string {
return if can_show_color_on_stdout() { bright_yellow(s) } else { s } return if can_show_color_on_stdout() {
bright_yellow(s)
} else {
s
}
} }
// h_divider returns a horizontal divider line with a dynamic width, // h_divider returns a horizontal divider line with a dynamic width,
// that depends on the current terminal settings. // that depends on the current terminal settings.
// If an empty string is passed in, print enough spaces to make a new line // If an empty string is passed in, print enough spaces to make a new line
pub fn h_divider(divider string) string { pub fn h_divider(divider string) string {
cols,_ := get_terminal_size() cols, _ := get_terminal_size()
result := if divider.len > 0 { divider.repeat(1 + (cols / divider.len)) } else { " ".repeat(1 + cols) } result := if divider.len > 0 { divider.repeat(1 + (cols / divider.len)) } else { ' '.repeat(1 +
cols) }
return result[0..cols] return result[0..cols]
} }
// header returns a horizontal divider line with a centered text in the middle. // header returns a horizontal divider line with a centered text in the middle.
// e.g: term.header('TEXT', '=') // e.g: term.header('TEXT', '=')
// =============== TEXT =============== // =============== TEXT ===============
pub fn header(text, divider string) string { pub fn header(text string, divider string) string {
if text.len == 0 { if text.len == 0 {
return h_divider(divider) return h_divider(divider)
} }
xcols,_ := get_terminal_size() xcols, _ := get_terminal_size()
cols := imax(1, xcols) cols := imax(1, xcols)
tlimit := imax(1, if cols > text.len + 2 + 2 * divider.len { text.len } else { cols - 3 - 2 * divider.len }) tlimit := imax(1, if cols > text.len + 2 + 2 * divider.len { text.len } else { cols - 3 -
2 * divider.len })
tlimit_alligned := if (tlimit % 2) != (cols % 2) { tlimit + 1 } else { tlimit } tlimit_alligned := if (tlimit % 2) != (cols % 2) { tlimit + 1 } else { tlimit }
tstart := imax(0, (cols - tlimit_alligned) / 2) tstart := imax(0, (cols - tlimit_alligned) / 2)
ln := if divider.len > 0 { divider.repeat(1 + cols / divider.len)[0..cols] } else { " ".repeat(1 + cols) } ln := if divider.len > 0 { divider.repeat(1 + cols / divider.len)[0..cols] } else { ' '.repeat(1 +
cols) }
if ln.len == 1 { if ln.len == 1 {
return ln + ' ' + text[0..tlimit] + ' ' + ln return ln + ' ' + text[0..tlimit] + ' ' + ln
} }
return ln[0..tstart] + ' ' + text[0..tlimit] + ' ' + ln[tstart + tlimit + 2..cols] return ln[0..tstart] + ' ' + text[0..tlimit] + ' ' + ln[tstart + tlimit + 2..cols]
} }
fn imax(x,y int) int { fn imax(x int, y int) int {
return if x > y { x } else { y } return if x > y {
x
} else {
y
}
} }
fn supports_escape_sequences(fd int) bool { fn supports_escape_sequences(fd int) bool {

View File

@ -4,23 +4,22 @@
module time module time
#include <time.h> #include <time.h>
const ( const (
days_string = 'MonTueWedThuFriSatSun' days_string = 'MonTueWedThuFriSatSun'
month_days = [31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31] month_days = [31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31]
months_string = 'JanFebMarAprMayJunJulAugSepOctNovDec' months_string = 'JanFebMarAprMayJunJulAugSepOctNovDec'
// The unsigned zero year for internal calculations. // The unsigned zero year for internal calculations.
// Must be 1 mod 400, and times before it will not compute correctly, // Must be 1 mod 400, and times before it will not compute correctly,
// but otherwise can be changed at will. // but otherwise can be changed at will.
absolute_zero_year = i64(-292277022399 )//as i64 absolute_zero_year = i64(-292277022399) // as i64
seconds_per_minute = 60 seconds_per_minute = 60
seconds_per_hour = 60 * seconds_per_minute seconds_per_hour = 60 * seconds_per_minute
seconds_per_day = 24 * seconds_per_hour seconds_per_day = 24 * seconds_per_hour
seconds_per_week = 7 * seconds_per_day seconds_per_week = 7 * seconds_per_day
days_per_400_years = 365 * 400 + 97 days_per_400_years = 365 * 400 + 97
days_per_100_years = 365 * 100 + 24 days_per_100_years = 365 * 100 + 24
days_per_4_years = 365 * 4 + 1 days_per_4_years = 365 * 4 + 1
days_before = [ days_before = [
0, 0,
31, 31,
31 + 28, 31 + 28,
@ -35,19 +34,19 @@ const (
31 + 28 + 31 + 30 + 31 + 30 + 31 + 31 + 30 + 31 + 30, 31 + 28 + 31 + 30 + 31 + 30 + 31 + 31 + 30 + 31 + 30,
31 + 28 + 31 + 30 + 31 + 30 + 31 + 31 + 30 + 31 + 30 + 31, 31 + 28 + 31 + 30 + 31 + 30 + 31 + 31 + 30 + 31 + 30 + 31,
] ]
long_days= ['Monday', 'Tuesday', 'Wednesday', 'Thusday', 'Friday', 'Saturday', 'Sunday'] long_days = ['Monday', 'Tuesday', 'Wednesday', 'Thusday', 'Friday', 'Saturday', 'Sunday']
) )
pub struct Time { pub struct Time {
pub: pub:
year int year int
month int month int
day int day int
hour int hour int
minute int minute int
second int second int
microsecond int microsecond int
unix u64 unix u64
} }
pub enum FormatTime { pub enum FormatTime {
@ -86,8 +85,8 @@ pub struct C.timeval {
} }
fn C.localtime(t &C.time_t) &C.tm fn C.localtime(t &C.time_t) &C.tm
fn C.time(t &C.time_t) C.time_t
fn C.time(t &C.time_t) C.time_t
// now returns current local time. // now returns current local time.
pub fn now() Time { pub fn now() Time {
@ -154,7 +153,10 @@ pub fn new_time(t Time) Time {
tm_year: t.year - 1900 tm_year: t.year - 1900
} }
utime := u64(make_unix_time(tt)) utime := u64(make_unix_time(tt))
return { t | unix: utime } return {
t |
unix: utime
}
} }
// unix_time returns Unix time. // unix_time returns Unix time.
@ -166,7 +168,7 @@ pub fn (t Time) unix_time() int {
// unix_time_milli returns Unix time with millisecond resolution. // unix_time_milli returns Unix time with millisecond resolution.
[inline] [inline]
pub fn (t Time) unix_time_milli() u64 { pub fn (t Time) unix_time_milli() u64 {
return t.unix * 1000 + u64(t.microsecond/1000) return t.unix * 1000 + u64(t.microsecond / 1000)
} }
// add_seconds returns a new time struct with an added number of seconds. // add_seconds returns a new time struct with an added number of seconds.
@ -189,7 +191,7 @@ fn since(t Time) int {
// relative returns a string representation of difference between time // relative returns a string representation of difference between time
// and current time. // and current time.
pub fn (t Time) relative() string { pub fn (t Time) relative() string {
znow := time.now() znow := now()
secs := znow.unix - t.unix secs := znow.unix - t.unix
if secs <= 30 { if secs <= 30 {
// right now or in the future // right now or in the future
@ -200,21 +202,21 @@ pub fn (t Time) relative() string {
return '1m' return '1m'
} }
if secs < 3600 { if secs < 3600 {
m := secs/60 m := secs / 60
if m == 1 { if m == 1 {
return '1 minute ago' return '1 minute ago'
} }
return '$m minutes ago' return '$m minutes ago'
} }
if secs < 3600 * 24 { if secs < 3600 * 24 {
h := secs/3600 h := secs / 3600
if h == 1 { if h == 1 {
return '1 hour ago' return '1 hour ago'
} }
return '$h hours ago' return '$h hours ago'
} }
if secs < 3600 * 24 * 5 { if secs < 3600 * 24 * 5 {
d:=secs/3600/24 d := secs / 3600 / 24
if d == 1 { if d == 1 {
return '1 day ago' return '1 day ago'
} }
@ -227,7 +229,7 @@ pub fn (t Time) relative() string {
} }
pub fn (t Time) relative_short() string { pub fn (t Time) relative_short() string {
znow := time.now() znow := now()
secs := znow.unix - t.unix secs := znow.unix - t.unix
if secs <= 30 { if secs <= 30 {
// right now or in the future // right now or in the future
@ -254,7 +256,7 @@ pub fn (t Time) relative_short() string {
// day_of_week returns the current day of a given year, month, and day, // day_of_week returns the current day of a given year, month, and day,
// as an integer. // as an integer.
pub fn day_of_week(y, m, d int) int { pub fn day_of_week(y int, m int, d int) int {
// Sakomotho's algorithm is explained here: // Sakomotho's algorithm is explained here:
// https://stackoverflow.com/a/6385934 // https://stackoverflow.com/a/6385934
t := [0, 3, 2, 5, 0, 3, 5, 1, 4, 6, 2, 4] t := [0, 3, 2, 5, 0, 3, 5, 1, 4, 6, 2, 4]
@ -330,7 +332,7 @@ pub fn is_leap_year(year int) bool {
} }
// days_in_month returns a number of days in a given month. // days_in_month returns a number of days in a given month.
pub fn days_in_month(month, year int) ?int { pub fn days_in_month(month int, year int) ?int {
if month > 12 || month < 1 { if month > 12 || month < 1 {
return error('Invalid month: $month') return error('Invalid month: $month')
} }
@ -362,7 +364,7 @@ fn convert_ctime(t C.tm, microsecond int) Time {
// A lot of these are taken from the Go library // A lot of these are taken from the Go library
pub type Duration = i64 pub type Duration = i64
pub const( pub const (
nanosecond = Duration(1) nanosecond = Duration(1)
microsecond = Duration(1000) * nanosecond microsecond = Duration(1000) * nanosecond
millisecond = Duration(1000) * microsecond millisecond = Duration(1000) * microsecond
@ -373,34 +375,39 @@ pub const(
) )
// nanoseconds returns the duration as an integer number of nanoseconds. // nanoseconds returns the duration as an integer number of nanoseconds.
pub fn (d Duration) nanoseconds() i64 { return i64(d) } pub fn (d Duration) nanoseconds() i64 {
return i64(d)
}
// microseconds returns the duration as an integer number of microseconds. // microseconds returns the duration as an integer number of microseconds.
pub fn (d Duration) microseconds() i64 { return i64(d) / 1000 } pub fn (d Duration) microseconds() i64 {
return i64(d) / 1000
}
// milliseconds returns the duration as an integer number of milliseconds. // milliseconds returns the duration as an integer number of milliseconds.
pub fn (d Duration) milliseconds() i64 { return i64(d) / 1_000_000 } pub fn (d Duration) milliseconds() i64 {
return i64(d) / 1000000
}
// The following functions return floating point numbers because it's common to // The following functions return floating point numbers because it's common to
// consider all of them in sub-one intervals // consider all of them in sub-one intervals
// seconds returns the duration as a floating point number of seconds. // seconds returns the duration as a floating point number of seconds.
pub fn (d Duration) seconds() f64 { pub fn (d Duration) seconds() f64 {
sec := d / second sec := d / second
nsec := d % second nsec := d % second
return f64(sec) + f64(nsec)/1e9 return f64(sec) + f64(nsec) / 1e9
} }
// minutes returns the duration as a floating point number of minutes. // minutes returns the duration as a floating point number of minutes.
pub fn (d Duration) minutes() f64 { pub fn (d Duration) minutes() f64 {
min := d / minute min := d / minute
nsec := d % minute nsec := d % minute
return f64(min) + f64(nsec)/(60*1e9) return f64(min) + f64(nsec) / (60 * 1e9)
} }
// hours returns the duration as a floating point number of hours. // hours returns the duration as a floating point number of hours.
pub fn (d Duration) hours() f64 { pub fn (d Duration) hours() f64 {
hr := d / hour hr := d / hour
nsec := d % hour nsec := d % hour
return f64(hr) + f64(nsec)/(60*60*1e9) return f64(hr) + f64(nsec) / (60 * 60 * 1e9)
} }

View File

@ -149,7 +149,7 @@ fn (s &Scope) contains(pos int) bool {
return pos >= s.start_pos && pos <= s.end_pos return pos >= s.start_pos && pos <= s.end_pos
} }
pub fn (sc &Scope) show(depth, max_depth int) string { pub fn (sc &Scope) show(depth int, max_depth int) string {
mut out := '' mut out := ''
mut indent := '' mut indent := ''
for _ in 0 .. depth * 4 { for _ in 0 .. depth * 4 {

View File

@ -228,7 +228,7 @@ fn module_path(mod string) string {
return mod.replace('.', os.path_separator) return mod.replace('.', os.path_separator)
} }
pub fn (b &Builder) find_module_path(mod, fpath string) ?string { pub fn (b &Builder) find_module_path(mod string, fpath string) ?string {
// support @VROOT/v.mod relative paths: // support @VROOT/v.mod relative paths:
mut mcache := vmod.get_cache() mut mcache := vmod.get_cache()
vmod_file_location := mcache.get_by_file(fpath) vmod_file_location := mcache.get_by_file(fpath)

View File

@ -792,7 +792,7 @@ fn missing_compiler_info() string {
return '' return ''
} }
fn error_context_lines(text, keyword string, before, after int) []string { fn error_context_lines(text string, keyword string, before int, after int) []string {
khighlight := if term.can_show_color_on_stdout() { term.red(keyword) } else { keyword } khighlight := if term.can_show_color_on_stdout() { term.red(keyword) } else { keyword }
mut eline_idx := 0 mut eline_idx := 0
mut lines := text.split_into_lines() mut lines := text.split_into_lines()

View File

@ -21,7 +21,7 @@ fn get_vtmp_folder() string {
return vtmp return vtmp
} }
fn get_vtmp_filename(base_file_name, postfix string) string { fn get_vtmp_filename(base_file_name string, postfix string) string {
vtmp := get_vtmp_folder() vtmp := get_vtmp_folder()
return os.real_path(os.join_path(vtmp, os.file_name(os.real_path(base_file_name)) + postfix)) return os.real_path(os.join_path(vtmp, os.file_name(os.real_path(base_file_name)) + postfix))
} }

View File

@ -97,7 +97,7 @@ fn find_windows_kit_root(host_arch string) ?WindowsKit {
return error('Unable to find a windows kit') return error('Unable to find a windows kit')
} }
kit_lib := kit_root + 'Lib' kit_lib := kit_root + 'Lib'
files := os.ls(kit_lib)? files := os.ls(kit_lib) ?
mut highest_path := '' mut highest_path := ''
mut highest_int := 0 mut highest_int := 0
for f in files { for f in files {
@ -128,7 +128,7 @@ struct VsInstallation {
exe_path string exe_path string
} }
fn find_vs(vswhere_dir, host_arch string) ?VsInstallation { fn find_vs(vswhere_dir string, host_arch string) ?VsInstallation {
$if !windows { $if !windows {
return error('Host OS does not support finding a Visual Studio installation') return error('Host OS does not support finding a Visual Studio installation')
} }
@ -136,7 +136,7 @@ fn find_vs(vswhere_dir, host_arch string) ?VsInstallation {
// VSWhere is guaranteed to be installed at this location now // VSWhere is guaranteed to be installed at this location now
// If its not there then end user needs to update their visual studio // If its not there then end user needs to update their visual studio
// installation! // installation!
res := os.exec('"$vswhere_dir\\Microsoft Visual Studio\\Installer\\vswhere.exe" -latest -prerelease -products * -requires Microsoft.VisualStudio.Component.VC.Tools.x86.x64 -property installationPath')? res := os.exec('"$vswhere_dir\\Microsoft Visual Studio\\Installer\\vswhere.exe" -latest -prerelease -products * -requires Microsoft.VisualStudio.Component.VC.Tools.x86.x64 -property installationPath') ?
res_output := res.output.trim_right('\r\n') res_output := res.output.trim_right('\r\n')
// println('res: "$res"') // println('res: "$res"')
version := os.read_file('$res_output\\VC\\Auxiliary\\Build\\Microsoft.VCToolsVersion.default.txt') or { version := os.read_file('$res_output\\VC\\Auxiliary\\Build\\Microsoft.VCToolsVersion.default.txt') or {

View File

@ -22,7 +22,7 @@ pub fn (c &CFlag) str() string {
pub fn (cf &CFlag) format() string { pub fn (cf &CFlag) format() string {
mut value := cf.value mut value := cf.value
if cf.name in ['-l', '-Wa', '-Wl', '-Wp'] && value.len > 0 { if cf.name in ['-l', '-Wa', '-Wl', '-Wp'] && value.len > 0 {
return '${cf.name}${value}'.trim_space() return '$cf.name$value'.trim_space()
} }
// convert to absolute path // convert to absolute path
if cf.name == '-I' || cf.name == '-L' || value.ends_with('.o') { if cf.name == '-I' || cf.name == '-L' || value.ends_with('.o') {

View File

@ -7,7 +7,7 @@ import v.table
import v.token import v.token
import v.ast import v.ast
pub fn (mut c Checker) check_basic(got, expected table.Type) bool { pub fn (mut c Checker) check_basic(got table.Type, expected table.Type) bool {
if got == expected { if got == expected {
return true return true
} }
@ -111,7 +111,7 @@ pub fn (mut c Checker) check_basic(got, expected table.Type) bool {
return false return false
} }
pub fn (mut c Checker) check_matching_function_symbols(got_type_sym, exp_type_sym &table.TypeSymbol) bool { pub fn (mut c Checker) check_matching_function_symbols(got_type_sym &table.TypeSymbol, exp_type_sym &table.TypeSymbol) bool {
got_info := got_type_sym.info as table.FnType got_info := got_type_sym.info as table.FnType
exp_info := exp_type_sym.info as table.FnType exp_info := exp_type_sym.info as table.FnType
got_fn := got_info.func got_fn := got_info.func
@ -142,7 +142,7 @@ pub fn (mut c Checker) check_matching_function_symbols(got_type_sym, exp_type_sy
} }
[inline] [inline]
fn (mut c Checker) check_shift(left_type, right_type table.Type, left_pos, right_pos token.Position) table.Type { fn (mut c Checker) check_shift(left_type table.Type, right_type table.Type, left_pos token.Position, right_pos token.Position) table.Type {
if !left_type.is_int() { if !left_type.is_int() {
// maybe it's an int alias? TODO move this to is_int() ? // maybe it's an int alias? TODO move this to is_int() ?
sym := c.table.get_type_symbol(left_type) sym := c.table.get_type_symbol(left_type)
@ -163,7 +163,7 @@ fn (mut c Checker) check_shift(left_type, right_type table.Type, left_pos, right
return left_type return left_type
} }
pub fn (c &Checker) promote(left_type, right_type table.Type) table.Type { pub fn (c &Checker) promote(left_type table.Type, right_type table.Type) table.Type {
if left_type.is_ptr() || left_type.is_pointer() { if left_type.is_ptr() || left_type.is_pointer() {
if right_type.is_int() { if right_type.is_int() {
return left_type return left_type
@ -190,7 +190,7 @@ pub fn (c &Checker) promote(left_type, right_type table.Type) table.Type {
} }
} }
fn (c &Checker) promote_num(left_type, right_type table.Type) table.Type { fn (c &Checker) promote_num(left_type table.Type, right_type table.Type) table.Type {
// sort the operands to save time // sort the operands to save time
mut type_hi := left_type mut type_hi := left_type
mut type_lo := right_type mut type_lo := right_type
@ -235,7 +235,7 @@ fn (c &Checker) promote_num(left_type, right_type table.Type) table.Type {
} }
// TODO: promote(), check_types(), symmetric_check() and check() overlap - should be rearranged // TODO: promote(), check_types(), symmetric_check() and check() overlap - should be rearranged
pub fn (mut c Checker) check_types(got, expected table.Type) bool { pub fn (mut c Checker) check_types(got table.Type, expected table.Type) bool {
if got == expected { if got == expected {
return true return true
} }
@ -278,7 +278,7 @@ pub fn (mut c Checker) check_types(got, expected table.Type) bool {
return true return true
} }
pub fn (mut c Checker) symmetric_check(left, right table.Type) bool { pub fn (mut c Checker) symmetric_check(left table.Type, right table.Type) bool {
// allow direct int-literal assignment for pointers for now // allow direct int-literal assignment for pointers for now
// maybe in the future optionals should be used for that // maybe in the future optionals should be used for that
if right.is_ptr() || right.is_pointer() { if right.is_ptr() || right.is_pointer() {
@ -295,7 +295,7 @@ pub fn (mut c Checker) symmetric_check(left, right table.Type) bool {
return c.check_basic(left, right) return c.check_basic(left, right)
} }
pub fn (c &Checker) get_default_fmt(ftyp, typ table.Type) byte { pub fn (c &Checker) get_default_fmt(ftyp table.Type, typ table.Type) byte {
if typ.is_float() { if typ.is_float() {
return `g` return `g`
} else if typ.is_signed() || typ.is_any_int() { } else if typ.is_signed() || typ.is_any_int() {
@ -315,7 +315,8 @@ pub fn (c &Checker) get_default_fmt(ftyp, typ table.Type) byte {
} }
} }
if ftyp in [table.string_type, table.bool_type] || if ftyp in [table.string_type, table.bool_type] ||
sym.kind in [.enum_, .array, .array_fixed, .struct_, .map, .multi_return, .sum_type] || ftyp.has_flag(.optional) || sym.kind in
[.enum_, .array, .array_fixed, .struct_, .map, .multi_return, .sum_type] || ftyp.has_flag(.optional) ||
sym.has_method('str') { sym.has_method('str') {
return `s` return `s`
} else { } else {
@ -369,7 +370,7 @@ pub fn (mut c Checker) string_inter_lit(mut node ast.StringInterLiteral) table.T
return table.string_type return table.string_type
} }
pub fn (c &Checker) check_sumtype_compatibility(a, b table.Type) bool { pub fn (c &Checker) check_sumtype_compatibility(a table.Type, b table.Type) bool {
return c.table.sumtype_has_variant(a, b) || c.table.sumtype_has_variant(b, a) return c.table.sumtype_has_variant(a, b) || c.table.sumtype_has_variant(b, a)
} }

View File

@ -69,7 +69,7 @@ fn (mut g Gen) gen_str_for_type_with_styp(typ table.Type, styp string) string {
return str_fn_name return str_fn_name
} }
fn (mut g Gen) gen_str_for_array(info table.Array, styp, str_fn_name string) { fn (mut g Gen) gen_str_for_array(info table.Array, styp string, str_fn_name string) {
sym := g.table.get_type_symbol(info.elem_type) sym := g.table.get_type_symbol(info.elem_type)
field_styp := g.typ(info.elem_type) field_styp := g.typ(info.elem_type)
is_elem_ptr := info.elem_type.is_ptr() is_elem_ptr := info.elem_type.is_ptr()
@ -133,7 +133,7 @@ fn (mut g Gen) gen_str_for_array(info table.Array, styp, str_fn_name string) {
g.auto_str_funcs.writeln('}') g.auto_str_funcs.writeln('}')
} }
fn (mut g Gen) gen_str_for_array_fixed(info table.ArrayFixed, styp, str_fn_name string) { fn (mut g Gen) gen_str_for_array_fixed(info table.ArrayFixed, styp string, str_fn_name string) {
sym := g.table.get_type_symbol(info.elem_type) sym := g.table.get_type_symbol(info.elem_type)
field_styp := g.typ(info.elem_type) field_styp := g.typ(info.elem_type)
is_elem_ptr := info.elem_type.is_ptr() is_elem_ptr := info.elem_type.is_ptr()
@ -179,7 +179,7 @@ fn (mut g Gen) gen_str_for_array_fixed(info table.ArrayFixed, styp, str_fn_name
g.auto_str_funcs.writeln('}') g.auto_str_funcs.writeln('}')
} }
fn (mut g Gen) gen_str_for_map(info table.Map, styp, str_fn_name string) { fn (mut g Gen) gen_str_for_map(info table.Map, styp string, str_fn_name string) {
key_sym := g.table.get_type_symbol(info.key_type) key_sym := g.table.get_type_symbol(info.key_type)
key_styp := g.typ(info.key_type) key_styp := g.typ(info.key_type)
if !key_sym.has_method('str') { if !key_sym.has_method('str') {
@ -224,7 +224,7 @@ fn (mut g Gen) gen_str_for_map(info table.Map, styp, str_fn_name string) {
g.auto_str_funcs.writeln('}') g.auto_str_funcs.writeln('}')
} }
fn (mut g Gen) gen_str_for_varg(styp, str_fn_name string, has_str_method bool) { fn (mut g Gen) gen_str_for_varg(styp string, str_fn_name string, has_str_method bool) {
g.definitions.writeln('string varg_${str_fn_name}(varg_$styp it); // auto') g.definitions.writeln('string varg_${str_fn_name}(varg_$styp it); // auto')
g.auto_str_funcs.writeln('string varg_${str_fn_name}(varg_$styp it) {') g.auto_str_funcs.writeln('string varg_${str_fn_name}(varg_$styp it) {')
g.auto_str_funcs.writeln('\tstrings__Builder sb = strings__new_builder(it.len);') g.auto_str_funcs.writeln('\tstrings__Builder sb = strings__new_builder(it.len);')
@ -240,7 +240,7 @@ fn (mut g Gen) gen_str_for_varg(styp, str_fn_name string, has_str_method bool) {
g.auto_str_funcs.writeln('}') g.auto_str_funcs.writeln('}')
} }
fn (mut g Gen) gen_str_for_multi_return(info table.MultiReturn, styp, str_fn_name string) { fn (mut g Gen) gen_str_for_multi_return(info table.MultiReturn, styp string, str_fn_name string) {
for typ in info.types { for typ in info.types {
sym := g.table.get_type_symbol(typ) sym := g.table.get_type_symbol(typ)
if !sym.has_method('str') { if !sym.has_method('str') {
@ -288,7 +288,7 @@ fn (mut g Gen) gen_str_for_multi_return(info table.MultiReturn, styp, str_fn_nam
g.auto_str_funcs.writeln('}') g.auto_str_funcs.writeln('}')
} }
fn (mut g Gen) gen_str_for_struct(info table.Struct, styp, str_fn_name string) { fn (mut g Gen) gen_str_for_struct(info table.Struct, styp string, str_fn_name string) {
// TODO: short it if possible // TODO: short it if possible
// generates all definitions of substructs // generates all definitions of substructs
mut fnames2strfunc := { mut fnames2strfunc := {
@ -337,7 +337,7 @@ fn (mut g Gen) gen_str_for_struct(info table.Struct, styp, str_fn_name string) {
} }
g.auto_str_funcs.writeln('\t\t"%.*s\\000 $field.name: $fmt\\n"') g.auto_str_funcs.writeln('\t\t"%.*s\\000 $field.name: $fmt\\n"')
} }
g.auto_str_funcs.write('\t\t"%.*s\\000}", ${2 * (info.fields.len + 1)}') g.auto_str_funcs.write('\t\t"%.*s\\000}", ${2*(info.fields.len+1)}')
if info.fields.len > 0 { if info.fields.len > 0 {
g.auto_str_funcs.write(',\n\t\t') g.auto_str_funcs.write(',\n\t\t')
for i, field in info.fields { for i, field in info.fields {
@ -348,7 +348,6 @@ fn (mut g Gen) gen_str_for_struct(info table.Struct, styp, str_fn_name string) {
field_styp = field_styp.replace('*', '') field_styp = field_styp.replace('*', '')
} }
field_styp_fn_name := if has_custom_str { '${field_styp}_str' } else { fnames2strfunc[field_styp] } field_styp_fn_name := if has_custom_str { '${field_styp}_str' } else { fnames2strfunc[field_styp] }
g.auto_str_funcs.write('indents, ') g.auto_str_funcs.write('indents, ')
func := struct_auto_str_func(sym, field.typ, field_styp_fn_name, field.name) func := struct_auto_str_func(sym, field.typ, field_styp_fn_name, field.name)
if field.typ.is_ptr() { if field.typ.is_ptr() {
@ -360,7 +359,6 @@ fn (mut g Gen) gen_str_for_struct(info table.Struct, styp, str_fn_name string) {
} }
} }
g.auto_str_funcs.write(func) g.auto_str_funcs.write(func)
if i < info.fields.len - 1 { if i < info.fields.len - 1 {
g.auto_str_funcs.write(',\n\t\t') g.auto_str_funcs.write(',\n\t\t')
} }
@ -372,7 +370,7 @@ fn (mut g Gen) gen_str_for_struct(info table.Struct, styp, str_fn_name string) {
g.auto_str_funcs.writeln('}') g.auto_str_funcs.writeln('}')
} }
fn struct_auto_str_func(sym table.TypeSymbol, field_type table.Type, fn_name, field_name string) string { fn struct_auto_str_func(sym table.TypeSymbol, field_type table.Type, fn_name string, field_name string) string {
has_custom_str := sym.has_method('str') has_custom_str := sym.has_method('str')
if sym.kind == .enum_ { if sym.kind == .enum_ {
return '${fn_name}(it->${c_name(field_name)})' return '${fn_name}(it->${c_name(field_name)})'
@ -409,7 +407,7 @@ fn struct_auto_str_func(sym table.TypeSymbol, field_type table.Type, fn_name, fi
} }
} }
fn (mut g Gen) gen_str_for_enum(info table.Enum, styp, str_fn_name string) { fn (mut g Gen) gen_str_for_enum(info table.Enum, styp string, str_fn_name string) {
s := util.no_dots(styp) s := util.no_dots(styp)
g.type_definitions.writeln('string ${str_fn_name}($styp it); // auto') g.type_definitions.writeln('string ${str_fn_name}($styp it); // auto')
g.auto_str_funcs.writeln('string ${str_fn_name}($styp it) { /* gen_str_for_enum */') g.auto_str_funcs.writeln('string ${str_fn_name}($styp it) { /* gen_str_for_enum */')
@ -429,8 +427,8 @@ fn (mut g Gen) gen_str_for_enum(info table.Enum, styp, str_fn_name string) {
g.auto_str_funcs.writeln('}') g.auto_str_funcs.writeln('}')
} }
fn (mut g Gen) gen_str_for_sum_type(info table.SumType, styp, str_fn_name string) { fn (mut g Gen) gen_str_for_sum_type(info table.SumType, styp string, str_fn_name string) {
mut gen_fn_names := map[string]string mut gen_fn_names := map[string]string{}
for typ in info.variants { for typ in info.variants {
sym := g.table.get_type_symbol(typ) sym := g.table.get_type_symbol(typ)
if !sym.has_method('str') { if !sym.has_method('str') {
@ -453,14 +451,11 @@ fn (mut g Gen) gen_str_for_sum_type(info table.SumType, styp, str_fn_name string
for typ in info.variants { for typ in info.variants {
mut value_fmt := '%.*s\\000' mut value_fmt := '%.*s\\000'
if typ == table.string_type { if typ == table.string_type {
value_fmt = '\'$value_fmt\'' value_fmt = "\'$value_fmt\'"
} }
typ_str := g.typ(typ) typ_str := g.typ(typ)
mut func_name := if typ_str in gen_fn_names { mut func_name := if typ_str in gen_fn_names { gen_fn_names[typ_str] } else { g.gen_str_for_type_with_styp(typ,
gen_fn_names[typ_str] typ_str) }
} else {
g.gen_str_for_type_with_styp(typ, typ_str)
}
sym := g.table.get_type_symbol(typ) sym := g.table.get_type_symbol(typ)
if sym.kind == .struct_ { if sym.kind == .struct_ {
func_name = 'indent_$func_name' func_name = 'indent_$func_name'

View File

@ -74,7 +74,7 @@ $enc_fn_dec {
// enc += g.encode_array(t) // enc += g.encode_array(t)
} else if sym.kind == .map { } else if sym.kind == .map {
// Handle maps // Handle maps
m := sym.info as table.Map m := sym.info as table.Map
g.gen_json_for_type(m.key_type) g.gen_json_for_type(m.key_type)
g.gen_json_for_type(m.value_type) g.gen_json_for_type(m.value_type)
dec.writeln(g.decode_map(m.key_type, m.value_type)) dec.writeln(g.decode_map(m.key_type, m.value_type))
@ -156,7 +156,6 @@ fn is_js_prim(typ string) bool {
fn (mut g Gen) decode_array(value_type table.Type) string { fn (mut g Gen) decode_array(value_type table.Type) string {
styp := g.typ(value_type) styp := g.typ(value_type)
fn_name := js_dec_name(styp) fn_name := js_dec_name(styp)
mut s := '' mut s := ''
if is_js_prim(styp) { if is_js_prim(styp) {
s = '$styp val = ${fn_name}(jsval); ' s = '$styp val = ${fn_name}(jsval); '
@ -165,7 +164,7 @@ fn (mut g Gen) decode_array(value_type table.Type) string {
Option_$styp val2 = $fn_name (jsval); Option_$styp val2 = $fn_name (jsval);
if(!val2.ok) { if(!val2.ok) {
array_free(&res); array_free(&res);
return *(Option_array_${styp}*)&val2; return *(Option_array_$styp*)&val2;
} }
$styp val = *($styp*)val2.data; $styp val = *($styp*)val2.data;
' '
@ -173,7 +172,7 @@ fn (mut g Gen) decode_array(value_type table.Type) string {
return ' return '
if(!cJSON_IsArray(root)) { if(!cJSON_IsArray(root)) {
Option err = v_error( string_add(tos_lit("Json element is not an array: "), tos2(cJSON_PrintUnformatted(root))) ); Option err = v_error( string_add(tos_lit("Json element is not an array: "), tos2(cJSON_PrintUnformatted(root))) );
return *(Option_array_${styp} *)&err; return *(Option_array_$styp *)&err;
} }
res = __new_array(0, 0, sizeof($styp)); res = __new_array(0, 0, sizeof($styp));
const cJSON *jsval = NULL; const cJSON *jsval = NULL;
@ -196,13 +195,10 @@ fn (mut g Gen) encode_array(value_type table.Type) string {
' '
} }
fn (mut g Gen) decode_map(key_type, value_type table.Type) string { fn (mut g Gen) decode_map(key_type table.Type, value_type table.Type) string {
styp := g.typ(key_type) styp := g.typ(key_type)
styp_v := g.typ(value_type) styp_v := g.typ(value_type)
fn_name_v := js_dec_name(styp_v) fn_name_v := js_dec_name(styp_v)
mut s := '' mut s := ''
if is_js_prim(styp_v) { if is_js_prim(styp_v) {
s = '$styp_v val = $fn_name_v (js_get(root, jsval->string));' s = '$styp_v val = $fn_name_v (js_get(root, jsval->string));'
@ -211,16 +207,15 @@ fn (mut g Gen) decode_map(key_type, value_type table.Type) string {
Option_$styp_v val2 = $fn_name_v (js_get(root, jsval->string)); Option_$styp_v val2 = $fn_name_v (js_get(root, jsval->string));
if(!val2.ok) { if(!val2.ok) {
map_free(&res); map_free(&res);
return *(Option_map_${styp}_${styp_v}*)&val2; return *(Option_map_${styp}_$styp_v*)&val2;
} }
$styp_v val = *($styp_v*)val2.data; $styp_v val = *($styp_v*)val2.data;
' '
} }
return ' return '
if(!cJSON_IsObject(root)) { if(!cJSON_IsObject(root)) {
Option err = v_error( string_add(tos_lit("Json element is not an object: "), tos2(cJSON_PrintUnformatted(root))) ); Option err = v_error( string_add(tos_lit("Json element is not an object: "), tos2(cJSON_PrintUnformatted(root))) );
return *(Option_map_${styp}_${styp_v} *)&err; return *(Option_map_${styp}_$styp_v *)&err;
} }
res = new_map_1(sizeof($styp_v)); res = new_map_1(sizeof($styp_v));
cJSON *jsval = NULL; cJSON *jsval = NULL;
@ -232,16 +227,12 @@ fn (mut g Gen) decode_map(key_type, value_type table.Type) string {
' '
} }
fn (mut g Gen) encode_map(key_type, value_type table.Type) string { fn (mut g Gen) encode_map(key_type table.Type, value_type table.Type) string {
styp := g.typ(key_type) styp := g.typ(key_type)
styp_v := g.typ(value_type) styp_v := g.typ(value_type)
fn_name_v := js_enc_name(styp_v) fn_name_v := js_enc_name(styp_v)
zero := g.type_default(value_type) zero := g.type_default(value_type)
keys_tmp := g.new_tmp_var() keys_tmp := g.new_tmp_var()
mut key := 'string key = ' mut key := 'string key = '
if key_type.is_string() { if key_type.is_string() {
key += '(($styp*)${keys_tmp}.data)[i];' key += '(($styp*)${keys_tmp}.data)[i];'
@ -250,7 +241,6 @@ fn (mut g Gen) encode_map(key_type, value_type table.Type) string {
// key += '${styp}_str((($styp*)${keys_tmp}.data)[i]);' // key += '${styp}_str((($styp*)${keys_tmp}.data)[i]);'
verror('json: encode only maps with string keys') verror('json: encode only maps with string keys')
} }
return ' return '
o = cJSON_CreateObject(); o = cJSON_CreateObject();
array_$styp $keys_tmp = map_keys(&val); array_$styp $keys_tmp = map_keys(&val);

View File

@ -38,7 +38,7 @@ fn (mut g Gen) sql_stmt(node ast.SqlStmt) {
if field.name == 'id' { if field.name == 'id' {
continue continue
} }
g.write('`${field.name}`') g.write('`$field.name`')
if i < node.fields.len - 1 { if i < node.fields.len - 1 {
g.write(', ') g.write(', ')
} }
@ -114,7 +114,7 @@ fn (mut g Gen) sql_select_expr(node ast.SqlExpr) {
} else { } else {
// `select id, name, country from User` // `select id, name, country from User`
for i, field in node.fields { for i, field in node.fields {
sql_query += '`${field.name}`' sql_query += '`$field.name`'
if i < node.fields.len - 1 { if i < node.fields.len - 1 {
sql_query += ', ' sql_query += ', '
} }
@ -188,7 +188,7 @@ fn (mut g Gen) sql_select_expr(node ast.SqlExpr) {
info := sym.info as table.Struct info := sym.info as table.Struct
for i, field in info.fields { for i, field in info.fields {
g.zero_struct_field(field) g.zero_struct_field(field)
if i != info.fields.len-1 { if i != info.fields.len - 1 {
g.write(', ') g.write(', ')
} }
} }
@ -203,7 +203,7 @@ fn (mut g Gen) sql_select_expr(node ast.SqlExpr) {
info := sym.info as table.Struct info := sym.info as table.Struct
for i, field in info.fields { for i, field in info.fields {
g.zero_struct_field(field) g.zero_struct_field(field)
if i != info.fields.len-1 { if i != info.fields.len - 1 {
g.write(', ') g.write(', ')
} }
} }
@ -246,7 +246,7 @@ fn (mut g Gen) sql_bind_int(val string) {
g.sql_buf.writeln('sqlite3_bind_int($g.sql_stmt_name, $g.sql_i, $val);') g.sql_buf.writeln('sqlite3_bind_int($g.sql_stmt_name, $g.sql_i, $val);')
} }
fn (mut g Gen) sql_bind_string(val, len string) { fn (mut g Gen) sql_bind_string(val string, len string) {
g.sql_buf.writeln('sqlite3_bind_text($g.sql_stmt_name, $g.sql_i, $val, $len, 0);') g.sql_buf.writeln('sqlite3_bind_text($g.sql_stmt_name, $g.sql_i, $val, $len, 0);')
} }

View File

@ -500,6 +500,10 @@ fn (mut p Parser) fn_args() ([]table.Param, bool, bool) {
mut arg_names := [p.check_name()] mut arg_names := [p.check_name()]
// `a, b, c int` // `a, b, c int`
for p.tok.kind == .comma { for p.tok.kind == .comma {
if !p.pref.is_fmt {
p.warn('`fn f(x, y Type)` syntax has been deprecated and will soon be removed. ' +
'Use `fn f(x Type, y Type)` instead. You can run `v fmt -w file.v` to automatically fix your code.')
}
p.next() p.next()
arg_pos << p.tok.position() arg_pos << p.tok.position()
arg_names << p.check_name() arg_names << p.check_name()

View File

@ -189,7 +189,7 @@ If you need to modify an array in a function, use a mutable argument instead: `f
return typ return typ
} }
pub fn (mut p Parser) parse_any_type(language table.Language, is_ptr, check_dot bool) table.Type { pub fn (mut p Parser) parse_any_type(language table.Language, is_ptr bool, check_dot bool) table.Type {
mut name := p.tok.lit mut name := p.tok.lit
if language == .c { if language == .c {
name = 'C.$name' name = 'C.$name'

View File

@ -82,7 +82,7 @@ pub fn (t Type) atomic_typename() string {
} }
} }
pub fn sharetype_from_flags(is_shared, is_atomic bool) ShareType { pub fn sharetype_from_flags(is_shared bool, is_atomic bool) ShareType {
return ShareType((int(is_atomic) << 1) | int(is_shared)) return ShareType((int(is_atomic) << 1) | int(is_shared))
} }
@ -187,7 +187,7 @@ pub fn new_type(idx int) Type {
// return new type with TypeSymbol idx set to `idx` & nr_muls set to `nr_muls` // return new type with TypeSymbol idx set to `idx` & nr_muls set to `nr_muls`
[inline] [inline]
pub fn new_type_ptr(idx, nr_muls int) Type { pub fn new_type_ptr(idx int, nr_muls int) Type {
if idx < 1 || idx > 65535 { if idx < 1 || idx > 65535 {
panic('new_type_ptr: idx must be between 1 & 65535') panic('new_type_ptr: idx must be between 1 & 65535')
} }

View File

@ -17,7 +17,7 @@ fn (table &Table) has_cflag(flag cflag.CFlag) bool {
// parse the flags to (table.cflags) []CFlag // parse the flags to (table.cflags) []CFlag
// Note: clean up big time (joe-c) // Note: clean up big time (joe-c)
pub fn (mut table Table) parse_cflag(cflg, mod string, ctimedefines []string) ?bool { pub fn (mut table Table) parse_cflag(cflg string, mod string, ctimedefines []string) ?bool {
allowed_flags := ['framework', 'library', 'Wa', 'Wl', 'Wp', 'I', 'l', 'L'] allowed_flags := ['framework', 'library', 'Wa', 'Wl', 'Wp', 'I', 'l', 'L']
flag_orig := cflg.trim_space() flag_orig := cflg.trim_space()
mut flag := flag_orig mut flag := flag_orig

View File

@ -12,10 +12,8 @@ pub fn find_working_diff_command() ?string {
if env_difftool.len > 0 { if env_difftool.len > 0 {
known_diff_tools << env_difftool known_diff_tools << env_difftool
} }
known_diff_tools << [ known_diff_tools <<
'colordiff', 'gdiff', 'diff', 'colordiff.exe', ['colordiff', 'gdiff', 'diff', 'colordiff.exe', 'diff.exe', 'opendiff', 'code', 'code.cmd']
'diff.exe', 'opendiff', 'code', 'code.cmd'
]
// NOTE: code.cmd is the Windows variant of the `code` cli tool // NOTE: code.cmd is the Windows variant of the `code` cli tool
for diffcmd in known_diff_tools { for diffcmd in known_diff_tools {
if diffcmd == 'opendiff' { // opendiff has no `--version` option if diffcmd == 'opendiff' { // opendiff has no `--version` option
@ -56,10 +54,9 @@ fn opendiff_exists() bool {
return false return false
} }
pub fn color_compare_files(diff_cmd, file1, file2 string) string { pub fn color_compare_files(diff_cmd string, file1 string, file2 string) string {
if diff_cmd != '' { if diff_cmd != '' {
full_cmd := '$diff_cmd --minimal --text --unified=2 ' + full_cmd := '$diff_cmd --minimal --text --unified=2 ' + ' --show-function-line="fn " "$file1" "$file2" '
' --show-function-line="fn " "$file1" "$file2" '
x := os.exec(full_cmd) or { x := os.exec(full_cmd) or {
return 'comparison command: `$full_cmd` failed' return 'comparison command: `$full_cmd` failed'
} }
@ -68,7 +65,7 @@ pub fn color_compare_files(diff_cmd, file1, file2 string) string {
return '' return ''
} }
pub fn color_compare_strings(diff_cmd, expected, found string) string { pub fn color_compare_strings(diff_cmd string, expected string, found string) string {
cdir := os.cache_dir() cdir := os.cache_dir()
ctime := time.sys_mono_now() ctime := time.sys_mono_now()
e_file := os.join_path(cdir, '${ctime}.expected.txt') e_file := os.join_path(cdir, '${ctime}.expected.txt')

View File

@ -53,7 +53,7 @@ pub fn bold(msg string) string {
return term.bold(msg) return term.bold(msg)
} }
fn color(kind, msg string) string { fn color(kind string, msg string) string {
if !emanager.support_color { if !emanager.support_color {
return msg return msg
} }
@ -65,7 +65,7 @@ fn color(kind, msg string) string {
} }
// formatted_error - `kind` may be 'error' or 'warn' // formatted_error - `kind` may be 'error' or 'warn'
pub fn formatted_error(kind, omsg, filepath string, pos token.Position) string { pub fn formatted_error(kind string, omsg string, filepath string, pos token.Position) string {
emsg := omsg.replace('main.', '') emsg := omsg.replace('main.', '')
mut path := filepath mut path := filepath
verror_paths_override := os.getenv('VERROR_PATHS') verror_paths_override := os.getenv('VERROR_PATHS')
@ -101,7 +101,7 @@ pub fn formatted_error(kind, omsg, filepath string, pos token.Position) string {
return '$final_position $final_kind $final_msg$final_context'.trim_space() return '$final_position $final_kind $final_msg$final_context'.trim_space()
} }
pub fn source_context(kind, source string, column int, pos token.Position) []string { pub fn source_context(kind string, source string, column int, pos token.Position) []string {
mut clines := []string{} mut clines := []string{}
if source.len == 0 { if source.len == 0 {
return clines return clines
@ -136,7 +136,7 @@ pub fn source_context(kind, source string, column int, pos token.Position) []str
return clines return clines
} }
pub fn verror(kind, s string) { pub fn verror(kind string, s string) {
final_kind := bold(color(kind, kind)) final_kind := bold(color(kind, kind))
eprintln('$final_kind: $s') eprintln('$final_kind: $s')
exit(1) exit(1)

View File

@ -9,7 +9,7 @@ mut:
similarity f32 similarity f32
} }
fn compare_by_similarity(a, b &Possibility) int { fn compare_by_similarity(a &Possibility, b &Possibility) int {
if a.similarity < b.similarity { if a.similarity < b.similarity {
return -1 return -1
} }

View File

@ -26,9 +26,7 @@ pub const (
pub fn vhash() string { pub fn vhash() string {
mut buf := [50]byte{} mut buf := [50]byte{}
buf[0] = 0 buf[0] = 0
unsafe { unsafe {C.snprintf(charptr(buf), 50, '%s', C.V_COMMIT_HASH)}
C.snprintf(charptr(buf), 50, '%s', C.V_COMMIT_HASH)
}
return tos_clone(buf) return tos_clone(buf)
} }
@ -98,9 +96,7 @@ pub fn githash(should_get_from_filesystem bool) string {
} }
mut buf := [50]byte{} mut buf := [50]byte{}
buf[0] = 0 buf[0] = 0
unsafe { unsafe {C.snprintf(charptr(buf), 50, '%s', C.V_CURRENT_COMMIT_HASH)}
C.snprintf(charptr(buf), 50, '%s', C.V_CURRENT_COMMIT_HASH)
}
return tos_clone(buf) return tos_clone(buf)
} }
@ -114,7 +110,7 @@ pub fn set_vroot_folder(vroot_path string) {
os.setenv('VCHILD', 'true', true) os.setenv('VCHILD', 'true', true)
} }
pub fn resolve_vroot(str, dir string) ?string { pub fn resolve_vroot(str string, dir string) ?string {
mut mcache := vmod.get_cache() mut mcache := vmod.get_cache()
vmod_file_location := mcache.get_by_folder(dir) vmod_file_location := mcache.get_by_folder(dir)
if vmod_file_location.vmod_file.len == 0 { if vmod_file_location.vmod_file.len == 0 {
@ -236,7 +232,7 @@ pub fn read_file(file_path string) ?string {
} }
[inline] [inline]
pub fn imin(a, b int) int { pub fn imin(a int, b int) int {
return if a < b { return if a < b {
a a
} else { } else {
@ -245,7 +241,7 @@ pub fn imin(a, b int) int {
} }
[inline] [inline]
pub fn imax(a, b int) int { pub fn imax(a int, b int) int {
return if a > b { return if a > b {
a a
} else { } else {
@ -369,7 +365,7 @@ const (
// but *only* when it is at the start, i.e.: // but *only* when it is at the start, i.e.:
// no_cur_mod('vproto.Abdcdef', 'proto') == 'vproto.Abdcdef' // no_cur_mod('vproto.Abdcdef', 'proto') == 'vproto.Abdcdef'
// even though proto. is a substring // even though proto. is a substring
pub fn no_cur_mod(typename, cur_mod string) string { pub fn no_cur_mod(typename string, cur_mod string) string {
mut res := typename mut res := typename
mod_prefix := cur_mod + '.' mod_prefix := cur_mod + '.'
has_map_prefix := res.starts_with(map_prefix) has_map_prefix := res.starts_with(map_prefix)

View File

@ -12,7 +12,7 @@ const (
) )
// compile_file compiles the content of a file by the given path as a template // compile_file compiles the content of a file by the given path as a template
pub fn compile_file(path, fn_name string) string { pub fn compile_file(path string, fn_name string) string {
html := os.read_file(path) or { html := os.read_file(path) or {
panic('html failed') panic('html failed')
} }
@ -26,7 +26,7 @@ enum State {
//span // span.{ //span // span.{
} }
pub fn compile_template(html_, fn_name string) string { pub fn compile_template(html_ string, fn_name string) string {
// lines := os.read_lines(path) // lines := os.read_lines(path)
mut html := html_.trim_space() mut html := html_.trim_space()
mut header := '' mut header := ''