parser: allow blank ident in nested loops

pull/4561/head
Enzo Baldisserri 2020-04-23 12:00:51 +02:00 committed by GitHub
parent fb97c2e01e
commit 7e400124e8
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 284 additions and 20 deletions

View File

@ -107,6 +107,9 @@ pub fn (s mut Scope) update_var_type(name string, typ table.Type) {
} }
pub fn (s mut Scope) register(name string, obj ScopeObject) { pub fn (s mut Scope) register(name string, obj ScopeObject) {
if name == '_' {
return
}
if x := s.find(name) { if x := s.find(name) {
// println('existing obect: $name') // println('existing obect: $name')
return return

View File

@ -595,7 +595,9 @@ fn (mut g Gen) for_in(it ast.ForInStmt) {
g.write('; $i < ') g.write('; $i < ')
g.expr(it.high) g.expr(it.high)
g.writeln('; $i++) {') g.writeln('; $i++) {')
if it.val_var != '_' {
g.writeln('\tint $it.val_var = $i;') g.writeln('\tint $it.val_var = $i;')
}
g.stmts(it.stmts) g.stmts(it.stmts)
g.writeln('}') g.writeln('}')
} else if it.kind == .array { } else if it.kind == .array {
@ -608,16 +610,11 @@ fn (mut g Gen) for_in(it ast.ForInStmt) {
g.write('${atmp_type} ${atmp} = ') g.write('${atmp_type} ${atmp} = ')
g.expr(it.cond) g.expr(it.cond)
g.writeln(';') g.writeln(';')
i := if it.key_var == '' { g.new_tmp_var() } else { it.key_var } i := if it.key_var in ['', '_'] { g.new_tmp_var() } else { it.key_var }
if cond_type_is_ptr { op_field := if cond_type_is_ptr { '->' } else { '.' }
g.writeln('for (int $i = 0; $i < ${atmp}->len; $i++) {') g.writeln('for (int $i = 0; $i < ${atmp}${op_field}len; $i++) {')
} else { if it.val_var != '_' {
g.writeln('for (int $i = 0; $i < ${atmp}.len; $i++) {') g.writeln('\t$styp $it.val_var = (($styp*)${atmp}${op_field}data)[$i];')
}
if cond_type_is_ptr {
g.writeln('\t$styp $it.val_var = (($styp*)${atmp}->data)[$i];')
} else {
g.writeln('\t$styp $it.val_var = (($styp*)${atmp}.data)[$i];')
} }
g.stmts(it.stmts) g.stmts(it.stmts)
g.writeln('}') g.writeln('}')
@ -628,21 +625,23 @@ fn (mut g Gen) for_in(it ast.ForInStmt) {
val_styp := g.typ(it.val_type) val_styp := g.typ(it.val_type)
keys_tmp := 'keys_' + g.new_tmp_var() keys_tmp := 'keys_' + g.new_tmp_var()
idx := g.new_tmp_var() idx := g.new_tmp_var()
key := if it.key_var == '' { g.new_tmp_var() } else { it.key_var } key := if it.key_var in ['', '_'] { g.new_tmp_var() } else { it.key_var }
zero := g.type_default(it.val_type) zero := g.type_default(it.val_type)
g.write('array_$key_styp $keys_tmp = map_keys(&') g.write('array_$key_styp $keys_tmp = map_keys(&')
g.expr(it.cond) g.expr(it.cond)
g.writeln(');') g.writeln(');')
g.writeln('for (int $idx = 0; $idx < ${keys_tmp}.len; $idx++) {') g.writeln('for (int $idx = 0; $idx < ${keys_tmp}.len; $idx++) {')
g.writeln('\t$key_styp $key = (($key_styp*)${keys_tmp}.data)[$idx];') g.writeln('\t$key_styp $key = (($key_styp*)${keys_tmp}.data)[$idx];')
if it.val_var != '_' {
g.write('\t$val_styp $it.val_var = (*($val_styp*)map_get3(') g.write('\t$val_styp $it.val_var = (*($val_styp*)map_get3(')
g.expr(it.cond) g.expr(it.cond)
g.writeln(', $key, &($val_styp[]){ $zero }));') g.writeln(', $key, &($val_styp[]){ $zero }));')
}
g.stmts(it.stmts) g.stmts(it.stmts)
g.writeln('}') g.writeln('}')
} else if table.type_is(it.cond_type, .variadic) { } else if table.type_is(it.cond_type, .variadic) {
g.writeln('// FOR IN cond_type/variadic') g.writeln('// FOR IN cond_type/variadic')
i := if it.key_var == '' { g.new_tmp_var() } else { it.key_var } i := if it.key_var in ['', '_'] { g.new_tmp_var() } else { it.key_var }
styp := g.typ(it.cond_type) styp := g.typ(it.cond_type)
g.write('for (int $i = 0; $i < ') g.write('for (int $i = 0; $i < ')
g.expr(it.cond) g.expr(it.cond)
@ -653,13 +652,15 @@ fn (mut g Gen) for_in(it ast.ForInStmt) {
g.stmts(it.stmts) g.stmts(it.stmts)
g.writeln('}') g.writeln('}')
} else if it.kind == .string { } else if it.kind == .string {
i := if it.key_var == '' { g.new_tmp_var() } else { it.key_var } i := if it.key_var in ['', '_'] { g.new_tmp_var() } else { it.key_var }
g.write('for (int $i = 0; $i < ') g.write('for (int $i = 0; $i < ')
g.expr(it.cond) g.expr(it.cond)
g.writeln('.len; $i++) {') g.writeln('.len; $i++) {')
if it.val_var != '_' {
g.write('byte $it.val_var = ') g.write('byte $it.val_var = ')
g.expr(it.cond) g.expr(it.cond)
g.writeln('.str[$i];') g.writeln('.str[$i];')
}
g.stmts(it.stmts) g.stmts(it.stmts)
g.writeln('}') g.writeln('}')
} }

View File

@ -0,0 +1,260 @@
fn test_assign() {
_ = 123
}
fn fn_with_blank_param(_ int) {
_ = 456
}
fn test_fn_with_blank_param() {
fn_with_blank_param(321)
}
fn test_for_in_range() {
for _ in 1 .. 10 {
assert true
}
}
fn test_nested_range() {
for _ in 1 .. 10 {
for _ in 1 .. 10 {
assert true
}
}
}
fn test_for_in_array_simple() {
for _ in [1, 2, 3] {
assert true
}
}
fn test_for_in_array_key() {
mut i := 1
for _, v in [1, 2, 3] {
assert v == i
i++
}
}
fn test_for_in_array_val() {
mut j := 0
for i, _ in [3, 4, 5] {
assert i == j
j++
}
}
fn test_for_in_array_both() {
for _, _ in [1, 2, 3] {
assert true
}
}
fn test_nested_for_in_array_simple() {
for _ in [1, 2, 3] {
for _ in [1, 2, 3] {
assert true
}
}
}
fn test_nested_for_in_array_key() {
for _, v in [1, 2, 3] {
for _, w in [1, 2, 3] {
assert true
}
}
}
fn test_nested_for_in_array_val() {
for i, _ in [1, 2, 3] {
for j, _ in [1, 2, 3] {
assert true
}
}
}
fn test_nested_for_in_array_both() {
for _, _ in [1, 2, 3] {
for _, _ in [1, 2, 3] {
assert true
}
}
}
const (
m = {
'key': 'value'
}
)
fn test_for_in_map_key() {
for _, v in m {
assert v == 'value'
}
}
fn test_for_in_map_val() {
for i, _ in m {
assert i == 'key'
}
}
fn test_for_in_map_both() {
for _, _ in m {
assert true
}
}
fn test_nested_for_in_map_key() {
for _, v in m {
assert v == 'value'
for _, w in m {
assert w == 'value'
}
}
}
fn test_nested_for_in_map_val() {
for i, _ in m {
assert i == 'key'
for j, _ in m {
assert j == 'key'
}
}
}
fn test_nested_for_in_map_both() {
for _, _ in m {
for _, _ in m {
assert true
}
}
}
fn fn_for_in_variadic_args_simple(arr ...string) {
for _ in arr {
assert true
}
}
fn fn_for_in_variadic_args_key(arr ...string) {
for _, v in arr {
assert true
}
}
fn fn_for_in_variadic_args_val(arr ...string) {
for i, _ in arr {
assert true
}
}
fn fn_for_in_variadic_args_both(arr ...string) {
for _, _ in arr {
assert true
}
}
fn fn_nested_for_in_variadic_args(arr ...string) {
for _ in arr {
for _ in arr {
assert true
}
}
}
fn fn_nested_for_in_variadic_args_key(arr ...string) {
for _, v in arr {
for _, w in arr {
assert true
}
}
}
fn fn_nested_for_in_variadic_args_val(arr ...string) {
for i, _ in arr {
for j, _ in arr {
assert true
}
}
}
fn fn_nested_for_in_variadic_args_both(arr ...string) {
for _, _ in arr {
for _, _ in arr {
assert true
}
}
}
fn test_for_in_variadic_args() {
fn_for_in_variadic_args_simple('a', 'b', 'c')
fn_for_in_variadic_args_key('a', 'b', 'c')
fn_for_in_variadic_args_val('a', 'b', 'c')
fn_for_in_variadic_args_both('a', 'b', 'c')
fn_nested_for_in_variadic_args('a', 'b', 'c')
fn_nested_for_in_variadic_args_key('a', 'b', 'c')
fn_nested_for_in_variadic_args_val('a', 'b', 'c')
fn_nested_for_in_variadic_args_both('a', 'b', 'c')
}
fn test_for_in_string_simple() {
for _ in 'abcd' {
assert true
}
}
fn test_for_in_string_key() {
for _, v in 'a' {
assert v == `a`
}
}
fn test_for_in_string_val() {
for i, _ in 'a' {
assert i == 0
}
}
fn test_for_in_string_both() {
for _, _ in 'abcd' {
assert true
}
}
fn test_nested_for_in_string_simple() {
for _ in 'abcd' {
for _ in 'abcd' {
assert true
}
}
}
fn test_nested_for_in_string_key() {
for _, v in 'a' {
assert v == `a`
for _, w in 'a' {
assert w == `a`
}
}
}
fn test_nested_for_in_string_val() {
for i, _ in 'a' {
assert i == 0
for j, _ in 'a' {
assert j == 0
}
}
}
fn test_nested_for_in_string_both() {
for _, _ in 'abcd' {
for _, _ in 'abcd' {
assert true
}
}
}