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`:
|
// If `arg` is mutable, the caller needs to provide `mut`:
|
||||||
// `mut numbers := [1,2,3]; reverse(mut numbers);`
|
// `mut numbers := [1,2,3]; reverse(mut numbers);`
|
||||||
if arg.is_mut {
|
if arg.is_mut {
|
||||||
if p.tok != .key_mut {
|
if p.tok != .key_mut && p.tok == .name {
|
||||||
p.error('`$arg.name` is a mutable argument, you need to provide `mut`: `$f.name(...mut a...)`')
|
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 {
|
if p.peek() != .name {
|
||||||
p.error('`$arg.name` is a mutable argument, you need to provide a variable to modify: `$f.name(... mut a...)`')
|
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
|
// Make sure this type has a `str()` method
|
||||||
if !T.has_method('str') {
|
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')
|
error_msg := ('`$typ` needs to have method `str() string` to be printable')
|
||||||
if T.fields.len > 0 {
|
if T.fields.len > 0 {
|
||||||
mut index := p.cgen.cur_line.len - 1
|
mut index := p.cgen.cur_line.len - 1
|
||||||
|
|
|
@ -793,7 +793,7 @@ fn (p mut Parser) error(s string) {
|
||||||
p.cgen.save()
|
p.cgen.save()
|
||||||
// V git pull hint
|
// V git pull hint
|
||||||
cur_path := os.getwd()
|
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('\n=========================')
|
||||||
println('It looks like you are building V. It is being frequently updated every day.')
|
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 ')
|
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 {
|
fn (p mut Parser) statement(add_semi bool) string {
|
||||||
if(p.returns) {
|
if p.returns { //&& !p.is_vweb {
|
||||||
p.error('unreachable code')
|
p.error('unreachable code')
|
||||||
}
|
}
|
||||||
p.cgen.is_tmp = false
|
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()}')
|
//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_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.is_c && !has_field && !has_method && !p.first_pass() {
|
||||||
if typ.name.starts_with('Option_') {
|
if typ.name.starts_with('Option_') {
|
||||||
opt_type := typ.name.right(7)
|
opt_type := typ.name.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
|
module main
|
||||||
|
|
||||||
import strings
|
import strings
|
||||||
|
@ -29,7 +33,7 @@ fn (p mut Parser) select_query(fn_ph int) string {
|
||||||
}
|
}
|
||||||
for field in typ.fields {
|
for field in typ.fields {
|
||||||
//println('registering sql field var $field.name')
|
//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
|
q += table_name
|
||||||
// `where` statement
|
// `where` statement
|
||||||
|
|
|
@ -60,6 +60,7 @@ mut:
|
||||||
// It allows having things like `fn (f Foo) bar()` before `Foo` is defined.
|
// It allows having things like `fn (f Foo) bar()` before `Foo` is defined.
|
||||||
// This information is needed in the first pass.
|
// This information is needed in the first pass.
|
||||||
is_placeholder bool
|
is_placeholder bool
|
||||||
|
gen_str bool // needs `.str()` method generation
|
||||||
}
|
}
|
||||||
|
|
||||||
// For debugging types
|
// 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)
|
typ := p.table.find_type(name)
|
||||||
if typ.name.len == 0 {
|
if typ.name.len == 0 {
|
||||||
return p.table.find_type(p.prepend_mod(name))
|
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[0] = 7
|
||||||
a << 4
|
a << 4
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO
|
// TODO
|
||||||
fn test_mut() {
|
fn test_mut() {
|
||||||
mut a := [1,2,3]
|
mut numbers := [1,2,3]
|
||||||
foo(mut a)
|
foo(7, numbers)
|
||||||
//assert a.len == 4
|
//assert a.len == 4
|
||||||
assert a[0] == 7
|
assert numbers[0] == 7
|
||||||
//assert a[3] == 4
|
//assert a[3] == 4
|
||||||
|
|
||||||
n := 1
|
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}')
|
app.vweb.json('{"a": 3}')
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
pub fn (app mut App) index() {
|
pub fn (app mut App) index() {
|
||||||
|
$vweb.html()
|
||||||
|
}
|
||||||
|
*/
|
||||||
|
|
||||||
|
pub fn (app mut App) text() {
|
||||||
app.vweb.text('hello world')
|
app.vweb.text('hello world')
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -4,6 +4,8 @@
|
||||||
|
|
||||||
module builtin
|
module builtin
|
||||||
|
|
||||||
|
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
|
||||||
|
@ -206,31 +208,6 @@ pub fn (a array) reverse() array {
|
||||||
return arr
|
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 []int) free() {
|
||||||
pub fn (a array) free() {
|
pub fn (a array) free() {
|
||||||
//if a.is_slice {
|
//if a.is_slice {
|
||||||
|
@ -239,19 +216,19 @@ pub fn (a array) free() {
|
||||||
C.free(a.data)
|
C.free(a.data)
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO generic
|
|
||||||
// "[ 'a', 'b', 'c' ]"
|
// "[ 'a', 'b', 'c' ]"
|
||||||
pub fn (a []string) str() string {
|
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++ {
|
for i := 0; i < a.len; i++ {
|
||||||
val := a[i]
|
val := a[i]
|
||||||
res += '"$val"'
|
sb.write('"$val"')
|
||||||
if i < a.len - 1 {
|
if i < a.len - 1 {
|
||||||
res += ', '
|
sb.write(', ')
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
res += ']'
|
sb.write(']')
|
||||||
return res
|
return sb.str()
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn (b []byte) hex() string {
|
pub fn (b []byte) hex() string {
|
||||||
|
|
Loading…
Reference in New Issue