implement-modules #43
@ -37,17 +37,9 @@ func (this *Parser) expect (allowed ...lexer.TokenKind) (lexer.Token, error) {
|
||||
token, err := this.next()
|
||||
if err != nil { return lexer.Token { }, err }
|
||||
if !token.Is(allowed...) {
|
||||
message := "expected"
|
||||
for index, token := range allowed {
|
||||
if index > 0 && len(allowed) > 2 {
|
||||
message += ", "
|
||||
}
|
||||
if index == len(allowed) - 1 {
|
||||
message += " or "
|
||||
}
|
||||
message += fmt.Sprintf(" %v", token)
|
||||
}
|
||||
return lexer.Token { }, errors.Errorf(token.Position, message)
|
||||
return lexer.Token { }, errors.Errorf (
|
||||
token.Position, "expected %s",
|
||||
commaList(allowed...))
|
||||
}
|
||||
return token, nil
|
||||
}
|
||||
@ -59,11 +51,35 @@ func (this *Parser) expectDesc (description string, allowed ...lexer.TokenKind)
|
||||
token, err := this.next()
|
||||
if err != nil { return lexer.Token { }, err }
|
||||
if !token.Is(allowed...) {
|
||||
return lexer.Token { }, errors.Errorf(token.Position, "expected %s", description)
|
||||
return lexer.Token { }, errors.Errorf (
|
||||
token.Position, "expected %s",
|
||||
description)
|
||||
}
|
||||
return token, nil
|
||||
}
|
||||
|
||||
// expectValue returns an error if the current token's value does not match the
|
||||
// allowed values.
|
||||
func (this *Parser) expectValue (allowed ...string) error {
|
||||
if !this.token.ValueIs(allowed...) {
|
||||
return errors.Errorf (
|
||||
this.token.Position, "expected %s",
|
||||
commaList(allowed))
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// expectValueDesc is like expectValue, but the expected value(s) are described
|
||||
// manually.
|
||||
func (this *Parser) expectValueDesc (description string, allowed ...string) error {
|
||||
if !this.token.ValueIs(allowed...) {
|
||||
return errors.Errorf (
|
||||
this.token.Position, "expected %s",
|
||||
description)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (this *Parser) next () (lexer.Token, error) {
|
||||
token, err := this.lexer.Next()
|
||||
if err != nil { return token, err }
|
||||
@ -71,16 +87,6 @@ func (this *Parser) next () (lexer.Token, error) {
|
||||
return token, nil
|
||||
}
|
||||
|
||||
func prependCopy[ELEMENT any] (item ELEMENT, array []ELEMENT) []ELEMENT {
|
||||
return append([]ELEMENT { item }, array...)
|
||||
}
|
||||
|
||||
func appendCopy[ELEMENT any] (array []ELEMENT, items ...ELEMENT) []ELEMENT {
|
||||
newArray := make([]ELEMENT, len(array) + len(items))
|
||||
copy(newArray[copy(newArray, array):], items)
|
||||
return array
|
||||
}
|
||||
|
||||
func (this *Parser) parse () error {
|
||||
for {
|
||||
token, err := this.expectDesc (
|
||||
@ -94,3 +100,27 @@ func (this *Parser) parse () error {
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func commaList[ELEMENT any] (items ...ELEMENT) string {
|
||||
list := ""
|
||||
for index, item := range items {
|
||||
if index > 0 && len(items) > 2 {
|
||||
list += ", "
|
||||
}
|
||||
if index == len(items) - 1 {
|
||||
list += " or "
|
||||
}
|
||||
list += fmt.Sprintf("%v", item)
|
||||
}
|
||||
return list
|
||||
}
|
||||
|
||||
func prependCopy[ELEMENT any] (item ELEMENT, array []ELEMENT) []ELEMENT {
|
||||
return append([]ELEMENT { item }, array...)
|
||||
}
|
||||
|
||||
func appendCopy[ELEMENT any] (array []ELEMENT, items ...ELEMENT) []ELEMENT {
|
||||
newArray := make([]ELEMENT, len(array) + len(items))
|
||||
copy(newArray[copy(newArray, array):], items)
|
||||
return array
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user