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 | ||||
| } | ||||
| 
 | ||||
| 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) | ||||
| 		} | ||||
| 	} | ||||
|  | ||||
		Loading…
	
		Reference in New Issue
	
	Block a user