Dict literal now accepts expressions as keys. Key values are computed at evalutetion time and still must be integer or string
This commit is contained in:
@@ -257,24 +257,41 @@ func (parser *parser) parseIterDef(scanner *scan.Scanner, ctx parserContext) (su
|
||||
return
|
||||
}
|
||||
|
||||
func (parser *parser) parseDictKey(scanner *scan.Scanner) (key any, err error) {
|
||||
tk := parser.Next(scanner)
|
||||
if tk.Sym == scan.SymError {
|
||||
err = tk.Error()
|
||||
return
|
||||
}
|
||||
if tk.Sym == scan.SymClosedBrace || tk.Sym == scan.SymEos {
|
||||
return
|
||||
}
|
||||
if tk.Sym == scan.SymInteger || tk.Sym == scan.SymString {
|
||||
tkSep := parser.Next(scanner)
|
||||
if tkSep.Sym != scan.SymColon {
|
||||
// func (parser *parser) parseDictKey(scanner *scan.Scanner) (key any, err error) {
|
||||
// tk := parser.Next(scanner)
|
||||
// if tk.Sym == scan.SymError {
|
||||
// err = tk.Error()
|
||||
// return
|
||||
// }
|
||||
// if tk.Sym == scan.SymClosedBrace || tk.Sym == scan.SymEos {
|
||||
// return
|
||||
// }
|
||||
// if tk.Sym == scan.SymInteger || tk.Sym == scan.SymString || tk.Sym == scan.SymIdentifier {
|
||||
// tkSep := parser.Next(scanner)
|
||||
// if tkSep.Sym != scan.SymColon {
|
||||
// err = tkSep.ErrorExpectedGot(":")
|
||||
// } else {
|
||||
// key = tk.Value
|
||||
// }
|
||||
// } else {
|
||||
// err = tk.ErrorExpectedGot("dictionary-key or }")
|
||||
// }
|
||||
// return
|
||||
// }
|
||||
|
||||
func (parser *parser) parseDictKey(scanner *scan.Scanner) (key *scan.Term, err error) {
|
||||
var keyTree *scan.Ast
|
||||
if keyTree, err = parser.parseItem(scanner, parserNoFlags, scan.SymColon, scan.SymClosedBrace); err == nil {
|
||||
key = keyTree.Root()
|
||||
tkSep := scanner.Previous()
|
||||
sym := tkSep.Sym
|
||||
if sym == scan.SymClosedBrace || sym == scan.SymEos {
|
||||
if key != nil {
|
||||
err = tkSep.ErrorExpectedGot(":")
|
||||
}
|
||||
} else if sym != scan.SymColon {
|
||||
err = tkSep.ErrorExpectedGot(":")
|
||||
} else {
|
||||
key = tk.Value
|
||||
}
|
||||
} else {
|
||||
err = tk.ErrorExpectedGot("dictionary-key or }")
|
||||
}
|
||||
return
|
||||
}
|
||||
@@ -284,11 +301,11 @@ func (parser *parser) parseDictionary(scanner *scan.Scanner, ctx parserContext)
|
||||
lastSym := scan.SymUnknown
|
||||
itemExpected := false
|
||||
for lastSym != scan.SymClosedBrace && lastSym != scan.SymEos {
|
||||
var subTree *scan.Ast
|
||||
var valueTree *scan.Ast
|
||||
var key any
|
||||
if key, err = parser.parseDictKey(scanner); err != nil {
|
||||
break
|
||||
} else if key == nil {
|
||||
} else if key.(*scan.Term) == nil {
|
||||
tk := scanner.Previous()
|
||||
lastSym = tk.Sym
|
||||
if itemExpected {
|
||||
@@ -296,9 +313,9 @@ func (parser *parser) parseDictionary(scanner *scan.Scanner, ctx parserContext)
|
||||
}
|
||||
break
|
||||
}
|
||||
if subTree, err = parser.parseItem(scanner, ctx, scan.SymComma, scan.SymClosedBrace); err == nil {
|
||||
if subTree.Root() != nil {
|
||||
args[key] = subTree.Root()
|
||||
if valueTree, err = parser.parseItem(scanner, ctx, scan.SymComma, scan.SymClosedBrace); err == nil {
|
||||
if valueTree.Root() != nil {
|
||||
args[key] = valueTree.Root()
|
||||
} else /*if key != nil*/ {
|
||||
prev := scanner.Previous()
|
||||
err = prev.ErrorExpectedGot("dictionary-value")
|
||||
@@ -464,7 +481,7 @@ func (parser *parser) parseGeneral(scanner *scan.Scanner, ctx parserContext, ter
|
||||
selectorTerm = nil
|
||||
continue
|
||||
} else {
|
||||
err = tk.Errorf(`unexpected token %q, expected ",", "]", or ")"`, tk.Source())
|
||||
err = tk.ErrorExpectedOneOfGot(termSymbols...)
|
||||
break
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user