Added list '[]' data type. Fix: function with no arguments
This commit is contained in:
		
							parent
							
								
									3ca415fc66
								
							
						
					
					
						commit
						c36c88d0fd
					
				
							
								
								
									
										35
									
								
								operand-list.go
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										35
									
								
								operand-list.go
									
									
									
									
									
										Normal file
									
								
							| @ -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 | ||||||
|  | } | ||||||
							
								
								
									
										90
									
								
								parser.go
									
									
									
									
									
								
							
							
						
						
									
										90
									
								
								parser.go
									
									
									
									
									
								
							| @ -21,6 +21,58 @@ func NewParser(ctx exprContext) (p *parser) { | |||||||
| 	return p | 	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) { | func (self *parser) parse(scanner *scanner, termSymbols ...Symbol) (tree *ast, err error) { | ||||||
| 	tree = NewAst() | 	tree = NewAst() | ||||||
| 	firstToken := true | 	firstToken := true | ||||||
| @ -38,40 +90,24 @@ func (self *parser) parse(scanner *scanner, termSymbols ...Symbol) (tree *ast, e | |||||||
| 			} | 			} | ||||||
| 		} | 		} | ||||||
| 		firstToken = false | 		firstToken = false | ||||||
| 		if tk.Sym == SymOpenRound { | 		switch tk.Sym { | ||||||
|  | 		case SymOpenRound: | ||||||
| 			var subTree *ast | 			var subTree *ast | ||||||
| 			if subTree, err = self.parse(scanner, SymClosedRound); err == nil { | 			if subTree, err = self.parse(scanner, SymClosedRound); err == nil { | ||||||
| 				subTree.root.priority = priValue | 				subTree.root.priority = priValue | ||||||
| 				tree.addTerm(subTree.root) | 				tree.addTerm(subTree.root) | ||||||
| 			} | 			} | ||||||
| 		} else if tk.Sym == SymFunction { | 		case SymFunction: | ||||||
| 			name, _ := tk.Value.(string) | 			var funcTerm *term | ||||||
| 			funcObj := self.ctx.GetFuncInfo(name) | 			if funcTerm, err = self.parseFunction(scanner, tk); err == nil { | ||||||
| 			if funcObj == nil { | 				err = tree.addTerm(funcTerm) | ||||||
| 				err = fmt.Errorf("unknown function %q", name) |  | ||||||
| 				break |  | ||||||
| 			} | 			} | ||||||
| 			maxArgs := funcObj.MaxArgs() | 		case SymOpenSquare: | ||||||
| 			if maxArgs < 0 { | 			var listTerm *term | ||||||
| 				maxArgs = funcObj.MinArgs() + 10 | 			if listTerm, err = self.parseList(scanner); err == nil { | ||||||
|  | 				err = tree.addTerm(listTerm) | ||||||
| 			} | 			} | ||||||
| 			args := make([]*term, 0, maxArgs) | 		default: | ||||||
| 			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 { |  | ||||||
| 			err = tree.addToken(tk) | 			err = tree.addToken(tk) | ||||||
| 		} | 		} | ||||||
| 	} | 	} | ||||||
|  | |||||||
		Loading…
	
		Reference in New Issue
	
	Block a user