Reworked array initialization value parsing

This commit is contained in:
Sasha Koshka 2022-08-17 11:30:17 -04:00
parent 7bb6582e01
commit 8c03aa880b
2 changed files with 117 additions and 70 deletions

View File

@ -60,104 +60,149 @@ func (parser *ParsingOperation) parseInitializationValues (
// check if line is indented one more than baseIndent // check if line is indented one more than baseIndent
if !parser.token.Is(lexer.TokenKindIndent) { return } if !parser.token.Is(lexer.TokenKindIndent) { return }
if parser.token.Value().(int) != baseIndent + 1 { return } if parser.token.Value().(int) != baseIndent + 1 { return }
err = parser.nextToken()
if err != nil { return }
initializationArgument.location = parser.token.Location() initializationArgument.location = parser.token.Location()
if parser.token.Is(lexer.TokenKindDot) { if parser.token.Is(lexer.TokenKindDot) {
var initializationValues ObjectInitializationValues var initializationValues ObjectInitializationValues
initializationValues, err = parser.parseObjectInitializationValues ( initializationValues, err = parser.parseObjectInitializationValues()
baseIndent + 1) initializationArgument.kind = ArgumentKindObjectInitializationValues
initializationArgument.kind = ArgumentKindObjectInitializationValues
initializationArgument.value = &initializationValues initializationArgument.value = &initializationValues
} else { } else {
var initializationValues ArrayInitializationValues var initializationValues ArrayInitializationValues
initializationValues, err = parser.parseArrayInitializationValues ( initializationValues, err = parser.parseArrayInitializationValues()
baseIndent + 1) initializationArgument.kind = ArgumentKindArrayInitializationValues
initializationArgument.kind = ArgumentKindArrayInitializationValues
initializationArgument.value = &initializationValues initializationArgument.value = &initializationValues
} }
return return
} }
// parseObjectInitializationValues parses a list of object initialization // parseObjectInitializationValues parses a list of object initialization
// values until the indentation level is not equal to indent. // values until the indentation level drops.
func (parser *ParsingOperation) parseObjectInitializationValues ( func (parser *ParsingOperation) parseObjectInitializationValues () (
indent int,
) (
values ObjectInitializationValues, values ObjectInitializationValues,
err error, err error,
) { ) {
values.attributes = make(map[string] Argument) // println("PARSING")
values.location = parser.token.Location() // defer println("DONE\n")
// values.attributes = make(map[string] Argument)
for { // values.location = parser.token.Location()
// get attribute name and value //
err = parser.nextToken(lexer.TokenKindName) // for {
if err != nil { return } // // get attribute name and value
name := parser.token.Value().(string) // err = parser.nextToken(lexer.TokenKindName)
// if err != nil { return }
_, exists := values.attributes[name] // name := parser.token.Value().(string)
if exists { // println(" name:", name)
err = parser.token.NewError ( //
"duplicate member \"" + name + "\" in object " + // _, exists := values.attributes[name]
"member initialization", // if exists {
file.ErrorKindError) // err = parser.token.NewError (
return // "duplicate member \"" + name + "\" in object " +
} // "member initialization",
// file.ErrorKindError)
err = parser.nextToken() // return
if err != nil { return } // }
var value Argument //
value, err = parser.parseArgument() // err = parser.nextToken()
// if err != nil { return }
// store in object //
values.attributes[name] = value // println(" parsing value argument")
// // parse value argument
// go onto the next line // var value Argument
err = parser.expect(lexer.TokenKindNewline) // if parser.token.Is(lexer.TokenKindNewline) {
if err != nil { return } // println(" is newline")
err = parser.nextToken() // // if there is none on this line, expect complex
if err != nil { return } // // initialization below
if !parser.token.Is(lexer.TokenKindIndent) { break } //
// TODO: if indent is greater, recurse instead // possibleErrorLocation := parser.token.Location()
if parser.token.Value().(int) != indent { break } // err = parser.nextToken(lexer.TokenKindIndent)
// if err != nil { return }
// the next line must start with a dot //
err = parser.nextToken(lexer.TokenKindDot) // value, err = parser.parseInitializationValues(indent)
if err != nil { return } // if err != nil { return }
} //
// // TODO: this doesn't seem to produce an error at the
// // correct location.
// if value.value == nil {
// err = possibleErrorLocation.NewError (
// "empty initialization value",
// file.ErrorKindError)
// return
// }
//
// } else {
// println(" is not newline")
// value, err = parser.parseArgument()
// if err != nil { return }
// err = parser.expect(lexer.TokenKindNewline)
// if err != nil { return }
// }
//
// // store in object
// values.attributes[name] = value
//
// // if indent drops, or does something strange, stop parsing
// err = parser.nextToken()
// if err != nil { return }
// if !parser.token.Is(lexer.TokenKindIndent) { break }
// if parser.token.Value().(int) != indent { break }
//
// // the next line must start with a dot
// err = parser.nextToken(lexer.TokenKindDot)
// if err != nil { return }
// }
return return
} }
// parseArrayInitializationValues parses a list of array initialization values // parseArrayInitializationValues parses a list of array initialization values
// until the indentation lexel is not equal to indent. // until the indentation lexel drops.
func (parser *ParsingOperation) parseArrayInitializationValues ( func (parser *ParsingOperation) parseArrayInitializationValues () (
indent int,
) (
values ArrayInitializationValues, values ArrayInitializationValues,
err error, err error,
) { ) {
values.location = parser.token.Location() baseIndent := 0
begin := true
for { for {
if parser.token.Is(lexer.TokenKindNewline) { // if there is no indent we can just stop parsing
err = parser.nextToken() if !parser.token.Is(lexer.TokenKindIndent) { break}
if err != nil { return } indent := parser.token.Value().(int)
if !parser.token.Is(lexer.TokenKindIndent) { break }
if parser.token.Value().(int) != indent { break }
err = parser.nextToken()
if err != nil { return }
}
var argument Argument if begin == true {
argument, err = parser.parseArgument() values.location = parser.token.Location()
baseIndent = indent
begin = false
}
// do not parse any further if the indent has changed
if indent != baseIndent { break }
// move on to the beginning of the line, which must contain
// arguments
err = parser.nextToken(validArgumentStartTokens...)
if err != nil { return } if err != nil { return }
values.values = append(values.values, argument)
for {
// stop parsing this line and go on to the next if a
// newline token is encountered
if parser.token.Is(lexer.TokenKindNewline) {
err = parser.nextToken()
if err != nil { return }
break
}
// otherwise, parse the argument
var argument Argument
argument, err = parser.parseArgument()
if err != nil { return }
values.values = append(values.values, argument)
}
} }
return return

View File

@ -88,10 +88,12 @@ type Phrase struct {
type ArgumentKind int type ArgumentKind int
const ( const (
ArgumentKindNil ArgumentKind = iota
// [name argument] // [name argument]
// [name argument argument] // [name argument argument]
// etc... // etc...
ArgumentKindPhrase ArgumentKind = iota ArgumentKindPhrase = iota
// {name} // {name}
ArgumentKindDereference ArgumentKindDereference