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

View File

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

View File

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

View File

@ -18,17 +18,17 @@ func NewByteSlider(size int) *ByteSlider {
} }
} }
func (self *ByteSlider) PushEnd(b byte) { func (slider *ByteSlider) PushEnd(b byte) {
if self.length == cap(self.buf) { if slider.length == cap(slider.buf) {
self.length-- slider.length--
for i := 0; i < self.length; i++ { for i := 0; i < slider.length; i++ {
self.buf[i] = self.buf[i+1] slider.buf[i] = slider.buf[i+1]
} }
} }
self.buf[self.length] = b slider.buf[slider.length] = b
self.length++ slider.length++
} }
func (self *ByteSlider) Equal(target []byte) bool { func (slider *ByteSlider) Equal(target []byte) bool {
return target != nil && bytes.Equal(self.buf, target) 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). // Copyright (c) 2024 Celestino Amoroso (celestino.amoroso@gmail.com).
// All rights reserved. // All rights reserved.
// context.go // expr-function.go
package expr package expr
// ---- Functor interface // ---- Functor interface
@ -35,21 +35,3 @@ type ExprFunc interface {
PrepareCall(parentCtx ExprContext, name string, varParams *[]any) (ctx ExprContext, err error) PrepareCall(parentCtx ExprContext, name string, varParams *[]any) (ctx ExprContext, err error)
AllocContext(parentCtx ExprContext) (ctx ExprContext) 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] == '+' { } else if s[0] == '+' {
s = s[1:] s = s[1:]
} }
if strings.HasSuffix(s, "()") { // if strings.HasSuffix(s, "()") {
s = s[0 : len(s)-2] // s = s[0 : len(s)-2]
} // }
s = strings.TrimSuffix(s, "()")
parts = strings.SplitN(s, ".", 2) parts = strings.SplitN(s, ".", 2)
if num, err = strconv.ParseInt(parts[0], 10, 64); err != nil { if num, err = strconv.ParseInt(parts[0], 10, 64); err != nil {
return return
@ -311,7 +312,6 @@ func divAnyFract(af1, af2 any) (quot any, err error) {
if f2.num == 0 { if f2.num == 0 {
err = errors.New("division by zero") err = errors.New("division by zero")
return return
return
} }
if f1.num == 0 || f2.den == 0 { if f1.num == 0 || f2.den == 0 {
quot = 0 quot = 0

View File

@ -112,7 +112,6 @@ type funcInfo struct {
func newFuncInfo(name string, functor Functor, returnType string, params []ExprFuncParam) (info *funcInfo, err error) { func newFuncInfo(name string, functor Functor, returnType string, params []ExprFuncParam) (info *funcInfo, err error) {
var minArgs = 0 var minArgs = 0
var maxArgs = 0 var maxArgs = 0
if params != nil {
for _, p := range params { for _, p := range params {
if maxArgs == -1 { if maxArgs == -1 {
return nil, fmt.Errorf("no more params can be specified after the ellipsis symbol: %q", p.Name()) return nil, fmt.Errorf("no more params can be specified after the ellipsis symbol: %q", p.Name())
@ -130,7 +129,7 @@ func newFuncInfo(name string, functor Functor, returnType string, params []ExprF
maxArgs = -1 maxArgs = -1
} }
} }
}
info = &funcInfo{ info = &funcInfo{
name: name, minArgs: minArgs, maxArgs: maxArgs, functor: functor, returnType: returnType, formalParams: params, 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 return
} }
func addSourceEnvImportDirs(varName string, dirList []string) []string { // func addSourceEnvImportDirs(varName string, dirList []string) []string {
return addEnvImportDirs(ENV_EXPR_SOURCE_PATH, dirList) // return addEnvImportDirs(ENV_EXPR_SOURCE_PATH, dirList)
} // }
func addPluginEnvImportDirs(varName string, dirList []string) []string { // func addPluginEnvImportDirs(varName string, dirList []string) []string {
return addEnvImportDirs(ENV_EXPR_PLUGIN_PATH, dirList) // return addEnvImportDirs(ENV_EXPR_PLUGIN_PATH, dirList)
} // }
func addEnvImportDirs(envVarName string, dirList []string) []string { func addEnvImportDirs(envVarName string, dirList []string) []string {
if dirSpec, exists := os.LookupEnv(envVarName); exists { 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) { func NewList(listAny []any) (list *ListType) {
if listAny != nil { if listAny != nil {
ls := make(ListType, len(listAny)) ls := make(ListType, len(listAny))
for i, item := range listAny { // for i, item := range listAny {
ls[i] = item // ls[i] = item
} // }
copy(ls, listAny)
list = &ls list = &ls
} }
return return
@ -105,16 +106,16 @@ func (ls *ListType) TypeName() string {
return "list" return "list"
} }
func (list *ListType) indexDeepCmp(target any) (index int) { // func (list *ListType) indexDeepCmp(target any) (index int) {
index = -1 // index = -1
for i, item := range *list { // for i, item := range *list {
if reflect.DeepEqual(item, target) { // if reflect.DeepEqual(item, target) {
index = i // index = i
break // break
} // }
} // }
return // return
} // }
func (ls *ListType) contains(t *ListType) (answer bool) { func (ls *ListType) contains(t *ListType) (answer bool) {
if len(*ls) >= len(*t) { if len(*ls) >= len(*t) {

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@ -41,10 +41,10 @@ func newSelectorCaseTerm(row, col int, filterList *term, caseExpr Expr) *term {
} }
// -------- eval selector case // -------- 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 var ok bool
if v, ok = self.value().(*selectorCase); !ok { if v, ok = opTerm.value().(*selectorCase); !ok {
err = fmt.Errorf("selector-case expected, got %T", self.value()) err = fmt.Errorf("selector-case expected, got %T", opTerm.value())
} }
return return
} }

View File

@ -21,9 +21,9 @@ func newVarTerm(tk *Token) *term {
} }
// -------- eval func // -------- 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 var exists bool
name := self.source() name := opTerm.source()
if v, exists = GetVar(ctx, name); !exists { if v, exists = GetVar(ctx, name); !exists {
if info, exists, _ := GetFuncInfo(ctx, name); exists { if info, exists, _ := GetFuncInfo(ctx, name); exists {
v = info.Functor() v = info.Functor()

View File

@ -60,19 +60,19 @@ func assignValue(ctx ExprContext, leftTerm *term, v any) (err error) {
return return
} }
func evalAssign(ctx ExprContext, self *term) (v any, err error) { func evalAssign(ctx ExprContext, opTerm *term) (v any, err error) {
if err = self.checkOperands(); err != nil { if err = opTerm.checkOperands(); err != nil {
return return
} }
leftTerm := self.children[0] leftTerm := opTerm.children[0]
leftSym := leftTerm.symbol() leftSym := leftTerm.symbol()
if leftSym != SymVariable && leftSym != SymIndex { 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 return
} }
rightChild := self.children[1] rightChild := opTerm.children[1]
if v, err = rightChild.compute(ctx); err == nil { if v, err = rightChild.compute(ctx); err == nil {
if functor, ok := v.(Functor); ok { 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) ctx.RegisterFunc(leftTerm.source(), functor, TypeAny, paramSpecs)
} else { } else {
err = self.Errorf("unknown function %s()", rightChild.source()) err = opTerm.Errorf("unknown function %s()", rightChild.source())
} }
} else { } else {
err = assignValue(ctx, leftTerm, v) 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 var rightValue any
if rightValue, err = self.evalPrefix(ctx); err != nil { if rightValue, err = opTerm.evalPrefix(ctx); err != nil {
return return
} }
if b, ok := ToBool(rightValue); ok { if b, ok := ToBool(rightValue); ok {
v = !b v = !b
} else { } else {
err = self.errIncompatibleType(rightValue) err = opTerm.errIncompatibleType(rightValue)
} }
return 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 var childValue any
if childValue, err = self.evalPrefix(ctx); err != nil { if childValue, err = opTerm.evalPrefix(ctx); err != nil {
return return
} }
@ -37,11 +37,11 @@ func evalBuiltin(ctx ExprContext, self *term) (v any, err error) {
if ImportInContext(module) { if ImportInContext(module) {
count++ count++
} else { } else {
err = self.Errorf("unknown builtin module %q", module) err = opTerm.Errorf("unknown builtin module %q", module)
break break
} }
} else { } 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 break
} }
} }

View File

@ -16,8 +16,8 @@ func newButTerm(tk *Token) (inst *term) {
} }
} }
func evalBut(ctx ExprContext, self *term) (v any, err error) { func evalBut(ctx ExprContext, opTerm *term) (v any, err error) {
_, v, err = self.evalInfix(ctx) _, v, err = opTerm.evalInfix(ctx)
return 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 childValue any
var sourceCtx ExprContext var sourceCtx ExprContext
if self.children == nil || len(self.children) == 0 { if opTerm.children == nil || len(opTerm.children) == 0 {
sourceCtx = ctx 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 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 { if dc, ok := childValue.(*dataCursor); ok {
sourceCtx = dc.ctx sourceCtx = dc.ctx
} }
@ -49,7 +49,7 @@ func evalContextValue(ctx ExprContext, self *term) (v any, err error) {
v = d v = d
} }
} else { } else {
err = self.errIncompatibleType(childValue) err = opTerm.errIncompatibleType(childValue)
} }
return 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) CtrlEnable(ctx, control_export_all)
return 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 var rightValue any
if err = self.checkOperands(); err != nil { if err = opTerm.checkOperands(); err != nil {
return return
} }
leftTerm := self.children[0] leftTerm := opTerm.children[0]
if leftTerm.tk.Sym != SymVariable { if leftTerm.tk.Sym != SymVariable {
// err = leftTerm.Errorf("left operand of %q must be a variable", self.tk.source) // err = leftTerm.Errorf("left operand of %q must be a variable", self.tk.source)
err = ErrLeftOperandMustBeVariable(leftTerm, self) err = ErrLeftOperandMustBeVariable(leftTerm, opTerm)
return return
} }
if leftValue, exists := ctx.GetVar(leftTerm.source()); exists { if leftValue, exists := ctx.GetVar(leftTerm.source()); exists {
v = leftValue 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 v = rightValue
} }
return 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 var rightValue any
if err = self.checkOperands(); err != nil { if err = opTerm.checkOperands(); err != nil {
return return
} }
leftTerm := self.children[0] leftTerm := opTerm.children[0]
if leftTerm.tk.Sym != SymVariable { if leftTerm.tk.Sym != SymVariable {
// err = leftTerm.Errorf("left operand of %q must be a variable", self.tk.source) // err = leftTerm.Errorf("left operand of %q must be a variable", self.tk.source)
err = ErrLeftOperandMustBeVariable(leftTerm, self) err = ErrLeftOperandMustBeVariable(leftTerm, opTerm)
return return
} }
if leftValue, exists := ctx.GetVar(leftTerm.source()); exists && leftValue != nil { 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 v = rightValue
} }
} else { } 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 var rightValue any
if err = self.checkOperands(); err != nil { if err = opTerm.checkOperands(); err != nil {
return return
} }
leftTerm := self.children[0] leftTerm := opTerm.children[0]
if leftTerm.tk.Sym != SymVariable { if leftTerm.tk.Sym != SymVariable {
// err = leftTerm.Errorf("left operand of %q must be a variable", self.tk.source) // err = leftTerm.Errorf("left operand of %q must be a variable", self.tk.source)
err = ErrLeftOperandMustBeVariable(leftTerm, self) err = ErrLeftOperandMustBeVariable(leftTerm, opTerm)
return return
} }
if leftValue, exists := ctx.GetVar(leftTerm.source()); exists { if leftValue, exists := ctx.GetVar(leftTerm.source()); exists {
v = leftValue 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 { if functor, ok := rightValue.(Functor); ok {
//ctx.RegisterFunc(leftTerm.source(), functor, 0, -1) //ctx.RegisterFunc(leftTerm.source(), functor, 0, -1)
ctx.RegisterFunc(leftTerm.source(), functor, TypeAny, []ExprFuncParam{ 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 var leftValue, rightValue any
if err = self.checkOperands(); err != nil { if err = opTerm.checkOperands(); err != nil {
return return
} }
if leftValue, err = self.children[0].compute(ctx); err != nil { if leftValue, err = opTerm.children[0].compute(ctx); err != nil {
return return
} }
indexTerm := self.children[1] indexTerm := opTerm.children[1]
switch unboxedValue := leftValue.(type) { switch unboxedValue := leftValue.(type) {
case ExtIterator: case ExtIterator:
@ -41,8 +41,8 @@ func evalDot(ctx ExprContext, self *term) (v any, err error) {
err = indexTerm.tk.ErrorExpectedGot("identifier") err = indexTerm.tk.ErrorExpectedGot("identifier")
} }
default: default:
if rightValue, err = self.children[1].compute(ctx); err == nil { if rightValue, err = opTerm.children[1].compute(ctx); err == nil {
err = self.errIncompatibleTypes(leftValue, rightValue) err = opTerm.errIncompatibleTypes(leftValue, rightValue)
} }
} }
return 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 var leftValue any
if leftValue, err = self.evalPrefix(ctx); err != nil { if leftValue, err = opTerm.evalPrefix(ctx); err != nil {
return 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) err = fmt.Errorf("factorial of a negative integer (%d) is not allowed", i)
} }
} else { } else {
err = self.errIncompatibleType(leftValue) err = opTerm.errIncompatibleType(leftValue)
} }
return return
} }

View File

@ -24,12 +24,12 @@ func newFractionTerm(tk *Token) *term {
} }
// -------- eval func // -------- 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 numValue, denValue any
var num, den int64 var num, den int64
var ok bool var ok bool
if numValue, denValue, err = self.evalInfix(ctx); err != nil { if numValue, denValue, err = opTerm.evalInfix(ctx); err != nil {
return return
} }
if num, ok = numValue.(int64); !ok { if num, ok = numValue.(int64); !ok {

View File

@ -21,10 +21,10 @@ func newInTerm(tk *Token) (inst *term) {
// return // 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 var leftValue, rightValue any
if leftValue, rightValue, err = self.evalInfix(ctx); err != nil { if leftValue, rightValue, err = opTerm.evalInfix(ctx); err != nil {
return return
} }
@ -35,7 +35,7 @@ func evalIn(ctx ExprContext, self *term) (v any, err error) {
dict, _ := rightValue.(*DictType) dict, _ := rightValue.(*DictType)
v = dict.hasKey(leftValue) v = dict.hasKey(leftValue)
} else { } else {
err = self.errIncompatibleTypes(leftValue, rightValue) err = opTerm.errIncompatibleTypes(leftValue, rightValue)
} }
return 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 var childValue any
if childValue, err = self.evalPrefix(ctx); err != nil { if childValue, err = opTerm.evalPrefix(ctx); err != nil {
return return
} }
@ -31,11 +31,11 @@ func evalInclude(ctx ExprContext, self *term) (v any, err error) {
if v, err = EvalFile(ctx, filePath); err == nil { if v, err = EvalFile(ctx, filePath); err == nil {
count++ count++
} else { } else {
err = self.Errorf("can't load file %q", filePath) err = opTerm.Errorf("can't load file %q", filePath)
break break
} }
} else { } 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 break
} }
} }
@ -45,7 +45,7 @@ func evalInclude(ctx ExprContext, self *term) (v any, err error) {
count++ count++
} }
} else { } else {
err = self.errIncompatibleType(childValue) err = opTerm.errIncompatibleType(childValue)
} }
if err == nil { if err == nil {
v = count 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] index = (*indexList)[0]
return return
} }
@ -59,18 +59,18 @@ func verifyRange(indexTerm *term, indexList *ListType, maxValue int) (startIndex
return 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 leftValue, rightValue any
var indexList *ListType var indexList *ListType
var ok bool var ok bool
if leftValue, rightValue, err = self.evalInfix(ctx); err != nil { if leftValue, rightValue, err = opTerm.evalInfix(ctx); err != nil {
return return
} }
indexTerm := self.children[1] indexTerm := opTerm.children[1]
if indexList, ok = rightValue.(*ListType); !ok { if indexList, ok = rightValue.(*ListType); !ok {
err = self.Errorf("invalid index expression") err = opTerm.Errorf("invalid index expression")
return return
} else if len(*indexList) != 1 { } else if len(*indexList) != 1 {
err = indexTerm.Errorf("one index only is allowed") 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]) v = string(unboxedValue[index])
} }
case *DictType: 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) v, err = getDictItem(unboxedValue, indexTerm, indexList, rightValue)
default: default:
err = self.errIncompatibleTypes(leftValue, rightValue) err = opTerm.errIncompatibleTypes(leftValue, rightValue)
} }
} else if isIntPair((*indexList)[0]) { } else if isIntPair((*indexList)[0]) {
switch unboxedValue := leftValue.(type) { switch unboxedValue := leftValue.(type) {
@ -115,18 +108,10 @@ func evalIndex(ctx ExprContext, self *term) (v any, err error) {
v = unboxedValue[start:end] v = unboxedValue[start:end]
} }
default: default:
err = self.errIncompatibleTypes(leftValue, rightValue) err = opTerm.errIncompatibleTypes(leftValue, rightValue)
} }
} else if IsDict(leftValue) { } else if IsDict(leftValue) {
d := leftValue.(*DictType) 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) v, err = getDictItem(d, indexTerm, indexList, rightValue)
} }
return return
@ -136,7 +121,7 @@ func getDictItem(d *DictType, indexTerm *term, indexList *ListType, rightValue a
var ok bool var ok bool
var indexValue any var indexValue any
if indexValue, err = verifyKey(indexTerm, indexList); err == nil { if indexValue, err = verifyKey(indexList); err == nil {
if v, ok = (*d)[indexValue]; !ok { if v, ok = (*d)[indexValue]; !ok {
err = indexTerm.Errorf("key %v does not belong to the dictionary", rightValue) 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 var leftValue, rightValue any
if leftValue, rightValue, err = self.evalInfix(ctx); err != nil { if leftValue, rightValue, err = opTerm.evalInfix(ctx); err != nil {
return return
} }
@ -37,19 +37,19 @@ func evalInsert(ctx ExprContext, self *term) (v any, err error) {
list, _ := rightValue.(*ListType) list, _ := rightValue.(*ListType)
newList := append(ListType{leftValue}, *list...) newList := append(ListType{leftValue}, *list...)
v = &newList v = &newList
if self.children[1].symbol() == SymVariable { if opTerm.children[1].symbol() == SymVariable {
ctx.UnsafeSetVar(self.children[1].source(), v) ctx.UnsafeSetVar(opTerm.children[1].source(), v)
} }
} else { } else {
err = self.errIncompatibleTypes(leftValue, rightValue) err = opTerm.errIncompatibleTypes(leftValue, rightValue)
} }
return 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 var leftValue, rightValue any
if leftValue, rightValue, err = self.evalInfix(ctx); err != nil { if leftValue, rightValue, err = opTerm.evalInfix(ctx); err != nil {
return return
} }
@ -57,11 +57,11 @@ func evalAppend(ctx ExprContext, self *term) (v any, err error) {
list, _ := leftValue.(*ListType) list, _ := leftValue.(*ListType)
newList := append(*list, rightValue) newList := append(*list, rightValue)
v = &newList v = &newList
if self.children[0].symbol() == SymVariable { if opTerm.children[0].symbol() == SymVariable {
ctx.UnsafeSetVar(self.children[0].source(), v) ctx.UnsafeSetVar(opTerm.children[0].source(), v)
} }
} else { } else {
err = self.errIncompatibleTypes(leftValue, rightValue) err = opTerm.errIncompatibleTypes(leftValue, rightValue)
} }
return 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 var childValue any
if childValue, err = self.evalPrefix(ctx); err != nil { if childValue, err = opTerm.evalPrefix(ctx); err != nil {
return return
} }
if it, ok := childValue.(Iterator); ok { if it, ok := childValue.(Iterator); ok {
v, err = it.Current() v, err = it.Current()
} else { } else {
err = self.errIncompatibleType(childValue) err = opTerm.errIncompatibleType(childValue)
} }
return 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 var childValue any
if childValue, err = self.evalPrefix(ctx); err != nil { if childValue, err = opTerm.evalPrefix(ctx); err != nil {
return return
} }
@ -41,7 +41,7 @@ func evalLength(ctx ExprContext, self *term) (v any, err error) {
v = int64(it.Index() + 1) v = int64(it.Index() + 1)
} }
} else { } else {
err = self.errIncompatibleType(childValue) err = opTerm.errIncompatibleType(childValue)
} }
return 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 childValue any
var moduleSpec any var moduleSpec any
if childValue, err = self.evalPrefix(ctx); err != nil { if childValue, err = opTerm.evalPrefix(ctx); err != nil {
return return
} }
@ -38,7 +38,7 @@ func evalPlugin(ctx ExprContext, self *term) (v any, err error) {
} }
count++ count++
} else { } 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 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 var childValue any
if childValue, err = self.evalPrefix(ctx); err != nil { if childValue, err = opTerm.evalPrefix(ctx); err != nil {
return return
} }
if it, ok := childValue.(Iterator); ok { if it, ok := childValue.(Iterator); ok {
v, err = it.Next() v, err = it.Next()
} else if IsInteger(childValue) && self.children[0].symbol() == SymVariable { } else if IsInteger(childValue) && opTerm.children[0].symbol() == SymVariable {
v = childValue v = childValue
i, _ := childValue.(int64) i, _ := childValue.(int64)
ctx.SetVar(self.children[0].source(), i+1) ctx.SetVar(opTerm.children[0].source(), i+1)
} else { } else {
err = self.errIncompatibleType(childValue) err = opTerm.errIncompatibleType(childValue)
} }
return return
} }

View File

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

View File

@ -45,10 +45,10 @@ func equals(a, b any, deepCmp deepFuncTemplate) (eq bool, err error) {
return 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 var leftValue, rightValue any
if leftValue, rightValue, err = self.evalInfix(ctx); err != nil { if leftValue, rightValue, err = opTerm.evalInfix(ctx); err != nil {
return return
} }
@ -68,8 +68,8 @@ func newNotEqualTerm(tk *Token) (inst *term) {
} }
} }
func evalNotEqual(ctx ExprContext, self *term) (v any, err error) { func evalNotEqual(ctx ExprContext, opTerm *term) (v any, err error) {
if v, err = evalEqual(ctx, self); err == nil { if v, err = evalEqual(ctx, opTerm); err == nil {
b, _ := ToBool(v) b, _ := ToBool(v)
v = !b v = !b
} }
@ -119,13 +119,13 @@ func lessThan(self *term, a, b any) (isLess bool, err error) {
return 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 var leftValue, rightValue any
if leftValue, rightValue, err = self.evalInfix(ctx); err != nil { if leftValue, rightValue, err = opTerm.evalInfix(ctx); err != nil {
return return
} }
v, err = lessThan(self, leftValue, rightValue) v, err = lessThan(opTerm, leftValue, rightValue)
return return
} }
@ -154,14 +154,14 @@ func lessThanOrEqual(self *term, a, b any) (isLessEq bool, err error) {
return 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 var leftValue, rightValue any
if leftValue, rightValue, err = self.evalInfix(ctx); err != nil { if leftValue, rightValue, err = opTerm.evalInfix(ctx); err != nil {
return return
} }
v, err = lessThanOrEqual(self, leftValue, rightValue) v, err = lessThanOrEqual(opTerm, leftValue, rightValue)
return 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 var leftValue, rightValue any
if leftValue, rightValue, err = self.evalInfix(ctx); err != nil { if leftValue, rightValue, err = opTerm.evalInfix(ctx); err != nil {
return return
} }
v, err = lessThan(self, rightValue, leftValue) v, err = lessThan(opTerm, rightValue, leftValue)
return 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 var leftValue, rightValue any
if leftValue, rightValue, err = self.evalInfix(ctx); err != nil { if leftValue, rightValue, err = opTerm.evalInfix(ctx); err != nil {
return return
} }
v, err = lessThanOrEqual(self, rightValue, leftValue) v, err = lessThanOrEqual(opTerm, rightValue, leftValue)
return return
} }

View File

@ -39,19 +39,19 @@ func trySelectorCase(ctx ExprContext, exprValue, caseSel any, caseIndex int) (ma
return 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 exprValue any
var match bool var match bool
if err = self.checkOperands(); err != nil { if err = opTerm.checkOperands(); err != nil {
return return
} }
exprTerm := self.children[0] exprTerm := opTerm.children[0]
if exprValue, err = exprTerm.compute(ctx); err != nil { if exprValue, err = exprTerm.compute(ctx); err != nil {
return return
} }
caseListTerm := self.children[1] caseListTerm := opTerm.children[1]
caseList, _ := caseListTerm.value().([]*term) caseList, _ := caseListTerm.value().([]*term)
for i, caseTerm := range caseList { for i, caseTerm := range caseList {
caseSel := caseTerm.value() 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 var rightValue any
if rightValue, err = self.evalPrefix(ctx); err != nil { if rightValue, err = opTerm.evalPrefix(ctx); err != nil {
return return
} }
if IsFloat(rightValue) { if IsFloat(rightValue) {
if self.tk.Sym == SymChangeSign { if opTerm.tk.Sym == SymChangeSign {
f, _ := rightValue.(float64) f, _ := rightValue.(float64)
v = -f v = -f
} else { } else {
v = rightValue v = rightValue
} }
} else if IsInteger(rightValue) { } else if IsInteger(rightValue) {
if self.tk.Sym == SymChangeSign { if opTerm.tk.Sym == SymChangeSign {
i, _ := rightValue.(int64) i, _ := rightValue.(int64)
v = -i v = -i
} else { } else {
v = rightValue v = rightValue
} }
} else { } else {
err = self.errIncompatibleType(rightValue) err = opTerm.errIncompatibleType(rightValue)
} }
return 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 var leftValue, rightValue any
if leftValue, rightValue, err = self.evalInfix(ctx); err != nil { if leftValue, rightValue, err = plusTerm.evalInfix(ctx); err != nil {
return return
} }
@ -44,12 +44,8 @@ func evalPlus(ctx ExprContext, self *term) (v any, err error) {
rightList, _ = rightValue.(*ListType) rightList, _ = rightValue.(*ListType)
sumList := make(ListType, 0, len(*leftList)+len(*rightList)) sumList := make(ListType, 0, len(*leftList)+len(*rightList))
for _, item := range *leftList { sumList = append(sumList, *leftList...)
sumList = append(sumList, item) sumList = append(sumList, *rightList...)
}
for _, item := range *rightList {
sumList = append(sumList, item)
}
v = &sumList v = &sumList
} else if (isFraction(leftValue) && IsNumber(rightValue)) || (isFraction(rightValue) && IsNumber(leftValue)) { } else if (isFraction(leftValue) && IsNumber(rightValue)) || (isFraction(rightValue) && IsNumber(leftValue)) {
if IsFloat(leftValue) || IsFloat(rightValue) { if IsFloat(leftValue) || IsFloat(rightValue) {
@ -64,7 +60,7 @@ func evalPlus(ctx ExprContext, self *term) (v any, err error) {
c.merge(rightDict) c.merge(rightDict)
v = c v = c
} else { } else {
err = self.errIncompatibleTypes(leftValue, rightValue) err = plusTerm.errIncompatibleTypes(leftValue, rightValue)
} }
return 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 var leftValue, rightValue any
if leftValue, rightValue, err = self.evalInfix(ctx); err != nil { if leftValue, rightValue, err = minusTerm.evalInfix(ctx); err != nil {
return return
} }
@ -109,7 +105,7 @@ func evalMinus(ctx ExprContext, self *term) (v any, err error) {
} }
v = &diffList v = &diffList
} else { } else {
err = self.errIncompatibleTypes(leftValue, rightValue) err = minusTerm.errIncompatibleTypes(leftValue, rightValue)
} }
return return
} }

View File

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

View File

@ -29,7 +29,7 @@ func pluginExists(name string) (exists bool) {
func makePluginName(name string) (decorated string) { func makePluginName(name string) (decorated string) {
var template 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" template = "expr-%s-plugin.so"
} else { } else {
template = "expr-%s-plugin.so.debug" template = "expr-%s-plugin.so.debug"

View File

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

View File

@ -6,7 +6,6 @@ package expr
import ( import (
"errors" "errors"
"fmt"
"reflect" "reflect"
"strings" "strings"
"testing" "testing"
@ -69,9 +68,9 @@ func TestScanner(t *testing.T) {
// continue // continue
// } // }
if input.wantErr == nil { 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 { } 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) r := strings.NewReader(input.source)

150
term.go
View File

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