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() 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 { fn (p &Parser) find_var(name string) ?Var {
for i in 0 .. p.var_idx { for i in 0 .. p.var_idx {
if p.local_vars[i].name == name { if p.local_vars[i].name == name {

View File

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

View File

@ -134,3 +134,23 @@ fn test_default_vals() {
assert d2.b == 20 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
}