parser: allow constant usage in assoc

pull/2895/head
ʇʞʌp 2019-11-25 19:41:56 -08:00 committed by Alexander Medvednikov
parent 5c217b9e61
commit 81d552038c
3 changed files with 43 additions and 7 deletions

View File

@ -70,6 +70,20 @@ fn (a []TypeInst) str() string {
return r.str()
}
fn (p mut Parser) find_var_or_const(name string) ?Var {
if p.known_var(name) {
return p.find_var(name)
}
if p.table.known_const(name) {
return p.table.find_const(name)
}
modname := p.prepend_mod(name)
if p.table.known_const(modname) {
return p.table.find_const(modname)
}
return none
}
fn (p &Parser) find_var(name string) ?Var {
for i in 0 .. p.var_idx {
if p.local_vars[i].name == name {

View File

@ -2150,11 +2150,13 @@ fn (p mut Parser) assoc() string {
// println('assoc()')
p.next()
name := p.check_name()
var := p.find_var(name) or {
var := p.find_var_or_const(name) or {
p.error('unknown variable `$name`')
exit(1)
}
p.mark_var_used(var)
if !var.is_const {
p.mark_var_used(var)
}
p.check(.pipe)
p.gen('($var.typ){')
mut fields := []string// track the fields user is setting, the rest will be copied from the old object
@ -2177,7 +2179,7 @@ fn (p mut Parser) assoc() string {
if f in fields {
continue
}
p.gen('.$f = ${name}.$f,')
p.gen('.$f = ${var.name}.$f,')
}
p.check(.rcbr)
p.gen('}')

View File

@ -111,19 +111,19 @@ fn test_reserved_keywords() {
struct User2 {
mut:
name string
}
}
fn test_mutable_fields() {
mut u := User2{}
u.name = 'Peter'
assert u.name == 'Peter'
}
}
struct Def {
a int
b int = 7
}
}
fn test_default_vals() {
d := Def{}
@ -132,5 +132,25 @@ fn test_default_vals() {
d2 := Def{10, 20}
assert d2.a == 10
assert d2.b == 20
}
}
fn test_assoc_with_vars() {
def2 := Def { a: 12 }
merged := { def2 | a: 42 }
assert merged.a == 42
assert merged.b == 7
}
const (
const_def = Def { a: 100 }
)
fn test_assoc_with_constants() {
merged := { const_def | a: 42 }
assert merged.a == 42
assert merged.b == 7
again := { const_def | b: 22 }
assert again.a == 100
assert again.b == 22
}