parser: enable module auto import (of `sync`) (#6271)

pull/6277/head
Uwe Krüger 2020-08-31 10:44:39 +02:00 committed by GitHub
parent b1a8e1e5b2
commit cbcba2e4cf
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
17 changed files with 88 additions and 93 deletions

View File

@ -6,24 +6,21 @@
// The receive threads add all received numbers and send them to the // The receive threads add all received numbers and send them to the
// main thread where the total sum is compare to the expected value. // main thread where the total sum is compare to the expected value.
import sync
import time import time
import os import os
fn do_rec(mut ch sync.Channel, mut resch sync.Channel, n int) { fn do_rec(ch chan int, resch chan i64, n int) {
mut sum := i64(0) mut sum := i64(0)
for _ in 0 .. n { for _ in 0 .. n {
mut a := 0 sum += <-ch
ch.pop(&a)
sum += a
} }
println(sum) println(sum)
resch.push(&sum) resch <- sum
} }
fn do_send(mut ch sync.Channel, start, end int) { fn do_send(ch chan int, start, end int) {
for i in start .. end { for i in start .. end {
ch.push(&i) ch <- i
} }
} }
@ -37,12 +34,12 @@ fn main() {
buflen := os.args[3].int() buflen := os.args[3].int()
nobj := os.args[4].int() nobj := os.args[4].int()
stopwatch := time.new_stopwatch({}) stopwatch := time.new_stopwatch({})
mut ch := sync.new_channel<int>(buflen) ch := chan int{cap: buflen}
mut resch := sync.new_channel<i64>(0) resch := chan i64{}
mut no := nobj mut no := nobj
for i in 0 .. nrec { for i in 0 .. nrec {
n := no / (nrec - i) n := no / (nrec - i)
go do_rec(mut ch, mut resch, n) go do_rec(ch, resch, n)
no -= n no -= n
} }
assert no == 0 assert no == 0
@ -51,14 +48,12 @@ fn main() {
n := no / (nsend - i) n := no / (nsend - i)
end := no end := no
no -= n no -= n
go do_send(mut ch, no, end) go do_send(ch, no, end)
} }
assert no == 0 assert no == 0
mut sum := i64(0) mut sum := i64(0)
for _ in 0 .. nrec { for _ in 0 .. nrec {
mut r := i64(0) sum += <-resch
resch.pop(&r)
sum += r
} }
elapsed := stopwatch.elapsed() elapsed := stopwatch.elapsed()
rate := f64(nobj)/elapsed*time.microsecond rate := f64(nobj)/elapsed*time.microsecond

View File

@ -1,23 +1,19 @@
import sync
const ( const (
num_iterations = 10000 num_iterations = 10000
) )
fn do_send(mut ch sync.Channel) { fn do_send(ch chan int) {
for i in 0 .. num_iterations { for i in 0 .. num_iterations {
ch.push(&i) ch <- i
} }
} }
fn test_channel_buffered() { fn test_channel_buffered() {
mut ch := sync.new_channel<int>(1000) ch := chan int{cap: 1000}
go do_send(mut ch) go do_send(ch)
mut sum := i64(0) mut sum := i64(0)
for _ in 0 .. num_iterations { for _ in 0 .. num_iterations {
a := 0 sum += <-ch
ch.pop(&a)
sum += a
} }
assert sum == u64(num_iterations)*(num_iterations-1)/2 assert sum == u64(num_iterations)*(num_iterations-1)/2
} }

View File

@ -1,23 +1,19 @@
import sync
const ( const (
num_iterations = 10000 num_iterations = 10000
) )
fn do_send(mut ch sync.Channel) { fn do_send(ch chan int) {
for i in 0 .. num_iterations { for i in 0 .. num_iterations {
ch.push(&i) ch <- i
} }
} }
fn test_channel_unbuffered() { fn test_channel_unbuffered() {
mut ch := sync.new_channel<int>(0) ch := chan int{}
go do_send(mut ch) go do_send(ch)
mut sum := i64(0) mut sum := i64(0)
for _ in 0 .. num_iterations { for _ in 0 .. num_iterations {
a := 0 sum += <-ch
ch.pop(&a)
sum += a
} }
assert sum == u64(num_iterations)*(num_iterations-1)/2 assert sum == u64(num_iterations)*(num_iterations-1)/2
} }

View File

@ -1,38 +1,32 @@
import sync fn do_rec(ch chan int, resch chan i64) {
fn do_rec(mut ch sync.Channel, mut resch sync.Channel) {
mut sum := i64(0) mut sum := i64(0)
for _ in 0 .. 2000 { for _ in 0 .. 2000 {
mut a := 0 sum += <-ch
ch.pop(&a)
sum += a
} }
println(sum) println(sum)
resch.push(&sum) resch <- sum
} }
fn do_send(mut ch sync.Channel) { fn do_send(ch chan int) {
for i in 0 .. 2000 { for i in 0 .. 2000 {
ch.push(&i) ch <- i
} }
} }
fn test_channel_multi_unbuffered() { fn test_channel_multi_unbuffered() {
mut ch := sync.new_channel<int>(0) ch := chan int{}
mut resch := sync.new_channel<i64>(0) resch := chan i64{}
go do_rec(mut ch, mut resch) go do_rec(ch, resch)
go do_rec(mut ch, mut resch) go do_rec(ch, resch)
go do_rec(mut ch, mut resch) go do_rec(ch, resch)
go do_rec(mut ch, mut resch) go do_rec(ch, resch)
go do_send(mut ch) go do_send(ch)
go do_send(mut ch) go do_send(ch)
go do_send(mut ch) go do_send(ch)
go do_send(mut ch) go do_send(ch)
mut sum := i64(0) mut sum := i64(0)
for _ in 0 .. 4 { for _ in 0 .. 4 {
mut r := i64(0) sum += <-resch
resch.pop(&r)
sum += r
} }
assert sum == i64(4) * 2000 * (2000 - 1) / 2 assert sum == i64(4) * 2000 * (2000 - 1) / 2
} }

View File

@ -1,38 +1,32 @@
import sync fn do_rec(ch chan int, resch chan i64) {
fn do_rec(mut ch sync.Channel, mut resch sync.Channel) {
mut sum := i64(0) mut sum := i64(0)
for _ in 0 .. 2000 { for _ in 0 .. 2000 {
mut a := 0 sum += <-ch
ch.pop(&a)
sum += a
} }
println(sum) println(sum)
resch.push(&sum) resch <- sum
} }
fn do_send(mut ch sync.Channel) { fn do_send(ch chan int) {
for i in 0 .. 2000 { for i in 0 .. 2000 {
ch.push(&i) ch <- i
} }
} }
fn test_channel_multi_buffered() { fn test_channel_multi_buffered() {
mut ch := sync.new_channel<int>(100) ch := chan int{cap: 100}
mut resch := sync.new_channel<i64>(0) resch := chan i64{}
go do_rec(mut ch, mut resch) go do_rec(ch, resch)
go do_rec(mut ch, mut resch) go do_rec(ch, resch)
go do_rec(mut ch, mut resch) go do_rec(ch, resch)
go do_rec(mut ch, mut resch) go do_rec(ch, resch)
go do_send(mut ch) go do_send(ch)
go do_send(mut ch) go do_send(ch)
go do_send(mut ch) go do_send(ch)
go do_send(mut ch) go do_send(ch)
mut sum := i64(0) mut sum := i64(0)
for _ in 0 .. 4 { for _ in 0 .. 4 {
mut r := i64(0) sum += <-resch
resch.pop(&r)
sum += r
} }
assert sum == i64(4) * 2000 * (2000 - 1) / 2 assert sum == i64(4) * 2000 * (2000 - 1) / 2
} }

View File

@ -197,7 +197,7 @@ Did you forget to add vlib to the path? (Use @vlib for default vlib)')
} }
pub fn (v &Builder) get_user_files() []string { pub fn (v &Builder) get_user_files() []string {
if v.pref.path in ['vlib/builtin', 'vlib/strconv', 'vlib/strings', 'vlib/hash', 'vlib/time'] { if v.pref.path in ['vlib/builtin', 'vlib/strconv', 'vlib/strings', 'vlib/hash'] {
// This means we are building a builtin module with `v build-module vlib/strings` etc // This means we are building a builtin module with `v build-module vlib/strings` etc
// get_builtin_files() has already added the files in this module, // get_builtin_files() has already added the files in this module,
// do nothing here to avoid duplicate definition errors. // do nothing here to avoid duplicate definition errors.

View File

@ -5,7 +5,7 @@ import v.table
fn (mut p Parser) lock_expr() ast.LockExpr { fn (mut p Parser) lock_expr() ast.LockExpr {
// TODO Handle aliasing sync // TODO Handle aliasing sync
p.register_used_import('sync') p.register_auto_import('sync')
pos := p.tok.position() pos := p.tok.position()
is_rlock := p.tok.kind == .key_rlock is_rlock := p.tok.kind == .key_rlock
p.next() p.next()

View File

@ -3,6 +3,8 @@
// that can be found in the LICENSE file. // that can be found in the LICENSE file.
module parser module parser
import v.ast
// return true if file being parsed imports `mod` // return true if file being parsed imports `mod`
pub fn (p &Parser) known_import(mod string) bool { pub fn (p &Parser) known_import(mod string) bool {
return mod in p.imports return mod in p.imports
@ -29,6 +31,20 @@ fn (mut p Parser) register_used_import(alias string) {
} }
} }
fn (mut p Parser) register_auto_import(alias string) {
if alias !in p.imports {
p.imports[alias] = alias
p.table.imports << alias
node := ast.Import{
pos: p.tok.position()
mod: alias
alias: alias
}
p.ast_imports << node
}
p.register_used_import(alias)
}
fn (mut p Parser) check_unused_imports() { fn (mut p Parser) check_unused_imports() {
if p.pref.is_repl || p.pref.is_fmt { if p.pref.is_repl || p.pref.is_fmt {
// The REPL should be much more liberal, and should not warn about // The REPL should be much more liberal, and should not warn about

View File

@ -52,10 +52,12 @@ pub fn (mut p Parser) parse_map_type() table.Type {
} }
pub fn (mut p Parser) parse_chan_type() table.Type { pub fn (mut p Parser) parse_chan_type() table.Type {
if p.peek_tok.kind != .name && p.peek_tok.kind != .key_mut && p.peek_tok.kind != .amp {
p.next() p.next()
if p.tok.kind != .name && p.tok.kind != .key_mut && p.tok.kind != .amp {
return table.chan_type return table.chan_type
} }
p.register_auto_import('sync')
p.next()
elem_type := p.parse_type() elem_type := p.parse_type()
idx := p.table.find_or_register_chan(elem_type) idx := p.table.find_or_register_chan(elem_type)
return table.new_type(idx) return table.new_type(idx)

View File

@ -282,6 +282,9 @@ pub fn (mut p Parser) expr(precedence int) ast.Expr {
fn (mut p Parser) infix_expr(left ast.Expr) ast.Expr { fn (mut p Parser) infix_expr(left ast.Expr) ast.Expr {
op := p.tok.kind op := p.tok.kind
if op == .arrow {
p.register_auto_import('sync')
}
// mut typ := p. // mut typ := p.
// println('infix op=$op.str()') // println('infix op=$op.str()')
precedence := p.tok.precedence() precedence := p.tok.precedence()
@ -310,6 +313,9 @@ fn (mut p Parser) prefix_expr() ast.PrefixExpr {
if op == .amp { if op == .amp {
p.is_amp = true p.is_amp = true
} }
if op == .arrow {
p.register_auto_import('sync')
}
// if op == .mul && !p.inside_unsafe { // if op == .mul && !p.inside_unsafe {
// p.warn('unsafe') // p.warn('unsafe')
// } // }
@ -322,7 +328,8 @@ fn (mut p Parser) prefix_expr() ast.PrefixExpr {
mut or_stmts := []ast.Stmt{} mut or_stmts := []ast.Stmt{}
mut or_kind := ast.OrKind.absent mut or_kind := ast.OrKind.absent
// allow `x := <-ch or {...}` to handle closed channel // allow `x := <-ch or {...}` to handle closed channel
if op == .arrow && p.tok.kind == .key_orelse { if op == .arrow {
if p.tok.kind == .key_orelse {
p.next() p.next()
p.open_scope() p.open_scope()
p.scope.register('errcode', ast.Var{ p.scope.register('errcode', ast.Var{
@ -345,6 +352,7 @@ fn (mut p Parser) prefix_expr() ast.PrefixExpr {
p.next() p.next()
or_kind = .propagate or_kind = .propagate
} }
}
return ast.PrefixExpr{ return ast.PrefixExpr{
op: op op: op
right: right right: right

View File

@ -1,4 +1,3 @@
import sync
import time import time
const ( const (

View File

@ -1,4 +1,3 @@
import sync
import time import time
fn incr(shared foo []int, index int) { fn incr(shared foo []int, index int) {

View File

@ -1,4 +1,3 @@
import sync
import time import time
struct St { struct St {

View File

@ -1,4 +1,3 @@
import sync
import time import time
struct St { struct St {

View File

@ -1,4 +1,3 @@
import sync
import time import time
struct St { struct St {

View File

@ -1,4 +1,3 @@
import sync
import time import time
struct St { struct St {

View File

@ -13,7 +13,7 @@ pub const (
// math.bits is needed by strconv.ftoa // math.bits is needed by strconv.ftoa
pub const ( pub const (
builtin_module_parts = ['math.bits', 'strconv', 'strconv.ftoa', 'hash', 'strings', 'time', 'builtin'] builtin_module_parts = ['math.bits', 'strconv', 'strconv.ftoa', 'hash', 'strings', 'builtin']
) )
pub const ( pub const (