From c36c88d0fdee3aabefbac633d30bcc367d61a23f Mon Sep 17 00:00:00 2001 From: Celestino Amoroso Date: Thu, 28 Mar 2024 08:51:02 +0100 Subject: [PATCH] Added list '[]' data type. Fix: function with no arguments --- operand-list.go | 35 +++++++++++++++++++ parser.go | 90 ++++++++++++++++++++++++++++++++++--------------- symbol.go | 1 + 3 files changed, 99 insertions(+), 27 deletions(-) create mode 100644 operand-list.go diff --git a/operand-list.go b/operand-list.go new file mode 100644 index 0000000..9a52522 --- /dev/null +++ b/operand-list.go @@ -0,0 +1,35 @@ +// Copyright (c) 2024 Celestino Amoroso (celestino.amoroso@gmail.com). +// All rights reserved. + +// operand-list.go +package expr + +// -------- list term +func newListTerm(args []*term) *term { + return &term{ + tk: *NewToken(SymList, "[]"), + class: classVar, + kind: kindUnknown, + parent: nil, + children: args, + position: posLeaf, + priority: priValue, + evalFunc: evalList, + } +} + +// -------- list func +func evalList(ctx exprContext, self *term) (v any, err error) { + items := make([]any, len(self.children)) + for i, tree := range self.children { + var param any + if param, err = tree.compute(ctx); err != nil { + break + } + items[i] = param + } + if err == nil { + v = items + } + return +} diff --git a/parser.go b/parser.go index 29d228f..717293c 100644 --- a/parser.go +++ b/parser.go @@ -21,6 +21,58 @@ func NewParser(ctx exprContext) (p *parser) { return p } +func (self *parser) parseFunction(scanner *scanner, tk *Token) (tree *term, err error) { + name, _ := tk.Value.(string) + funcObj := self.ctx.GetFuncInfo(name) + if funcObj == nil { + err = fmt.Errorf("unknown function %q", name) + return + } + maxArgs := funcObj.MaxArgs() + if maxArgs < 0 { + maxArgs = funcObj.MinArgs() + 10 + } + args := make([]*term, 0, maxArgs) + lastSym := SymUnknown + for lastSym != SymClosedRound && lastSym != SymEos { + var subTree *ast + if subTree, err = self.parse(scanner, SymComma, SymClosedRound); err == nil { + if subTree.root != nil { + args = append(args, subTree.root) + } + } else { + break + } + lastSym = scanner.Previous().Sym + } + if err == nil { + // TODO Check arguments + tree = newFuncTerm(tk, args) + } + return +} + +func (self *parser) parseList(scanner *scanner) (tree *term, err error) { + args := make([]*term, 0) + lastSym := SymUnknown + for lastSym != SymClosedSquare && lastSym != SymEos { + var subTree *ast + if subTree, err = self.parse(scanner, SymComma, SymClosedSquare); err == nil { + if subTree.root != nil { + args = append(args, subTree.root) + } + } else { + break + } + lastSym = scanner.Previous().Sym + } + if err == nil { + // TODO Check arguments + tree = newListTerm(args) + } + return +} + func (self *parser) parse(scanner *scanner, termSymbols ...Symbol) (tree *ast, err error) { tree = NewAst() firstToken := true @@ -38,40 +90,24 @@ func (self *parser) parse(scanner *scanner, termSymbols ...Symbol) (tree *ast, e } } firstToken = false - if tk.Sym == SymOpenRound { + switch tk.Sym { + case SymOpenRound: var subTree *ast if subTree, err = self.parse(scanner, SymClosedRound); err == nil { subTree.root.priority = priValue tree.addTerm(subTree.root) } - } else if tk.Sym == SymFunction { - name, _ := tk.Value.(string) - funcObj := self.ctx.GetFuncInfo(name) - if funcObj == nil { - err = fmt.Errorf("unknown function %q", name) - break + case SymFunction: + var funcTerm *term + if funcTerm, err = self.parseFunction(scanner, tk); err == nil { + err = tree.addTerm(funcTerm) } - maxArgs := funcObj.MaxArgs() - if maxArgs < 0 { - maxArgs = funcObj.MinArgs() + 10 + case SymOpenSquare: + var listTerm *term + if listTerm, err = self.parseList(scanner); err == nil { + err = tree.addTerm(listTerm) } - args := make([]*term, 0, maxArgs) - lastSym := SymUnknown - for lastSym != SymClosedRound && lastSym != SymEos { - var subTree *ast - if subTree, err = self.parse(scanner, SymComma, SymClosedRound); err == nil { - args = append(args, subTree.root) - } else { - break - } - lastSym = scanner.Previous().Sym - } - if err == nil { - // TODO Check arguments - t := newFuncTerm(tk, args) - tree.addTerm(t) - } - } else { + default: err = tree.addToken(tk) } } diff --git a/symbol.go b/symbol.go index 95987c9..e9983b3 100644 --- a/symbol.go +++ b/symbol.go @@ -70,6 +70,7 @@ const ( SymNot SymComment SymFunction + SymList // SymOpenComment // 0: '/*' // SymClosedComment // 0: '*/' // SymOneLineComment // 0: '//'