cgen: implement channel `push()`/`pop()` using `<-` operator (#6154)
parent
5c98c0760b
commit
0d7cc8829a
|
@ -1,45 +1,42 @@
|
|||
import sync
|
||||
import time
|
||||
|
||||
fn do_rec_i64(ch chan i64) {
|
||||
mut sum := i64(0)
|
||||
for _ in 0 .. 300 {
|
||||
mut a := i64(0)
|
||||
(&sync.Channel(ch)).pop(&a)
|
||||
sum += a
|
||||
sum += <-ch
|
||||
}
|
||||
assert sum == 300 * (300 - 1) / 2
|
||||
}
|
||||
|
||||
fn do_send_int(ch chan int) {
|
||||
for i in 0 .. 300 {
|
||||
(&sync.Channel(ch)).push(&i)
|
||||
ch <- i
|
||||
}
|
||||
}
|
||||
|
||||
fn do_send_byte(ch chan byte) {
|
||||
for i in 0 .. 300 {
|
||||
ii := byte(i)
|
||||
(&sync.Channel(ch)).push(&ii)
|
||||
ch <- byte(i)
|
||||
}
|
||||
}
|
||||
|
||||
fn do_send_i64(mut ch sync.Channel) {
|
||||
fn do_send_i64(ch chan i64) {
|
||||
for i in 0 .. 300 {
|
||||
ii := i64(i)
|
||||
ch.push(&ii)
|
||||
ch <- i
|
||||
}
|
||||
}
|
||||
|
||||
fn test_select() {
|
||||
chi := chan int{}
|
||||
mut chl := sync.new_channel<i64>(1)
|
||||
chl := chan i64{cap: 1}
|
||||
chb := chan byte{cap: 10}
|
||||
recch := chan i64{cap: 0}
|
||||
go do_rec_i64(recch)
|
||||
go do_send_int(chi)
|
||||
go do_send_byte(chb)
|
||||
go do_send_i64(mut chl)
|
||||
mut channels := [&sync.Channel(chi), &sync.Channel(recch), chl, &sync.Channel(chb)]
|
||||
go do_send_i64(chl)
|
||||
mut channels := [&sync.Channel(chi), &sync.Channel(recch), &sync.Channel(chl), &sync.Channel(chb)]
|
||||
directions := [sync.Direction.pop, .push, .pop, .pop]
|
||||
mut sum := i64(0)
|
||||
mut rl := i64(0)
|
||||
|
@ -73,4 +70,5 @@ fn test_select() {
|
|||
256 * (256 - 1) / 2 +
|
||||
44 * (44 - 1) / 2
|
||||
assert sum == expected_sum
|
||||
time.sleep_ms(20) // to give assert in coroutine enough time
|
||||
}
|
||||
|
|
|
@ -438,6 +438,8 @@ pub:
|
|||
op token.Kind
|
||||
right Expr
|
||||
pos token.Position
|
||||
pub mut:
|
||||
right_type table.Type
|
||||
}
|
||||
|
||||
pub struct IndexExpr {
|
||||
|
|
|
@ -2439,6 +2439,7 @@ pub fn (mut c Checker) expr(node ast.Expr) table.Type {
|
|||
}
|
||||
ast.PrefixExpr {
|
||||
right_type := c.expr(node.right)
|
||||
node.right_type = right_type
|
||||
// TODO: testing ref/deref strategy
|
||||
if node.op == .amp && !right_type.is_ptr() {
|
||||
return right_type.to_ptr()
|
||||
|
|
|
@ -498,8 +498,21 @@ typedef struct {
|
|||
g.type_definitions.writeln('typedef _Interface ${c_name(typ.name)};')
|
||||
}
|
||||
.chan {
|
||||
if typ.name != 'chan' {
|
||||
styp := util.no_dots(typ.name)
|
||||
g.type_definitions.writeln('typedef chan $styp;')
|
||||
el_stype := g.typ(typ.chan_info().elem_type)
|
||||
g.hotcode_definitions.writeln('
|
||||
static inline $el_stype __${styp}_popval($styp ch) {
|
||||
$el_stype val;
|
||||
sync__Channel_try_pop_priv(ch, &val, false);
|
||||
return val;
|
||||
}')
|
||||
g.hotcode_definitions.writeln('
|
||||
static inline void __${styp}_pushval($styp ch, $el_stype val) {
|
||||
sync__Channel_try_push_priv(ch, &val, false);
|
||||
}')
|
||||
}
|
||||
}
|
||||
.map {
|
||||
styp := util.no_dots(typ.name)
|
||||
|
@ -1969,11 +1982,20 @@ fn (mut g Gen) expr(node ast.Expr) {
|
|||
if node.op == .amp {
|
||||
g.is_amp = true
|
||||
}
|
||||
if node.op == .arrow {
|
||||
right_type := g.unwrap_generic(node.right_type)
|
||||
right_sym := g.table.get_type_symbol(right_type)
|
||||
styp := util.no_dots(right_sym.name)
|
||||
g.write('__${styp}_popval(')
|
||||
} else {
|
||||
// g.write('/*pref*/')
|
||||
g.write(node.op.str())
|
||||
// g.write('(')
|
||||
}
|
||||
g.expr(node.right)
|
||||
// g.write(')')
|
||||
if node.op == .arrow {
|
||||
g.write(')')
|
||||
}
|
||||
g.is_amp = false
|
||||
}
|
||||
ast.RangeExpr {
|
||||
|
@ -2326,6 +2348,14 @@ fn (mut g Gen) infix_expr(node ast.InfixExpr) {
|
|||
}
|
||||
g.write(' }))')
|
||||
}
|
||||
} else if node.op == .arrow {
|
||||
// chan <- val
|
||||
styp := util.no_dots(left_sym.name)
|
||||
g.write('__${styp}_pushval(')
|
||||
g.expr(node.left)
|
||||
g.write(', ')
|
||||
g.expr(node.right)
|
||||
g.write(')')
|
||||
} else if unaliased_left.idx() in [table.u32_type_idx, table.u64_type_idx] && unaliased_right.is_signed() &&
|
||||
node.op in [.eq, .ne, .gt, .lt, .ge, .le] {
|
||||
bitsize := if unaliased_left.idx() == table.u32_type_idx &&
|
||||
|
|
Loading…
Reference in New Issue