Compare commits

...

23 Commits

Author SHA1 Message Date
3ebba83bce term.go: replaced self receiver 2024-07-09 07:50:50 +02:00
6b3bfa2a11 self param replaced as opTerm 2024-07-09 07:50:06 +02:00
867806155e scanner.go: replaced self receiver 2024-07-08 07:30:58 +02:00
a711333a2e simple-store.go: commented out an unused function 2024-07-08 07:30:26 +02:00
af3e946bd4 operator-sum.go: replaced self receiver 2024-07-08 07:29:42 +02:00
22a36fa630 context.go renamed as expr-context.go 2024-07-07 16:20:29 +02:00
6d9a379c92 token.go: replaced self receiver 2024-07-07 16:19:58 +02:00
dd6404c786 t_scanner_test.go: replaced t.Log(fmtStringf()) with t.Logf() 2024-07-07 16:18:39 +02:00
34874ef663 plugins.go: replaced stringsIndex()<0 with !strings.Contains() 2024-07-07 16:17:48 +02:00
9bc8e8ca05 operator-sum.go: replaced for-loop with append() 2024-07-07 16:15:56 +02:00
7f367cfc49 parser.go: renamed self receiver 2024-07-07 16:14:52 +02:00
fe999acf2c operator-index.go: removed unused parameter from the function verifyKey() 2024-07-07 16:14:04 +02:00
2ed1a1842b operand-iterator.go: commented out an unused function and replaced self receiver 2024-07-07 16:10:43 +02:00
bb9493d0cc list-type.go: commented out an unused fuction 2024-07-07 16:08:45 +02:00
f279bf163e import-utils.go: commented out unused fuctions 2024-07-07 15:59:23 +02:00
6834d9f47b function.go: removed useless param != nil check 2024-07-07 15:58:29 +02:00
8051faa2bf fraction-type.go: use of strings.TrimSuffix() in place of check suffix and slice 2024-07-07 15:57:17 +02:00
f30e687a79 changed the file name comment 2024-07-07 15:55:51 +02:00
2b6e46576b byte-slider.go: renamed function receiver from self to slider 2024-07-07 15:54:26 +02:00
dc06c03112 builtin-string.go: removed useless err == nil check 2024-07-07 15:53:29 +02:00
e8f5d3e445 builtin-base.go: unused function iteratorFunc() commented out 2024-07-07 15:52:16 +02:00
76ce0945f7 context.go splitted in two files: expr-context.go and expr-function-go.
Expr interface moved from ast.go to the new file expr.go
2024-07-07 15:51:29 +02:00
340b99bad7 list-type.go: use of copy() for copying lists 2024-07-07 07:34:58 +02:00
50 changed files with 625 additions and 642 deletions

67
ast.go
View File

@ -8,11 +8,6 @@ import (
"strings"
)
type Expr interface {
Eval(ctx ExprContext) (result any, err error)
String() string
}
//-------- ast
type ast struct {
@ -24,65 +19,65 @@ func NewAst() *ast {
return &ast{}
}
func (self *ast) ToForest() {
if self.root != nil {
if self.forest == nil {
self.forest = make([]*term, 0)
func (expr *ast) ToForest() {
if expr.root != nil {
if expr.forest == nil {
expr.forest = make([]*term, 0)
}
self.forest = append(self.forest, self.root)
self.root = nil
expr.forest = append(expr.forest, expr.root)
expr.root = nil
}
}
func (self *ast) String() string {
func (expr *ast) String() string {
var sb strings.Builder
if self.root == nil {
if expr.root == nil {
sb.WriteString("(nil)")
} else {
self.root.toString(&sb)
expr.root.toString(&sb)
}
return sb.String()
}
func (self *ast) addTokens(tokens ...*Token) (err error) {
func (expr *ast) addTokens(tokens ...*Token) (err error) {
for _, tk := range tokens {
if err = self.addToken(tk); err != nil {
if err = expr.addToken(tk); err != nil {
break
}
}
return
}
func (self *ast) addToken(tk *Token) (err error) {
_, err = self.addToken2(tk)
func (expr *ast) addToken(tk *Token) (err error) {
_, err = expr.addToken2(tk)
return
}
func (self *ast) addToken2(tk *Token) (t *term, err error) {
func (expr *ast) addToken2(tk *Token) (t *term, err error) {
if t = newTerm(tk); t != nil {
err = self.addTerm(t)
err = expr.addTerm(t)
} else {
err = tk.Errorf("unexpected token %q", tk.String())
}
return
}
func (self *ast) addTerm(node *term) (err error) {
if self.root == nil {
self.root = node
func (expr *ast) addTerm(node *term) (err error) {
if expr.root == nil {
expr.root = node
} else {
self.root, err = self.insert(self.root, node)
expr.root, err = expr.insert(expr.root, node)
}
return
}
func (self *ast) insert(tree, node *term) (root *term, err error) {
func (expr *ast) insert(tree, node *term) (root *term, err error) {
if tree.getPriority() < node.getPriority() {
root = tree
if tree.isComplete() {
var subRoot *term
last := tree.removeLastChild()
if subRoot, err = self.insert(last, node); err == nil {
if subRoot, err = expr.insert(last, node); err == nil {
subRoot.setParent(tree)
}
} else {
@ -97,20 +92,20 @@ func (self *ast) insert(tree, node *term) (root *term, err error) {
return
}
func (self *ast) Finish() {
if self.root == nil && self.forest != nil && len(self.forest) >= 1 {
self.root = self.forest[len(self.forest)-1]
self.forest = self.forest[0 : len(self.forest)-1]
func (expr *ast) Finish() {
if expr.root == nil && expr.forest != nil && len(expr.forest) >= 1 {
expr.root = expr.forest[len(expr.forest)-1]
expr.forest = expr.forest[0 : len(expr.forest)-1]
}
}
func (self *ast) Eval(ctx ExprContext) (result any, err error) {
self.Finish()
func (expr *ast) Eval(ctx ExprContext) (result any, err error) {
expr.Finish()
if self.root != nil {
if expr.root != nil {
// initDefaultVars(ctx)
if self.forest != nil {
for _, root := range self.forest {
if expr.forest != nil {
for _, root := range expr.forest {
if result, err = root.compute(ctx); err == nil {
ctx.UnsafeSetVar(ControlLastResult, result)
} else {
@ -120,7 +115,7 @@ func (self *ast) Eval(ctx ExprContext) (result any, err error) {
}
}
if err == nil {
if result, err = self.root.compute(ctx); err == nil {
if result, err = expr.root.compute(ctx); err == nil {
ctx.UnsafeSetVar(ControlLastResult, result)
}
}

View File

@ -180,9 +180,9 @@ func fractFunc(ctx ExprContext, name string, args []any) (result any, err error)
return
}
func iteratorFunc(ctx ExprContext, name string, args []any) (result any, err error) {
return
}
// func iteratorFunc(ctx ExprContext, name string, args []any) (result any, err error) {
// return
// }
func ImportBuiltinsFuncs(ctx ExprContext) {
anyParams := []ExprFuncParam{

View File

@ -25,7 +25,7 @@ func doJoinStr(funcName string, sep string, it Iterator) (result any, err error)
return
}
}
if err == nil || err == io.EOF {
if err == io.EOF {
err = nil
result = sb.String()
}

View File

@ -18,17 +18,17 @@ func NewByteSlider(size int) *ByteSlider {
}
}
func (self *ByteSlider) PushEnd(b byte) {
if self.length == cap(self.buf) {
self.length--
for i := 0; i < self.length; i++ {
self.buf[i] = self.buf[i+1]
func (slider *ByteSlider) PushEnd(b byte) {
if slider.length == cap(slider.buf) {
slider.length--
for i := 0; i < slider.length; i++ {
slider.buf[i] = slider.buf[i+1]
}
}
self.buf[self.length] = b
self.length++
slider.buf[slider.length] = b
slider.length++
}
func (self *ByteSlider) Equal(target []byte) bool {
return target != nil && bytes.Equal(self.buf, target)
func (slider *ByteSlider) Equal(target []byte) bool {
return target != nil && bytes.Equal(slider.buf, target)
}

23
expr-context.go Normal file
View File

@ -0,0 +1,23 @@
// Copyright (c) 2024 Celestino Amoroso (celestino.amoroso@gmail.com).
// All rights reserved.
// expr-context.go
package expr
// ----Expression Context
type ExprContext interface {
Clone() ExprContext
// Merge(ctx ExprContext)
SetParent(ctx ExprContext)
GetParent() (ctx ExprContext)
GetVar(varName string) (value any, exists bool)
GetLast() any
SetVar(varName string, value any)
UnsafeSetVar(varName string, value any)
EnumVars(func(name string) (accept bool)) (varNames []string)
EnumFuncs(func(name string) (accept bool)) (funcNames []string)
GetFuncInfo(name string) (item ExprFunc, exists bool)
Call(name string, args []any) (result any, err error)
RegisterFuncInfo(info ExprFunc)
RegisterFunc(name string, f Functor, returnType string, param []ExprFuncParam) error
}

View File

@ -1,7 +1,7 @@
// Copyright (c) 2024 Celestino Amoroso (celestino.amoroso@gmail.com).
// All rights reserved.
// context.go
// expr-function.go
package expr
// ---- Functor interface
@ -35,21 +35,3 @@ type ExprFunc interface {
PrepareCall(parentCtx ExprContext, name string, varParams *[]any) (ctx ExprContext, err error)
AllocContext(parentCtx ExprContext) (ctx ExprContext)
}
// ----Expression Context
type ExprContext interface {
Clone() ExprContext
// Merge(ctx ExprContext)
SetParent(ctx ExprContext)
GetParent() (ctx ExprContext)
GetVar(varName string) (value any, exists bool)
GetLast() any
SetVar(varName string, value any)
UnsafeSetVar(varName string, value any)
EnumVars(func(name string) (accept bool)) (varNames []string)
EnumFuncs(func(name string) (accept bool)) (funcNames []string)
GetFuncInfo(name string) (item ExprFunc, exists bool)
Call(name string, args []any) (result any, err error)
RegisterFuncInfo(info ExprFunc)
RegisterFunc(name string, f Functor, returnType string, param []ExprFuncParam) error
}

11
expr.go Normal file
View File

@ -0,0 +1,11 @@
// Copyright (c) 2024 Celestino Amoroso (celestino.amoroso@gmail.com).
// All rights reserved.
// expr.go
package expr
// ----Expression interface
type Expr interface {
Eval(ctx ExprContext) (result any, err error)
String() string
}

View File

@ -50,9 +50,10 @@ func makeGeneratingFraction(s string) (f *FractionType, err error) {
} else if s[0] == '+' {
s = s[1:]
}
if strings.HasSuffix(s, "()") {
s = s[0 : len(s)-2]
}
// if strings.HasSuffix(s, "()") {
// s = s[0 : len(s)-2]
// }
s = strings.TrimSuffix(s, "()")
parts = strings.SplitN(s, ".", 2)
if num, err = strconv.ParseInt(parts[0], 10, 64); err != nil {
return
@ -311,7 +312,6 @@ func divAnyFract(af1, af2 any) (quot any, err error) {
if f2.num == 0 {
err = errors.New("division by zero")
return
return
}
if f1.num == 0 || f2.den == 0 {
quot = 0

View File

@ -112,25 +112,24 @@ type funcInfo struct {
func newFuncInfo(name string, functor Functor, returnType string, params []ExprFuncParam) (info *funcInfo, err error) {
var minArgs = 0
var maxArgs = 0
if params != nil {
for _, p := range params {
if maxArgs == -1 {
return nil, fmt.Errorf("no more params can be specified after the ellipsis symbol: %q", p.Name())
}
if p.IsDefault() || p.IsOptional() {
maxArgs++
} else if maxArgs == minArgs {
minArgs++
maxArgs++
} else {
return nil, fmt.Errorf("can't specify non-optional param after optional ones: %q", p.Name())
}
if p.IsRepeat() {
minArgs--
maxArgs = -1
}
for _, p := range params {
if maxArgs == -1 {
return nil, fmt.Errorf("no more params can be specified after the ellipsis symbol: %q", p.Name())
}
if p.IsDefault() || p.IsOptional() {
maxArgs++
} else if maxArgs == minArgs {
minArgs++
maxArgs++
} else {
return nil, fmt.Errorf("can't specify non-optional param after optional ones: %q", p.Name())
}
if p.IsRepeat() {
minArgs--
maxArgs = -1
}
}
info = &funcInfo{
name: name, minArgs: minArgs, maxArgs: maxArgs, functor: functor, returnType: returnType, formalParams: params,
}

View File

@ -25,13 +25,13 @@ func checkStringParamExpected(funcName string, paramValue any, paramPos int) (er
return
}
func addSourceEnvImportDirs(varName string, dirList []string) []string {
return addEnvImportDirs(ENV_EXPR_SOURCE_PATH, dirList)
}
// func addSourceEnvImportDirs(varName string, dirList []string) []string {
// return addEnvImportDirs(ENV_EXPR_SOURCE_PATH, dirList)
// }
func addPluginEnvImportDirs(varName string, dirList []string) []string {
return addEnvImportDirs(ENV_EXPR_PLUGIN_PATH, dirList)
}
// func addPluginEnvImportDirs(varName string, dirList []string) []string {
// return addEnvImportDirs(ENV_EXPR_PLUGIN_PATH, dirList)
// }
func addEnvImportDirs(envVarName string, dirList []string) []string {
if dirSpec, exists := os.LookupEnv(envVarName); exists {

View File

@ -26,9 +26,10 @@ func newList(listAny []any) (list *ListType) {
func NewList(listAny []any) (list *ListType) {
if listAny != nil {
ls := make(ListType, len(listAny))
for i, item := range listAny {
ls[i] = item
}
// for i, item := range listAny {
// ls[i] = item
// }
copy(ls, listAny)
list = &ls
}
return
@ -105,16 +106,16 @@ func (ls *ListType) TypeName() string {
return "list"
}
func (list *ListType) indexDeepCmp(target any) (index int) {
index = -1
for i, item := range *list {
if reflect.DeepEqual(item, target) {
index = i
break
}
}
return
}
// func (list *ListType) indexDeepCmp(target any) (index int) {
// index = -1
// for i, item := range *list {
// if reflect.DeepEqual(item, target) {
// index = i
// break
// }
// }
// return
// }
func (ls *ListType) contains(t *ListType) (answer bool) {
if len(*ls) >= len(*t) {

View File

@ -18,8 +18,8 @@ func newDictTerm(args map[any]*term) *term {
}
// -------- dict func
func evalDict(ctx ExprContext, self *term) (v any, err error) {
dict, _ := self.value().(map[any]*term)
func evalDict(ctx ExprContext, opTerm *term) (v any, err error) {
dict, _ := opTerm.value().(map[any]*term)
items := make(DictType, len(dict))
for key, tree := range dict {
var param any

View File

@ -20,11 +20,11 @@ func newExprTerm(root *term) *term {
}
// -------- eval expr
func evalExpr(ctx ExprContext, self *term) (v any, err error) {
if expr, ok := self.value().(*term); ok {
func evalExpr(ctx ExprContext, opTerm *term) (v any, err error) {
if expr, ok := opTerm.value().(*term); ok {
v, err = expr.compute(ctx)
} else {
err = fmt.Errorf("expression expected, got %T", self.value())
err = fmt.Errorf("expression expected, got %T", opTerm.value())
}
return
}

View File

@ -21,10 +21,10 @@ func newFuncCallTerm(tk *Token, args []*term) *term {
}
// -------- eval func call
func evalFuncCall(ctx ExprContext, self *term) (v any, err error) {
name, _ := self.tk.Value.(string)
params := make([]any, len(self.children), len(self.children)+5)
for i, tree := range self.children {
func evalFuncCall(ctx ExprContext, opTerm *term) (v any, err error) {
name, _ := opTerm.tk.Value.(string)
params := make([]any, len(opTerm.children), len(opTerm.children)+5)
for i, tree := range opTerm.children {
var param any
if param, err = tree.compute(ctx); err != nil {
break
@ -51,11 +51,11 @@ func newFuncDefTerm(tk *Token, args []*term) *term {
}
// -------- eval func def
func evalFuncDef(ctx ExprContext, self *term) (v any, err error) {
bodySpec := self.value()
func evalFuncDef(ctx ExprContext, opTerm *term) (v any, err error) {
bodySpec := opTerm.value()
if expr, ok := bodySpec.(*ast); ok {
paramList := make([]ExprFuncParam, 0, len(self.children))
for _, param := range self.children {
paramList := make([]ExprFuncParam, 0, len(opTerm.children))
for _, param := range opTerm.children {
var defValue any
flags := paramFlags(0)
if len(param.children) > 0 {

View File

@ -5,28 +5,27 @@
package expr
import (
"fmt"
"slices"
"strings"
)
// -------- iterator term
func newDsIteratorTerm(tk *Token, dsTerm *term, args []*term) *term {
tk.Sym = SymIterator
// func newDsIteratorTerm(tk *Token, dsTerm *term, args []*term) *term {
// tk.Sym = SymIterator
children := make([]*term, 0, 1+len(args))
children = append(children, dsTerm)
children = append(children, args...)
return &term{
tk: *tk,
parent: nil,
children: children,
position: posLeaf,
priority: priValue,
evalFunc: evalIterator,
}
}
// children := make([]*term, 0, 1+len(args))
// children = append(children, dsTerm)
// children = append(children, args...)
// return &term{
// tk: *tk,
// parent: nil,
// children: children,
// position: posLeaf,
// priority: priValue,
// evalFunc: evalIterator,
// }
// }
func newIteratorTerm(tk *Token, args []*term) *term {
tk.Sym = SymIterator
@ -42,9 +41,9 @@ func newIteratorTerm(tk *Token, args []*term) *term {
// -------- eval iterator
func evalTermArray(ctx ExprContext, a []*term) (values []any, err error) {
values = make([]any, len(a))
for i, t := range a {
func evalTermArray(ctx ExprContext, terms []*term) (values []any, err error) {
values = make([]any, len(terms))
for i, t := range terms {
var value any
if value, err = t.compute(ctx); err == nil {
values[i] = value
@ -55,18 +54,17 @@ func evalTermArray(ctx ExprContext, a []*term) (values []any, err error) {
return
}
func evalFirstChild(ctx ExprContext, self *term) (value any, err error) {
if len(self.children) < 1 || self.children[0] == nil {
err = self.Errorf("missing the data-source parameter")
func evalFirstChild(ctx ExprContext, iteratorTerm *term) (value any, err error) {
if len(iteratorTerm.children) < 1 || iteratorTerm.children[0] == nil {
err = iteratorTerm.Errorf("missing the data-source parameter")
return
}
value, err = self.children[0].compute(ctx)
value, err = iteratorTerm.children[0].compute(ctx)
return
}
func getDataSourceDict(ctx ExprContext, self *term, firstChildValue any) (ds map[string]Functor, err error) {
// if dictAny, ok := firstChildValue.(map[any]any); ok {
func getDataSourceDict(iteratorTerm *term, firstChildValue any) (ds map[string]Functor, err error) {
if dictAny, ok := firstChildValue.(*DictType); ok {
requiredFields := []string{currentName, nextName}
fieldsMask := 0b11
@ -74,7 +72,6 @@ func getDataSourceDict(ctx ExprContext, self *term, firstChildValue any) (ds map
ds = make(map[string]Functor)
for keyAny, item := range *dictAny {
if key, ok := keyAny.(string); ok {
//if functor, ok := item.(*funcDefFunctor); ok {
if functor, ok := item.(Functor); ok {
ds[key] = functor
if index := slices.Index(requiredFields, key); index >= 0 {
@ -91,21 +88,22 @@ func getDataSourceDict(ctx ExprContext, self *term, firstChildValue any) (ds map
missingFields = append(missingFields, field)
}
}
err = fmt.Errorf("the data-source must provide a non-nil %q operator(s)", strings.Join(missingFields, ", "))
// err = fmt.Errorf("the data-source must provide a non-nil %q operator(s)", strings.Join(missingFields, ", "))
err = iteratorTerm.children[0].Errorf("the data-source must provide a non-nil %q operator(s)", strings.Join(missingFields, ", "))
}
}
return
}
func evalIterator(ctx ExprContext, self *term) (v any, err error) {
func evalIterator(ctx ExprContext, opTerm *term) (v any, err error) {
var firstChildValue any
var ds map[string]Functor
if firstChildValue, err = evalFirstChild(ctx, self); err != nil {
if firstChildValue, err = evalFirstChild(ctx, opTerm); err != nil {
return
}
if ds, err = getDataSourceDict(ctx, self, firstChildValue); err != nil {
if ds, err = getDataSourceDict(opTerm, firstChildValue); err != nil {
return
}
@ -113,8 +111,8 @@ func evalIterator(ctx ExprContext, self *term) (v any, err error) {
dc := newDataCursor(ctx, ds)
if initFunc, exists := ds[initName]; exists && initFunc != nil {
var args []any
if len(self.children) > 1 {
if args, err = evalTermArray(ctx, self.children[1:]); err != nil {
if len(opTerm.children) > 1 {
if args, err = evalTermArray(ctx, opTerm.children[1:]); err != nil {
return
}
} else {
@ -128,20 +126,20 @@ func evalIterator(ctx ExprContext, self *term) (v any, err error) {
exportObjects(dc.ctx, initCtx)
}
dc.nextFunc, _ = ds[nextName]
dc.currentFunc, _ = ds[currentName]
dc.cleanFunc, _ = ds[cleanName]
dc.resetFunc, _ = ds[resetName]
dc.nextFunc = ds[nextName]
dc.currentFunc = ds[currentName]
dc.cleanFunc = ds[cleanName]
dc.resetFunc = ds[resetName]
v = dc
} else if list, ok := firstChildValue.(*ListType); ok {
var args []any
if args, err = evalSibling(ctx, self.children, nil); err == nil {
if args, err = evalSibling(ctx, opTerm.children, nil); err == nil {
v = NewListIterator(list, args)
}
} else {
var list []any
if list, err = evalSibling(ctx, self.children, firstChildValue); err == nil {
if list, err = evalSibling(ctx, opTerm.children, firstChildValue); err == nil {
v = NewArrayIterator(list)
}
}

View File

@ -21,8 +21,8 @@ func newListTerm(row, col int, args []*term) *term {
}
// -------- list func
func evalList(ctx ExprContext, self *term) (v any, err error) {
list, _ := self.value().([]*term)
func evalList(ctx ExprContext, opTerm *term) (v any, err error) {
list, _ := opTerm.value().([]*term)
items := make(ListType, len(list))
for i, tree := range list {
var param any

View File

@ -17,8 +17,8 @@ func newLiteralTerm(tk *Token) *term {
}
// -------- eval func
func evalLiteral(ctx ExprContext, self *term) (v any, err error) {
v = self.tk.Value
func evalLiteral(ctx ExprContext, opTerm *term) (v any, err error) {
v = opTerm.tk.Value
return
}

View File

@ -41,10 +41,10 @@ func newSelectorCaseTerm(row, col int, filterList *term, caseExpr Expr) *term {
}
// -------- eval selector case
func evalSelectorCase(ctx ExprContext, self *term) (v any, err error) {
func evalSelectorCase(ctx ExprContext, opTerm *term) (v any, err error) {
var ok bool
if v, ok = self.value().(*selectorCase); !ok {
err = fmt.Errorf("selector-case expected, got %T", self.value())
if v, ok = opTerm.value().(*selectorCase); !ok {
err = fmt.Errorf("selector-case expected, got %T", opTerm.value())
}
return
}

View File

@ -21,9 +21,9 @@ func newVarTerm(tk *Token) *term {
}
// -------- eval func
func evalVar(ctx ExprContext, self *term) (v any, err error) {
func evalVar(ctx ExprContext, opTerm *term) (v any, err error) {
var exists bool
name := self.source()
name := opTerm.source()
if v, exists = GetVar(ctx, name); !exists {
if info, exists, _ := GetFuncInfo(ctx, name); exists {
v = info.Functor()

View File

@ -60,19 +60,19 @@ func assignValue(ctx ExprContext, leftTerm *term, v any) (err error) {
return
}
func evalAssign(ctx ExprContext, self *term) (v any, err error) {
if err = self.checkOperands(); err != nil {
func evalAssign(ctx ExprContext, opTerm *term) (v any, err error) {
if err = opTerm.checkOperands(); err != nil {
return
}
leftTerm := self.children[0]
leftTerm := opTerm.children[0]
leftSym := leftTerm.symbol()
if leftSym != SymVariable && leftSym != SymIndex {
err = leftTerm.tk.Errorf("left operand of %q must be a variable or a collection's item", self.tk.source)
err = leftTerm.tk.Errorf("left operand of %q must be a variable or a collection's item", opTerm.tk.source)
return
}
rightChild := self.children[1]
rightChild := opTerm.children[1]
if v, err = rightChild.compute(ctx); err == nil {
if functor, ok := v.(Functor); ok {
@ -83,7 +83,7 @@ func evalAssign(ctx ExprContext, self *term) (v any, err error) {
ctx.RegisterFunc(leftTerm.source(), functor, TypeAny, paramSpecs)
} else {
err = self.Errorf("unknown function %s()", rightChild.source())
err = opTerm.Errorf("unknown function %s()", rightChild.source())
}
} else {
err = assignValue(ctx, leftTerm, v)

View File

@ -18,17 +18,17 @@ func newNotTerm(tk *Token) (inst *term) {
}
}
func evalNot(ctx ExprContext, self *term) (v any, err error) {
func evalNot(ctx ExprContext, opTerm *term) (v any, err error) {
var rightValue any
if rightValue, err = self.evalPrefix(ctx); err != nil {
if rightValue, err = opTerm.evalPrefix(ctx); err != nil {
return
}
if b, ok := ToBool(rightValue); ok {
v = !b
} else {
err = self.errIncompatibleType(rightValue)
err = opTerm.errIncompatibleType(rightValue)
}
return
}

View File

@ -18,10 +18,10 @@ func newBuiltinTerm(tk *Token) (inst *term) {
}
}
func evalBuiltin(ctx ExprContext, self *term) (v any, err error) {
func evalBuiltin(ctx ExprContext, opTerm *term) (v any, err error) {
var childValue any
if childValue, err = self.evalPrefix(ctx); err != nil {
if childValue, err = opTerm.evalPrefix(ctx); err != nil {
return
}
@ -37,11 +37,11 @@ func evalBuiltin(ctx ExprContext, self *term) (v any, err error) {
if ImportInContext(module) {
count++
} else {
err = self.Errorf("unknown builtin module %q", module)
err = opTerm.Errorf("unknown builtin module %q", module)
break
}
} else {
err = self.Errorf("expected string at item nr %d, got %s", it.Index()+1, TypeName(moduleSpec))
err = opTerm.Errorf("expected string at item nr %d, got %s", it.Index()+1, TypeName(moduleSpec))
break
}
}

View File

@ -16,8 +16,8 @@ func newButTerm(tk *Token) (inst *term) {
}
}
func evalBut(ctx ExprContext, self *term) (v any, err error) {
_, v, err = self.evalInfix(ctx)
func evalBut(ctx ExprContext, opTerm *term) (v any, err error) {
_, v, err = opTerm.evalInfix(ctx)
return
}

View File

@ -16,15 +16,15 @@ func newContextTerm(tk *Token) (inst *term) {
}
}
func evalContextValue(ctx ExprContext, self *term) (v any, err error) {
func evalContextValue(ctx ExprContext, opTerm *term) (v any, err error) {
var childValue any
var sourceCtx ExprContext
if self.children == nil || len(self.children) == 0 {
if opTerm.children == nil || len(opTerm.children) == 0 {
sourceCtx = ctx
} else if self.children[0].symbol() == SymVariable && self.children[0].source() == "global" {
} else if opTerm.children[0].symbol() == SymVariable && opTerm.children[0].source() == "global" {
sourceCtx = globalCtx
} else if childValue, err = self.evalPrefix(ctx); err == nil {
} else if childValue, err = opTerm.evalPrefix(ctx); err == nil {
if dc, ok := childValue.(*dataCursor); ok {
sourceCtx = dc.ctx
}
@ -49,7 +49,7 @@ func evalContextValue(ctx ExprContext, self *term) (v any, err error) {
v = d
}
} else {
err = self.errIncompatibleType(childValue)
err = opTerm.errIncompatibleType(childValue)
}
return
}

View File

@ -16,7 +16,7 @@ func newExportAllTerm(tk *Token) (inst *term) {
}
}
func evalExportAll(ctx ExprContext, self *term) (v any, err error) {
func evalExportAll(ctx ExprContext, opTerm *term) (v any, err error) {
CtrlEnable(ctx, control_export_all)
return
}

View File

@ -16,23 +16,23 @@ func newDefaultTerm(tk *Token) (inst *term) {
}
}
func evalDefault(ctx ExprContext, self *term) (v any, err error) {
func evalDefault(ctx ExprContext, opTerm *term) (v any, err error) {
var rightValue any
if err = self.checkOperands(); err != nil {
if err = opTerm.checkOperands(); err != nil {
return
}
leftTerm := self.children[0]
leftTerm := opTerm.children[0]
if leftTerm.tk.Sym != SymVariable {
// err = leftTerm.Errorf("left operand of %q must be a variable", self.tk.source)
err = ErrLeftOperandMustBeVariable(leftTerm, self)
err = ErrLeftOperandMustBeVariable(leftTerm, opTerm)
return
}
if leftValue, exists := ctx.GetVar(leftTerm.source()); exists {
v = leftValue
} else if rightValue, err = self.children[1].compute(ctx); err == nil {
} else if rightValue, err = opTerm.children[1].compute(ctx); err == nil {
v = rightValue
}
return
@ -50,22 +50,22 @@ func newAlternateTerm(tk *Token) (inst *term) {
}
}
func evalAlternate(ctx ExprContext, self *term) (v any, err error) {
func evalAlternate(ctx ExprContext, opTerm *term) (v any, err error) {
var rightValue any
if err = self.checkOperands(); err != nil {
if err = opTerm.checkOperands(); err != nil {
return
}
leftTerm := self.children[0]
leftTerm := opTerm.children[0]
if leftTerm.tk.Sym != SymVariable {
// err = leftTerm.Errorf("left operand of %q must be a variable", self.tk.source)
err = ErrLeftOperandMustBeVariable(leftTerm, self)
err = ErrLeftOperandMustBeVariable(leftTerm, opTerm)
return
}
if leftValue, exists := ctx.GetVar(leftTerm.source()); exists && leftValue != nil {
if rightValue, err = self.children[1].compute(ctx); err == nil {
if rightValue, err = opTerm.children[1].compute(ctx); err == nil {
v = rightValue
}
} else {
@ -86,23 +86,23 @@ func newDefaultAssignTerm(tk *Token) (inst *term) {
}
}
func evalAssignDefault(ctx ExprContext, self *term) (v any, err error) {
func evalAssignDefault(ctx ExprContext, opTerm *term) (v any, err error) {
var rightValue any
if err = self.checkOperands(); err != nil {
if err = opTerm.checkOperands(); err != nil {
return
}
leftTerm := self.children[0]
leftTerm := opTerm.children[0]
if leftTerm.tk.Sym != SymVariable {
// err = leftTerm.Errorf("left operand of %q must be a variable", self.tk.source)
err = ErrLeftOperandMustBeVariable(leftTerm, self)
err = ErrLeftOperandMustBeVariable(leftTerm, opTerm)
return
}
if leftValue, exists := ctx.GetVar(leftTerm.source()); exists {
v = leftValue
} else if rightValue, err = self.children[1].compute(ctx); err == nil {
} else if rightValue, err = opTerm.children[1].compute(ctx); err == nil {
if functor, ok := rightValue.(Functor); ok {
//ctx.RegisterFunc(leftTerm.source(), functor, 0, -1)
ctx.RegisterFunc(leftTerm.source(), functor, TypeAny, []ExprFuncParam{

View File

@ -15,17 +15,17 @@ func newDotTerm(tk *Token) (inst *term) {
}
}
func evalDot(ctx ExprContext, self *term) (v any, err error) {
func evalDot(ctx ExprContext, opTerm *term) (v any, err error) {
var leftValue, rightValue any
if err = self.checkOperands(); err != nil {
if err = opTerm.checkOperands(); err != nil {
return
}
if leftValue, err = self.children[0].compute(ctx); err != nil {
if leftValue, err = opTerm.children[0].compute(ctx); err != nil {
return
}
indexTerm := self.children[1]
indexTerm := opTerm.children[1]
switch unboxedValue := leftValue.(type) {
case ExtIterator:
@ -41,8 +41,8 @@ func evalDot(ctx ExprContext, self *term) (v any, err error) {
err = indexTerm.tk.ErrorExpectedGot("identifier")
}
default:
if rightValue, err = self.children[1].compute(ctx); err == nil {
err = self.errIncompatibleTypes(leftValue, rightValue)
if rightValue, err = opTerm.children[1].compute(ctx); err == nil {
err = opTerm.errIncompatibleTypes(leftValue, rightValue)
}
}
return

View File

@ -18,10 +18,10 @@ func newFactTerm(tk *Token) (inst *term) {
}
}
func evalFact(ctx ExprContext, self *term) (v any, err error) {
func evalFact(ctx ExprContext, opTerm *term) (v any, err error) {
var leftValue any
if leftValue, err = self.evalPrefix(ctx); err != nil {
if leftValue, err = opTerm.evalPrefix(ctx); err != nil {
return
}
@ -36,7 +36,7 @@ func evalFact(ctx ExprContext, self *term) (v any, err error) {
err = fmt.Errorf("factorial of a negative integer (%d) is not allowed", i)
}
} else {
err = self.errIncompatibleType(leftValue)
err = opTerm.errIncompatibleType(leftValue)
}
return
}

View File

@ -24,12 +24,12 @@ func newFractionTerm(tk *Token) *term {
}
// -------- eval func
func evalFraction(ctx ExprContext, self *term) (v any, err error) {
func evalFraction(ctx ExprContext, opTerm *term) (v any, err error) {
var numValue, denValue any
var num, den int64
var ok bool
if numValue, denValue, err = self.evalInfix(ctx); err != nil {
if numValue, denValue, err = opTerm.evalInfix(ctx); err != nil {
return
}
if num, ok = numValue.(int64); !ok {

View File

@ -21,10 +21,10 @@ func newInTerm(tk *Token) (inst *term) {
// return
// }
func evalIn(ctx ExprContext, self *term) (v any, err error) {
func evalIn(ctx ExprContext, opTerm *term) (v any, err error) {
var leftValue, rightValue any
if leftValue, rightValue, err = self.evalInfix(ctx); err != nil {
if leftValue, rightValue, err = opTerm.evalInfix(ctx); err != nil {
return
}
@ -35,7 +35,7 @@ func evalIn(ctx ExprContext, self *term) (v any, err error) {
dict, _ := rightValue.(*DictType)
v = dict.hasKey(leftValue)
} else {
err = self.errIncompatibleTypes(leftValue, rightValue)
err = opTerm.errIncompatibleTypes(leftValue, rightValue)
}
return
}

View File

@ -16,10 +16,10 @@ func newIncludeTerm(tk *Token) (inst *term) {
}
}
func evalInclude(ctx ExprContext, self *term) (v any, err error) {
func evalInclude(ctx ExprContext, opTerm *term) (v any, err error) {
var childValue any
if childValue, err = self.evalPrefix(ctx); err != nil {
if childValue, err = opTerm.evalPrefix(ctx); err != nil {
return
}
@ -31,11 +31,11 @@ func evalInclude(ctx ExprContext, self *term) (v any, err error) {
if v, err = EvalFile(ctx, filePath); err == nil {
count++
} else {
err = self.Errorf("can't load file %q", filePath)
err = opTerm.Errorf("can't load file %q", filePath)
break
}
} else {
err = self.Errorf("expected string at item nr %d, got %T", i+1, filePathSpec)
err = opTerm.Errorf("expected string at item nr %d, got %T", i+1, filePathSpec)
break
}
}
@ -45,7 +45,7 @@ func evalInclude(ctx ExprContext, self *term) (v any, err error) {
count++
}
} else {
err = self.errIncompatibleType(childValue)
err = opTerm.errIncompatibleType(childValue)
}
if err == nil {
v = count

View File

@ -15,7 +15,7 @@ func newIndexTerm(tk *Token) (inst *term) {
}
}
func verifyKey(indexTerm *term, indexList *ListType) (index any, err error) {
func verifyKey(indexList *ListType) (index any, err error) {
index = (*indexList)[0]
return
}
@ -59,18 +59,18 @@ func verifyRange(indexTerm *term, indexList *ListType, maxValue int) (startIndex
return
}
func evalIndex(ctx ExprContext, self *term) (v any, err error) {
func evalIndex(ctx ExprContext, opTerm *term) (v any, err error) {
var leftValue, rightValue any
var indexList *ListType
var ok bool
if leftValue, rightValue, err = self.evalInfix(ctx); err != nil {
if leftValue, rightValue, err = opTerm.evalInfix(ctx); err != nil {
return
}
indexTerm := self.children[1]
indexTerm := opTerm.children[1]
if indexList, ok = rightValue.(*ListType); !ok {
err = self.Errorf("invalid index expression")
err = opTerm.Errorf("invalid index expression")
return
} else if len(*indexList) != 1 {
err = indexTerm.Errorf("one index only is allowed")
@ -90,16 +90,9 @@ func evalIndex(ctx ExprContext, self *term) (v any, err error) {
v = string(unboxedValue[index])
}
case *DictType:
/* var ok bool
var indexValue any
if indexValue, err = verifyKey(indexTerm, indexList); err == nil {
if v, ok = (*unboxedValue)[indexValue]; !ok {
err = indexTerm.Errorf("key %v does not belong to the dictionary", rightValue)
}
} */
v, err = getDictItem(unboxedValue, indexTerm, indexList, rightValue)
default:
err = self.errIncompatibleTypes(leftValue, rightValue)
err = opTerm.errIncompatibleTypes(leftValue, rightValue)
}
} else if isIntPair((*indexList)[0]) {
switch unboxedValue := leftValue.(type) {
@ -115,18 +108,10 @@ func evalIndex(ctx ExprContext, self *term) (v any, err error) {
v = unboxedValue[start:end]
}
default:
err = self.errIncompatibleTypes(leftValue, rightValue)
err = opTerm.errIncompatibleTypes(leftValue, rightValue)
}
} else if IsDict(leftValue) {
d := leftValue.(*DictType)
/* var ok bool
var indexValue any
if indexValue, err = verifyKey(indexTerm, indexList); err == nil {
if v, ok = (*d)[indexValue]; !ok {
err = indexTerm.Errorf("key %v does not belong to the dictionary", rightValue)
}
}*/
v, err = getDictItem(d, indexTerm, indexList, rightValue)
}
return
@ -136,7 +121,7 @@ func getDictItem(d *DictType, indexTerm *term, indexList *ListType, rightValue a
var ok bool
var indexValue any
if indexValue, err = verifyKey(indexTerm, indexList); err == nil {
if indexValue, err = verifyKey(indexList); err == nil {
if v, ok = (*d)[indexValue]; !ok {
err = indexTerm.Errorf("key %v does not belong to the dictionary", rightValue)
}

View File

@ -26,10 +26,10 @@ func newAppendTerm(tk *Token) (inst *term) {
}
}
func evalInsert(ctx ExprContext, self *term) (v any, err error) {
func evalInsert(ctx ExprContext, opTerm *term) (v any, err error) {
var leftValue, rightValue any
if leftValue, rightValue, err = self.evalInfix(ctx); err != nil {
if leftValue, rightValue, err = opTerm.evalInfix(ctx); err != nil {
return
}
@ -37,19 +37,19 @@ func evalInsert(ctx ExprContext, self *term) (v any, err error) {
list, _ := rightValue.(*ListType)
newList := append(ListType{leftValue}, *list...)
v = &newList
if self.children[1].symbol() == SymVariable {
ctx.UnsafeSetVar(self.children[1].source(), v)
if opTerm.children[1].symbol() == SymVariable {
ctx.UnsafeSetVar(opTerm.children[1].source(), v)
}
} else {
err = self.errIncompatibleTypes(leftValue, rightValue)
err = opTerm.errIncompatibleTypes(leftValue, rightValue)
}
return
}
func evalAppend(ctx ExprContext, self *term) (v any, err error) {
func evalAppend(ctx ExprContext, opTerm *term) (v any, err error) {
var leftValue, rightValue any
if leftValue, rightValue, err = self.evalInfix(ctx); err != nil {
if leftValue, rightValue, err = opTerm.evalInfix(ctx); err != nil {
return
}
@ -57,11 +57,11 @@ func evalAppend(ctx ExprContext, self *term) (v any, err error) {
list, _ := leftValue.(*ListType)
newList := append(*list, rightValue)
v = &newList
if self.children[0].symbol() == SymVariable {
ctx.UnsafeSetVar(self.children[0].source(), v)
if opTerm.children[0].symbol() == SymVariable {
ctx.UnsafeSetVar(opTerm.children[0].source(), v)
}
} else {
err = self.errIncompatibleTypes(leftValue, rightValue)
err = opTerm.errIncompatibleTypes(leftValue, rightValue)
}
return
}

View File

@ -16,17 +16,17 @@ func newIterValueTerm(tk *Token) (inst *term) {
}
}
func evalIterValue(ctx ExprContext, self *term) (v any, err error) {
func evalIterValue(ctx ExprContext, opTerm *term) (v any, err error) {
var childValue any
if childValue, err = self.evalPrefix(ctx); err != nil {
if childValue, err = opTerm.evalPrefix(ctx); err != nil {
return
}
if it, ok := childValue.(Iterator); ok {
v, err = it.Current()
} else {
err = self.errIncompatibleType(childValue)
err = opTerm.errIncompatibleType(childValue)
}
return
}

View File

@ -16,10 +16,10 @@ func newLengthTerm(tk *Token) (inst *term) {
}
}
func evalLength(ctx ExprContext, self *term) (v any, err error) {
func evalLength(ctx ExprContext, opTerm *term) (v any, err error) {
var childValue any
if childValue, err = self.evalPrefix(ctx); err != nil {
if childValue, err = opTerm.evalPrefix(ctx); err != nil {
return
}
@ -41,7 +41,7 @@ func evalLength(ctx ExprContext, self *term) (v any, err error) {
v = int64(it.Index() + 1)
}
} else {
err = self.errIncompatibleType(childValue)
err = opTerm.errIncompatibleType(childValue)
}
return
}

View File

@ -20,11 +20,11 @@ func newPluginTerm(tk *Token) (inst *term) {
}
}
func evalPlugin(ctx ExprContext, self *term) (v any, err error) {
func evalPlugin(ctx ExprContext, opTerm *term) (v any, err error) {
var childValue any
var moduleSpec any
if childValue, err = self.evalPrefix(ctx); err != nil {
if childValue, err = opTerm.evalPrefix(ctx); err != nil {
return
}
@ -38,7 +38,7 @@ func evalPlugin(ctx ExprContext, self *term) (v any, err error) {
}
count++
} else {
err = self.Errorf("expected string as item nr %d, got %s", it.Index()+1, TypeName(moduleSpec))
err = opTerm.Errorf("expected string as item nr %d, got %s", it.Index()+1, TypeName(moduleSpec))
break
}
}

View File

@ -17,20 +17,20 @@ func newPostIncTerm(tk *Token) *term {
}
}
func evalPostInc(ctx ExprContext, self *term) (v any, err error) {
func evalPostInc(ctx ExprContext, opTerm *term) (v any, err error) {
var childValue any
if childValue, err = self.evalPrefix(ctx); err != nil {
if childValue, err = opTerm.evalPrefix(ctx); err != nil {
return
}
if it, ok := childValue.(Iterator); ok {
v, err = it.Next()
} else if IsInteger(childValue) && self.children[0].symbol() == SymVariable {
} else if IsInteger(childValue) && opTerm.children[0].symbol() == SymVariable {
v = childValue
i, _ := childValue.(int64)
ctx.SetVar(self.children[0].source(), i+1)
ctx.SetVar(opTerm.children[0].source(), i+1)
} else {
err = self.errIncompatibleType(childValue)
err = opTerm.errIncompatibleType(childValue)
}
return
}

View File

@ -14,8 +14,6 @@ import (
func newMultiplyTerm(tk *Token) (inst *term) {
return &term{
tk: *tk,
// class: classOperator,
// kind: kindUnknown,
children: make([]*term, 0, 2),
position: posInfix,
priority: priProduct,
@ -23,10 +21,10 @@ func newMultiplyTerm(tk *Token) (inst *term) {
}
}
func evalMultiply(ctx ExprContext, self *term) (v any, err error) {
func evalMultiply(ctx ExprContext, prodTerm *term) (v any, err error) {
var leftValue, rightValue any
if leftValue, rightValue, err = self.evalInfix(ctx); err != nil {
if leftValue, rightValue, err = prodTerm.evalInfix(ctx); err != nil {
return
}
@ -45,7 +43,7 @@ func evalMultiply(ctx ExprContext, self *term) (v any, err error) {
v = leftInt * rightInt
}
} else {
err = self.errIncompatibleTypes(leftValue, rightValue)
err = prodTerm.errIncompatibleTypes(leftValue, rightValue)
}
return
}
@ -55,8 +53,6 @@ func evalMultiply(ctx ExprContext, self *term) (v any, err error) {
func newDivideTerm(tk *Token) (inst *term) {
return &term{
tk: *tk,
// class: classOperator,
// kind: kindUnknown,
children: make([]*term, 0, 2),
position: posInfix,
priority: priProduct,
@ -64,10 +60,10 @@ func newDivideTerm(tk *Token) (inst *term) {
}
}
func evalDivide(ctx ExprContext, self *term) (v any, err error) {
func evalDivide(ctx ExprContext, opTerm *term) (v any, err error) {
var leftValue, rightValue any
if leftValue, rightValue, err = self.evalInfix(ctx); err != nil {
if leftValue, rightValue, err = opTerm.evalInfix(ctx); err != nil {
return
}
@ -90,7 +86,7 @@ func evalDivide(ctx ExprContext, self *term) (v any, err error) {
}
}
} else {
err = self.errIncompatibleTypes(leftValue, rightValue)
err = opTerm.errIncompatibleTypes(leftValue, rightValue)
}
return
}
@ -107,10 +103,10 @@ func newDivideAsFloatTerm(tk *Token) (inst *term) {
}
}
func evalDivideAsFloat(ctx ExprContext, self *term) (v any, err error) {
func evalDivideAsFloat(ctx ExprContext, floatDivTerm *term) (v any, err error) {
var leftValue, rightValue any
if leftValue, rightValue, err = self.evalInfix(ctx); err != nil {
if leftValue, rightValue, err = floatDivTerm.evalInfix(ctx); err != nil {
return
}
@ -122,18 +118,16 @@ func evalDivideAsFloat(ctx ExprContext, self *term) (v any, err error) {
v = numAsFloat(leftValue) / d
}
} else {
err = self.errIncompatibleTypes(leftValue, rightValue)
err = floatDivTerm.errIncompatibleTypes(leftValue, rightValue)
}
return
}
//-------- reminder term
func newReminderTerm(tk *Token) (inst *term) {
func newRemainderTerm(tk *Token) (inst *term) {
return &term{
tk: *tk,
// class: classOperator,
// kind: kindUnknown,
children: make([]*term, 0, 2),
position: posInfix,
priority: priProduct,
@ -141,10 +135,10 @@ func newReminderTerm(tk *Token) (inst *term) {
}
}
func evalReminder(ctx ExprContext, self *term) (v any, err error) {
func evalReminder(ctx ExprContext, ramainderTerm *term) (v any, err error) {
var leftValue, rightValue any
if leftValue, rightValue, err = self.evalInfix(ctx); err != nil {
if leftValue, rightValue, err = ramainderTerm.evalInfix(ctx); err != nil {
return
}
@ -157,7 +151,7 @@ func evalReminder(ctx ExprContext, self *term) (v any, err error) {
v = leftInt % rightInt
}
} else {
err = self.errIncompatibleTypes(leftValue, rightValue)
err = ramainderTerm.errIncompatibleTypes(leftValue, rightValue)
}
return
}
@ -167,5 +161,5 @@ func init() {
registerTermConstructor(SymStar, newMultiplyTerm)
registerTermConstructor(SymSlash, newDivideTerm)
registerTermConstructor(SymDotSlash, newDivideAsFloatTerm)
registerTermConstructor(SymPercent, newReminderTerm)
registerTermConstructor(SymPercent, newRemainderTerm)
}

View File

@ -34,25 +34,25 @@ func newRangeTerm(tk *Token) (inst *term) {
}
}
func evalRange(ctx ExprContext, self *term) (v any, err error) {
func evalRange(ctx ExprContext, opTerm *term) (v any, err error) {
var leftValue, rightValue any
// if err = self.checkOperands(); err != nil {
// return
// }
if len(self.children) == 0 {
if len(opTerm.children) == 0 {
leftValue = int64(0)
rightValue = int64(-1)
} else if len(self.children) == 1 {
if leftValue, err = self.children[0].compute(ctx); err != nil {
} else if len(opTerm.children) == 1 {
if leftValue, err = opTerm.children[0].compute(ctx); err != nil {
return
}
rightValue = int64(ConstLastIndex)
} else if leftValue, rightValue, err = self.evalInfix(ctx); err != nil {
} else if leftValue, rightValue, err = opTerm.evalInfix(ctx); err != nil {
return
}
if !(IsInteger(leftValue) && IsInteger(rightValue)) {
err = self.errIncompatibleTypes(leftValue, rightValue)
err = opTerm.errIncompatibleTypes(leftValue, rightValue)
return
}

View File

@ -45,10 +45,10 @@ func equals(a, b any, deepCmp deepFuncTemplate) (eq bool, err error) {
return
}
func evalEqual(ctx ExprContext, self *term) (v any, err error) {
func evalEqual(ctx ExprContext, opTerm *term) (v any, err error) {
var leftValue, rightValue any
if leftValue, rightValue, err = self.evalInfix(ctx); err != nil {
if leftValue, rightValue, err = opTerm.evalInfix(ctx); err != nil {
return
}
@ -68,8 +68,8 @@ func newNotEqualTerm(tk *Token) (inst *term) {
}
}
func evalNotEqual(ctx ExprContext, self *term) (v any, err error) {
if v, err = evalEqual(ctx, self); err == nil {
func evalNotEqual(ctx ExprContext, opTerm *term) (v any, err error) {
if v, err = evalEqual(ctx, opTerm); err == nil {
b, _ := ToBool(v)
v = !b
}
@ -119,13 +119,13 @@ func lessThan(self *term, a, b any) (isLess bool, err error) {
return
}
func evalLess(ctx ExprContext, self *term) (v any, err error) {
func evalLess(ctx ExprContext, opTerm *term) (v any, err error) {
var leftValue, rightValue any
if leftValue, rightValue, err = self.evalInfix(ctx); err != nil {
if leftValue, rightValue, err = opTerm.evalInfix(ctx); err != nil {
return
}
v, err = lessThan(self, leftValue, rightValue)
v, err = lessThan(opTerm, leftValue, rightValue)
return
}
@ -154,14 +154,14 @@ func lessThanOrEqual(self *term, a, b any) (isLessEq bool, err error) {
return
}
func evalLessEqual(ctx ExprContext, self *term) (v any, err error) {
func evalLessEqual(ctx ExprContext, opTerm *term) (v any, err error) {
var leftValue, rightValue any
if leftValue, rightValue, err = self.evalInfix(ctx); err != nil {
if leftValue, rightValue, err = opTerm.evalInfix(ctx); err != nil {
return
}
v, err = lessThanOrEqual(self, leftValue, rightValue)
v, err = lessThanOrEqual(opTerm, leftValue, rightValue)
return
}
@ -178,14 +178,14 @@ func newGreaterTerm(tk *Token) (inst *term) {
}
}
func evalGreater(ctx ExprContext, self *term) (v any, err error) {
func evalGreater(ctx ExprContext, opTerm *term) (v any, err error) {
var leftValue, rightValue any
if leftValue, rightValue, err = self.evalInfix(ctx); err != nil {
if leftValue, rightValue, err = opTerm.evalInfix(ctx); err != nil {
return
}
v, err = lessThan(self, rightValue, leftValue)
v, err = lessThan(opTerm, rightValue, leftValue)
return
}
@ -201,14 +201,14 @@ func newGreaterEqualTerm(tk *Token) (inst *term) {
}
}
func evalGreaterEqual(ctx ExprContext, self *term) (v any, err error) {
func evalGreaterEqual(ctx ExprContext, opTerm *term) (v any, err error) {
var leftValue, rightValue any
if leftValue, rightValue, err = self.evalInfix(ctx); err != nil {
if leftValue, rightValue, err = opTerm.evalInfix(ctx); err != nil {
return
}
v, err = lessThanOrEqual(self, rightValue, leftValue)
v, err = lessThanOrEqual(opTerm, rightValue, leftValue)
return
}

View File

@ -39,19 +39,19 @@ func trySelectorCase(ctx ExprContext, exprValue, caseSel any, caseIndex int) (ma
return
}
func evalSelector(ctx ExprContext, self *term) (v any, err error) {
func evalSelector(ctx ExprContext, opTerm *term) (v any, err error) {
var exprValue any
var match bool
if err = self.checkOperands(); err != nil {
if err = opTerm.checkOperands(); err != nil {
return
}
exprTerm := self.children[0]
exprTerm := opTerm.children[0]
if exprValue, err = exprTerm.compute(ctx); err != nil {
return
}
caseListTerm := self.children[1]
caseListTerm := opTerm.children[1]
caseList, _ := caseListTerm.value().([]*term)
for i, caseTerm := range caseList {
caseSel := caseTerm.value()

View File

@ -28,29 +28,29 @@ func newMinusSignTerm(tk *Token) (inst *term) {
}
}
func evalSign(ctx ExprContext, self *term) (v any, err error) {
func evalSign(ctx ExprContext, opTerm *term) (v any, err error) {
var rightValue any
if rightValue, err = self.evalPrefix(ctx); err != nil {
if rightValue, err = opTerm.evalPrefix(ctx); err != nil {
return
}
if IsFloat(rightValue) {
if self.tk.Sym == SymChangeSign {
if opTerm.tk.Sym == SymChangeSign {
f, _ := rightValue.(float64)
v = -f
} else {
v = rightValue
}
} else if IsInteger(rightValue) {
if self.tk.Sym == SymChangeSign {
if opTerm.tk.Sym == SymChangeSign {
i, _ := rightValue.(int64)
v = -i
} else {
v = rightValue
}
} else {
err = self.errIncompatibleType(rightValue)
err = opTerm.errIncompatibleType(rightValue)
}
return
}

View File

@ -21,10 +21,10 @@ func newPlusTerm(tk *Token) (inst *term) {
}
}
func evalPlus(ctx ExprContext, self *term) (v any, err error) {
func evalPlus(ctx ExprContext, plusTerm *term) (v any, err error) {
var leftValue, rightValue any
if leftValue, rightValue, err = self.evalInfix(ctx); err != nil {
if leftValue, rightValue, err = plusTerm.evalInfix(ctx); err != nil {
return
}
@ -44,12 +44,8 @@ func evalPlus(ctx ExprContext, self *term) (v any, err error) {
rightList, _ = rightValue.(*ListType)
sumList := make(ListType, 0, len(*leftList)+len(*rightList))
for _, item := range *leftList {
sumList = append(sumList, item)
}
for _, item := range *rightList {
sumList = append(sumList, item)
}
sumList = append(sumList, *leftList...)
sumList = append(sumList, *rightList...)
v = &sumList
} else if (isFraction(leftValue) && IsNumber(rightValue)) || (isFraction(rightValue) && IsNumber(leftValue)) {
if IsFloat(leftValue) || IsFloat(rightValue) {
@ -64,7 +60,7 @@ func evalPlus(ctx ExprContext, self *term) (v any, err error) {
c.merge(rightDict)
v = c
} else {
err = self.errIncompatibleTypes(leftValue, rightValue)
err = plusTerm.errIncompatibleTypes(leftValue, rightValue)
}
return
}
@ -81,10 +77,10 @@ func newMinusTerm(tk *Token) (inst *term) {
}
}
func evalMinus(ctx ExprContext, self *term) (v any, err error) {
func evalMinus(ctx ExprContext, minusTerm *term) (v any, err error) {
var leftValue, rightValue any
if leftValue, rightValue, err = self.evalInfix(ctx); err != nil {
if leftValue, rightValue, err = minusTerm.evalInfix(ctx); err != nil {
return
}
@ -109,7 +105,7 @@ func evalMinus(ctx ExprContext, self *term) (v any, err error) {
}
v = &diffList
} else {
err = self.errIncompatibleTypes(leftValue, rightValue)
err = minusTerm.errIncompatibleTypes(leftValue, rightValue)
}
return
}

View File

@ -18,13 +18,13 @@ func NewParser() (p *parser) {
return p
}
func (self *parser) parseFuncCall(scanner *scanner, allowVarRef bool, tk *Token) (tree *term, err error) {
func (parser *parser) parseFuncCall(scanner *scanner, allowVarRef bool, tk *Token) (tree *term, err error) {
args := make([]*term, 0, 10)
itemExpected := false
lastSym := SymUnknown
for lastSym != SymClosedRound && lastSym != SymEos {
var subTree *ast
if subTree, err = self.parseItem(scanner, allowVarRef, SymComma, SymClosedRound); err != nil {
if subTree, err = parser.parseItem(scanner, allowVarRef, SymComma, SymClosedRound); err != nil {
break
}
prev := scanner.Previous()
@ -48,7 +48,7 @@ func (self *parser) parseFuncCall(scanner *scanner, allowVarRef bool, tk *Token)
return
}
func (self *parser) parseFuncDef(scanner *scanner) (tree *term, err error) {
func (parser *parser) parseFuncDef(scanner *scanner) (tree *term, err error) {
// Example: "add = func(x,y) {x+y}
var body *ast
args := make([]*term, 0)
@ -65,7 +65,7 @@ func (self *parser) parseFuncDef(scanner *scanner) (tree *term, err error) {
if tk.Sym == SymEqual {
var paramExpr *ast
defaultParamsStarted = true
if paramExpr, err = self.parseItem(scanner, false, SymComma, SymClosedRound); err != nil {
if paramExpr, err = parser.parseItem(scanner, false, SymComma, SymClosedRound); err != nil {
break
}
param.forceChild(paramExpr.root)
@ -88,7 +88,7 @@ func (self *parser) parseFuncDef(scanner *scanner) (tree *term, err error) {
if err == nil {
tk = scanner.Next()
if tk.IsSymbol(SymOpenBrace) {
body, err = self.parseGeneral(scanner, true, true, SymClosedBrace)
body, err = parser.parseGeneral(scanner, true, true, SymClosedBrace)
} else {
err = tk.ErrorExpectedGot("{")
}
@ -104,7 +104,7 @@ func (self *parser) parseFuncDef(scanner *scanner) (tree *term, err error) {
return
}
func (self *parser) parseList(scanner *scanner, parsingIndeces bool, allowVarRef bool) (subtree *term, err error) {
func (parser *parser) parseList(scanner *scanner, parsingIndeces bool, allowVarRef bool) (subtree *term, err error) {
r, c := scanner.lastPos()
args := make([]*term, 0)
lastSym := SymUnknown
@ -112,7 +112,7 @@ func (self *parser) parseList(scanner *scanner, parsingIndeces bool, allowVarRef
for lastSym != SymClosedSquare && lastSym != SymEos {
var subTree *ast
zeroRequired := scanner.current.Sym == SymColon
if subTree, err = self.parseItem(scanner, allowVarRef, SymComma, SymClosedSquare); err == nil {
if subTree, err = parser.parseItem(scanner, allowVarRef, SymComma, SymClosedSquare); err == nil {
root := subTree.root
if root != nil {
if !parsingIndeces && root.symbol() == SymColon {
@ -153,14 +153,14 @@ func (self *parser) parseList(scanner *scanner, parsingIndeces bool, allowVarRef
return
}
func (self *parser) parseIterDef(scanner *scanner, allowVarRef bool) (subtree *term, err error) {
func (parser *parser) parseIterDef(scanner *scanner, allowVarRef bool) (subtree *term, err error) {
tk := scanner.Previous()
args := make([]*term, 0)
lastSym := SymUnknown
itemExpected := false
for lastSym != SymClosedRound && lastSym != SymEos {
var subTree *ast
if subTree, err = self.parseItem(scanner, allowVarRef, SymComma, SymClosedRound); err == nil {
if subTree, err = parser.parseItem(scanner, allowVarRef, SymComma, SymClosedRound); err == nil {
if subTree.root != nil {
args = append(args, subTree.root)
} else if itemExpected {
@ -184,7 +184,7 @@ func (self *parser) parseIterDef(scanner *scanner, allowVarRef bool) (subtree *t
return
}
func (self *parser) parseDictKey(scanner *scanner, allowVarRef bool) (key any, err error) {
func (parser *parser) parseDictKey(scanner *scanner, allowVarRef bool) (key any, err error) {
tk := scanner.Next()
if tk.Sym == SymError {
err = tk.Error()
@ -206,14 +206,14 @@ func (self *parser) parseDictKey(scanner *scanner, allowVarRef bool) (key any, e
return
}
func (self *parser) parseDictionary(scanner *scanner, allowVarRef bool) (subtree *term, err error) {
func (parser *parser) parseDictionary(scanner *scanner, allowVarRef bool) (subtree *term, err error) {
args := make(map[any]*term, 0)
lastSym := SymUnknown
itemExpected := false
for lastSym != SymClosedBrace && lastSym != SymEos {
var subTree *ast
var key any
if key, err = self.parseDictKey(scanner, allowVarRef); err != nil {
if key, err = parser.parseDictKey(scanner, allowVarRef); err != nil {
break
} else if key == nil {
tk := scanner.Previous()
@ -223,10 +223,10 @@ func (self *parser) parseDictionary(scanner *scanner, allowVarRef bool) (subtree
}
break
}
if subTree, err = self.parseItem(scanner, allowVarRef, SymComma, SymClosedBrace); err == nil {
if subTree, err = parser.parseItem(scanner, allowVarRef, SymComma, SymClosedBrace); err == nil {
if subTree.root != nil {
args[key] = subTree.root
} else if key != nil {
} else /*if key != nil*/ {
prev := scanner.Previous()
err = prev.ErrorExpectedGot("dictionary-value")
break
@ -248,7 +248,7 @@ func (self *parser) parseDictionary(scanner *scanner, allowVarRef bool) (subtree
return
}
func (self *parser) parseSelectorCase(scanner *scanner, allowVarRef bool, defaultCase bool) (caseTerm *term, err error) {
func (parser *parser) parseSelectorCase(scanner *scanner, allowVarRef bool, defaultCase bool) (caseTerm *term, err error) {
var filterList *term
var caseExpr *ast
tk := scanner.Next()
@ -259,7 +259,7 @@ func (self *parser) parseSelectorCase(scanner *scanner, allowVarRef bool, defaul
err = tk.Errorf("case list in default clause")
return
}
if filterList, err = self.parseList(scanner, false, allowVarRef); err != nil {
if filterList, err = parser.parseList(scanner, false, allowVarRef); err != nil {
return
}
tk = scanner.Next()
@ -270,7 +270,7 @@ func (self *parser) parseSelectorCase(scanner *scanner, allowVarRef bool, defaul
}
if tk.Sym == SymOpenBrace {
if caseExpr, err = self.parseGeneral(scanner, true, allowVarRef, SymClosedBrace); err != nil {
if caseExpr, err = parser.parseGeneral(scanner, true, allowVarRef, SymClosedBrace); err != nil {
return
}
} else {
@ -296,25 +296,25 @@ func addSelectorCase(selectorTerm, caseTerm *term) {
caseTerm.parent = selectorTerm
}
func (self *parser) parseSelector(scanner *scanner, tree *ast, allowVarRef bool) (selectorTerm *term, err error) {
func (parser *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 {
if caseTerm, err = parser.parseSelectorCase(scanner, allowVarRef, false); err == nil {
addSelectorCase(selectorTerm, caseTerm)
}
return
}
func (self *parser) parseItem(scanner *scanner, allowVarRef bool, termSymbols ...Symbol) (tree *ast, err error) {
return self.parseGeneral(scanner, false, allowVarRef, termSymbols...)
func (parser *parser) parseItem(scanner *scanner, allowVarRef bool, termSymbols ...Symbol) (tree *ast, err error) {
return parser.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 (parser *parser) Parse(scanner *scanner, termSymbols ...Symbol) (tree *ast, err error) {
return parser.parseGeneral(scanner, true, false, termSymbols...)
}
func couldBeACollection(t *term) bool {
@ -333,7 +333,7 @@ func couldBeACollection(t *term) bool {
// return areOut
// }
func (self *parser) parseGeneral(scanner *scanner, allowForest bool, allowVarRef bool, termSymbols ...Symbol) (tree *ast, err error) {
func (parser *parser) parseGeneral(scanner *scanner, allowForest bool, allowVarRef bool, termSymbols ...Symbol) (tree *ast, err error) {
var selectorTerm *term = nil
var currentTerm *term = nil
var tk *Token
@ -371,21 +371,21 @@ func (self *parser) parseGeneral(scanner *scanner, allowForest bool, allowVarRef
switch tk.Sym {
case SymOpenRound:
var subTree *ast
if subTree, err = self.parseGeneral(scanner, false, allowVarRef, SymClosedRound); err == nil {
if subTree, err = parser.parseGeneral(scanner, false, allowVarRef, SymClosedRound); err == nil {
subTree.root.priority = priValue
err = tree.addTerm(newExprTerm(subTree.root))
currentTerm = subTree.root
}
case SymFuncCall:
var funcCallTerm *term
if funcCallTerm, err = self.parseFuncCall(scanner, allowVarRef, tk); err == nil {
if funcCallTerm, err = parser.parseFuncCall(scanner, allowVarRef, tk); err == nil {
err = tree.addTerm(funcCallTerm)
currentTerm = funcCallTerm
}
case SymOpenSquare:
var listTerm *term
parsingIndeces := couldBeACollection(currentTerm)
if listTerm, err = self.parseList(scanner, parsingIndeces, allowVarRef); err == nil {
if listTerm, err = parser.parseList(scanner, parsingIndeces, allowVarRef); err == nil {
if parsingIndeces {
indexTk := NewToken(listTerm.tk.row, listTerm.tk.col, SymIndex, listTerm.source())
indexTerm := newTerm(indexTk)
@ -402,7 +402,7 @@ func (self *parser) parseGeneral(scanner *scanner, allowForest bool, allowVarRef
err = currentTerm.Errorf(`selector-case outside of a selector context`)
} else {
var mapTerm *term
if mapTerm, err = self.parseDictionary(scanner, allowVarRef); err == nil {
if mapTerm, err = parser.parseDictionary(scanner, allowVarRef); err == nil {
err = tree.addTerm(mapTerm)
currentTerm = mapTerm
}
@ -413,13 +413,13 @@ func (self *parser) parseGeneral(scanner *scanner, allowForest bool, allowVarRef
// }
case SymFuncDef:
var funcDefTerm *term
if funcDefTerm, err = self.parseFuncDef(scanner); err == nil {
if funcDefTerm, err = parser.parseFuncDef(scanner); err == nil {
err = tree.addTerm(funcDefTerm)
currentTerm = funcDefTerm
}
case SymDollarRound:
var iterDefTerm *term
if iterDefTerm, err = self.parseIterDef(scanner, allowVarRef); err == nil {
if iterDefTerm, err = parser.parseIterDef(scanner, allowVarRef); err == nil {
err = tree.addTerm(iterDefTerm)
currentTerm = iterDefTerm
}
@ -430,13 +430,13 @@ func (self *parser) parseGeneral(scanner *scanner, allowForest bool, allowVarRef
currentTerm, err = tree.addToken2(tk)
}
case SymQuestion:
if selectorTerm, err = self.parseSelector(scanner, tree, allowVarRef); err == nil {
if selectorTerm, err = parser.parseSelector(scanner, tree, allowVarRef); err == nil {
currentTerm = selectorTerm
}
case SymColon, SymDoubleColon:
var caseTerm *term
if selectorTerm != nil {
if caseTerm, err = self.parseSelectorCase(scanner, allowVarRef, tk.Sym == SymDoubleColon); err == nil {
if caseTerm, err = parser.parseSelectorCase(scanner, allowVarRef, tk.Sym == SymDoubleColon); err == nil {
addSelectorCase(selectorTerm, caseTerm)
currentTerm = caseTerm
if tk.Sym == SymDoubleColon {

View File

@ -29,7 +29,7 @@ func pluginExists(name string) (exists bool) {
func makePluginName(name string) (decorated string) {
var template string
if execName, err := os.Executable(); err != nil || strings.Index(execName, "debug") < 0 {
if execName, err := os.Executable(); err != nil || !strings.Contains(execName, "debug") {
template = "expr-%s-plugin.so"
} else {
template = "expr-%s-plugin.so.debug"

View File

@ -49,257 +49,257 @@ func DefaultTranslations() map[Symbol]Symbol {
// return self.current
// }
func (self *scanner) readChar() (ch byte, err error) {
if ch, err = self.stream.ReadByte(); err == nil {
func (scanner *scanner) readChar() (ch byte, err error) {
if ch, err = scanner.stream.ReadByte(); err == nil {
if ch == '\n' {
self.row++
self.column = 0
scanner.row++
scanner.column = 0
} else {
self.column++
scanner.column++
}
}
return
}
func (self *scanner) unreadChar() (err error) {
if err = self.stream.UnreadByte(); err == nil {
if self.column--; self.column == 0 {
if self.row--; self.row == 0 {
func (scanner *scanner) unreadChar() (err error) {
if err = scanner.stream.UnreadByte(); err == nil {
if scanner.column--; scanner.column == 0 {
if scanner.row--; scanner.row == 0 {
err = errors.New("unread beyond the stream boundary")
} else {
self.column = 1
scanner.column = 1
}
}
}
return
}
func (self *scanner) lastPos() (r, c int) {
if self.prev != nil {
r = self.prev.row
c = self.prev.col
func (scanner *scanner) lastPos() (r, c int) {
if scanner.prev != nil {
r = scanner.prev.row
c = scanner.prev.col
}
return
}
func (self *scanner) Previous() *Token {
return self.prev
func (scanner *scanner) Previous() *Token {
return scanner.prev
}
func (self *scanner) Next() (tk *Token) {
self.prev = self.current
tk = self.current
self.current = self.fetchNextToken()
func (scanner *scanner) Next() (tk *Token) {
scanner.prev = scanner.current
tk = scanner.current
scanner.current = scanner.fetchNextToken()
return tk
}
func (self *scanner) fetchNextToken() (tk *Token) {
func (scanner *scanner) fetchNextToken() (tk *Token) {
var ch byte
if err := self.skipBlanks(); err != nil {
return self.makeErrorToken(err)
if err := scanner.skipBlanks(); err != nil {
return scanner.makeErrorToken(err)
}
escape := false
for {
ch, _ = self.readChar()
ch, _ = scanner.readChar()
switch ch {
case '+':
if next, _ := self.peek(); next == '+' {
tk = self.moveOn(SymDoublePlus, ch, next)
if next, _ := scanner.peek(); next == '+' {
tk = scanner.moveOn(SymDoublePlus, ch, next)
} else if next == '=' {
tk = self.moveOn(SymPlusEqual, ch, next)
tk = scanner.moveOn(SymPlusEqual, ch, next)
} else {
tk = self.makeToken(SymPlus, ch)
tk = scanner.makeToken(SymPlus, ch)
}
case '-':
if next, _ := self.peek(); next == '-' {
tk = self.moveOn(SymDoubleMinus, ch, next)
if next, _ := scanner.peek(); next == '-' {
tk = scanner.moveOn(SymDoubleMinus, ch, next)
} else if next == '=' {
tk = self.moveOn(SymMinusEqual, ch, next)
tk = scanner.moveOn(SymMinusEqual, ch, next)
} else {
tk = self.makeToken(SymMinus, ch)
tk = scanner.makeToken(SymMinus, ch)
}
case '*':
if next, _ := self.peek(); next == '*' {
tk = self.moveOn(SymDoubleStar, ch, next)
if next, _ := scanner.peek(); next == '*' {
tk = scanner.moveOn(SymDoubleStar, ch, next)
// } else if next == '/' {
// tk = self.moveOn(SymClosedComment, ch, next)
} else {
tk = self.makeToken(SymStar, ch)
tk = scanner.makeToken(SymStar, ch)
}
case '/':
if next, _ := self.peek(); next == '*' {
self.readChar()
tk = self.fetchBlockComment()
if next, _ := scanner.peek(); next == '*' {
scanner.readChar()
tk = scanner.fetchBlockComment()
} else if next == '/' {
self.readChar()
tk = self.fetchOnLineComment()
scanner.readChar()
tk = scanner.fetchOnLineComment()
} else {
tk = self.makeToken(SymSlash, ch)
tk = scanner.makeToken(SymSlash, ch)
}
case '\\':
if escape {
tk = self.makeToken(SymBackSlash, ch)
tk = scanner.makeToken(SymBackSlash, ch)
escape = false
} else {
escape = true
}
case '|':
if next, _ := self.peek(); next == '|' {
tk = self.moveOn(SymDoubleVertBar, ch, next)
if next, _ := scanner.peek(); next == '|' {
tk = scanner.moveOn(SymDoubleVertBar, ch, next)
} else {
tk = self.makeToken(SymVertBar, ch)
tk = scanner.makeToken(SymVertBar, ch)
}
case ',':
tk = self.makeToken(SymComma, ch)
tk = scanner.makeToken(SymComma, ch)
case '^':
tk = self.makeToken(SymCaret, ch)
tk = scanner.makeToken(SymCaret, ch)
case ':':
if next, _ := self.peek(); next == ':' {
tk = self.moveOn(SymDoubleColon, ch, next)
if next, _ := scanner.peek(); next == ':' {
tk = scanner.moveOn(SymDoubleColon, ch, next)
} else {
tk = self.makeToken(SymColon, ch)
tk = scanner.makeToken(SymColon, ch)
}
case ';':
tk = self.makeToken(SymSemiColon, ch)
tk = scanner.makeToken(SymSemiColon, ch)
case '.':
//if next, _ := self.peek(); next >= '0' && next <= '9' {
// tk = self.parseNumber(ch)
//} else if next == '/' {
if next, _ := self.peek(); next == '/' {
tk = self.moveOn(SymDotSlash, ch, next)
if next, _ := scanner.peek(); next == '/' {
tk = scanner.moveOn(SymDotSlash, ch, next)
} else if next == '.' {
if next1, _ := self.peek(); next1 == '.' {
tk = self.moveOn(SymTripleDot, ch, next, next1)
if next1, _ := scanner.peek(); next1 == '.' {
tk = scanner.moveOn(SymTripleDot, ch, next, next1)
} else {
tk = self.moveOn(SymDoubleDot, ch, next)
tk = scanner.moveOn(SymDoubleDot, ch, next)
}
} else {
tk = self.makeToken(SymDot, ch)
tk = scanner.makeToken(SymDot, ch)
}
case '\'':
if escape {
tk = self.makeToken(SymQuote, ch)
tk = scanner.makeToken(SymQuote, ch)
escape = false
} else {
tk = self.fetchString(ch)
tk = scanner.fetchString(ch)
}
case '"':
if escape {
tk = self.makeToken(SymDoubleQuote, ch)
tk = scanner.makeToken(SymDoubleQuote, ch)
escape = false
} else {
tk = self.fetchString(ch)
tk = scanner.fetchString(ch)
}
case '`':
tk = self.makeToken(SymBackTick, ch)
tk = scanner.makeToken(SymBackTick, ch)
case '!':
if next, _ := self.peek(); next == '=' {
tk = self.moveOn(SymNotEqual, ch, next)
if next, _ := scanner.peek(); next == '=' {
tk = scanner.moveOn(SymNotEqual, ch, next)
} else {
tk = self.makeToken(SymExclamation, ch)
tk = scanner.makeToken(SymExclamation, ch)
}
case '?':
if next, _ := self.peek(); next == '?' {
tk = self.moveOn(SymDoubleQuestion, ch, next)
if next, _ := scanner.peek(); next == '?' {
tk = scanner.moveOn(SymDoubleQuestion, ch, next)
} else if next == '=' {
tk = self.moveOn(SymQuestionEqual, ch, next)
tk = scanner.moveOn(SymQuestionEqual, ch, next)
} else if next == '!' {
tk = self.moveOn(SymQuestionExclam, ch, next)
tk = scanner.moveOn(SymQuestionExclam, ch, next)
} else {
tk = self.makeToken(SymQuestion, ch)
tk = scanner.makeToken(SymQuestion, ch)
}
case '&':
if next, _ := self.peek(); next == '&' {
tk = self.moveOn(SymDoubleAmpersand, ch, next)
if next, _ := scanner.peek(); next == '&' {
tk = scanner.moveOn(SymDoubleAmpersand, ch, next)
} else {
tk = self.makeToken(SymAmpersand, ch)
tk = scanner.makeToken(SymAmpersand, ch)
}
case '%':
tk = self.makeToken(SymPercent, ch)
tk = scanner.makeToken(SymPercent, ch)
case '#':
tk = self.makeToken(SymHash, ch)
tk = scanner.makeToken(SymHash, ch)
case '@':
if next, _ := self.peek(); (next >= 'a' && next <= 'z') || (next >= 'A' && next <= 'Z') {
self.readChar()
if tk = self.fetchIdentifier(next); tk.Sym == SymIdentifier {
if next, _ := scanner.peek(); (next >= 'a' && next <= 'z') || (next >= 'A' && next <= 'Z') {
scanner.readChar()
if tk = scanner.fetchIdentifier(next); tk.Sym == SymIdentifier {
//tk.Sym = SymIdRef
tk.source = "@" + tk.source
} else {
tk = self.makeErrorToken(fmt.Errorf("invalid variable reference %q", tk.source))
tk = scanner.makeErrorToken(fmt.Errorf("invalid variable reference %q", tk.source))
}
} else if next == '@' {
tk = self.moveOn(SymDoubleAt, ch, next)
tk = scanner.moveOn(SymDoubleAt, ch, next)
} else {
tk = self.makeToken(SymAt, ch)
tk = scanner.makeToken(SymAt, ch)
}
case '_':
tk = self.makeToken(SymUndescore, ch)
tk = scanner.makeToken(SymUndescore, ch)
case '=':
if next, _ := self.peek(); next == '=' {
tk = self.moveOn(SymDoubleEqual, ch, next)
if next, _ := scanner.peek(); next == '=' {
tk = scanner.moveOn(SymDoubleEqual, ch, next)
} else {
tk = self.makeToken(SymEqual, ch)
tk = scanner.makeToken(SymEqual, ch)
}
case '<':
if next, _ := self.peek(); next == '=' {
tk = self.moveOn(SymLessOrEqual, ch, next)
if next, _ := scanner.peek(); next == '=' {
tk = scanner.moveOn(SymLessOrEqual, ch, next)
} else if next == '<' {
tk = self.moveOn(SymAppend, ch, next)
tk = scanner.moveOn(SymAppend, ch, next)
} else if next == '>' {
tk = self.moveOn(SymLessGreater, ch, next)
tk = scanner.moveOn(SymLessGreater, ch, next)
} else {
tk = self.makeToken(SymLess, ch)
tk = scanner.makeToken(SymLess, ch)
}
case '>':
if next, _ := self.peek(); next == '=' {
tk = self.moveOn(SymGreaterOrEqual, ch, next)
if next, _ := scanner.peek(); next == '=' {
tk = scanner.moveOn(SymGreaterOrEqual, ch, next)
} else if next == '>' {
tk = self.moveOn(SymInsert, ch, next)
tk = scanner.moveOn(SymInsert, ch, next)
} else {
tk = self.makeToken(SymGreater, ch)
tk = scanner.makeToken(SymGreater, ch)
}
case '$':
if next, _ := self.peek(); next == '(' {
tk = self.moveOn(SymDollarRound, ch, next)
if next, _ := scanner.peek(); next == '(' {
tk = scanner.moveOn(SymDollarRound, ch, next)
tk.source += ")"
} else if next == '$' {
tk = self.moveOn(SymDoubleDollar, ch, next)
tk = scanner.moveOn(SymDoubleDollar, ch, next)
} else {
tk = self.makeToken(SymDollar, ch)
tk = scanner.makeToken(SymDollar, ch)
}
case '(':
if next, _ := self.peek(); next == ')' {
tk = self.moveOn(SymOpenClosedRound, ch, next)
if next, _ := scanner.peek(); next == ')' {
tk = scanner.moveOn(SymOpenClosedRound, ch, next)
} else {
tk = self.makeToken(SymOpenRound, ch)
tk = scanner.makeToken(SymOpenRound, ch)
}
case ')':
tk = self.makeToken(SymClosedRound, ch)
tk = scanner.makeToken(SymClosedRound, ch)
case '[':
tk = self.makeToken(SymOpenSquare, ch)
tk = scanner.makeToken(SymOpenSquare, ch)
case ']':
tk = self.makeToken(SymClosedSquare, ch)
tk = scanner.makeToken(SymClosedSquare, ch)
case '{':
tk = self.makeToken(SymOpenBrace, ch)
tk = scanner.makeToken(SymOpenBrace, ch)
case '}':
tk = self.makeToken(SymClosedBrace, ch)
tk = scanner.makeToken(SymClosedBrace, ch)
case '~':
tk = self.makeToken(SymTilde, ch)
tk = scanner.makeToken(SymTilde, ch)
case 0:
if escape {
tk = self.makeErrorToken(errors.New("incomplete escape sequence"))
tk = scanner.makeErrorToken(errors.New("incomplete escape sequence"))
}
escape = false
default:
if /*ch == '_' ||*/ (ch >= 'a' && ch <= 'z') || (ch >= 'A' && ch <= 'Z') {
if tk = self.fetchIdentifier(ch); tk.Sym == SymKwFunc {
if next, _ := self.peek(); next == '(' {
tk = self.moveOn(SymFuncDef, ch, next)
if tk = scanner.fetchIdentifier(ch); tk.Sym == SymKwFunc {
if next, _ := scanner.peek(); next == '(' {
tk = scanner.moveOn(SymFuncDef, ch, next)
}
}
} else if ch >= '0' && ch <= '9' {
tk = self.parseNumber(ch)
tk = scanner.parseNumber(ch)
}
}
if !escape {
@ -307,14 +307,14 @@ func (self *scanner) fetchNextToken() (tk *Token) {
}
}
if tk == nil {
tk = NewErrorToken(self.row, self.column, fmt.Errorf("unknown symbol '%c'", ch))
tk = NewErrorToken(scanner.row, scanner.column, fmt.Errorf("unknown symbol '%c'", ch))
}
return
}
func (self *scanner) sync(err error) error {
func (scanner *scanner) sync(err error) error {
if err == nil {
err = self.unreadChar()
err = scanner.unreadChar()
}
return err
}
@ -335,32 +335,32 @@ func isHexDigit(ch byte) bool {
return (ch >= '0' && ch <= '9') || (ch >= 'a' && ch <= 'f') || (ch >= 'A' && ch <= 'F')
}
func (self *scanner) initBase(sb *strings.Builder, currentFirstCh byte) (firstCh byte, numBase int, digitFunc func(byte) bool, err error) {
func (scanner *scanner) initBase(currentFirstCh byte) (firstCh byte, numBase int, digitFunc func(byte) bool, err error) {
var ch byte
var digitType string
firstCh = currentFirstCh
digitFunc = isDecimalDigit
numBase = 10
if ch, err = self.peek(); err == nil {
if ch, err = scanner.peek(); err == nil {
if ch == 'b' || ch == 'B' {
numBase = 2
digitType = "binary"
self.readChar()
scanner.readChar()
digitFunc = isBinaryDigit
firstCh, err = self.readChar()
firstCh, err = scanner.readChar()
} else if ch == 'o' || ch == 'O' {
numBase = 8
digitType = "octal"
self.readChar()
scanner.readChar()
digitFunc = isOctalDigit
firstCh, err = self.readChar()
firstCh, err = scanner.readChar()
} else if ch == 'x' || ch == 'X' {
numBase = 16
digitType = "hex"
self.readChar()
scanner.readChar()
digitFunc = isHexDigit
firstCh, err = self.readChar()
firstCh, err = scanner.readChar()
}
if err == nil && !digitFunc(firstCh) {
if len(digitType) == 0 {
@ -374,7 +374,7 @@ func (self *scanner) initBase(sb *strings.Builder, currentFirstCh byte) (firstCh
return
}
func (self *scanner) parseNumber(firstCh byte) (tk *Token) {
func (scanner *scanner) parseNumber(firstCh byte) (tk *Token) {
var err error
var ch byte
var sym Symbol = SymInteger
@ -383,9 +383,9 @@ func (self *scanner) parseNumber(firstCh byte) (tk *Token) {
var numBase = 10
if firstCh == '0' {
firstCh, numBase, isDigit, err = self.initBase(&sb, firstCh)
firstCh, numBase, isDigit, err = scanner.initBase(firstCh)
}
for ch = firstCh; err == nil && isDigit(ch); ch, err = self.readChar() {
for ch = firstCh; err == nil && isDigit(ch); ch, err = scanner.readChar() {
sb.WriteByte(ch)
}
@ -393,9 +393,9 @@ func (self *scanner) parseNumber(firstCh byte) (tk *Token) {
if err == nil && ch == '.' {
sym = SymFloat
sb.WriteByte(ch)
ch, err = self.readChar()
ch, err = scanner.readChar()
if ch >= '0' && ch <= '9' {
for ; err == nil && (ch >= '0' && ch <= '9'); ch, err = self.readChar() {
for ; err == nil && (ch >= '0' && ch <= '9'); ch, err = scanner.readChar() {
sb.WriteByte(ch)
}
}
@ -404,32 +404,32 @@ func (self *scanner) parseNumber(firstCh byte) (tk *Token) {
if ch == 'e' || ch == 'E' {
sym = SymFloat
sb.WriteByte(ch)
if ch, err = self.readChar(); err == nil {
if ch, err = scanner.readChar(); err == nil {
if ch == '+' || ch == '-' {
sb.WriteByte(ch)
ch, err = self.readChar()
ch, err = scanner.readChar()
}
if ch >= '0' && ch <= '9' {
for ; err == nil && (ch >= '0' && ch <= '9'); ch, err = self.readChar() {
for ; err == nil && (ch >= '0' && ch <= '9'); ch, err = scanner.readChar() {
sb.WriteByte(ch)
}
} else {
err = fmt.Errorf("[%d:%d] expected integer exponent, got %c", self.row, self.column, ch)
err = fmt.Errorf("[%d:%d] expected integer exponent, got %c", scanner.row, scanner.column, ch)
}
}
} else if ch == '(' {
sym = SymFraction
sb.WriteByte(ch)
ch, err = self.readChar()
for ; err == nil && (ch >= '0' && ch <= '9'); ch, err = self.readChar() {
ch, err = scanner.readChar()
for ; err == nil && (ch >= '0' && ch <= '9'); ch, err = scanner.readChar() {
sb.WriteByte(ch)
}
if err == nil {
if ch != ')' {
err = fmt.Errorf("[%d:%d] expected ')', got '%c'", self.row, self.column, ch)
err = fmt.Errorf("[%d:%d] expected ')', got '%c'", scanner.row, scanner.column, ch)
} else {
sb.WriteByte(ch)
_, err = self.readChar()
_, err = scanner.readChar()
}
}
}
@ -437,10 +437,10 @@ func (self *scanner) parseNumber(firstCh byte) (tk *Token) {
}
if err != nil && err != io.EOF {
tk = self.makeErrorToken(err)
tk = scanner.makeErrorToken(err)
} else {
var value any
err = self.sync(err)
err = scanner.sync(err) // TODO: Check this function
txt := sb.String()
if sym == SymFloat {
value, err = strconv.ParseFloat(txt, 64)
@ -450,39 +450,39 @@ func (self *scanner) parseNumber(firstCh byte) (tk *Token) {
value, err = strconv.ParseInt(txt, numBase, 64)
}
if err == nil {
tk = self.makeValueToken(sym, txt, value)
tk = scanner.makeValueToken(sym, txt, value)
} else {
tk = self.makeErrorToken(err)
tk = scanner.makeErrorToken(err)
}
}
return
}
func (self *scanner) fetchIdentifier(firstCh byte) (tk *Token) {
func (scanner *scanner) fetchIdentifier(firstCh byte) (tk *Token) {
var err error
var sb strings.Builder
for ch := firstCh; err == nil && (ch == '_' || (ch >= 'a' && ch <= 'z') || (ch >= 'A' && ch <= 'Z') || (ch >= '0' && ch <= '9')); ch, err = self.readChar() {
for ch := firstCh; err == nil && (ch == '_' || (ch >= 'a' && ch <= 'z') || (ch >= 'A' && ch <= 'Z') || (ch >= '0' && ch <= '9')); ch, err = scanner.readChar() {
sb.WriteByte(ch)
}
if err != nil && err != io.EOF {
tk = self.makeErrorToken(err)
} else if err = self.sync(err); err != nil && err != io.EOF {
tk = self.makeErrorToken(err)
tk = scanner.makeErrorToken(err)
} else if err = scanner.sync(err); err != nil && err != io.EOF {
tk = scanner.makeErrorToken(err)
} else {
txt := sb.String()
uptxt := strings.ToUpper(txt)
if sym, ok := keywords[uptxt]; ok {
tk = self.makeKeywordToken(sym, uptxt)
tk = scanner.makeKeywordToken(sym, uptxt)
} else if uptxt == `TRUE` {
tk = self.makeValueToken(SymBool, txt, true)
tk = scanner.makeValueToken(SymBool, txt, true)
} else if uptxt == `FALSE` {
tk = self.makeValueToken(SymBool, txt, false)
} else if ch, _ := self.peek(); ch == '(' {
self.readChar()
tk = self.makeValueToken(SymFuncCall, txt+"(", txt)
tk = scanner.makeValueToken(SymBool, txt, false)
} else if ch, _ := scanner.peek(); ch == '(' {
scanner.readChar()
tk = scanner.makeValueToken(SymFuncCall, txt+"(", txt)
} else {
tk = self.makeValueToken(SymIdentifier, txt, txt)
tk = scanner.makeValueToken(SymIdentifier, txt, txt)
}
}
@ -502,29 +502,29 @@ func (self *scanner) fetchIdentifier(firstCh byte) (tk *Token) {
return
}
func (self *scanner) fetchBlockComment() *Token {
return self.fetchUntil(SymComment, false, '*', '/')
func (scanner *scanner) fetchBlockComment() *Token {
return scanner.fetchUntil(SymComment, false, '*', '/')
}
func (self *scanner) fetchOnLineComment() *Token {
return self.fetchUntil(SymComment, true, '\n')
func (scanner *scanner) fetchOnLineComment() *Token {
return scanner.fetchUntil(SymComment, true, '\n')
}
func (self *scanner) fetchUntil(sym Symbol, allowEos bool, endings ...byte) (tk *Token) {
func (scanner *scanner) fetchUntil(sym Symbol, allowEos bool, endings ...byte) (tk *Token) {
var err error
var ch byte
var sb strings.Builder
var value string
ring := NewByteSlider(len(endings))
endReached := false
for ch, err = self.readChar(); err == nil && !endReached; {
for ch, err = scanner.readChar(); err == nil && !endReached; {
sb.WriteByte(ch)
ring.PushEnd(ch)
if ring.Equal(endings) {
value = sb.String()[0 : sb.Len()-len(endings)]
endReached = true
} else {
ch, err = self.readChar()
ch, err = scanner.readChar()
}
}
if !endReached && allowEos {
@ -533,18 +533,18 @@ func (self *scanner) fetchUntil(sym Symbol, allowEos bool, endings ...byte) (tk
}
if endReached {
tk = self.makeValueToken(sym, "", value)
tk = scanner.makeValueToken(sym, "", value)
} else {
tk = self.makeErrorToken(err)
tk = scanner.makeErrorToken(err)
}
return
}
func (self *scanner) fetchString(termCh byte) (tk *Token) {
func (scanner *scanner) fetchString(termCh byte) (tk *Token) {
var err error
var ch, prev byte
var sb strings.Builder
for ch, err = self.readChar(); err == nil; ch, err = self.readChar() {
for ch, err = scanner.readChar(); err == nil; ch, err = scanner.readChar() {
if prev == '\\' {
switch ch {
case '"':
@ -572,65 +572,65 @@ func (self *scanner) fetchString(termCh byte) (tk *Token) {
}
if err != nil {
if err == io.EOF {
tk = self.makeErrorToken(errors.New("missing string termination \""))
tk = scanner.makeErrorToken(errors.New("missing string termination \""))
} else {
tk = self.makeErrorToken(err)
tk = scanner.makeErrorToken(err)
}
} else {
txt := sb.String()
tk = self.makeValueToken(SymString, `"`+txt+`"`, txt)
tk = scanner.makeValueToken(SymString, `"`+txt+`"`, txt)
}
return
}
func (self *scanner) peek() (next byte, err error) {
func (scanner *scanner) peek() (next byte, err error) {
var one []byte
if one, err = self.stream.Peek(1); err == nil {
if one, err = scanner.stream.Peek(1); err == nil {
next = one[0]
}
return
}
func (self *scanner) skipBlanks() (err error) {
func (scanner *scanner) skipBlanks() (err error) {
var one []byte
for one, err = self.stream.Peek(1); err == nil && one[0] <= 32; one, err = self.stream.Peek(1) {
self.readChar()
for one, err = scanner.stream.Peek(1); err == nil && one[0] <= 32; one, err = scanner.stream.Peek(1) {
scanner.readChar()
}
return
}
func (self *scanner) translate(sym Symbol) Symbol {
if self.translations != nil {
if translatedSym, ok := self.translations[sym]; ok {
func (scanner *scanner) translate(sym Symbol) Symbol {
if scanner.translations != nil {
if translatedSym, ok := scanner.translations[sym]; ok {
return translatedSym
}
}
return sym
}
func (self *scanner) moveOn(sym Symbol, chars ...byte) (tk *Token) {
tk = NewToken(self.row, self.column, self.translate(sym), string(chars))
func (scanner *scanner) moveOn(sym Symbol, chars ...byte) (tk *Token) {
tk = NewToken(scanner.row, scanner.column, scanner.translate(sym), string(chars))
for i := 1; i < len(chars); i++ {
self.readChar()
scanner.readChar()
}
return
}
func (self *scanner) makeToken(sym Symbol, chars ...byte) (tk *Token) {
tk = NewToken(self.row, self.column, self.translate(sym), string(chars))
func (scanner *scanner) makeToken(sym Symbol, chars ...byte) (tk *Token) {
tk = NewToken(scanner.row, scanner.column, scanner.translate(sym), string(chars))
return
}
func (self *scanner) makeKeywordToken(sym Symbol, upperCaseKeyword string) (tk *Token) {
tk = NewToken(self.row, self.column, self.translate(sym), upperCaseKeyword)
func (scanner *scanner) makeKeywordToken(sym Symbol, upperCaseKeyword string) (tk *Token) {
tk = NewToken(scanner.row, scanner.column, scanner.translate(sym), upperCaseKeyword)
return
}
func (self *scanner) makeValueToken(sym Symbol, source string, value any) (tk *Token) {
tk = NewValueToken(self.row, self.column, self.translate(sym), source, value)
func (scanner *scanner) makeValueToken(sym Symbol, source string, value any) (tk *Token) {
tk = NewValueToken(scanner.row, scanner.column, scanner.translate(sym), source, value)
return
}
func (self *scanner) makeErrorToken(err error) *Token {
return NewErrorToken(self.row, self.column, err)
func (scanner *scanner) makeErrorToken(err error) *Token {
return NewErrorToken(scanner.row, scanner.column, err)
}

View File

@ -25,7 +25,7 @@ func NewSimpleStore() *SimpleStore {
}
func filterRefName(name string) bool { return name[0] != '@' }
func filterPrivName(name string) bool { return name[0] != '_' }
//func filterPrivName(name string) bool { return name[0] != '_' }
func (ctx *SimpleStore) SetParent(parentCtx ExprContext) {
ctx.parent = parentCtx

View File

@ -6,7 +6,6 @@ package expr
import (
"errors"
"fmt"
"reflect"
"strings"
"testing"
@ -69,9 +68,9 @@ func TestScanner(t *testing.T) {
// continue
// }
if input.wantErr == nil {
t.Log(fmt.Sprintf("[+]Test nr %2d -- %q", i+1, input.source))
t.Logf("[+]Test nr %2d -- %q", i+1, input.source)
} else {
t.Log(fmt.Sprintf("[-]Test nr %2d -- %q", i+1, input.source))
t.Logf("[-]Test nr %2d -- %q", i+1, input.source)
}
r := strings.NewReader(input.source)

150
term.go
View File

@ -53,21 +53,21 @@ type term struct {
evalFunc evalFuncType
}
func (self *term) String() string {
func (term *term) String() string {
var sb strings.Builder
self.toString(&sb)
term.toString(&sb)
return sb.String()
}
func (self *term) toString(sb *strings.Builder) {
if self.position == posLeaf {
sb.WriteString(self.tk.String())
func (term *term) toString(sb *strings.Builder) {
if term.position == posLeaf {
sb.WriteString(term.tk.String())
} else {
sb.WriteByte('[')
sb.WriteString(self.tk.String())
if self.children != nil {
sb.WriteString(term.tk.String())
if term.children != nil {
sb.WriteByte('(')
for i, c := range self.children {
for i, c := range term.children {
if i > 0 {
sb.WriteByte(' ')
}
@ -79,17 +79,17 @@ func (self *term) toString(sb *strings.Builder) {
}
}
func (self *term) getChildrenCount() (count int) {
if self.position == posLeaf || self.children == nil {
func (term *term) getChildrenCount() (count int) {
if term.position == posLeaf || term.children == nil {
count = 0
} else {
count = len(self.children)
count = len(term.children)
}
return
}
func (self *term) getRoom() (room int) {
switch self.position {
func (term *term) getRoom() (room int) {
switch term.position {
case posLeaf:
room = 0
case posInfix:
@ -102,139 +102,139 @@ func (self *term) getRoom() (room int) {
return
}
func (self *term) isComplete() bool {
return self.getChildrenCount() == self.getRoom()
func (term *term) isComplete() bool {
return term.getChildrenCount() == term.getRoom()
}
func (self *term) removeLastChild() (child *term) {
if self.children != nil {
child = self.children[len(self.children)-1]
self.children = self.children[0 : len(self.children)-1]
func (term *term) removeLastChild() (child *term) {
if term.children != nil {
child = term.children[len(term.children)-1]
term.children = term.children[0 : len(term.children)-1]
} else {
panic("Can't get last child")
}
return
}
func (self *term) isLeaf() bool {
return self.position == posLeaf
func (term *term) isLeaf() bool {
return term.position == posLeaf
}
func (self *term) getPriority() termPriority {
return self.priority
func (term *term) getPriority() termPriority {
return term.priority
}
func (self *term) setParent(parent *term) {
self.parent = parent
func (term *term) setParent(parent *term) {
term.parent = parent
if parent != nil && len(parent.children) < cap(parent.children) {
parent.children = append(parent.children, self)
parent.children = append(parent.children, term)
}
}
func (self *term) symbol() Symbol {
return self.tk.Sym
func (term *term) symbol() Symbol {
return term.tk.Sym
}
func (self *term) source() string {
return self.tk.source
func (term *term) source() string {
return term.tk.source
}
func (self *term) value() any {
return self.tk.Value
func (term *term) value() any {
return term.tk.Value
}
func (self *term) compute(ctx ExprContext) (v any, err error) {
if self.evalFunc == nil {
err = self.tk.Errorf("undefined eval-func for %q term", self.source())
func (term *term) compute(ctx ExprContext) (v any, err error) {
if term.evalFunc == nil {
err = term.tk.Errorf("undefined eval-func for %q term", term.source())
} else {
v, err = self.evalFunc(ctx, self)
v, err = term.evalFunc(ctx, term)
}
return
}
func (self *term) toInt(computedValue any, valueDescription string) (i int, err error) {
if index64, ok := computedValue.(int64); ok {
i = int(index64)
} else {
err = self.Errorf("%s, got %s (%v)", valueDescription, TypeName(computedValue), computedValue)
}
return
}
// func (term *term) toInt(computedValue any, valueDescription string) (i int, err error) {
// if index64, ok := computedValue.(int64); ok {
// i = int(index64)
// } else {
// err = term.Errorf("%s, got %s (%v)", valueDescription, TypeName(computedValue), computedValue)
// }
// return
// }
func (self *term) errIncompatibleTypes(leftValue, rightValue any) error {
func (term *term) errIncompatibleTypes(leftValue, rightValue any) error {
leftType := TypeName(leftValue)
leftText := getFormatted(leftValue, Truncate)
rightType := TypeName(rightValue)
rightText := getFormatted(rightValue, Truncate)
return self.tk.Errorf(
return term.tk.Errorf(
"left operand '%s' [%s] and right operand '%s' [%s] are not compatible with operator %q",
leftText, leftType,
rightText, rightType,
self.source())
term.source())
}
func (self *term) errIncompatibleType(value any) error {
return self.tk.Errorf(
func (term *term) errIncompatibleType(value any) error {
return term.tk.Errorf(
"prefix/postfix operator %q do not support operand '%v' [%s]",
self.source(), value, TypeName(value))
term.source(), value, TypeName(value))
}
func (self *term) Errorf(template string, args ...any) (err error) {
err = self.tk.Errorf(template, args...)
func (term *term) Errorf(template string, args ...any) (err error) {
err = term.tk.Errorf(template, args...)
return
}
func (self *term) checkOperands() (err error) {
switch self.position {
func (term *term) checkOperands() (err error) {
switch term.position {
case posInfix:
if self.children == nil || len(self.children) != 2 || self.anyChildrenNil() {
err = self.tk.Errorf("infix operator %q requires two non-nil operands, got %d", self.source(), self.getChildrenCount())
if term.children == nil || len(term.children) != 2 || term.anyChildrenNil() {
err = term.tk.Errorf("infix operator %q requires two non-nil operands, got %d", term.source(), term.getChildrenCount())
}
case posPrefix:
if self.children == nil || len(self.children) != 1 || self.children[0] == nil {
err = self.tk.Errorf("prefix operator %q requires one not nil operand", self.tk.String())
if term.children == nil || len(term.children) != 1 || term.children[0] == nil {
err = term.tk.Errorf("prefix operator %q requires one not nil operand", term.tk.String())
}
case posPostfix:
if self.children == nil || len(self.children) != 1 || self.anyChildrenNil() {
err = self.tk.Errorf("postfix operator %q requires one not nil operand", self.tk.String())
if term.children == nil || len(term.children) != 1 || term.anyChildrenNil() {
err = term.tk.Errorf("postfix operator %q requires one not nil operand", term.tk.String())
}
case posMultifix:
if self.children == nil || len(self.children) < 3 || self.anyChildrenNil() {
err = self.tk.Errorf("infix operator %q requires at least three not operands, got %d", self.source(), self.getChildrenCount())
if term.children == nil || len(term.children) < 3 || term.anyChildrenNil() {
err = term.tk.Errorf("infix operator %q requires at least three not operands, got %d", term.source(), term.getChildrenCount())
}
}
return
}
func (self *term) anyChildrenNil() bool {
for _, child := range self.children {
func (term *term) anyChildrenNil() bool {
for _, child := range term.children {
if child == nil {
return true
}
}
return false
}
func (self *term) evalInfix(ctx ExprContext) (leftValue, rightValue any, err error) {
if err = self.checkOperands(); err == nil {
if leftValue, err = self.children[0].compute(ctx); err == nil {
rightValue, err = self.children[1].compute(ctx)
func (term *term) evalInfix(ctx ExprContext) (leftValue, rightValue any, err error) {
if err = term.checkOperands(); err == nil {
if leftValue, err = term.children[0].compute(ctx); err == nil {
rightValue, err = term.children[1].compute(ctx)
}
}
return
}
func (self *term) evalPrefix(ctx ExprContext) (childValue any, err error) {
if err = self.checkOperands(); err == nil {
childValue, err = self.children[0].compute(ctx)
func (term *term) evalPrefix(ctx ExprContext) (childValue any, err error) {
if err = term.checkOperands(); err == nil {
childValue, err = term.children[0].compute(ctx)
}
return
}
// NOTE Temporary solution to support function parameters with default value
func (self *term) forceChild(c *term) {
if self.children == nil {
self.children = make([]*term, 0, 1)
func (t *term) forceChild(c *term) {
if t.children == nil {
t.children = make([]*term, 0, 1)
}
self.children = append(self.children, c)
t.children = append(t.children, c)
}

View File

@ -33,7 +33,7 @@ func (tk *Token) String() string {
return fmt.Sprintf("%v", tk.Value)
}
}
return fmt.Sprintf("%s", tk.source)
return tk.source
}
func NewToken(row, col int, sym Symbol, source string) *Token {
@ -71,31 +71,31 @@ func (tk *Token) IsSymbol(sym Symbol) bool {
return tk.Sym == sym
}
func (self *Token) Errorf(template string, args ...any) (err error) {
err = fmt.Errorf(fmt.Sprintf("[%d:%d] ", self.row, self.col)+template, args...)
func (tk *Token) Errorf(template string, args ...any) (err error) {
err = fmt.Errorf(fmt.Sprintf("[%d:%d] ", tk.row, tk.col)+template, args...)
return
}
func (self *Token) Error() (err error) {
if self.Sym == SymError {
if msg, ok := self.Value.(error); ok {
err = fmt.Errorf("[%d:%d] %v", self.row, self.col, msg)
func (tk *Token) Error() (err error) {
if tk.Sym == SymError {
if msg, ok := tk.Value.(error); ok {
err = fmt.Errorf("[%d:%d] %v", tk.row, tk.col, msg)
}
}
return
}
func (self *Token) Errors(msg string) (err error) {
err = fmt.Errorf("[%d:%d] %v", self.row, self.col, msg)
func (tk *Token) Errors(msg string) (err error) {
err = fmt.Errorf("[%d:%d] %v", tk.row, tk.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)
func (tk *Token) ErrorExpectedGot(symbol string) (err error) {
err = fmt.Errorf("[%d:%d] expected %q, got %q", tk.row, tk.col, symbol, tk)
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)
func (tk *Token) ErrorExpectedGotString(symbol, got string) (err error) {
err = fmt.Errorf("[%d:%d] expected %q, got %q", tk.row, tk.col, symbol, got)
return
}