run vfmt on array.v

pull/3141/head
Alexander Medvednikov 2019-12-18 20:07:32 +03:00
parent 9e11de4a8c
commit 1cef83aea4
5 changed files with 46 additions and 43 deletions

View File

@ -1,15 +1,14 @@
// Copyright (c) 2019 Alexander Medvednikov. All rights reserved. // Copyright (c) 2019 Alexander Medvednikov. All rights reserved.
// Use of this source code is governed by an MIT license // Use of this source code is governed by an MIT license
// that can be found in the LICENSE file. // that can be found in the LICENSE file.
module builtin module builtin
import strings import strings
struct array { struct array {
pub: pub:
// Using a void pointer allows to implement arrays without generics and without generating // Using a void pointer allows to implement arrays without generics and without generating
// extra code for every type. // extra code for every type.
data voidptr data voidptr
len int len int
cap int cap int
@ -18,8 +17,8 @@ pub:
// Private function, used by V (`nums := []int`) // Private function, used by V (`nums := []int`)
fn new_array(mylen, cap, elm_size int) array { fn new_array(mylen, cap, elm_size int) array {
cap_ := if cap == 0 { 1 } else { cap } cap_ := if cap == 0 {1}else {cap}
arr := array { arr := array{
len: mylen len: mylen
cap: cap cap: cap
element_size: elm_size element_size: elm_size
@ -28,17 +27,15 @@ fn new_array(mylen, cap, elm_size int) array {
return arr return arr
} }
// TODO // TODO
pub fn make(len, cap, elm_size int) array { pub fn make(len, cap, elm_size int) array {
return new_array(len, cap, elm_size) return new_array(len, cap, elm_size)
} }
// 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, cap, elm_size int, c_array voidptr) array {
cap_ := if cap == 0 { 1 } else { cap } cap_ := if cap == 0 {1}else {cap}
arr := array { arr := array{
len: len len: len
cap: cap cap: cap
element_size: elm_size element_size: elm_size
@ -51,7 +48,7 @@ fn new_array_from_c_array(len, cap, elm_size int, c_array voidptr) array {
// 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, cap, elm_size int, c_array voidptr) array {
arr := array { arr := array{
len: len len: len
cap: cap cap: cap
element_size: elm_size element_size: elm_size
@ -63,8 +60,10 @@ fn new_array_from_c_array_no_alloc(len, cap, elm_size int, c_array voidptr) arra
// Private function. Doubles array capacity if needed // Private function. Doubles array capacity if needed
fn (a mut array) ensure_cap(required int) { fn (a mut array) ensure_cap(required int) {
if required > a.cap { if required > a.cap {
mut cap := if a.cap == 0 { 2 } else { a.cap * 2 } mut cap := if a.cap == 0 {2}else {a.cap * 2}
for required > cap { cap *= 2 } for required > cap {
cap *= 2
}
if a.cap == 0 { if a.cap == 0 {
a.data = calloc(cap * a.element_size) a.data = calloc(cap * a.element_size)
} }
@ -80,7 +79,7 @@ fn array_repeat_old(val voidptr, nr_repeats, elm_size int) array {
if nr_repeats < 0 { if nr_repeats < 0 {
panic('[0; len]: `len` is negative (len == $nr_repeats)') panic('[0; len]: `len` is negative (len == $nr_repeats)')
} }
arr := array { arr := array{
len: nr_repeats len: nr_repeats
cap: nr_repeats cap: nr_repeats
element_size: elm_size element_size: elm_size
@ -102,7 +101,7 @@ pub fn (a array) repeat(nr_repeats int) array {
if size == 0 { if size == 0 {
size = a.element_size size = a.element_size
} }
arr := array { arr := array{
len: nr_repeats * a.len len: nr_repeats * a.len
cap: nr_repeats * a.len cap: nr_repeats * a.len
element_size: a.element_size element_size: a.element_size
@ -122,8 +121,8 @@ pub fn (a mut array) sort_with_compare(compare voidptr) {
// TODO array.insert is broken // TODO array.insert is broken
// Cannot pass literal or primitive type as it cannot be cast to voidptr. // Cannot pass literal or primitive type as it cannot be cast to voidptr.
// In the current state only that would work: // In the current state only that would work:
// i := 3 // i := 3
// a.insert(0, &i) // a.insert(0, &i)
// ---------------------------- // ----------------------------
pub fn (a mut array) insert(i int, val voidptr) { pub fn (a mut array) insert(i int, val voidptr) {
if i < 0 || i > a.len { if i < 0 || i > a.len {
@ -205,7 +204,7 @@ fn (a array) right(n 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, _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)
} }
@ -225,7 +224,7 @@ fn (a array) slice(start, _end int) array {
panic('array.slice: slice bounds out of range ($start < 0)') panic('array.slice: slice bounds out of range ($start < 0)')
} }
l := end - start l := end - start
res := array { res := array{
element_size: a.element_size element_size: a.element_size
data: a.data + start * a.element_size data: a.data + start * a.element_size
len: l len: l
@ -246,7 +245,7 @@ fn (a array) slice_clone(start, _end int) array {
panic('array.slice: slice bounds out of range ($start < 0)') panic('array.slice: slice bounds out of range ($start < 0)')
} }
l := end - start l := end - start
res := array { res := array{
element_size: a.element_size element_size: a.element_size
data: a.data + start * a.element_size data: a.data + start * a.element_size
len: l len: l
@ -280,14 +279,14 @@ pub fn (a mut array) push_many(val voidptr, size int) {
// array.reverse returns a new array with the elements of // array.reverse returns a new array with the elements of
// the original array in reverse order. // the original array in reverse order.
pub fn (a array) reverse() array { pub fn (a array) reverse() array {
arr := array { arr := array{
len: a.len len: a.len
cap: a.cap cap: a.cap
element_size: a.element_size element_size: a.element_size
data: calloc(a.cap * a.element_size) data: calloc(a.cap * a.element_size)
} }
for i := 0; i < a.len; i++ { for i := 0; i < a.len; i++ {
C.memcpy(arr.data + i * arr.element_size, &a[a.len-1-i], arr.element_size) C.memcpy(arr.data + i * arr.element_size, &a[a.len - 1 - i], arr.element_size)
} }
return arr return arr
} }
@ -298,7 +297,7 @@ pub fn (a array) clone() array {
if size == 0 { if size == 0 {
size++ size++
} }
arr := array { arr := array{
len: a.len len: a.len
cap: a.cap cap: a.cap
element_size: a.element_size element_size: a.element_size
@ -308,12 +307,12 @@ pub fn (a array) clone() array {
return arr return arr
} }
//pub fn (a []int) free() { // pub fn (a []int) free() {
[unsafe_fn] [unsafe_fn]
pub fn (a array) free() { pub fn (a array) free() {
//if a.is_slice { // if a.is_slice {
//return // return
//} // }
C.free(a.data) C.free(a.data)
} }
@ -344,7 +343,8 @@ pub fn (a []bool) str() string {
val := a[i] val := a[i]
if val { if val {
sb.write('true') sb.write('true')
} else { }
else {
sb.write('false') sb.write('false')
} }
if i < a.len - 1 { if i < a.len - 1 {
@ -358,9 +358,9 @@ pub fn (a []bool) str() string {
// []byte.hex returns a string with the hexadecimal representation // []byte.hex returns a string with the hexadecimal representation
// of the byte elements of the array // of the byte elements of the array
pub fn (b []byte) hex() string { pub fn (b []byte) hex() string {
mut hex := malloc(b.len*2+1) mut hex := malloc(b.len * 2 + 1)
mut ptr := &hex[0] mut ptr := &hex[0]
for i := 0; i < b.len ; i++ { for i := 0; i < b.len; i++ {
ptr += C.sprintf(charptr(ptr), '%02x', b[i]) ptr += C.sprintf(charptr(ptr), '%02x', b[i])
} }
return string(hex) return string(hex)
@ -372,8 +372,8 @@ pub fn (b []byte) hex() string {
// TODO: implement for all types // TODO: implement for all types
pub fn copy(dst, src []byte) int { pub fn copy(dst, src []byte) int {
if dst.len > 0 && src.len > 0 { if dst.len > 0 && src.len > 0 {
min := if dst.len < src.len { dst.len } else { src.len } min := if dst.len < src.len {dst.len}else {src.len}
C.memcpy(dst.data, src.left(min).data, dst.element_size*min) C.memcpy(dst.data, src.left(min).data, dst.element_size * min)
return min return min
} }
return 0 return 0
@ -442,11 +442,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(accum, curr int)int, accum_start int) int {
mut _accum := 0 mut _accum := 0
_accum = accum_start _accum = accum_start
for i := 0; i < a.len; i++ { for i := 0; i < a.len; i++ {
_accum = iter(_accum, a[i]) _accum = iter(_accum, a[i])
} }
return _accum return _accum
} }

View File

@ -15,7 +15,7 @@ fn todo() {
} }
fn (v &V) no_cc_installed() bool { fn (v &V) no_cc_installed() bool {
$if windows { $if windows {
os.exec('$v.pref.ccompiler -v') or { os.exec('$v.pref.ccompiler -v') or {
if v.pref.is_verbose { if v.pref.is_verbose {
println('C compiler not found, trying to build with msvc...') println('C compiler not found, trying to build with msvc...')
@ -27,6 +27,9 @@ fn (v &V) no_cc_installed() bool {
} }
fn (v mut V) cc() { fn (v mut V) cc() {
if os.executable().contains('vfmt') {
return
}
v.build_thirdparty_obj_files() v.build_thirdparty_obj_files()
vexe := vexe_path() vexe := vexe_path()
vdir := os.dir(vexe) vdir := os.dir(vexe)

View File

@ -221,7 +221,7 @@ fn (p mut Parser) fn_decl() {
mut f := Fn{ mut f := Fn{
mod: p.mod mod: p.mod
is_public: is_pub || p.is_vh // functions defined in .vh are always public is_public: is_pub || p.is_vh // functions defined in .vh are always public
is_unsafe: p.attr == 'unsafe_fn' is_unsafe: p.attr == 'unsafe_fn'
is_deprecated: p.attr == 'deprecated' is_deprecated: p.attr == 'deprecated'
comptime_define: if p.attr.starts_with('if ') {p.attr[3..]}else {''} comptime_define: if p.attr.starts_with('if ') {p.attr[3..]}else {''}
@ -454,7 +454,7 @@ fn (p mut Parser) fn_decl() {
p.genln('; // $f.name') p.genln('; // $f.name')
} }
// Generic functions are inserted as needed from the call site // Generic functions are inserted as needed from the call site
if f.is_generic { if f.is_generic && !p.scanner.is_fmt {
if p.first_pass() { if p.first_pass() {
if !p.scanner.is_vh { if !p.scanner.is_vh {
gpidx := p.v.get_file_parser_index(p.file_path) or { gpidx := p.v.get_file_parser_index(p.file_path) or {
@ -885,7 +885,7 @@ fn (p mut Parser) fn_args(f mut Fn) {
typ: typ typ: typ
is_arg: true is_arg: true
// is_mut: is_mut // is_mut: is_mut
line_nr: p.scanner.line_nr line_nr: p.scanner.line_nr
token_idx: p.cur_tok_index() token_idx: p.cur_tok_index()
} }
@ -1271,7 +1271,7 @@ fn (p mut Parser) fn_call_args(f mut Fn) {
p.error('wrong number of arguments in call to `${f.str_for_error()}`') p.error('wrong number of arguments in call to `${f.str_for_error()}`')
} }
p.check(.rpar) p.check(.rpar)
if f.is_generic { if f.is_generic && !p.scanner.is_fmt {
type_map := p.extract_type_inst(f, saved_args) type_map := p.extract_type_inst(f, saved_args)
p.dispatch_generic_fn_instance(mut f, &type_map) p.dispatch_generic_fn_instance(mut f, &type_map)
} }

View File

@ -124,7 +124,7 @@ pub mut:
comptime_define string // -D vfmt for `if $vfmt {` comptime_define string // -D vfmt for `if $vfmt {`
fast bool // use tcc/x64 codegen fast bool // use tcc/x64 codegen
enable_globals bool // allow __global for low level code enable_globals bool // allow __global for low level code
is_fmt bool //is_fmt bool
is_bare bool is_bare bool
user_mod_path string // `v -user_mod_path /Users/user/modules` adds a new lookup path for imported modules user_mod_path string // `v -user_mod_path /Users/user/modules` adds a new lookup path for imported modules
@ -1093,7 +1093,7 @@ pub fn new_v(args[]string) &V {
ccompiler: find_c_compiler() ccompiler: find_c_compiler()
building_v: !is_repl && (rdir_name == 'compiler' || rdir_name == 'v.v' || dir.contains('vlib')) building_v: !is_repl && (rdir_name == 'compiler' || rdir_name == 'v.v' || dir.contains('vlib'))
comptime_define: comptime_define comptime_define: comptime_define
is_fmt: comptime_define == 'vfmt' //is_fmt: comptime_define == 'vfmt'
user_mod_path: user_mod_path user_mod_path: user_mod_path
vlib_path: vlib_path vlib_path: vlib_path
vpath: vpath vpath: vpath

View File

@ -130,11 +130,11 @@ fn (p mut Parser) fmt_dec() {
} }
[if vfmt] [if vfmt]
fn (p mut Scanner) init_fmt() { fn (s mut Scanner) init_fmt() {
// Right now we can't do `$if vfmt {`, so I'm using // Right now we can't do `$if vfmt {`, so I'm using
// a conditional function init_fmt to set this flag. // a conditional function init_fmt to set this flag.
// This function will only be called if `-d vfmt` is passed. // This function will only be called if `-d vfmt` is passed.
p.is_fmt = true s.is_fmt = true
} }
[if vfmt] [if vfmt]
@ -243,7 +243,7 @@ fn (p &Parser) gen_fmt() {
if s == '' { if s == '' {
return return
} }
if !p.file_name.contains('fn.v') {return} if !p.file_name.contains('parser.v') {return}
path := os.tmpdir() + '/' + p.file_name path := os.tmpdir() + '/' + p.file_name
println('generating ${path}') println('generating ${path}')
mut out := os.create(path) or { mut out := os.create(path) or {