diff --git a/parser.go b/parser.go index 9868dec..f23a009 100644 --- a/parser.go +++ b/parser.go @@ -72,11 +72,11 @@ func (self *parser) parseFuncDef(scanner *scanner) (tree *term, err error) { if subTree.root.symbol() == SymIdentifier { args = append(args, subTree.root) } else { - err = tk.Errorf("exptected identifier, got %q", subTree.root) + err = tk.ErrorExpectedGotString("param-name", subTree.root.String()) } } else if itemExpected { prev := scanner.Previous() - err = prev.Errorf("expected function parameter, got %q", prev) + err = prev.ErrorExpectedGot("function-param", prev) break } } else { @@ -87,18 +87,20 @@ func (self *parser) parseFuncDef(scanner *scanner) (tree *term, err error) { } if err == nil && lastSym != SymClosedRound { - err = tk.Errorf("unterminated function parameters list") + err = tk.ErrorExpectedGot(")") } if err == nil { tk = scanner.Next() if tk.Sym == SymOpenBrace { body, err = self.parseGeneral(scanner, true, true, SymClosedBrace) + } else { + err = tk.ErrorExpectedGot("{") } } if err == nil { // TODO Check arguments if scanner.Previous().Sym != SymClosedBrace { - err = scanner.Previous().Errorf("not properly terminated function body") + err = scanner.Previous().ErrorExpectedGot("}") } else { tk = scanner.makeValueToken(SymExpression, "", body) tree = newFuncDefTerm(tk, args) @@ -118,7 +120,7 @@ func (self *parser) parseList(scanner *scanner, allowVarRef bool) (subtree *term args = append(args, subTree.root) } else if itemExpected { prev := scanner.Previous() - err = prev.Errorf("expected list item, got %q", prev) + err = prev.ErrorExpectedGot("list-item") break } } else { @@ -130,7 +132,7 @@ func (self *parser) parseList(scanner *scanner, allowVarRef bool) (subtree *term if err == nil { // TODO Check arguments if lastSym != SymClosedSquare { - err = scanner.Previous().Errorf("unterminate items list") + err = scanner.Previous().ErrorExpectedGot("]") } else { subtree = newListTerm(args) } @@ -150,7 +152,7 @@ func (self *parser) parseIterDef(scanner *scanner, allowVarRef bool) (subtree *t args = append(args, subTree.root) } else if itemExpected { prev := scanner.Previous() - err = prev.Errorf("expected iterator argument, got %q", prev) + err = prev.ErrorExpectedGot("iterator-param") break } } else { @@ -162,7 +164,7 @@ func (self *parser) parseIterDef(scanner *scanner, allowVarRef bool) (subtree *t if err == nil { // TODO Check arguments if lastSym != SymClosedRound { - err = scanner.Previous().Errorf("unterminate iterator param list") + err = scanner.Previous().ErrorExpectedGot(")") } else { subtree = newIteratorTerm(tk, args) } @@ -182,12 +184,13 @@ func (self *parser) parseDictKey(scanner *scanner, allowVarRef bool) (key any, e if tk.Sym == SymInteger || tk.Sym == SymString { tkSep := scanner.Next() if tkSep.Sym != SymColon { - err = tkSep.Errorf("expected \":\", got %q", tkSep) + err = tkSep.ErrorExpectedGot(":") } else { key = tk.Value } } else { - err = tk.Errorf("expected dictionary key or closed brace, got %q", tk) + // err = tk.Errorf("expected dictionary key or closed brace, got %q", tk) + err = tk.ErrorExpectedGot("dictionary-key or }") } return } @@ -205,7 +208,7 @@ func (self *parser) parseDictionary(scanner *scanner, allowVarRef bool) (subtree tk := scanner.Previous() lastSym = tk.Sym if itemExpected { - err = tk.Errorf("expected dictionary key, got %q", tk) + err = tk.ErrorExpectedGot("dictionary-key") } break } @@ -214,7 +217,7 @@ func (self *parser) parseDictionary(scanner *scanner, allowVarRef bool) (subtree args[key] = subTree.root } else if key != nil { prev := scanner.Previous() - err = prev.Errorf("expected dictionary value, got %q", prev) + err = prev.ErrorExpectedGot("dictionary-value") break } } else { @@ -226,7 +229,7 @@ func (self *parser) parseDictionary(scanner *scanner, allowVarRef bool) (subtree if err == nil { // TODO Check arguments if lastSym != SymClosedBrace { - err = scanner.Previous().Errorf("unterminated dictionary") + err = scanner.Previous().ErrorExpectedGot("}") } else { subtree = newDictTerm(args) } @@ -260,7 +263,7 @@ func (self *parser) parseSelectorCase(scanner *scanner, allowVarRef bool, defaul return } } else { - err = tk.Errorf("selector-case expected, got %q", tk.source) + err = tk.ErrorExpectedGot("{") } if err == nil { diff --git a/scanner.go b/scanner.go index 8a6ba93..bc6d8ef 100644 --- a/scanner.go +++ b/scanner.go @@ -160,6 +160,12 @@ func (self *scanner) fetchNextToken() (tk *Token) { //} else if next == '/' { if next, _ := self.peek(); next == '/' { tk = self.moveOn(SymDotSlash, ch, next) + } else if next == '.' { + if next1, _ := self.peek(); next1 == '.' { + tk = self.moveOn(SymTripleDot, ch, next, next1) + } else { + tk = self.moveOn(SymDoubleDot, ch, next) + } } else { tk = self.makeToken(SymDot, ch) } diff --git a/symbol.go b/symbol.go index 0ccf089..7c930a5 100644 --- a/symbol.go +++ b/symbol.go @@ -65,6 +65,8 @@ const ( SymDollarRound // 54: '$(' SymOpenClosedRound // 55: '()' SymDoubleDollar // 56: '$$' + SymDoubleDot // 57: '..' + SymTripleDot // 58: '...' SymChangeSign SymUnchangeSign SymIdentifier diff --git a/token.go b/token.go index c515e35..2fadb27 100644 --- a/token.go +++ b/token.go @@ -46,7 +46,7 @@ func NewValueToken(row, col int, sym Symbol, source string, value any) *Token { func NewErrorToken(row, col int, err error) *Token { if err == io.EOF { - return NewToken(row, col, SymEos, "") + return NewToken(row, col, SymEos, "") } return NewValueToken(row, col, SymError, fmt.Sprintf("[%d:%d]", row, col), err) } @@ -81,3 +81,13 @@ func (self *Token) Errors(msg string) (err error) { err = fmt.Errorf("[%d:%d] %v", self.row, self.col, msg) return } + +func (self *Token) ErrorExpectedGot(symbol string) (err error) { + err = fmt.Errorf("[%d:%d] expected %q, got %q", self.row, self.col, symbol, self) + return +} + +func (self *Token) ErrorExpectedGotString(symbol, got string) (err error) { + err = fmt.Errorf("[%d:%d] expected %q, got %q", self.row, self.col, symbol, got) + return +}