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