short struct init syntax
parent
d9af06f2ad
commit
39434155f8
|
@ -76,6 +76,14 @@ pub fn (c mut Checker) struct_init(struct_init mut ast.StructInit) table.Type {
|
|||
// c.error('unknown struct: $struct_init.typ.typ.name', struct_init.pos)
|
||||
// panic('')
|
||||
// }
|
||||
if struct_init.typ == table.void_type {
|
||||
// Short syntax `({foo: bar})`
|
||||
if c.expected_type == table.void_type {
|
||||
c.error('unexpected short struct syntax', struct_init.pos)
|
||||
return table.void_type
|
||||
}
|
||||
struct_init.typ = c.expected_type
|
||||
}
|
||||
typ_sym := c.table.get_type_symbol(struct_init.typ)
|
||||
// println('check struct $typ_sym.name')
|
||||
match typ_sym.kind {
|
||||
|
|
|
@ -548,12 +548,14 @@ pub fn (p mut Parser) parse_ident(is_c bool) ast.Ident {
|
|||
return ident
|
||||
}
|
||||
|
||||
fn (p mut Parser) struct_init() ast.StructInit {
|
||||
typ := p.parse_type()
|
||||
fn (p mut Parser) struct_init(short_syntax bool) ast.StructInit {
|
||||
typ := if short_syntax { table.void_type } else { p.parse_type() }
|
||||
p.expr_mod = ''
|
||||
// sym := p.table.get_type_symbol(typ)
|
||||
// p.warn('struct init typ=$sym.name')
|
||||
p.check(.lcbr)
|
||||
if !short_syntax {
|
||||
p.check(.lcbr)
|
||||
}
|
||||
mut field_names := []string
|
||||
mut exprs := []ast.Expr
|
||||
mut i := 0
|
||||
|
@ -585,7 +587,9 @@ fn (p mut Parser) struct_init() ast.StructInit {
|
|||
fields: field_names
|
||||
pos: p.tok.position()
|
||||
}
|
||||
p.check(.rcbr)
|
||||
if !short_syntax {
|
||||
p.check(.rcbr)
|
||||
}
|
||||
return node
|
||||
}
|
||||
|
||||
|
@ -674,7 +678,7 @@ pub fn (p mut Parser) name_expr() ast.Expr {
|
|||
//
|
||||
{
|
||||
// || p.table.known_type(p.tok.lit)) {
|
||||
return p.struct_init()
|
||||
return p.struct_init(false) // short_syntax: false
|
||||
}
|
||||
else if p.peek_tok.kind == .dot && (p.tok.lit[0].is_capital() && !known_var) {
|
||||
// `Color.green`
|
||||
|
@ -798,53 +802,17 @@ pub fn (p mut Parser) expr(precedence int) ast.Expr {
|
|||
.lcbr {
|
||||
p.next()
|
||||
if p.tok.kind == .string {
|
||||
mut keys := []ast.Expr
|
||||
mut vals := []ast.Expr
|
||||
for p.tok.kind != .rcbr && p.tok.kind != .eof {
|
||||
// p.check(.str)
|
||||
key := p.expr(0)
|
||||
keys << key
|
||||
p.check(.colon)
|
||||
val := p.expr(0)
|
||||
vals << val
|
||||
if p.tok.kind == .comma {
|
||||
p.next()
|
||||
}
|
||||
}
|
||||
node = ast.MapInit{
|
||||
keys: keys
|
||||
vals: vals
|
||||
pos: p.tok.position()
|
||||
}
|
||||
node = p.map_init()
|
||||
}
|
||||
else {
|
||||
name := p.check_name()
|
||||
var := p.scope.find_var(name) or {
|
||||
p.error('unknown variable `$name`')
|
||||
return node
|
||||
if p.peek_tok.kind == .pipe {
|
||||
node = p.assoc()
|
||||
}
|
||||
// println('assoc var $name typ=$var.typ')
|
||||
mut fields := []string
|
||||
mut vals := []ast.Expr
|
||||
p.check(.pipe)
|
||||
for {
|
||||
fields << p.check_name()
|
||||
p.check(.colon)
|
||||
expr := p.expr(0)
|
||||
vals << expr
|
||||
if p.tok.kind == .comma {
|
||||
p.check(.comma)
|
||||
}
|
||||
if p.tok.kind == .rcbr {
|
||||
break
|
||||
}
|
||||
else if p.peek_tok.kind == .colon || p.tok.kind == .rcbr {
|
||||
node = p.struct_init(true) // short_syntax: true
|
||||
}
|
||||
node = ast.Assoc{
|
||||
var_name: name
|
||||
fields: fields
|
||||
exprs: vals
|
||||
pos: p.tok.position()
|
||||
typ: var.typ
|
||||
else {
|
||||
p.error('unexpected {')
|
||||
}
|
||||
}
|
||||
p.check(.rcbr)
|
||||
|
@ -1374,6 +1342,28 @@ fn (p mut Parser) array_init() ast.ArrayInit {
|
|||
}
|
||||
}
|
||||
|
||||
fn (p mut Parser) map_init() ast.MapInit {
|
||||
pos := p.tok.position()
|
||||
mut keys := []ast.Expr
|
||||
mut vals := []ast.Expr
|
||||
for p.tok.kind != .rcbr && p.tok.kind != .eof {
|
||||
// p.check(.str)
|
||||
key := p.expr(0)
|
||||
keys << key
|
||||
p.check(.colon)
|
||||
val := p.expr(0)
|
||||
vals << val
|
||||
if p.tok.kind == .comma {
|
||||
p.next()
|
||||
}
|
||||
}
|
||||
return ast.MapInit{
|
||||
keys: keys
|
||||
vals: vals
|
||||
pos: pos
|
||||
}
|
||||
}
|
||||
|
||||
fn (p mut Parser) parse_number_literal() ast.Expr {
|
||||
lit := p.tok.lit
|
||||
mut node := ast.Expr{}
|
||||
|
@ -1943,6 +1933,38 @@ fn (p mut Parser) type_decl() ast.TypeDecl {
|
|||
}
|
||||
}
|
||||
|
||||
fn (p mut Parser) assoc() ast.Assoc{
|
||||
var_name := p.check_name()
|
||||
pos := p.tok.position()
|
||||
var := p.scope.find_var(var_name) or {
|
||||
p.error('unknown variable `$var_name`')
|
||||
return ast.Assoc{}
|
||||
}
|
||||
// println('assoc var $name typ=$var.typ')
|
||||
mut fields := []string
|
||||
mut vals := []ast.Expr
|
||||
p.check(.pipe)
|
||||
for {
|
||||
fields << p.check_name()
|
||||
p.check(.colon)
|
||||
expr := p.expr(0)
|
||||
vals << expr
|
||||
if p.tok.kind == .comma {
|
||||
p.check(.comma)
|
||||
}
|
||||
if p.tok.kind == .rcbr {
|
||||
break
|
||||
}
|
||||
}
|
||||
return ast.Assoc{
|
||||
var_name: var_name
|
||||
fields: fields
|
||||
exprs: vals
|
||||
pos: pos
|
||||
typ: var.typ
|
||||
}
|
||||
}
|
||||
|
||||
fn (p &Parser) new_true_expr() ast.Expr {
|
||||
return ast.BoolLiteral{
|
||||
val: true
|
||||
|
|
|
@ -236,7 +236,6 @@ fn foo_config(c Config) {}
|
|||
fn foo2(u User) {}
|
||||
|
||||
fn test_config() {
|
||||
/*
|
||||
foo_config({
|
||||
n: 10
|
||||
def: 20
|
||||
|
@ -245,5 +244,4 @@ fn test_config() {
|
|||
foo2({
|
||||
name: 'Peter'
|
||||
})
|
||||
*/
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue