IsOptional() function of ExprFuncParam renamed as IdDefault(). A new IsOptional() function created to check if a param is optional without requiring a default value

This commit is contained in:
Celestino Amoroso 2024-06-07 09:45:02 +02:00
parent 227944b3fb
commit 115ce26ce9
12 changed files with 44 additions and 25 deletions

View File

@ -16,6 +16,7 @@ type Functor interface {
type ExprFuncParam interface { type ExprFuncParam interface {
Name() string Name() string
Type() string Type() string
IsDefault() bool
IsOptional() bool IsOptional() bool
IsRepeat() bool IsRepeat() bool
DefaultValue() any DefaultValue() any
@ -36,6 +37,8 @@ type ExprFunc interface {
type ExprContext interface { type ExprContext interface {
Clone() ExprContext Clone() ExprContext
Merge(ctx ExprContext) Merge(ctx ExprContext)
SetParent(ctx ExprContext)
GetParent() (ctx ExprContext)
GetVar(varName string) (value any, exists bool) GetVar(varName string) (value any, exists bool)
SetVar(varName string, value any) SetVar(varName string, value any)
UnsafeSetVar(varName string, value any) UnsafeSetVar(varName string, value any)

View File

@ -177,7 +177,7 @@ func ImportBuiltinsFuncs(ctx ExprContext) {
ctx.RegisterFunc("dec", NewGolangFunctor(decFunc), TypeFloat, anyParams) ctx.RegisterFunc("dec", NewGolangFunctor(decFunc), TypeFloat, anyParams)
ctx.RegisterFunc("fract", NewGolangFunctor(fractFunc), TypeFraction, []ExprFuncParam{ ctx.RegisterFunc("fract", NewGolangFunctor(fractFunc), TypeFraction, []ExprFuncParam{
NewFuncParam(paramValue), NewFuncParam(paramValue),
NewFuncParamFlagDef("denominator", PfOptional, 1), NewFuncParamFlagDef("denominator", PfDefault, 1),
}) })
} }

View File

@ -16,7 +16,7 @@ func importFunc(ctx ExprContext, name string, args []any) (result any, err error
} }
func importAllFunc(ctx ExprContext, name string, args []any) (result any, err error) { func importAllFunc(ctx ExprContext, name string, args []any) (result any, err error) {
enable(ctx, control_export_all) CtrlEnable(ctx, control_export_all)
return importGeneral(ctx, name, args) return importGeneral(ctx, name, args)
} }
@ -30,7 +30,8 @@ func importGeneral(ctx ExprContext, name string, args []any) (result any, err er
} }
func addPresetImportDirs(ctx ExprContext, dirList []string) []string { func addPresetImportDirs(ctx ExprContext, dirList []string) []string {
return addPresetDirs(ctx, ControlImportPath, dirList) // return addPresetDirs(ctx, ControlImportPath, dirList)
return addSearchDirs(ctx, "sources", dirList)
} }
func doImport(ctx ExprContext, name string, dirList []string, it Iterator) (result any, err error) { func doImport(ctx ExprContext, name string, dirList []string, it Iterator) (result any, err error) {
@ -49,9 +50,9 @@ func doImport(ctx ExprContext, name string, dirList []string, it Iterator) (resu
defer file.Close() defer file.Close()
var expr *ast var expr *ast
scanner := NewScanner(file, DefaultTranslations()) scanner := NewScanner(file, DefaultTranslations())
parser := NewParser(ctx) parser := NewParser()
if expr, err = parser.parseGeneral(scanner, true, true); err == nil { if expr, err = parser.parseGeneral(scanner, true, true); err == nil {
result, err = expr.eval(ctx, false) result, err = expr.Eval(ctx)
} }
if err != nil { if err != nil {
break break

View File

@ -168,11 +168,11 @@ func mulFunc(ctx ExprContext, name string, args []any) (result any, err error) {
func ImportMathFuncs(ctx ExprContext) { func ImportMathFuncs(ctx ExprContext) {
ctx.RegisterFunc("add", &golangFunctor{f: addFunc}, TypeNumber, []ExprFuncParam{ ctx.RegisterFunc("add", &golangFunctor{f: addFunc}, TypeNumber, []ExprFuncParam{
NewFuncParamFlagDef(paramValue, PfOptional|PfRepeat, int64(0)), NewFuncParamFlagDef(paramValue, PfDefault|PfRepeat, int64(0)),
}) })
ctx.RegisterFunc("mul", &golangFunctor{f: mulFunc}, TypeNumber, []ExprFuncParam{ ctx.RegisterFunc("mul", &golangFunctor{f: mulFunc}, TypeNumber, []ExprFuncParam{
NewFuncParamFlagDef(paramValue, PfOptional|PfRepeat, int64(1)), NewFuncParamFlagDef(paramValue, PfDefault|PfRepeat, int64(1)),
}) })
} }

View File

@ -198,11 +198,11 @@ func ImportOsFuncs(ctx ExprContext) {
}) })
ctx.RegisterFunc("writeFile", NewGolangFunctor(writeFileFunc), TypeInt, []ExprFuncParam{ ctx.RegisterFunc("writeFile", NewGolangFunctor(writeFileFunc), TypeInt, []ExprFuncParam{
NewFuncParam(TypeHandle), NewFuncParam(TypeHandle),
NewFuncParamFlagDef(TypeItem, PfOptional|PfRepeat, ""), NewFuncParamFlagDef(TypeItem, PfDefault|PfRepeat, ""),
}) })
ctx.RegisterFunc("readFile", NewGolangFunctor(readFileFunc), TypeString, []ExprFuncParam{ ctx.RegisterFunc("readFile", NewGolangFunctor(readFileFunc), TypeString, []ExprFuncParam{
NewFuncParam(TypeHandle), NewFuncParam(TypeHandle),
NewFuncParamFlagDef("limitCh", PfOptional, "\n"), NewFuncParamFlagDef("limitCh", PfDefault, "\n"),
}) })
ctx.RegisterFunc("closeFile", NewGolangFunctor(closeFileFunc), TypeBoolean, []ExprFuncParam{ ctx.RegisterFunc("closeFile", NewGolangFunctor(closeFileFunc), TypeBoolean, []ExprFuncParam{
NewFuncParam(TypeHandle), NewFuncParam(TypeHandle),

View File

@ -189,14 +189,14 @@ func ImportStringFuncs(ctx ExprContext) {
ctx.RegisterFunc("subStr", NewGolangFunctor(subStrFunc), TypeString, []ExprFuncParam{ ctx.RegisterFunc("subStr", NewGolangFunctor(subStrFunc), TypeString, []ExprFuncParam{
NewFuncParam(paramSource), NewFuncParam(paramSource),
NewFuncParamFlagDef(paramStart, PfOptional, int64(0)), NewFuncParamFlagDef(paramStart, PfDefault, int64(0)),
NewFuncParamFlagDef(paramCount, PfOptional, int64(-1)), NewFuncParamFlagDef(paramCount, PfDefault, int64(-1)),
}) })
ctx.RegisterFunc("splitStr", NewGolangFunctor(splitStrFunc), "list of "+TypeString, []ExprFuncParam{ ctx.RegisterFunc("splitStr", NewGolangFunctor(splitStrFunc), "list of "+TypeString, []ExprFuncParam{
NewFuncParam(paramSource), NewFuncParam(paramSource),
NewFuncParamFlagDef(paramSeparator, PfOptional, ""), NewFuncParamFlagDef(paramSeparator, PfDefault, ""),
NewFuncParamFlagDef(paramCount, PfOptional, int64(-1)), NewFuncParamFlagDef(paramCount, PfDefault, int64(-1)),
}) })
ctx.RegisterFunc("trimStr", NewGolangFunctor(trimStrFunc), TypeString, []ExprFuncParam{ ctx.RegisterFunc("trimStr", NewGolangFunctor(trimStrFunc), TypeString, []ExprFuncParam{

View File

@ -91,7 +91,7 @@ func (functor *exprFunctor) Invoke(ctx ExprContext, name string, args []any) (re
ctx.UnsafeSetVar(p.Name(), nil) ctx.UnsafeSetVar(p.Name(), nil)
} }
} }
result, err = functor.expr.eval(ctx, false) result, err = functor.expr.Eval(ctx)
return return
} }
@ -99,7 +99,8 @@ func (functor *exprFunctor) Invoke(ctx ExprContext, name string, args []any) (re
type paramFlags uint16 type paramFlags uint16
const ( const (
PfOptional paramFlags = 1 << iota PfDefault paramFlags = 1 << iota
PfOptional
PfRepeat PfRepeat
) )
@ -126,7 +127,11 @@ func (param *funcParamInfo) Name() string {
} }
func (param *funcParamInfo) Type() string { func (param *funcParamInfo) Type() string {
return "any" return TypeAny
}
func (param *funcParamInfo) IsDefault() bool {
return (param.flags & PfDefault) != 0
} }
func (param *funcParamInfo) IsOptional() bool { func (param *funcParamInfo) IsOptional() bool {
@ -159,7 +164,7 @@ func newFuncInfo(name string, functor Functor, returnType string, params []ExprF
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())
} }
if p.IsOptional() { if p.IsDefault() || p.IsOptional() {
maxArgs++ maxArgs++
} else if maxArgs == minArgs { } else if maxArgs == minArgs {
minArgs++ minArgs++
@ -207,7 +212,7 @@ func (info *funcInfo) ToString(opt FmtOpt) string {
} }
sb.WriteString(p.Name()) sb.WriteString(p.Name())
if p.IsOptional() { if p.IsDefault() {
sb.WriteByte('=') sb.WriteByte('=')
if s, ok := p.DefaultValue().(string); ok { if s, ok := p.DefaultValue().(string); ok {
sb.WriteByte('"') sb.WriteByte('"')

View File

@ -30,7 +30,7 @@ func checkFunctionCall(ctx ExprContext, name string, varParams *[]any) (err erro
} }
for i, p := range info.Params() { for i, p := range info.Params() {
if i >= passedCount { if i >= passedCount {
if !p.IsOptional() { if !p.IsDefault() {
break break
} }
*varParams = append(*varParams, p.DefaultValue()) *varParams = append(*varParams, p.DefaultValue())
@ -50,6 +50,7 @@ func checkFunctionCall(ctx ExprContext, name string, varParams *[]any) (err erro
func evalFuncCall(parentCtx ExprContext, self *term) (v any, err error) { func evalFuncCall(parentCtx ExprContext, self *term) (v any, err error) {
ctx := cloneContext(parentCtx) ctx := cloneContext(parentCtx)
ctx.SetParent(parentCtx)
name, _ := self.tk.Value.(string) name, _ := self.tk.Value.(string)
params := make([]any, len(self.children), len(self.children)+5) params := make([]any, len(self.children), len(self.children)+5)
for i, tree := range self.children { for i, tree := range self.children {
@ -91,7 +92,7 @@ func evalFuncDef(ctx ExprContext, self *term) (v any, err error) {
var defValue any var defValue any
flags := paramFlags(0) flags := paramFlags(0)
if len(param.children) > 0 { if len(param.children) > 0 {
flags |= PfOptional flags |= PfDefault
if defValue, err = param.children[0].compute(ctx); err != nil { if defValue, err = param.children[0].compute(ctx); err != nil {
return return
} }

View File

@ -68,7 +68,7 @@ func evalAssignCoalesce(ctx ExprContext, self *term) (v any, err error) {
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{
NewFuncParamFlag(paramValue, PfOptional|PfRepeat), NewFuncParamFlag(paramValue, PfDefault|PfRepeat),
}) })
} else { } else {
v = rightValue v = rightValue

View File

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

View File

@ -19,17 +19,17 @@ func newSelectorTerm(tk *Token) (inst *term) {
func trySelectorCase(ctx ExprContext, exprValue, caseSel any, caseIndex int) (match bool, selectedValue any, err error) { func trySelectorCase(ctx ExprContext, exprValue, caseSel any, caseIndex int) (match bool, selectedValue any, err error) {
caseData, _ := caseSel.(*selectorCase) caseData, _ := caseSel.(*selectorCase)
if caseData.filterList == nil { if caseData.filterList == nil {
selectedValue, err = caseData.caseExpr.eval(ctx, false) selectedValue, err = caseData.caseExpr.Eval(ctx)
match = true match = true
} else if filterList, ok := caseData.filterList.value().([]*term); ok { } else if filterList, ok := caseData.filterList.value().([]*term); ok {
if len(filterList) == 0 && exprValue == int64(caseIndex) { if len(filterList) == 0 && exprValue == int64(caseIndex) {
selectedValue, err = caseData.caseExpr.eval(ctx, false) selectedValue, err = caseData.caseExpr.Eval(ctx)
match = true match = true
} else { } else {
var caseValue any var caseValue any
for _, caseTerm := range filterList { for _, caseTerm := range filterList {
if caseValue, err = caseTerm.compute(ctx); err != nil || caseValue == exprValue { if caseValue, err = caseTerm.compute(ctx); err != nil || caseValue == exprValue {
selectedValue, err = caseData.caseExpr.eval(ctx, false) selectedValue, err = caseData.caseExpr.Eval(ctx)
match = true match = true
break break
} }

View File

@ -11,6 +11,7 @@ import (
) )
type SimpleStore struct { type SimpleStore struct {
parent ExprContext
varStore map[string]any varStore map[string]any
funcStore map[string]ExprFunc funcStore map[string]ExprFunc
} }
@ -26,6 +27,14 @@ 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) {
ctx.parent = parentCtx
}
func (ctx *SimpleStore) GetParent() ExprContext {
return ctx.parent
}
func (ctx *SimpleStore) Clone() ExprContext { func (ctx *SimpleStore) Clone() ExprContext {
return &SimpleStore{ return &SimpleStore{
varStore: CloneFilteredMap(ctx.varStore, filterRefName), varStore: CloneFilteredMap(ctx.varStore, filterRefName),