parser: map or block; checker: require ref field init
parent
3a86f27b9f
commit
1f74f83bc6
|
@ -404,9 +404,9 @@ fn test_mut_map_with_relation_op_in_fn() {
|
|||
|
||||
fn test_map_str_after_delete() {
|
||||
mut m := {
|
||||
'first': 1
|
||||
'first': 1
|
||||
'second': 2
|
||||
'third': 3
|
||||
'third': 3
|
||||
}
|
||||
osm := '$m'
|
||||
m.delete('second')
|
||||
|
@ -429,7 +429,7 @@ fn test_modify_map_value() {
|
|||
|
||||
fn test_map_clone() {
|
||||
mut nums := {
|
||||
'foo': 1,
|
||||
'foo': 1
|
||||
'bar': 2
|
||||
}
|
||||
mut nums2 := nums.clone()
|
||||
|
@ -442,14 +442,23 @@ fn test_map_clone() {
|
|||
}
|
||||
|
||||
struct MValue {
|
||||
name string
|
||||
misc map[string]string
|
||||
name string
|
||||
misc map[string]string
|
||||
}
|
||||
|
||||
fn test_map_default_zero() {
|
||||
m := map[string]MValue{}
|
||||
v := m['unknown']
|
||||
x := v.misc['x']
|
||||
println(x)
|
||||
m := map[string]MValue{}
|
||||
v := m['unknown']
|
||||
x := v.misc['x']
|
||||
println(x)
|
||||
assert x == ''
|
||||
}
|
||||
|
||||
fn test_map_or() {
|
||||
m := {
|
||||
'first': 1
|
||||
'second': 2
|
||||
'third': 3
|
||||
}
|
||||
// num := m['first'] or { return }
|
||||
}
|
||||
|
|
|
@ -524,6 +524,7 @@ pub:
|
|||
pos token.Position
|
||||
left Expr
|
||||
index Expr // [0], RangeExpr [start..end] or map[key]
|
||||
or_expr OrExpr
|
||||
pub mut:
|
||||
left_type table.Type // array, map, fixed array
|
||||
is_setter bool
|
||||
|
|
|
@ -591,7 +591,7 @@ pub fn (mut c Checker) struct_init(mut struct_init ast.StructInit) table.Type {
|
|||
continue
|
||||
}
|
||||
if field.typ.is_ptr() && !c.pref.translated {
|
||||
c.warn('reference field `${type_sym.name}.$field.name` must be initialized',
|
||||
c.error('reference field `${type_sym.name}.$field.name` must be initialized',
|
||||
struct_init.pos)
|
||||
}
|
||||
// Check for `[required]` struct attr
|
||||
|
|
|
@ -54,7 +54,7 @@ pub fn (mut p Parser) call_expr(language table.Language, mod string) ast.CallExp
|
|||
p.next()
|
||||
}
|
||||
pos := first_pos.extend(last_pos)
|
||||
mut or_stmts := []ast.Stmt{}
|
||||
mut or_stmts := []ast.Stmt{} // TODO remove unnecessary allocations by just using .absent
|
||||
mut or_pos := p.tok.position()
|
||||
if p.tok.kind == .key_orelse {
|
||||
// `foo() or {}``
|
||||
|
|
|
@ -1326,10 +1326,34 @@ fn (mut p Parser) index_expr(left ast.Expr) ast.IndexExpr {
|
|||
// [expr]
|
||||
pos := start_pos.extend(p.tok.position())
|
||||
p.check(.rsbr)
|
||||
// a[i] or { ... }
|
||||
if p.tok.kind == .key_orelse {
|
||||
was_inside_or_expr := p.inside_or_expr
|
||||
mut or_pos := p.tok.position()
|
||||
p.next()
|
||||
p.open_scope()
|
||||
or_stmts := p.parse_block_no_scope(false)
|
||||
or_pos = or_pos.extend(p.prev_tok.position())
|
||||
p.close_scope()
|
||||
p.inside_or_expr = was_inside_or_expr
|
||||
return ast.IndexExpr{
|
||||
left: left
|
||||
index: expr
|
||||
pos: pos
|
||||
or_expr: ast.OrExpr{
|
||||
kind: .block
|
||||
stmts: or_stmts
|
||||
pos: or_pos
|
||||
}
|
||||
}
|
||||
}
|
||||
return ast.IndexExpr{
|
||||
left: left
|
||||
index: expr
|
||||
pos: pos
|
||||
or_expr: ast.OrExpr{
|
||||
kind: .absent
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -244,7 +244,7 @@ pub fn (mut p Parser) expr(precedence int) ast.Expr {
|
|||
else {
|
||||
if p.tok.kind != .eof {
|
||||
// eof should be handled where it happens
|
||||
p.error_with_pos('invalid expression: unexpected $p.tok.kind.str() token',
|
||||
p.error_with_pos('invalid expression: unexpected `$p.tok.kind.str()` token',
|
||||
p.tok.position())
|
||||
return ast.Expr{}
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue