generate `.str()` for all arrays
parent
f628d6d35d
commit
8c3475b902
|
@ -236,3 +236,30 @@ fn (p mut Parser) comptime_method_call(typ Type) {
|
|||
}
|
||||
}
|
||||
|
||||
fn (p mut Parser) gen_array_str(typ mut Type) {
|
||||
typ.add_method(Fn{
|
||||
name: 'str',
|
||||
typ: 'string'
|
||||
args: [Var{typ: typ.name, is_arg:true}]
|
||||
is_method: true
|
||||
receiver_typ: typ.name
|
||||
})
|
||||
t := typ.name
|
||||
elm_type := t.right(6)
|
||||
p.cgen.fns << '
|
||||
string ${t}_str($t a) {
|
||||
strings__Builder sb = strings__new_builder(a.len * 3);
|
||||
strings__Builder_write(&sb, tos2("[")) ;
|
||||
for (int i = 0; i < a.len; i++) {
|
||||
strings__Builder_write(&sb, ${elm_type}_str( (($elm_type *) a.data)[i]));
|
||||
|
||||
if (i < a.len - 1) {
|
||||
strings__Builder_write(&sb, tos2(", ")) ;
|
||||
|
||||
}
|
||||
}
|
||||
strings__Builder_write(&sb, tos2("]")) ;
|
||||
return strings__Builder_str(sb);
|
||||
} '
|
||||
}
|
||||
|
||||
|
|
|
@ -794,8 +794,15 @@ fn (p mut Parser) fn_call_args(f mut Fn) *Fn {
|
|||
// If `arg` is mutable, the caller needs to provide `mut`:
|
||||
// `mut numbers := [1,2,3]; reverse(mut numbers);`
|
||||
if arg.is_mut {
|
||||
if p.tok != .key_mut {
|
||||
p.error('`$arg.name` is a mutable argument, you need to provide `mut`: `$f.name(...mut a...)`')
|
||||
if p.tok != .key_mut && p.tok == .name {
|
||||
mut dots_example := 'mut $p.lit'
|
||||
if i > 0 {
|
||||
dots_example = '.., ' + dots_example
|
||||
}
|
||||
if i < f.args.len - 1 {
|
||||
dots_example = dots_example + ',..'
|
||||
}
|
||||
p.error('`$arg.name` is a mutable argument, you need to provide `mut`: `$f.name($dots_example)`')
|
||||
}
|
||||
if p.peek() != .name {
|
||||
p.error('`$arg.name` is a mutable argument, you need to provide a variable to modify: `$f.name(... mut a...)`')
|
||||
|
@ -831,6 +838,13 @@ fn (p mut Parser) fn_call_args(f mut Fn) *Fn {
|
|||
}
|
||||
// Make sure this type has a `str()` method
|
||||
if !T.has_method('str') {
|
||||
// Arrays have automatic `str()` methods
|
||||
if T.name.starts_with('array_') {
|
||||
p.gen_array_str(mut T)
|
||||
p.cgen.set_placeholder(ph, '${typ}_str(')
|
||||
p.gen(')')
|
||||
continue
|
||||
}
|
||||
error_msg := ('`$typ` needs to have method `str() string` to be printable')
|
||||
if T.fields.len > 0 {
|
||||
mut index := p.cgen.cur_line.len - 1
|
||||
|
|
|
@ -793,7 +793,7 @@ fn (p mut Parser) error(s string) {
|
|||
p.cgen.save()
|
||||
// V git pull hint
|
||||
cur_path := os.getwd()
|
||||
if !p.pref.is_repl && ( p.file_path.contains('v/compiler') || cur_path.contains('v/compiler') ){
|
||||
if !p.pref.is_repl && !p.pref.is_test && ( p.file_path.contains('v/compiler') || cur_path.contains('v/compiler') ){
|
||||
println('\n=========================')
|
||||
println('It looks like you are building V. It is being frequently updated every day.')
|
||||
println('If you didn\'t modify the compiler\'s code, most likely there was a change that ')
|
||||
|
@ -1102,7 +1102,7 @@ fn (p mut Parser) vh_genln(s string) {
|
|||
}
|
||||
|
||||
fn (p mut Parser) statement(add_semi bool) string {
|
||||
if(p.returns) {
|
||||
if p.returns { //&& !p.is_vweb {
|
||||
p.error('unreachable code')
|
||||
}
|
||||
p.cgen.is_tmp = false
|
||||
|
@ -1780,7 +1780,12 @@ fn (p mut Parser) dot(str_typ string, method_ph int) string {
|
|||
//println('dot() field_name=$field_name typ=$str_typ prev_tok=${prev_tok.str()}')
|
||||
//}
|
||||
has_field := p.table.type_has_field(typ, field_name)
|
||||
has_method := p.table.type_has_method(typ, field_name)
|
||||
mut has_method := p.table.type_has_method(typ, field_name)
|
||||
// generate `.str()`
|
||||
if !has_method && field_name == 'str' && typ.name.starts_with('array_') {
|
||||
p.gen_array_str(mut typ)
|
||||
has_method = true
|
||||
}
|
||||
if !typ.is_c && !has_field && !has_method && !p.first_pass() {
|
||||
if typ.name.starts_with('Option_') {
|
||||
opt_type := typ.name.right(7)
|
||||
|
|
|
@ -1,3 +1,7 @@
|
|||
// Copyright (c) 2019 Alexander Medvednikov. All rights reserved.
|
||||
// Use of this source code is governed by an MIT license
|
||||
// that can be found in the LICENSE file.
|
||||
|
||||
module main
|
||||
|
||||
import strings
|
||||
|
@ -29,7 +33,7 @@ fn (p mut Parser) select_query(fn_ph int) string {
|
|||
}
|
||||
for field in typ.fields {
|
||||
//println('registering sql field var $field.name')
|
||||
p.cur_fn.register_var({ field | is_used:true})
|
||||
p.cur_fn.register_var({ field | is_used:true })
|
||||
}
|
||||
q += table_name
|
||||
// `where` statement
|
||||
|
|
|
@ -60,6 +60,7 @@ mut:
|
|||
// It allows having things like `fn (f Foo) bar()` before `Foo` is defined.
|
||||
// This information is needed in the first pass.
|
||||
is_placeholder bool
|
||||
gen_str bool // needs `.str()` method generation
|
||||
}
|
||||
|
||||
// For debugging types
|
||||
|
@ -434,7 +435,7 @@ fn (t mut Type) add_gen_type(type_name string) {
|
|||
}
|
||||
*/
|
||||
|
||||
fn (p &Parser) find_type(name string) *Type {
|
||||
fn (p &Parser) find_type(name string) &Type {
|
||||
typ := p.table.find_type(name)
|
||||
if typ.name.len == 0 {
|
||||
return p.table.find_type(p.prepend_mod(name))
|
||||
|
|
|
@ -1,14 +1,14 @@
|
|||
fn foo(a mut []int) {
|
||||
fn foo(b int, a mut []int) {
|
||||
a[0] = 7
|
||||
a << 4
|
||||
}
|
||||
|
||||
// TODO
|
||||
fn test_mut() {
|
||||
mut a := [1,2,3]
|
||||
foo(mut a)
|
||||
mut numbers := [1,2,3]
|
||||
foo(7, numbers)
|
||||
//assert a.len == 4
|
||||
assert a[0] == 7
|
||||
assert numbers[0] == 7
|
||||
//assert a[3] == 4
|
||||
|
||||
n := 1
|
||||
|
|
|
@ -0,0 +1,16 @@
|
|||
struct Foo {
|
||||
a int
|
||||
}
|
||||
|
||||
fn test_array_str() {
|
||||
f := Foo{34}
|
||||
println(f)
|
||||
//s := f.str()
|
||||
//println(s)
|
||||
n := [i64(1), 2, 3]
|
||||
assert n.str() == '[1, 2, 3]'
|
||||
println(n) // make sure the array is printable
|
||||
n2 := [4,5,6]
|
||||
assert n2.str() == '[4, 5, 6]'
|
||||
println(n2)
|
||||
}
|
|
@ -23,7 +23,13 @@ pub fn (app mut App) json_endpoint() {
|
|||
app.vweb.json('{"a": 3}')
|
||||
}
|
||||
|
||||
/*
|
||||
pub fn (app mut App) index() {
|
||||
$vweb.html()
|
||||
}
|
||||
*/
|
||||
|
||||
pub fn (app mut App) text() {
|
||||
app.vweb.text('hello world')
|
||||
}
|
||||
|
||||
|
|
|
@ -4,6 +4,8 @@
|
|||
|
||||
module builtin
|
||||
|
||||
import strings
|
||||
|
||||
struct array {
|
||||
pub:
|
||||
// Using a void pointer allows to implement arrays without generics and without generating
|
||||
|
@ -206,31 +208,6 @@ pub fn (a array) reverse() array {
|
|||
return arr
|
||||
}
|
||||
|
||||
pub fn (a []int) str() string {
|
||||
mut res := '['
|
||||
for i := 0; i < a.len; i++ {
|
||||
val := a[i]
|
||||
res += '$val'
|
||||
if i < a.len - 1 {
|
||||
res += ', '
|
||||
}
|
||||
}
|
||||
res += ']'
|
||||
return res
|
||||
}
|
||||
|
||||
pub fn (a []u64) str() string {
|
||||
mut res := '['
|
||||
for i := 0; i < a.len; i++ {
|
||||
val := a[i]
|
||||
res += '$val'
|
||||
if i < a.len - 1 {
|
||||
res += ', '
|
||||
}
|
||||
}
|
||||
res += ']'
|
||||
return res
|
||||
}
|
||||
//pub fn (a []int) free() {
|
||||
pub fn (a array) free() {
|
||||
//if a.is_slice {
|
||||
|
@ -239,19 +216,19 @@ pub fn (a array) free() {
|
|||
C.free(a.data)
|
||||
}
|
||||
|
||||
// TODO generic
|
||||
// "[ 'a', 'b', 'c' ]"
|
||||
pub fn (a []string) str() string {
|
||||
mut res := '['
|
||||
mut sb := strings.new_builder(a.len * 3)
|
||||
sb.write('[')
|
||||
for i := 0; i < a.len; i++ {
|
||||
val := a[i]
|
||||
res += '"$val"'
|
||||
sb.write('"$val"')
|
||||
if i < a.len - 1 {
|
||||
res += ', '
|
||||
sb.write(', ')
|
||||
}
|
||||
}
|
||||
res += ']'
|
||||
return res
|
||||
sb.write(']')
|
||||
return sb.str()
|
||||
}
|
||||
|
||||
pub fn (b []byte) hex() string {
|
||||
|
|
Loading…
Reference in New Issue