implement-modules #43
@ -37,17 +37,9 @@ func (this *Parser) expect (allowed ...lexer.TokenKind) (lexer.Token, error) {
|
|||||||
token, err := this.next()
|
token, err := this.next()
|
||||||
if err != nil { return lexer.Token { }, err }
|
if err != nil { return lexer.Token { }, err }
|
||||||
if !token.Is(allowed...) {
|
if !token.Is(allowed...) {
|
||||||
message := "expected"
|
return lexer.Token { }, errors.Errorf (
|
||||||
for index, token := range allowed {
|
token.Position, "expected %s",
|
||||||
if index > 0 && len(allowed) > 2 {
|
commaList(allowed...))
|
||||||
message += ", "
|
|
||||||
}
|
|
||||||
if index == len(allowed) - 1 {
|
|
||||||
message += " or "
|
|
||||||
}
|
|
||||||
message += fmt.Sprintf(" %v", token)
|
|
||||||
}
|
|
||||||
return lexer.Token { }, errors.Errorf(token.Position, message)
|
|
||||||
}
|
}
|
||||||
return token, nil
|
return token, nil
|
||||||
}
|
}
|
||||||
@ -59,11 +51,35 @@ func (this *Parser) expectDesc (description string, allowed ...lexer.TokenKind)
|
|||||||
token, err := this.next()
|
token, err := this.next()
|
||||||
if err != nil { return lexer.Token { }, err }
|
if err != nil { return lexer.Token { }, err }
|
||||||
if !token.Is(allowed...) {
|
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
|
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) {
|
func (this *Parser) next () (lexer.Token, error) {
|
||||||
token, err := this.lexer.Next()
|
token, err := this.lexer.Next()
|
||||||
if err != nil { return token, err }
|
if err != nil { return token, err }
|
||||||
@ -71,16 +87,6 @@ func (this *Parser) next () (lexer.Token, error) {
|
|||||||
return token, nil
|
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 {
|
func (this *Parser) parse () error {
|
||||||
for {
|
for {
|
||||||
token, err := this.expectDesc (
|
token, err := this.expectDesc (
|
||||||
@ -94,3 +100,27 @@ func (this *Parser) parse () error {
|
|||||||
}
|
}
|
||||||
return nil
|
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