Compare commits
7 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| 4aaffd6c44 | |||
| 924051fbcd | |||
| 5a9b6525a2 | |||
| 8c66d90532 | |||
| 4aa0113c6a | |||
| d035fa0d5e | |||
| cf73b5c98d |
+2
-15
@@ -23,22 +23,9 @@ func TestDictParser(t *testing.T) {
|
|||||||
inputs := []inputType{
|
inputs := []inputType{
|
||||||
/* 1 */ {`{}`, map[any]any{}, nil},
|
/* 1 */ {`{}`, map[any]any{}, nil},
|
||||||
/* 2 */ {`{123}`, nil, errors.New(`[1:6] expected ":", got "}"`)},
|
/* 2 */ {`{123}`, nil, errors.New(`[1:6] expected ":", got "}"`)},
|
||||||
/* 3 */ {`{1:"one",2:"two",3:"three"}`, map[int64]any{int64(1):"one", int64(2):"two", int64(3):"three"}, nil},
|
/* 3 */ {`{1:"one",2:"two",3:"three"}`, map[int64]any{int64(1): "one", int64(2): "two", int64(3): "three"}, nil},
|
||||||
/* 4 */ {`{1:"one",2:"two",3:"three"}.2`, "three", nil},
|
/* 4 */ {`{1:"one",2:"two",3:"three"}.2`, "three", nil},
|
||||||
// /* 3 */ {`[1,2,"hello"]`, []any{int64(1), int64(2), "hello"}, nil},
|
/* 5 */ {`#{1:"one",2:"two",3:"three"}`, int64(3), nil},
|
||||||
// /* 4 */ {`[1+2, not true, "hello"]`, []any{int64(3), false, "hello"}, nil},
|
|
||||||
// /* 5 */ {`[1,2]+[3]`, []any{int64(1), int64(2), int64(3)}, nil},
|
|
||||||
// /* 6 */ {`[1,4,3,2]-[3]`, []any{int64(1), int64(4), int64(2)}, nil},
|
|
||||||
// /* 7 */ {`add([1,4,3,2])`, int64(10), nil},
|
|
||||||
// /* 8 */ {`add([1,[2,2],3,2])`, int64(10), nil},
|
|
||||||
// /* 9 */ {`mul([1,4,3.0,2])`, float64(24.0), nil},
|
|
||||||
// /* 10 */ {`add([1,"hello"])`, nil, errors.New(`add(): param nr 2 (2 in 1) has wrong type string, number expected`)},
|
|
||||||
// /* 11 */ {`[a=1,b=2,c=3] but a+b+c`, int64(6), nil},
|
|
||||||
// /* 12 */ {`[1,2,3] << 2+2`, []any{int64(1), int64(2), int64(3), int64(4)}, nil},
|
|
||||||
// /* 13 */ {`2-1 >> [2,3]`, []any{int64(1), int64(2), int64(3)}, nil},
|
|
||||||
// /* 14 */ {`[1,2,3].1`, int64(2), nil},
|
|
||||||
// /* 15 */ {`ls=[1,2,3] but ls.1`, int64(2), nil},
|
|
||||||
// /* 16 */ {`ls=[1,2,3] but ls.(-1)`, int64(3), nil},
|
|
||||||
}
|
}
|
||||||
|
|
||||||
succeeded := 0
|
succeeded := 0
|
||||||
|
|||||||
+9
-8
@@ -22,17 +22,23 @@ Expressions calculator
|
|||||||
|
|
||||||
toc::[]
|
toc::[]
|
||||||
|
|
||||||
#TODO: Work in progress (last update on 2024/05/09, 07:17 am)#
|
#TODO: Work in progress (last update on 2024/05/10, 06:52 a.m.)#
|
||||||
|
|
||||||
== Expr
|
== Expr
|
||||||
_Expr_ is a GO package capable of analysing, interpreting and calculating expressions.
|
_Expr_ is a GO package capable of analysing, interpreting and calculating expressions.
|
||||||
|
|
||||||
|
=== Concepts and terminology
|
||||||
|
#TODO#
|
||||||
|
|
||||||
|
image::expression-diagram.png[]
|
||||||
|
|
||||||
=== `dev-expr` test tool
|
=== `dev-expr` test tool
|
||||||
`dev-expr` is a simple program that can be used to evaluate expressions interactively. As its name suggests, it was created for testing purpose. In fact, beyond in additon to the automatic test suite based on the Go test framework, `dev-expr` provides an important aid for quickly testing of new features during their development.
|
`dev-expr` is a simple program that can be used to evaluate expressions interactively. As its name suggests, it was created for testing purpose. In fact, beyond in additon to the automatic test suite based on the Go test framework, `dev-expr` provides an important aid for quickly testing of new features during their development.
|
||||||
|
|
||||||
It cat work as a REPL, *R*ead-*E*xecute-*P*rint-*L*oop, or it can process expression acquired from files or standard input.
|
It cat work as a _REPL_, _**R**ead-**E**xecute-**P**rint-**L**oop_, or it can process expression acquired from files or standard input.
|
||||||
|
|
||||||
|
The program can be downloaded from https://git.portale-stac.it/go-pkg/-/packages/generic/dev-expr/[dev-expr].
|
||||||
|
|
||||||
The program in located in the _tools_ directory.
|
|
||||||
Here are some examples of execution.
|
Here are some examples of execution.
|
||||||
|
|
||||||
.Run `dev-expr` in REPL mode and ask for help
|
.Run `dev-expr` in REPL mode and ask for help
|
||||||
@@ -103,11 +109,6 @@ Here are some examples of execution.
|
|||||||
<4> But operator, see <<_but_operator>>.
|
<4> But operator, see <<_but_operator>>.
|
||||||
<5> Multi-expression: the same result of the previous single expression but this it is obtained with two separated calculations.
|
<5> Multi-expression: the same result of the previous single expression but this it is obtained with two separated calculations.
|
||||||
|
|
||||||
=== Concepts and terminology
|
|
||||||
#TODO#
|
|
||||||
|
|
||||||
image::expression-diagram.png[]
|
|
||||||
|
|
||||||
== Data types
|
== Data types
|
||||||
_Expr_ supports numerical, string, relational, boolean expressions, and mixed-type lists.
|
_Expr_ supports numerical, string, relational, boolean expressions, and mixed-type lists.
|
||||||
|
|
||||||
|
|||||||
+52
-23
@@ -535,8 +535,8 @@ pre.rouge .ss {
|
|||||||
<ul class="sectlevel1">
|
<ul class="sectlevel1">
|
||||||
<li><a href="#_expr">1. Expr</a>
|
<li><a href="#_expr">1. Expr</a>
|
||||||
<ul class="sectlevel2">
|
<ul class="sectlevel2">
|
||||||
<li><a href="#_dev_expr_test_tool">1.1. <code>dev-expr</code> test tool</a></li>
|
<li><a href="#_concepts_and_terminology">1.1. Concepts and terminology</a></li>
|
||||||
<li><a href="#_concepts_and_terminology">1.2. Concepts and terminology</a></li>
|
<li><a href="#_dev_expr_test_tool">1.2. <code>dev-expr</code> test tool</a></li>
|
||||||
</ul>
|
</ul>
|
||||||
</li>
|
</li>
|
||||||
<li><a href="#_data_types">2. Data types</a>
|
<li><a href="#_data_types">2. Data types</a>
|
||||||
@@ -545,7 +545,7 @@ pre.rouge .ss {
|
|||||||
<li><a href="#_fractions">2.2. Fractions</a></li>
|
<li><a href="#_fractions">2.2. Fractions</a></li>
|
||||||
<li><a href="#_strings">2.3. Strings</a></li>
|
<li><a href="#_strings">2.3. Strings</a></li>
|
||||||
<li><a href="#_boolean">2.4. Boolean</a></li>
|
<li><a href="#_boolean">2.4. Boolean</a></li>
|
||||||
<li><a href="#_list">2.5. List</a></li>
|
<li><a href="#_lists">2.5. Lists</a></li>
|
||||||
</ul>
|
</ul>
|
||||||
</li>
|
</li>
|
||||||
<li><a href="#_dictionaries">3. Dictionaries</a></li>
|
<li><a href="#_dictionaries">3. Dictionaries</a></li>
|
||||||
@@ -579,7 +579,7 @@ pre.rouge .ss {
|
|||||||
<div class="sectionbody">
|
<div class="sectionbody">
|
||||||
<!-- toc disabled -->
|
<!-- toc disabled -->
|
||||||
<div class="paragraph">
|
<div class="paragraph">
|
||||||
<p><mark>TODO: Work in progress (last update on 2024/05/09, 07:17 am)</mark></p>
|
<p><mark>TODO: Work in progress (last update on 2024/05/10, 06:52 a.m.)</mark></p>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
@@ -590,16 +590,29 @@ pre.rouge .ss {
|
|||||||
<p><em>Expr</em> is a GO package capable of analysing, interpreting and calculating expressions.</p>
|
<p><em>Expr</em> is a GO package capable of analysing, interpreting and calculating expressions.</p>
|
||||||
</div>
|
</div>
|
||||||
<div class="sect2">
|
<div class="sect2">
|
||||||
<h3 id="_dev_expr_test_tool"><a class="anchor" href="#_dev_expr_test_tool"></a><a class="link" href="#_dev_expr_test_tool">1.1. <code>dev-expr</code> test tool</a></h3>
|
<h3 id="_concepts_and_terminology"><a class="anchor" href="#_concepts_and_terminology"></a><a class="link" href="#_concepts_and_terminology">1.1. Concepts and terminology</a></h3>
|
||||||
|
<div class="paragraph">
|
||||||
|
<p><mark>TODO</mark></p>
|
||||||
|
</div>
|
||||||
|
<div class="imageblock">
|
||||||
|
<div class="content">
|
||||||
|
<img src="expression-diagram.png" alt="expression diagram">
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="sect2">
|
||||||
|
<h3 id="_dev_expr_test_tool"><a class="anchor" href="#_dev_expr_test_tool"></a><a class="link" href="#_dev_expr_test_tool">1.2. <code>dev-expr</code> test tool</a></h3>
|
||||||
<div class="paragraph">
|
<div class="paragraph">
|
||||||
<p><code>dev-expr</code> is a simple program that can be used to evaluate expressions interactively. As its name suggests, it was created for testing purpose. In fact, beyond in additon to the automatic test suite based on the Go test framework, <code>dev-expr</code> provides an important aid for quickly testing of new features during their development.</p>
|
<p><code>dev-expr</code> is a simple program that can be used to evaluate expressions interactively. As its name suggests, it was created for testing purpose. In fact, beyond in additon to the automatic test suite based on the Go test framework, <code>dev-expr</code> provides an important aid for quickly testing of new features during their development.</p>
|
||||||
</div>
|
</div>
|
||||||
<div class="paragraph">
|
<div class="paragraph">
|
||||||
<p>It cat work as a REPL, *R*ead-*E*xecute-*P*rint-*L*oop, or it can process expression acquired from files or standard input.</p>
|
<p>It cat work as a <em>REPL</em>, <em><strong>R</strong>ead-<strong>E</strong>xecute-<strong>P</strong>rint-<strong>L</strong>oop</em>, or it can process expression acquired from files or standard input.</p>
|
||||||
</div>
|
</div>
|
||||||
<div class="paragraph">
|
<div class="paragraph">
|
||||||
<p>The program in located in the <em>tools</em> directory.
|
<p>The program can be downloaded from <a href="https://git.portale-stac.it/go-pkg/-/packages/generic/dev-expr/">dev-expr</a>.</p>
|
||||||
Here are some examples of execution.</p>
|
</div>
|
||||||
|
<div class="paragraph">
|
||||||
|
<p>Here are some examples of execution.</p>
|
||||||
</div>
|
</div>
|
||||||
<div class="listingblock">
|
<div class="listingblock">
|
||||||
<div class="title">Run <code>dev-expr</code> in REPL mode and ask for help</div>
|
<div class="title">Run <code>dev-expr</code> in REPL mode and ask for help</div>
|
||||||
@@ -697,17 +710,6 @@ Here are some examples of execution.</p>
|
|||||||
</table>
|
</table>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="sect2">
|
|
||||||
<h3 id="_concepts_and_terminology"><a class="anchor" href="#_concepts_and_terminology"></a><a class="link" href="#_concepts_and_terminology">1.2. Concepts and terminology</a></h3>
|
|
||||||
<div class="paragraph">
|
|
||||||
<p><mark>TODO</mark></p>
|
|
||||||
</div>
|
|
||||||
<div class="imageblock">
|
|
||||||
<div class="content">
|
|
||||||
<img src="expression-diagram.png" alt="expression diagram">
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="sect1">
|
<div class="sect1">
|
||||||
@@ -791,14 +793,14 @@ Here are some examples of execution.</p>
|
|||||||
<div class="sect2">
|
<div class="sect2">
|
||||||
<h3 id="_fractions"><a class="anchor" href="#_fractions"></a><a class="link" href="#_fractions">2.2. Fractions</a></h3>
|
<h3 id="_fractions"><a class="anchor" href="#_fractions"></a><a class="link" href="#_fractions">2.2. Fractions</a></h3>
|
||||||
<div class="paragraph">
|
<div class="paragraph">
|
||||||
<p><em>Expr</em> also suports fractions. Fraction literals are made with tow integers separated by a vertical bar <code>|</code>.</p>
|
<p><em>Expr</em> also supports fractions. Fraction literals are made with two integers separated by a vertical bar <code>|</code>.</p>
|
||||||
</div>
|
</div>
|
||||||
<div class="paragraph">
|
<div class="paragraph">
|
||||||
<div class="title">Examples</div>
|
<div class="title">Examples</div>
|
||||||
<p><code>>>></code> <code class="blue">1 | 2</code><br>
|
<p><code>>>></code> <code class="blue">1 | 2</code><br>
|
||||||
<code class="green">1|2</code><br>
|
<code class="green">1|2</code><br>
|
||||||
<code>>>></code> <code class="blue">4|6</code><br>
|
<code>>>></code> <code class="blue">4|6</code><br>
|
||||||
<code class="green">2|3</code> <em class="gray">Fractions are always reduced to theri lowest terms</em><br>
|
<code class="green">2|3</code> <em class="gray">Fractions are always reduced to their lowest terms</em><br>
|
||||||
<code>>>></code> <code class="blue">1|2 + 2|3</code><br>
|
<code>>>></code> <code class="blue">1|2 + 2|3</code><br>
|
||||||
<code class="green">7|6</code><br>
|
<code class="green">7|6</code><br>
|
||||||
<code>>>></code> <code class="blue">1|2 * 2|3</code><br>
|
<code>>>></code> <code class="blue">1|2 * 2|3</code><br>
|
||||||
@@ -1003,7 +1005,7 @@ Here are some examples of execution.</p>
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="sect2">
|
<div class="sect2">
|
||||||
<h3 id="_list"><a class="anchor" href="#_list"></a><a class="link" href="#_list">2.5. List</a></h3>
|
<h3 id="_lists"><a class="anchor" href="#_lists"></a><a class="link" href="#_lists">2.5. Lists</a></h3>
|
||||||
<div class="paragraph">
|
<div class="paragraph">
|
||||||
<p><em>Expr</em> supports list of mixed-type values, also specified by normal expressions.</p>
|
<p><em>Expr</em> supports list of mixed-type values, also specified by normal expressions.</p>
|
||||||
</div>
|
</div>
|
||||||
@@ -1048,6 +1050,33 @@ Here are some examples of execution.</p>
|
|||||||
</tr>
|
</tr>
|
||||||
</tbody>
|
</tbody>
|
||||||
</table>
|
</table>
|
||||||
|
<div class="paragraph">
|
||||||
|
<p>The items of array can be accessed using the dot <code>.</code> operator.</p>
|
||||||
|
</div>
|
||||||
|
<div class="listingblock">
|
||||||
|
<div class="title">Item access syntax</div>
|
||||||
|
<div class="content">
|
||||||
|
<pre class="rouge highlight"><code data-lang="bnf"><item> ::= <list-expr>"."<index-expr></code></pre>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="listingblock">
|
||||||
|
<div class="title">Items of list</div>
|
||||||
|
<div class="content">
|
||||||
|
<pre class="rouge highlight"><code data-lang="go"><span class="s">`>>>`</span> <span class="p">[</span><span class="n">blue</span><span class="p">]</span><span class="s">`[1,2,3].1`</span>
|
||||||
|
<span class="p">[</span><span class="n">green</span><span class="p">]</span><span class="s">`2`</span>
|
||||||
|
<span class="s">`>>>`</span> <span class="p">[</span><span class="n">blue</span><span class="p">]</span><span class="s">`list=[1,2,3]; list.1`</span>
|
||||||
|
<span class="p">[</span><span class="n">green</span><span class="p">]</span><span class="s">`2`</span>
|
||||||
|
<span class="s">`>>>`</span> <span class="p">[</span><span class="n">blue</span><span class="p">]</span><span class="s">`["one","two","three"].1`</span>
|
||||||
|
<span class="p">[</span><span class="n">green</span><span class="p">]</span><span class="s">`two`</span>
|
||||||
|
<span class="s">`>>>`</span> <span class="p">[</span><span class="n">blue</span><span class="p">]</span><span class="s">`list=["one","two","three"]; list.(2-1)`</span>
|
||||||
|
<span class="p">[</span><span class="n">green</span><span class="p">]</span><span class="s">`two`</span>
|
||||||
|
<span class="s">`>>>`</span> <span class="p">[</span><span class="n">blue</span><span class="p">]</span><span class="s">`list.(-1)`</span>
|
||||||
|
<span class="p">[</span><span class="n">green</span><span class="p">]</span><span class="s">`three`</span>
|
||||||
|
<span class="s">`>>>`</span> <span class="p">[</span><span class="n">blue</span><span class="p">]</span><span class="s">`list.(-1)`</span>
|
||||||
|
<span class="p">[</span><span class="n">green</span><span class="p">]</span><span class="s">`three`</span>
|
||||||
|
<span class="s">`>>>`</span> <span class="p">[</span><span class="n">blue</span><span class="p">]</span><span class="s">`list.(10)`</span></code></pre>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
@@ -1461,7 +1490,7 @@ The value on the left side of <code class="blue">=</code> must be an identifier.
|
|||||||
</div>
|
</div>
|
||||||
<div id="footer">
|
<div id="footer">
|
||||||
<div id="footer-text">
|
<div id="footer-text">
|
||||||
Last updated 2024-05-09 07:18:01 +0200
|
Last updated 2024-05-10 06:38:03 +0200
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</body>
|
</body>
|
||||||
|
|||||||
+6
-1
@@ -43,6 +43,11 @@ func isFractionFunc(ctx ExprContext, name string, args []any) (result any, err e
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func isRationalFunc(ctx ExprContext, name string, args []any) (result any, err error) {
|
||||||
|
result = IsRational(args[0])
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
func isListFunc(ctx ExprContext, name string, args []any) (result any, err error) {
|
func isListFunc(ctx ExprContext, name string, args []any) (result any, err error) {
|
||||||
result = IsList(args[0])
|
result = IsList(args[0])
|
||||||
return
|
return
|
||||||
@@ -53,7 +58,6 @@ func isDictionaryFunc(ctx ExprContext, name string, args []any) (result any, err
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
func intFunc(ctx ExprContext, name string, args []any) (result any, err error) {
|
func intFunc(ctx ExprContext, name string, args []any) (result any, err error) {
|
||||||
if len(args) == 1 {
|
if len(args) == 1 {
|
||||||
switch v := args[0].(type) {
|
switch v := args[0].(type) {
|
||||||
@@ -93,6 +97,7 @@ func ImportBuiltinsFuncs(ctx ExprContext) {
|
|||||||
ctx.RegisterFunc("isString", &simpleFunctor{f: isStringFunc}, 1, 1)
|
ctx.RegisterFunc("isString", &simpleFunctor{f: isStringFunc}, 1, 1)
|
||||||
ctx.RegisterFunc("isFraction", &simpleFunctor{f: isFractionFunc}, 1, 1)
|
ctx.RegisterFunc("isFraction", &simpleFunctor{f: isFractionFunc}, 1, 1)
|
||||||
ctx.RegisterFunc("isFract", &simpleFunctor{f: isFractionFunc}, 1, 1)
|
ctx.RegisterFunc("isFract", &simpleFunctor{f: isFractionFunc}, 1, 1)
|
||||||
|
ctx.RegisterFunc("isRational", &simpleFunctor{f: isRationalFunc}, 1, 1)
|
||||||
ctx.RegisterFunc("isList", &simpleFunctor{f: isListFunc}, 1, 1)
|
ctx.RegisterFunc("isList", &simpleFunctor{f: isListFunc}, 1, 1)
|
||||||
ctx.RegisterFunc("isDictionary", &simpleFunctor{f: isDictionaryFunc}, 1, 1)
|
ctx.RegisterFunc("isDictionary", &simpleFunctor{f: isDictionaryFunc}, 1, 1)
|
||||||
ctx.RegisterFunc("isDict", &simpleFunctor{f: isDictionaryFunc}, 1, 1)
|
ctx.RegisterFunc("isDict", &simpleFunctor{f: isDictionaryFunc}, 1, 1)
|
||||||
|
|||||||
+8
-6
@@ -57,12 +57,14 @@ func TestFuncs(t *testing.T) {
|
|||||||
/* 44 */ {`builtin "string"; splitStr("one-two-three", "-", )`, newListA("one", "two", "three"), nil},
|
/* 44 */ {`builtin "string"; splitStr("one-two-three", "-", )`, newListA("one", "two", "three"), nil},
|
||||||
/* 45 */ {`isInt(2+1)`, true, nil},
|
/* 45 */ {`isInt(2+1)`, true, nil},
|
||||||
/* 46 */ {`isInt(3.1)`, false, nil},
|
/* 46 */ {`isInt(3.1)`, false, nil},
|
||||||
/* 46 */ {`isFloat(3.1)`, true, nil},
|
/* 47 */ {`isFloat(3.1)`, true, nil},
|
||||||
/* 47 */ {`isString("3.1")`, true, nil},
|
/* 48 */ {`isString("3.1")`, true, nil},
|
||||||
/* 48 */ {`isString("3" + 1)`, true, nil},
|
/* 49 */ {`isString("3" + 1)`, true, nil},
|
||||||
/* 49 */ {`isList(["3", 1])`, true, nil},
|
/* 50 */ {`isList(["3", 1])`, true, nil},
|
||||||
/* 50 */ {`isDict({"a":"3", "b":1})`, true, nil},
|
/* 51 */ {`isDict({"a":"3", "b":1})`, true, nil},
|
||||||
/* 51 */ {`isFract(3|1)`, true, nil},
|
/* 52 */ {`isFract(1|3)`, true, nil},
|
||||||
|
/* 53 */ {`isFract(3|1)`, false, nil},
|
||||||
|
/* 54 */ {`isRational(3|1)`, true, nil},
|
||||||
}
|
}
|
||||||
|
|
||||||
t.Setenv("EXPR_PATH", ".")
|
t.Setenv("EXPR_PATH", ".")
|
||||||
|
|||||||
@@ -39,6 +39,7 @@ func TestListParser(t *testing.T) {
|
|||||||
/* 17 */ {`list=["one","two","three"]; list.10`, nil, errors.New(`[1:36] index 10 out of bounds`)},
|
/* 17 */ {`list=["one","two","three"]; list.10`, nil, errors.New(`[1:36] index 10 out of bounds`)},
|
||||||
/* 18 */ {`["a", "b", "c"]`, newListA("a", "b", "c"), nil},
|
/* 18 */ {`["a", "b", "c"]`, newListA("a", "b", "c"), nil},
|
||||||
/* 19 */ {`["a", "b", "c"]`, newList([]any{"a", "b", "c"}), nil},
|
/* 19 */ {`["a", "b", "c"]`, newList([]any{"a", "b", "c"}), nil},
|
||||||
|
/* 20 */ {`#["a", "b", "c"]`, int64(3), nil},
|
||||||
|
|
||||||
// /* 8 */ {`[int(x)|x=csv("test.csv",1,all(),1)]`, []any{int64(10), int64(40), int64(20)}, nil},
|
// /* 8 */ {`[int(x)|x=csv("test.csv",1,all(),1)]`, []any{int64(10), int64(40), int64(20)}, nil},
|
||||||
// /* 9 */ {`sum(@[int(x)|x=csv("test.csv",1,all(),1)])`, []any{int64(10), int64(40), int64(20)}, nil},
|
// /* 9 */ {`sum(@[int(x)|x=csv("test.csv",1,all(),1)])`, []any{int64(10), int64(40), int64(20)}, nil},
|
||||||
|
|||||||
+1
-1
@@ -57,7 +57,7 @@ func evalDot(ctx ExprContext, self *term) (v any, err error) {
|
|||||||
case string:
|
case string:
|
||||||
var index int
|
var index int
|
||||||
if index, err = verifyIndex(ctx, indexTerm, len(unboxedValue)); err == nil {
|
if index, err = verifyIndex(ctx, indexTerm, len(unboxedValue)); err == nil {
|
||||||
v = unboxedValue[index]
|
v = string(unboxedValue[index])
|
||||||
}
|
}
|
||||||
case map[any]any:
|
case map[any]any:
|
||||||
var ok bool
|
var ok bool
|
||||||
|
|||||||
+5
-2
@@ -24,11 +24,14 @@ func evalLength(ctx ExprContext, self *term) (v any, err error) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if IsList(childValue) {
|
if IsList(childValue) {
|
||||||
list, _ := childValue.([]any)
|
ls, _ := childValue.(*ListType)
|
||||||
v = int64(len(list))
|
v = int64(len(*ls))
|
||||||
} else if IsString(childValue) {
|
} else if IsString(childValue) {
|
||||||
s, _ := childValue.(string)
|
s, _ := childValue.(string)
|
||||||
v = int64(len(s))
|
v = int64(len(s))
|
||||||
|
} else if IsDict(childValue) {
|
||||||
|
m, _ := childValue.(map[any]any)
|
||||||
|
v = int64(len(m))
|
||||||
} else if it, ok := childValue.(Iterator); ok {
|
} else if it, ok := childValue.(Iterator); ok {
|
||||||
if extIt, ok := childValue.(ExtIterator); ok && extIt.HasOperation(countName) {
|
if extIt, ok := childValue.(ExtIterator); ok && extIt.HasOperation(countName) {
|
||||||
count, _ := extIt.CallOperation(countName, nil)
|
count, _ := extIt.CallOperation(countName, nil)
|
||||||
|
|||||||
+4
-4
@@ -35,10 +35,10 @@ func TestGeneralParser(t *testing.T) {
|
|||||||
/* 14 */ {`not true`, false, nil},
|
/* 14 */ {`not true`, false, nil},
|
||||||
/* 15 */ {`true and false`, false, nil},
|
/* 15 */ {`true and false`, false, nil},
|
||||||
/* 16 */ {`true or false`, true, nil},
|
/* 16 */ {`true or false`, true, nil},
|
||||||
/* 17 */ {`"uno" + "due"`, `unodue`, nil},
|
/* *17 */ {`"uno" + "due"`, `unodue`, nil},
|
||||||
/* 18 */ {`"uno" + 2`, `uno2`, nil},
|
/* *18 */ {`"uno" + 2`, `uno2`, nil},
|
||||||
/* 19 */ {`"uno" + (2+1)`, `uno3`, nil},
|
/* *19 */ {`"uno" + (2+1)`, `uno3`, nil},
|
||||||
/* 20 */ {`"uno" * (2+1)`, `unounouno`, nil},
|
/* *20 */ {`"uno" * (2+1)`, `unounouno`, nil},
|
||||||
/* 21 */ {"1", int64(1), nil},
|
/* 21 */ {"1", int64(1), nil},
|
||||||
/* 22 */ {"1.5", float64(1.5), nil},
|
/* 22 */ {"1.5", float64(1.5), nil},
|
||||||
/* 23 */ {"1.5*2", float64(3.0), nil},
|
/* 23 */ {"1.5*2", float64(3.0), nil},
|
||||||
|
|||||||
@@ -0,0 +1,21 @@
|
|||||||
|
// Copyright (c) 2024 Celestino Amoroso (celestino.amoroso@gmail.com).
|
||||||
|
// All rights reserved.
|
||||||
|
|
||||||
|
// strings_test.go
|
||||||
|
package expr
|
||||||
|
|
||||||
|
import (
|
||||||
|
"testing"
|
||||||
|
)
|
||||||
|
|
||||||
|
func TestStringsParser(t *testing.T) {
|
||||||
|
inputs := []inputType{
|
||||||
|
/* 1 */ {`"uno" + "due"`, `unodue`, nil},
|
||||||
|
/* 2 */ {`"uno" + 2`, `uno2`, nil},
|
||||||
|
/* 3 */ {`"uno" + (2+1)`, `uno3`, nil},
|
||||||
|
/* 4 */ {`"uno" * (2+1)`, `unounouno`, nil},
|
||||||
|
/* 5 */ {`"abc".1`, `b`, nil},
|
||||||
|
/* 5 */ {`#"abc"`, int64(3), nil},
|
||||||
|
}
|
||||||
|
parserTest(t, "String", inputs)
|
||||||
|
}
|
||||||
@@ -44,6 +44,13 @@ func IsFract(v any) (ok bool) {
|
|||||||
return ok
|
return ok
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func IsRational(v any) (ok bool) {
|
||||||
|
if _, ok = v.(*fraction); !ok {
|
||||||
|
_, ok = v.(int64)
|
||||||
|
}
|
||||||
|
return ok
|
||||||
|
}
|
||||||
|
|
||||||
func IsNumber(v any) (ok bool) {
|
func IsNumber(v any) (ok bool) {
|
||||||
return IsFloat(v) || IsInteger(v)
|
return IsFloat(v) || IsInteger(v)
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user