Selector operator, multi-operand, added

This commit is contained in:
2024-04-08 22:16:07 +02:00
parent f74e523617
commit d3f388f7e1
10 changed files with 263 additions and 34 deletions
+88 -8
View File
@@ -94,7 +94,7 @@ func (self *parser) parseFuncDef(scanner *scanner) (tree *term, err error) {
return
}
func (self *parser) parseList(scanner *scanner, allowVarRef bool) (tree *term, err error) {
func (self *parser) parseList(scanner *scanner, allowVarRef bool) (subtree *term, err error) {
args := make([]*term, 0)
lastSym := SymUnknown
for lastSym != SymClosedSquare && lastSym != SymEos {
@@ -113,21 +113,72 @@ func (self *parser) parseList(scanner *scanner, allowVarRef bool) (tree *term, e
if lastSym != SymClosedSquare {
err = scanner.Previous().Errorf("unterminate items list")
} else {
tree = newListTerm(args)
subtree = newListTerm(args)
}
}
return
}
func (self *parser) parse(scanner *scanner, termSymbols ...Symbol) (tree *ast, err error) {
return self.parseGeneral(scanner, true, false, termSymbols...)
func (self *parser) parseSelectorCase(scanner *scanner, allowVarRef bool, defaultCase bool) (caseTerm *term, err error) {
var filterList *term
var caseExpr *ast
tk := scanner.Next()
startRow := tk.row
startCol := tk.col
if tk.Sym == SymOpenSquare {
if defaultCase {
err = tk.Errorf("case list in default clause")
return
}
if filterList, err = self.parseList(scanner, allowVarRef); err != nil {
return
}
tk = scanner.Next()
startRow = tk.row
startCol = tk.col
} else if !defaultCase {
filterList = newListTerm(make([]*term, 0))
}
if tk.Sym == SymOpenBrace {
if caseExpr, err = self.parseGeneral(scanner, true, allowVarRef, SymClosedBrace); err != nil {
return
}
} else {
err = tk.Errorf("selector-case expected, got %q", tk.source)
}
if err == nil {
caseTerm = newSelectorCaseTerm(startRow, startCol, filterList, caseExpr)
}
return
}
func (self *parser) parseSelector(scanner *scanner, tree *ast, allowVarRef bool) (selectorTerm *term, err error) {
var caseTerm *term
tk := scanner.makeToken(SymSelector, '?')
if selectorTerm, err = tree.addToken2(tk); err != nil {
return
}
if caseTerm, err = self.parseSelectorCase(scanner, allowVarRef, false); err == nil {
selectorTerm.children = append(selectorTerm.children, caseTerm)
caseTerm.parent = selectorTerm
}
return
}
func (self *parser) parseItem(scanner *scanner, allowVarRef bool, termSymbols ...Symbol) (tree *ast, err error) {
return self.parseGeneral(scanner, false, allowVarRef, termSymbols...)
}
func (self *parser) Parse(scanner *scanner, termSymbols ...Symbol) (tree *ast, err error) {
return self.parseGeneral(scanner, true, false, termSymbols...)
}
func (self *parser) parseGeneral(scanner *scanner, allowForest bool, allowVarRef bool, termSymbols ...Symbol) (tree *ast, err error) {
var selectorTerm *term = nil
var currentTerm *term = nil
tree = NewAst()
firstToken := true
lastSym := SymUnknown
@@ -135,6 +186,7 @@ func (self *parser) parseGeneral(scanner *scanner, allowForest bool, allowVarRef
if tk.Sym == SymComment {
continue
}
//resetSelector := true
if tk.Sym == SymSemiColon {
if allowForest {
@@ -162,36 +214,64 @@ func (self *parser) parseGeneral(scanner *scanner, allowForest bool, allowVarRef
var subTree *ast
if subTree, err = self.parseGeneral(scanner, false, allowVarRef, SymClosedRound); err == nil {
subTree.root.priority = priValue
tree.addTerm(subTree.root)
err = tree.addTerm(subTree.root)
currentTerm = subTree.root
}
case SymFuncCall:
var funcCallTerm *term
if funcCallTerm, err = self.parseFuncCall(scanner, allowVarRef, tk); err == nil {
err = tree.addTerm(funcCallTerm)
currentTerm = funcCallTerm
}
case SymOpenSquare:
var listTerm *term
if listTerm, err = self.parseList(scanner, allowVarRef); err == nil {
err = tree.addTerm(listTerm)
currentTerm = listTerm
}
case SymEqual:
if err = checkPrevSymbol(lastSym, SymIdentifier, tk); err == nil {
err = tree.addToken(tk)
currentTerm, err = tree.addToken2(tk)
}
case SymFuncDef:
var funcDefTerm *term
if funcDefTerm, err = self.parseFuncDef(scanner); err == nil {
err = tree.addTerm(funcDefTerm)
currentTerm = funcDefTerm
}
case SymIdentifier:
if tk.source[0] == '@' && !allowVarRef {
err = tk.Errorf("variable references are not allowed in top level expressions: %q", tk.source)
} else {
err = tree.addToken(tk)
currentTerm, err = tree.addToken2(tk)
}
case SymQuestion:
if selectorTerm != nil {
err = tk.Errorf("nested selectors must be enclosed in parentheses")
} else if selectorTerm, err = self.parseSelector(scanner, tree, allowVarRef); err == nil {
currentTerm = selectorTerm
}
case SymColon, SymDoubleColon:
var caseTerm *term
if selectorTerm == nil {
err = tk.Errorf("selector-case outside of a selector context")
} else if caseTerm, err = self.parseSelectorCase(scanner, allowVarRef, tk.Sym == SymDoubleColon); err == nil {
selectorTerm.children = append(selectorTerm.children, caseTerm)
caseTerm.parent = selectorTerm
currentTerm = caseTerm
}
//resetSelector = tk.Sym == SymDoubleColon
default:
err = tree.addToken(tk)
currentTerm, err = tree.addToken2(tk)
}
if currentTerm != nil && currentTerm.parent != nil && currentTerm.parent.tk.Sym != SymSelector {
selectorTerm = nil
}
// if resetSelector {
// selectorTree = nil
// }
lastSym = tk.Sym
}
return