Compare commits
	
		
			No commits in common. "99454227d5f9a5d298f96aa22c1ba737bbe250be" and "9bba40f155651100818b327350d3ad37df2e3b74" have entirely different histories.
		
	
	
		
			99454227d5
			...
			9bba40f155
		
	
		
| @ -16,6 +16,15 @@ const ( | |||||||
| 	paramEnd       = "end" | 	paramEnd       = "end" | ||||||
| 	paramValue     = "value" | 	paramValue     = "value" | ||||||
| 	paramEllipsis  = "..." | 	paramEllipsis  = "..." | ||||||
| 	paramFilepath  = "filepath" | 	typeFilepath   = "filepath" | ||||||
| 	paramDirpath   = "dirpath" | 	typeDirpath    = "dirpath" | ||||||
| ) | ) | ||||||
|  | 
 | ||||||
|  | // const (
 | ||||||
|  | // 	typeInteger  = "int"
 | ||||||
|  | // 	typeFloat    = "float"
 | ||||||
|  | // 	typeString   = "string"
 | ||||||
|  | // 	typeFraction = "fract"
 | ||||||
|  | // 	typeList     = "list"
 | ||||||
|  | // 	typeDict     = "dict"
 | ||||||
|  | // )
 | ||||||
|  | |||||||
| @ -615,10 +615,7 @@ The table below shows all supported operators by decreasing priorities. | |||||||
| |=== | |=== | ||||||
| 
 | 
 | ||||||
| == Functions | == Functions | ||||||
| Functions in _Expr_ are very similar to functions available in many programming languages. Actually, _Expr_ supports two types of function, _expr-functions_ and _go-functions_. | Functions in _Expr_ are very similar to functions in many programming languages. | ||||||
| 
 |  | ||||||
| * _expr-functions_ are defined using _Expr_ syntax. They can be passed as arguments to other functions and can be returned from functions. Moreover, they bind themselves to the defining context, thus becoming closures. |  | ||||||
| * _go-functions_ are regular Golang functions callable from _Expr_ expressions. They are defined in Golang source file called _modules_ and compiled within the _Expr_ package. To make Golang functions available in _Expr_ contextes, it is required to _import_ the module within they are defined. |  | ||||||
| 
 | 
 | ||||||
| In _Expr_ functions compute values in a local context (scope) that do not make effects on the calling context. This is the normal behavior. Using the reference operator [blue]`@` it is possibile to export local definition to the calling context. | In _Expr_ functions compute values in a local context (scope) that do not make effects on the calling context. This is the normal behavior. Using the reference operator [blue]`@` it is possibile to export local definition to the calling context. | ||||||
| 
 | 
 | ||||||
|  | |||||||
| @ -1609,7 +1609,7 @@ These operators have a high priority, in particular higher than the operator <co | |||||||
| <td class="tableblock halign-center valign-top"><p class="tableblock"><code class="blue">.</code></p></td> | <td class="tableblock halign-center valign-top"><p class="tableblock"><code class="blue">.</code></p></td> | ||||||
| <td class="tableblock halign-center valign-top"><p class="tableblock"><em>Infix</em></p></td> | <td class="tableblock halign-center valign-top"><p class="tableblock"><em>Infix</em></p></td> | ||||||
| <td class="tableblock halign-center valign-top"><p class="tableblock"><em>Dict item</em></p></td> | <td class="tableblock halign-center valign-top"><p class="tableblock"><em>Dict item</em></p></td> | ||||||
| <td class="tableblock halign-center valign-top"><p class="tableblock"><em>dict</em> <code>"."</code> <em>any</em> → <em>any</em></p></td> | <td class="tableblock halign-center valign-top"><p class="tableblock"><em>dict</em> <code>""</code> <em>any</em> → <em>any</em></p></td> | ||||||
| </tr> | </tr> | ||||||
| <tr> | <tr> | ||||||
| <td class="tableblock halign-center valign-top" rowspan="2"><p class="tableblock"><strong>INC</strong></p></td> | <td class="tableblock halign-center valign-top" rowspan="2"><p class="tableblock"><strong>INC</strong></p></td> | ||||||
| @ -1834,17 +1834,7 @@ These operators have a high priority, in particular higher than the operator <co | |||||||
| <h2 id="_functions"><a class="anchor" href="#_functions"></a><a class="link" href="#_functions">6. Functions</a></h2> | <h2 id="_functions"><a class="anchor" href="#_functions"></a><a class="link" href="#_functions">6. Functions</a></h2> | ||||||
| <div class="sectionbody"> | <div class="sectionbody"> | ||||||
| <div class="paragraph"> | <div class="paragraph"> | ||||||
| <p>Functions in <em>Expr</em> are very similar to functions available in many programming languages. Actually, <em>Expr</em> supports two types of function, <em>expr-functions</em> and <em>go-functions</em>.</p> | <p>Functions in <em>Expr</em> are very similar to functions in many programming languages.</p> | ||||||
| </div> |  | ||||||
| <div class="ulist"> |  | ||||||
| <ul> |  | ||||||
| <li> |  | ||||||
| <p><em>expr-functions</em> are defined using <em>Expr</em> syntax. They can be passed as arguments to other functions and can be returned from functions. Moreover, they bind themselves to the defining context, thus becoming closures.</p> |  | ||||||
| </li> |  | ||||||
| <li> |  | ||||||
| <p><em>go-functions</em> are regular Golang functions callable from <em>Expr</em> expressions. They are defined in Golang source file called <em>modules</em> and compiled within the <em>Expr</em> package. To make Golang functions available in <em>Expr</em> contextes, it is required to <em>import</em> the module within they are defined.</p> |  | ||||||
| </li> |  | ||||||
| </ul> |  | ||||||
| </div> | </div> | ||||||
| <div class="paragraph"> | <div class="paragraph"> | ||||||
| <p>In <em>Expr</em> functions compute values in a local context (scope) that do not make effects on the calling context. This is the normal behavior. Using the reference operator <code class="blue">@</code> it is possibile to export local definition to the calling context.</p> | <p>In <em>Expr</em> functions compute values in a local context (scope) that do not make effects on the calling context. This is the normal behavior. Using the reference operator <code class="blue">@</code> it is possibile to export local definition to the calling context.</p> | ||||||
| @ -1884,7 +1874,7 @@ These operators have a high priority, in particular higher than the operator <co | |||||||
| </div> | </div> | ||||||
| <div id="footer"> | <div id="footer"> | ||||||
| <div id="footer-text"> | <div id="footer-text"> | ||||||
| Last updated 2024-06-02 10:44:09 +0200 | Last updated 2024-05-20 09:40:23 +0200 | ||||||
| </div> | </div> | ||||||
| </div> | </div> | ||||||
| </body> | </body> | ||||||
|  | |||||||
							
								
								
									
										36
									
								
								func-fmt.go
									
									
									
									
									
								
							
							
						
						
									
										36
									
								
								func-fmt.go
									
									
									
									
									
								
							| @ -1,36 +0,0 @@ | |||||||
| // Copyright (c) 2024 Celestino Amoroso (celestino.amoroso@gmail.com).
 |  | ||||||
| // All rights reserved.
 |  | ||||||
| 
 |  | ||||||
| // func-fmt.go
 |  | ||||||
| package expr |  | ||||||
| 
 |  | ||||||
| import "fmt" |  | ||||||
| 
 |  | ||||||
| func printFunc(ctx ExprContext, name string, args []any) (result any, err error) { |  | ||||||
| 	var n int |  | ||||||
| 	if n, err = fmt.Print(args...); err == nil { |  | ||||||
| 		result = int64(n) |  | ||||||
| 	} |  | ||||||
| 	return |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| func printLnFunc(ctx ExprContext, name string, args []any) (result any, err error) { |  | ||||||
| 	var n int |  | ||||||
| 	if n, err = fmt.Println(args...); err == nil { |  | ||||||
| 		result = int64(n) |  | ||||||
| 	} |  | ||||||
| 	return |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| func ImportFmtFuncs(ctx ExprContext) { |  | ||||||
| 	ctx.RegisterFunc("print", newGolangFunctor(printFunc), typeInt, []ExprFuncParam{ |  | ||||||
| 		newFuncParamFlag(paramItem, pfRepeat), |  | ||||||
| 	}) |  | ||||||
| 	ctx.RegisterFunc("println", newGolangFunctor(printLnFunc), typeInt, []ExprFuncParam{ |  | ||||||
| 		newFuncParamFlag(paramItem, pfRepeat), |  | ||||||
| 	}) |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| func init() { |  | ||||||
| 	registerImport("fmt", ImportFmtFuncs, "String and console formatting functions") |  | ||||||
| } |  | ||||||
| @ -138,10 +138,10 @@ func doImport(ctx ExprContext, name string, dirList []string, it Iterator) (resu | |||||||
| 
 | 
 | ||||||
| func ImportImportFuncs(ctx ExprContext) { | func ImportImportFuncs(ctx ExprContext) { | ||||||
| 	ctx.RegisterFunc("import", newGolangFunctor(importFunc), typeAny, []ExprFuncParam{ | 	ctx.RegisterFunc("import", newGolangFunctor(importFunc), typeAny, []ExprFuncParam{ | ||||||
| 		newFuncParamFlag(paramFilepath, pfRepeat), | 		newFuncParamFlag(typeFilepath, pfRepeat), | ||||||
| 	}) | 	}) | ||||||
| 	ctx.RegisterFunc("importAll", newGolangFunctor(importAllFunc), typeAny, []ExprFuncParam{ | 	ctx.RegisterFunc("importAll", newGolangFunctor(importAllFunc), typeAny, []ExprFuncParam{ | ||||||
| 		newFuncParamFlag(paramFilepath, pfRepeat), | 		newFuncParamFlag(typeFilepath, pfRepeat), | ||||||
| 	}) | 	}) | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
|  | |||||||
| @ -188,13 +188,13 @@ func readFileFunc(ctx ExprContext, name string, args []any) (result any, err err | |||||||
| 
 | 
 | ||||||
| func ImportOsFuncs(ctx ExprContext) { | func ImportOsFuncs(ctx ExprContext) { | ||||||
| 	ctx.RegisterFunc("openFile", newGolangFunctor(openFileFunc), typeHandle, []ExprFuncParam{ | 	ctx.RegisterFunc("openFile", newGolangFunctor(openFileFunc), typeHandle, []ExprFuncParam{ | ||||||
| 		newFuncParam(paramFilepath), | 		newFuncParam(typeFilepath), | ||||||
| 	}) | 	}) | ||||||
| 	ctx.RegisterFunc("appendFile", newGolangFunctor(appendFileFunc), typeHandle, []ExprFuncParam{ | 	ctx.RegisterFunc("appendFile", newGolangFunctor(appendFileFunc), typeHandle, []ExprFuncParam{ | ||||||
| 		newFuncParam(paramFilepath), | 		newFuncParam(typeFilepath), | ||||||
| 	}) | 	}) | ||||||
| 	ctx.RegisterFunc("createFile", newGolangFunctor(createFileFunc), typeHandle, []ExprFuncParam{ | 	ctx.RegisterFunc("createFile", newGolangFunctor(createFileFunc), typeHandle, []ExprFuncParam{ | ||||||
| 		newFuncParam(paramFilepath), | 		newFuncParam(typeFilepath), | ||||||
| 	}) | 	}) | ||||||
| 	ctx.RegisterFunc("writeFile", newGolangFunctor(writeFileFunc), typeInt, []ExprFuncParam{ | 	ctx.RegisterFunc("writeFile", newGolangFunctor(writeFileFunc), typeInt, []ExprFuncParam{ | ||||||
| 		newFuncParam(typeHandle), | 		newFuncParam(typeHandle), | ||||||
|  | |||||||
| @ -184,7 +184,7 @@ func splitStrFunc(ctx ExprContext, name string, args []any) (result any, err err | |||||||
| func ImportStringFuncs(ctx ExprContext) { | func ImportStringFuncs(ctx ExprContext) { | ||||||
| 	ctx.RegisterFunc("joinStr", newGolangFunctor(joinStrFunc), typeString, []ExprFuncParam{ | 	ctx.RegisterFunc("joinStr", newGolangFunctor(joinStrFunc), typeString, []ExprFuncParam{ | ||||||
| 		newFuncParam(paramSeparator), | 		newFuncParam(paramSeparator), | ||||||
| 		newFuncParamFlag(paramItem, pfRepeat), | 		newFuncParamFlagDef(paramItem, pfOptional|pfRepeat, ""), | ||||||
| 	}) | 	}) | ||||||
| 
 | 
 | ||||||
| 	ctx.RegisterFunc("subStr", newGolangFunctor(subStrFunc), typeString, []ExprFuncParam{ | 	ctx.RegisterFunc("subStr", newGolangFunctor(subStrFunc), typeString, []ExprFuncParam{ | ||||||
| @ -205,14 +205,12 @@ func ImportStringFuncs(ctx ExprContext) { | |||||||
| 
 | 
 | ||||||
| 	ctx.RegisterFunc("startsWithStr", newGolangFunctor(startsWithStrFunc), typeBoolean, []ExprFuncParam{ | 	ctx.RegisterFunc("startsWithStr", newGolangFunctor(startsWithStrFunc), typeBoolean, []ExprFuncParam{ | ||||||
| 		newFuncParam(paramSource), | 		newFuncParam(paramSource), | ||||||
| 		newFuncParam(paramPrefix), | 		newFuncParamFlag(paramPrefix, pfRepeat), | ||||||
| 		newFuncParamFlag("other "+paramPrefix, pfRepeat), |  | ||||||
| 	}) | 	}) | ||||||
| 
 | 
 | ||||||
| 	ctx.RegisterFunc("endsWithStr", newGolangFunctor(endsWithStrFunc), typeBoolean, []ExprFuncParam{ | 	ctx.RegisterFunc("endsWithStr", newGolangFunctor(endsWithStrFunc), typeBoolean, []ExprFuncParam{ | ||||||
| 		newFuncParam(paramSource), | 		newFuncParam(paramSource), | ||||||
| 		newFuncParam(paramSuffix), | 		newFuncParamFlag(paramSuffix, pfRepeat), | ||||||
| 		newFuncParamFlag("other "+paramSuffix, pfRepeat), |  | ||||||
| 	}) | 	}) | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
|  | |||||||
| @ -168,7 +168,6 @@ func newFuncInfo(name string, functor Functor, returnType string, params []ExprF | |||||||
| 				return nil, fmt.Errorf("can't specify non-optional param after optional ones: %q", p.Name()) | 				return nil, fmt.Errorf("can't specify non-optional param after optional ones: %q", p.Name()) | ||||||
| 			} | 			} | ||||||
| 			if p.IsRepeat() { | 			if p.IsRepeat() { | ||||||
| 				minArgs-- |  | ||||||
| 				maxArgs = -1 | 				maxArgs = -1 | ||||||
| 			} | 			} | ||||||
| 		} | 		} | ||||||
| @ -222,7 +221,7 @@ func (info *funcInfo) ToString(opt FmtOpt) string { | |||||||
| 	if info.maxArgs < 0 { | 	if info.maxArgs < 0 { | ||||||
| 		sb.WriteString(" ...") | 		sb.WriteString(" ...") | ||||||
| 	} | 	} | ||||||
| 	sb.WriteString("):") | 	sb.WriteString("): ") | ||||||
| 	if len(info.returnType) > 0 { | 	if len(info.returnType) > 0 { | ||||||
| 		sb.WriteString(info.returnType) | 		sb.WriteString(info.returnType) | ||||||
| 	} else { | 	} else { | ||||||
|  | |||||||
| @ -91,6 +91,8 @@ func funcsCtxToBuilder(sb *strings.Builder, ctx ExprContext, indent int) { | |||||||
| 		} | 		} | ||||||
| 		value, _ := ctx.GetFuncInfo(name) | 		value, _ := ctx.GetFuncInfo(name) | ||||||
| 		sb.WriteString(strings.Repeat("\t", indent+1)) | 		sb.WriteString(strings.Repeat("\t", indent+1)) | ||||||
|  | 		sb.WriteString(name) | ||||||
|  | 		//sb.WriteString("=")
 | ||||||
| 		if formatter, ok := value.(Formatter); ok { | 		if formatter, ok := value.(Formatter); ok { | ||||||
| 			sb.WriteString(formatter.ToString(0)) | 			sb.WriteString(formatter.ToString(0)) | ||||||
| 		} else { | 		} else { | ||||||
|  | |||||||
| @ -64,6 +64,6 @@ func TestFuncString(t *testing.T) { | |||||||
| 
 | 
 | ||||||
| 	//t.Setenv("EXPR_PATH", ".")
 | 	//t.Setenv("EXPR_PATH", ".")
 | ||||||
| 
 | 
 | ||||||
| 	// parserTestSpec(t, section, inputs, 19)
 | 	// parserTestSpec(t, "Func", inputs, 69)
 | ||||||
| 	parserTest(t, section, inputs) | 	parserTest(t, section, inputs) | ||||||
| } | } | ||||||
|  | |||||||
| @ -29,7 +29,6 @@ func TestFuncs(t *testing.T) { | |||||||
| 		/*  15 */ {`f=func(x,n=2){x+n}; f(3)`, int64(5), nil}, | 		/*  15 */ {`f=func(x,n=2){x+n}; f(3)`, int64(5), nil}, | ||||||
| 		/*  16 */ {`f=func(x,n=2,y){x+n}`, nil, errors.New(`[1:16] can't mix default and non-default parameters`)}, | 		/*  16 */ {`f=func(x,n=2,y){x+n}`, nil, errors.New(`[1:16] can't mix default and non-default parameters`)}, | ||||||
| 		/*  17 */ {`f=func(x,n){1}; f(3,4,)`, nil, errors.New(`[1:24] expected "function-param-value", got ")"`)}, | 		/*  17 */ {`f=func(x,n){1}; f(3,4,)`, nil, errors.New(`[1:24] expected "function-param-value", got ")"`)}, | ||||||
| 		// /*  18 */ {`f=func(a){a*2}`, nil, errors.New(`[1:24] expected "function-param-value", got ")"`)},
 |  | ||||||
| 	} | 	} | ||||||
| 
 | 
 | ||||||
| 	// t.Setenv("EXPR_PATH", ".")
 | 	// t.Setenv("EXPR_PATH", ".")
 | ||||||
|  | |||||||
		Loading…
	
		Reference in New Issue
	
	Block a user