fmt: add support for `chan` types and operations (#6328)

pull/6358/head
Uwe Krüger 2020-09-08 00:36:05 +02:00 committed by GitHub
parent 9a5b86e454
commit 5258f52497
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
4 changed files with 106 additions and 24 deletions

View File

@ -5,7 +5,7 @@ const (
) )
fn get_val_from_chan(ch chan i64) ?i64 { fn get_val_from_chan(ch chan i64) ?i64 {
r := <-ch? r := <-ch ?
return r return r
} }
@ -33,7 +33,7 @@ fn test_channel_array_mut() {
chs[0] <- t chs[0] <- t
t = <-chs[1] t = <-chs[1]
} }
(&sync.Channel(chs[0])).close() chs[0].close()
sem.wait() sem.wait()
assert t == 100 + num_iterations assert t == 100 + num_iterations
} }

View File

@ -717,9 +717,17 @@ pub fn (mut f Fmt) prefix_expr_cast_expr(fexpr ast.Expr) {
is_pe_amp_ce = true is_pe_amp_ce = true
f.expr(ce) f.expr(ce)
} }
} else if fexpr is ast.CastExpr {
last := f.out.cut_last(1)
if last != '&' {
f.out.write(last)
}
} }
if !is_pe_amp_ce { if !is_pe_amp_ce {
f.expr(fexpr) f.expr(fexpr)
if fexpr is ast.PrefixExpr {
f.or_expr(fexpr.or_block)
}
} }
} }
@ -1628,12 +1636,17 @@ fn expr_is_single_line(expr ast.Expr) bool {
} }
pub fn (mut f Fmt) chan_init(mut it ast.ChanInit) { pub fn (mut f Fmt) chan_init(mut it ast.ChanInit) {
if it.elem_type == 0 && it.typ > 0 {
info := f.table.get_type_symbol(it.typ).chan_info() info := f.table.get_type_symbol(it.typ).chan_info()
if it.elem_type == 0 && it.typ > 0 {
it.elem_type = info.elem_type it.elem_type = info.elem_type
} }
is_mut := info.is_mut
el_typ := if is_mut { it.elem_type.set_nr_muls(it.elem_type.nr_muls() - 1) } else { it.elem_type }
f.write('chan ') f.write('chan ')
f.write(f.type_to_str(it.elem_type)) if is_mut {
f.write('mut ')
}
f.write(f.type_to_str(el_typ))
f.write('{') f.write('{')
if it.has_cap { if it.has_cap {
f.write('cap: ') f.write('cap: ')

View File

@ -0,0 +1,65 @@
import sync
const (
num_iterations = 10000
)
struct St {
a int
}
fn get_val_from_chan(ch chan i64) ?i64 {
r := <-ch ?
return r
}
fn get_val_from_chan2(ch chan i64) ?i64 {
r := <-ch or {
println('error')
return error(err)
}
return r
}
// this function gets an array of channels for `i64`
fn do_rec_calc_send(chs []chan i64, sem sync.Semaphore) {
mut msg := ''
for {
mut s := get_val_from_chan(chs[0]) or {
msg = err.str()
break
}
s++
chs[1] <- s
}
assert msg == 'channel closed'
sem.post()
}
fn test_channel_array_mut() {
mut chs := [chan i64{}, chan i64{cap: 10}]
sem := sync.new_semaphore()
go do_rec_calc_send(chs, sem)
mut t := i64(100)
for _ in 0 .. num_iterations {
chs[0] <- t
t = <-chs[1]
}
(&sync.Channel(chs[0])).close()
orr := &sync.Channel(chs[0])
chs[1].close()
ch := chan int{}
ch.close()
a := ch.cap
b := ch.len
c := ch[1].cap
d := ch[o].len
sem.wait()
assert t == 100 + num_iterations
ch2 := chan mut St{cap: 10}
go g(ch2)
}
fn g(ch chan mut St) {
return
}

View File

@ -804,32 +804,36 @@ pub fn (table &Table) type_to_str(t Type) string {
map_start = 'map[string]' map_start = 'map[string]'
} }
if sym.kind == .chan || 'chan_' in res { if sym.kind == .chan || 'chan_' in res {
res = res.replace('chan_', '') res = res.replace('chan_', 'chan ')
} }
// mod.submod.submod2.Type => submod2.Type // mod.submod.submod2.Type => submod2.Type
if res.contains('.') { mut parts := res.split(' ')
vals := res.split('.') for i, _ in parts {
if parts[i].contains('.') {
vals := parts[i].split('.')
if vals.len > 2 { if vals.len > 2 {
res = vals[vals.len - 2] + '.' + vals[vals.len - 1] parts[i] = vals[vals.len - 2] + '.' + vals[vals.len - 1]
} }
if res.starts_with(table.cmod_prefix) || if parts[i].starts_with(table.cmod_prefix) ||
(sym.kind == .array && res.starts_with('[]' + table.cmod_prefix)) { (sym.kind == .array && parts[i].starts_with('[]' + table.cmod_prefix)) {
res = res.replace_once(table.cmod_prefix, '') parts[i] = parts[i].replace_once(table.cmod_prefix, '')
} }
if sym.kind == .array && !res.starts_with('[]') { if sym.kind == .array && !parts[i].starts_with('[]') {
res = '[]' + res parts[i] = '[]' + parts[i]
} }
if sym.kind == .map && !res.starts_with('map') { if sym.kind == .map && !parts[i].starts_with('map') {
res = map_start + res parts[i] = map_start + parts[i]
} }
if sym.kind == .chan && !res.starts_with('chan') {
res = 'chan ' + res
} }
if parts[i].contains('_mut') {
parts[i] = 'mut ' + parts[i].replace('_mut', '')
} }
nr_muls := t.nr_muls() nr_muls := t.nr_muls()
if nr_muls > 0 { if nr_muls > 0 {
res = strings.repeat(`&`, nr_muls) + res parts[i] = strings.repeat(`&`, nr_muls) + parts[i]
} }
}
res = parts.join(' ')
if t.has_flag(.optional) { if t.has_flag(.optional) {
if sym.kind == .void { if sym.kind == .void {
res = '?' res = '?'