Compare commits

..

No commits in common. "52a627c7476b90e0b526872f5e4b26da183d2322" and "cca3b76baa9bbbcc43964e1dd91e8c94509572d1" have entirely different histories.

10 changed files with 69 additions and 175 deletions

View File

@ -439,8 +439,8 @@ _non-empty-list_ = "**[**" _any-value_ {"**,**" _any-value_} "**]**" +
| [blue]`+` | _Join_ | Joins two lists | [blue]`[1,2] + [3]` -> _[1,2,3]_ | [blue]`+` | _Join_ | Joins two lists | [blue]`[1,2] + [3]` -> _[1,2,3]_
| [blue]`-` | _Difference_ | Left list without elements in the right list | [blue]`[1,2,3] - [2]` -> _[1,3]_ | [blue]`-` | _Difference_ | Left list without elements in the right list | [blue]`[1,2,3] - [2]` -> _[1,3]_
| [blue]`+>` | _Front insertion_ | Insert an item in front | [blue]`0 +> [1,2]` -> _[0,1,2]_ | [blue]`>>` | _Front insertion_ | Insert an item in front | [blue]`0 >> [1,2]` -> _[0,1,2]_
| [blue]`<+` | _Back insertion_ | Insert an item at end | [blue]`[1,2] <+ 3` -> _[1,2,3]_ | [blue]`<<` | _Back insertion_ | Insert an item at end | [blue]`[1,2] << 3` -> _[1,2,3]_
| [blue]`[]` | _Item at index_ | Item at given position | [blue]`[1,2,3][1]` -> _2_ | [blue]`[]` | _Item at index_ | Item at given position | [blue]`[1,2,3][1]` -> _2_
| [blue]`in` | _Item in list_ | True if item is in list | [blue]`2 in [1,2,3]` -> _true_ + | [blue]`in` | _Item in list_ | True if item is in list | [blue]`2 in [1,2,3]` -> _true_ +
[blue]`6 in [1,2,3]` -> _false_ [blue]`6 in [1,2,3]` -> _false_
@ -735,7 +735,7 @@ NOTE: These operators have a high priority, in particular higher than the operat
The table below shows all supported operators by decreasing priorities. The table below shows all supported operators by decreasing priorities.
.Operators priorities .Operators priorities
[cols="^3,^2,^2,^5,^6"] [cols="^2,^2,^2,^5,^6"]
|=== |===
| Priority | Operators | Position | Operation | Operands and results | Priority | Operators | Position | Operation | Operands and results
@ -765,9 +765,9 @@ The table below shows all supported operators by decreasing priorities.
| [blue]`+` | _Infix_ | _Dict-join_ | _dict_ `+` _dict_ -> _dict_ | [blue]`+` | _Infix_ | _Dict-join_ | _dict_ `+` _dict_ -> _dict_
| [blue]`-` | _Infix_ | _Subtraction_ | _number_ `-` _number_ -> _number_ | [blue]`-` | _Infix_ | _Subtraction_ | _number_ `-` _number_ -> _number_
| [blue]`-` | _Infix_ | _List-difference_ | _list_ `-` _list_ -> _list_ | [blue]`-` | _Infix_ | _List-difference_ | _list_ `-` _list_ -> _list_
.1+|*BINARY NOT*| [blue]`~` | _Prefix_ | _Binary Not_ | `~` _number_ -> _number_ .3+|*BINARY*| [blue]`&` | _Infix_ | _Binary And_ | _number_ `&` _number_ -> _number_
.1+|*BINARY AND*| [blue]`&` | _Infix_ | _Binary And_ | _number_ `&` _number_ -> _number_ | [blue]`\|` | _Infix_ | _Binary Or_ | _number_ `\|` _number_ -> _number_
.1+|*BINARY OR*| [blue]`\|` | _Infix_ | _Binary Or_ | _number_ `\|` _number_ -> _number_ | [blue]`~` | _Prefix_ | _Binary Not_ | `~` _number_ -> _number_
.8+|*RELATION*| [blue]`<` | _Infix_ | _Less_ | _comparable_ `<` _comparable_ -> _boolean_ .8+|*RELATION*| [blue]`<` | _Infix_ | _Less_ | _comparable_ `<` _comparable_ -> _boolean_
| [blue]`\<=` | _Infix_ | _less-equal_ | _comparable_ `\<=` _comparable_ -> _boolean_ | [blue]`\<=` | _Infix_ | _less-equal_ | _comparable_ `\<=` _comparable_ -> _boolean_
| [blue]`>` | _Infix_ | _Greater_ | _comparable_ `>` _comparable_ -> _boolean_ | [blue]`>` | _Infix_ | _Greater_ | _comparable_ `>` _comparable_ -> _boolean_
@ -776,13 +776,11 @@ The table below shows all supported operators by decreasing priorities.
| [blue]`!=` | _Infix_ | _Not-equal_ | _comparable_ `!=` _comparable_ -> _boolean_ | [blue]`!=` | _Infix_ | _Not-equal_ | _comparable_ `!=` _comparable_ -> _boolean_
| [blue]`in` | _Infix_ | _Member-of-list_ | _any_ `in` _list_ -> _boolean_ | [blue]`in` | _Infix_ | _Member-of-list_ | _any_ `in` _list_ -> _boolean_
| [blue]`in` | _Infix_ | _Key-of-dict_ | _any_ `in` _dict_ -> _boolean_ | [blue]`in` | _Infix_ | _Key-of-dict_ | _any_ `in` _dict_ -> _boolean_
.1+|*LOGIC NOT*| [blue]`not` | _Prefix_ | _Not_ | `not` _boolean_ -> _boolean_ .1+|*NOT*| [blue]`not` | _Prefix_ | _Not_ | `not` _boolean_ -> _boolean_
.2+|*LOGIC AND*| [blue]`and` | _Infix_ | _And_ | _boolean_ `and` _boolean_ -> _boolean_ .2+|*AND*| [blue]`and` | _Infix_ | _And_ | _boolean_ `and` _boolean_ -> _boolean_
| [blue]`&&` | _Infix_ | _And_ | _boolean_ `&&` _boolean_ -> _boolean_ | [blue]`&&` | _Infix_ | _And_ | _boolean_ `&&` _boolean_ -> _boolean_
.2+|*LOGIC OR*| [blue]`or` | _Infix_ | _Or_ | _boolean_ `or` _boolean_ -> _boolean_ .2+|*OR*| [blue]`or` | _Infix_ | _Or_ | _boolean_ `or` _boolean_ -> _boolean_
| [blue]`\|\|` | _Infix_ | _Or_ | _boolean_ `\|\|` _boolean_ -> _boolean_ | [blue]`\|\|` | _Infix_ | _Or_ | _boolean_ `\|\|` _boolean_ -> _boolean_
.2+|*INSERT*| [blue]`+>` | _Infix_ | _Prepend_ | _any_ `+>` _list_ -> _list_
| [blue]`<+` | _Infix_ | _Append_ | _list_ `<+` _any_ -> _list_
.3+|*ASSIGN*| [blue]`=` | _Infix_ | _Assignment_ | _identifier_ `=` _any_ -> _any_ .3+|*ASSIGN*| [blue]`=` | _Infix_ | _Assignment_ | _identifier_ `=` _any_ -> _any_
| [blue]`>>` | _Infix_ | _Front-insert_ | _any_ `>>` _list_ -> _list_ | [blue]`>>` | _Infix_ | _Front-insert_ | _any_ `>>` _list_ -> _list_
| [blue]`<<` | _Infix_ | _Back-insert_ | _list_ `<<` _any_ -> _list_ | [blue]`<<` | _Infix_ | _Back-insert_ | _list_ `<<` _any_ -> _list_

View File

@ -1380,16 +1380,16 @@ dev-expr <span class="nt">--</span> Expressions calculator v1.10.0<span class="o
<td class="tableblock halign-left valign-top"><p class="tableblock"><code class="blue">[1,2,3] - [2]</code> &#8594; <em>[1,3]</em></p></td> <td class="tableblock halign-left valign-top"><p class="tableblock"><code class="blue">[1,2,3] - [2]</code> &#8594; <em>[1,3]</em></p></td>
</tr> </tr>
<tr> <tr>
<td class="tableblock halign-center valign-top"><p class="tableblock"><code class="blue">+&gt;</code></p></td> <td class="tableblock halign-center valign-top"><p class="tableblock"><code class="blue">&gt;&gt;</code></p></td>
<td class="tableblock halign-center valign-top"><p class="tableblock"><em>Front insertion</em></p></td> <td class="tableblock halign-center valign-top"><p class="tableblock"><em>Front insertion</em></p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">Insert an item in front</p></td> <td class="tableblock halign-left valign-top"><p class="tableblock">Insert an item in front</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock"><code class="blue">0 +&gt; [1,2]</code> &#8594; <em>[0,1,2]</em></p></td> <td class="tableblock halign-left valign-top"><p class="tableblock"><code class="blue">0 &gt;&gt; [1,2]</code> &#8594; <em>[0,1,2]</em></p></td>
</tr> </tr>
<tr> <tr>
<td class="tableblock halign-center valign-top"><p class="tableblock"><code class="blue">&lt;+</code></p></td> <td class="tableblock halign-center valign-top"><p class="tableblock"><code class="blue">&lt;&lt;</code></p></td>
<td class="tableblock halign-center valign-top"><p class="tableblock"><em>Back insertion</em></p></td> <td class="tableblock halign-center valign-top"><p class="tableblock"><em>Back insertion</em></p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">Insert an item at end</p></td> <td class="tableblock halign-left valign-top"><p class="tableblock">Insert an item at end</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock"><code class="blue">[1,2] &lt;+ 3</code> &#8594; <em>[1,2,3]</em></p></td> <td class="tableblock halign-left valign-top"><p class="tableblock"><code class="blue">[1,2] &lt;&lt; 3</code> &#8594; <em>[1,2,3]</em></p></td>
</tr> </tr>
<tr> <tr>
<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>
@ -1900,11 +1900,11 @@ These operators have a high priority, in particular higher than the operator <co
<table class="tableblock frame-all grid-all stretch"> <table class="tableblock frame-all grid-all stretch">
<caption class="title">Table 8. Operators priorities</caption> <caption class="title">Table 8. Operators priorities</caption>
<colgroup> <colgroup>
<col style="width: 16.6666%;"> <col style="width: 11.7647%;">
<col style="width: 11.1111%;"> <col style="width: 11.7647%;">
<col style="width: 11.1111%;"> <col style="width: 11.7647%;">
<col style="width: 27.7777%;"> <col style="width: 29.4117%;">
<col style="width: 33.3335%;"> <col style="width: 35.2942%;">
</colgroup> </colgroup>
<thead> <thead>
<tr> <tr>
@ -2076,27 +2076,25 @@ These operators have a high priority, in particular higher than the operator <co
<td class="tableblock halign-center valign-top"><p class="tableblock"><em>list</em> <code>-</code> <em>list</em> &#8594; <em>list</em></p></td> <td class="tableblock halign-center valign-top"><p class="tableblock"><em>list</em> <code>-</code> <em>list</em> &#8594; <em>list</em></p></td>
</tr> </tr>
<tr> <tr>
<td class="tableblock halign-center valign-top"><p class="tableblock"><strong>BINARY NOT</strong></p></td> <td class="tableblock halign-center valign-top" rowspan="3"><p class="tableblock"><strong>BINARY</strong></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>Prefix</em></p></td>
<td class="tableblock halign-center valign-top"><p class="tableblock"><em>Binary Not</em></p></td>
<td class="tableblock halign-center valign-top"><p class="tableblock"><code>~</code> <em>number</em> &#8594; <em>number</em></p></td>
</tr>
<tr>
<td class="tableblock halign-center valign-top"><p class="tableblock"><strong>BINARY AND</strong></p></td>
<td class="tableblock halign-center valign-top"><p class="tableblock"><code class="blue">&amp;</code></p></td> <td class="tableblock halign-center valign-top"><p class="tableblock"><code class="blue">&amp;</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>Binary And</em></p></td> <td class="tableblock halign-center valign-top"><p class="tableblock"><em>Binary And</em></p></td>
<td class="tableblock halign-center valign-top"><p class="tableblock"><em>number</em> <code>&amp;</code> <em>number</em> &#8594; <em>number</em></p></td> <td class="tableblock halign-center valign-top"><p class="tableblock"><em>number</em> <code>&amp;</code> <em>number</em> &#8594; <em>number</em></p></td>
</tr> </tr>
<tr> <tr>
<td class="tableblock halign-center valign-top"><p class="tableblock"><strong>BINARY OR</strong></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"><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>Binary Or</em></p></td> <td class="tableblock halign-center valign-top"><p class="tableblock"><em>Binary Or</em></p></td>
<td class="tableblock halign-center valign-top"><p class="tableblock"><em>number</em> <code>|</code> <em>number</em> &#8594; <em>number</em></p></td> <td class="tableblock halign-center valign-top"><p class="tableblock"><em>number</em> <code>|</code> <em>number</em> &#8594; <em>number</em></p></td>
</tr> </tr>
<tr> <tr>
<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>Prefix</em></p></td>
<td class="tableblock halign-center valign-top"><p class="tableblock"><em>Binary Not</em></p></td>
<td class="tableblock halign-center valign-top"><p class="tableblock"><code>~</code> <em>number</em> &#8594; <em>number</em></p></td>
</tr>
<tr>
<td class="tableblock halign-center valign-top" rowspan="8"><p class="tableblock"><strong>RELATION</strong></p></td> <td class="tableblock halign-center valign-top" rowspan="8"><p class="tableblock"><strong>RELATION</strong></p></td>
<td class="tableblock halign-center valign-top"><p class="tableblock"><code class="blue">&lt;</code></p></td> <td class="tableblock halign-center valign-top"><p class="tableblock"><code class="blue">&lt;</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>
@ -2146,14 +2144,14 @@ These operators have a high priority, in particular higher than the operator <co
<td class="tableblock halign-center valign-top"><p class="tableblock"><em>any</em> <code>in</code> <em>dict</em> &#8594; <em>boolean</em></p></td> <td class="tableblock halign-center valign-top"><p class="tableblock"><em>any</em> <code>in</code> <em>dict</em> &#8594; <em>boolean</em></p></td>
</tr> </tr>
<tr> <tr>
<td class="tableblock halign-center valign-top"><p class="tableblock"><strong>LOGIC NOT</strong></p></td> <td class="tableblock halign-center valign-top"><p class="tableblock"><strong>NOT</strong></p></td>
<td class="tableblock halign-center valign-top"><p class="tableblock"><code class="blue">not</code></p></td> <td class="tableblock halign-center valign-top"><p class="tableblock"><code class="blue">not</code></p></td>
<td class="tableblock halign-center valign-top"><p class="tableblock"><em>Prefix</em></p></td> <td class="tableblock halign-center valign-top"><p class="tableblock"><em>Prefix</em></p></td>
<td class="tableblock halign-center valign-top"><p class="tableblock"><em>Not</em></p></td> <td class="tableblock halign-center valign-top"><p class="tableblock"><em>Not</em></p></td>
<td class="tableblock halign-center valign-top"><p class="tableblock"><code>not</code> <em>boolean</em> &#8594; <em>boolean</em></p></td> <td class="tableblock halign-center valign-top"><p class="tableblock"><code>not</code> <em>boolean</em> &#8594; <em>boolean</em></p></td>
</tr> </tr>
<tr> <tr>
<td class="tableblock halign-center valign-top" rowspan="2"><p class="tableblock"><strong>LOGIC AND</strong></p></td> <td class="tableblock halign-center valign-top" rowspan="2"><p class="tableblock"><strong>AND</strong></p></td>
<td class="tableblock halign-center valign-top"><p class="tableblock"><code class="blue">and</code></p></td> <td class="tableblock halign-center valign-top"><p class="tableblock"><code class="blue">and</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>And</em></p></td> <td class="tableblock halign-center valign-top"><p class="tableblock"><em>And</em></p></td>
@ -2166,7 +2164,7 @@ These operators have a high priority, in particular higher than the operator <co
<td class="tableblock halign-center valign-top"><p class="tableblock"><em>boolean</em> <code>&amp;&amp;</code> <em>boolean</em> &#8594; <em>boolean</em></p></td> <td class="tableblock halign-center valign-top"><p class="tableblock"><em>boolean</em> <code>&amp;&amp;</code> <em>boolean</em> &#8594; <em>boolean</em></p></td>
</tr> </tr>
<tr> <tr>
<td class="tableblock halign-center valign-top" rowspan="2"><p class="tableblock"><strong>LOGIC OR</strong></p></td> <td class="tableblock halign-center valign-top" rowspan="2"><p class="tableblock"><strong>OR</strong></p></td>
<td class="tableblock halign-center valign-top"><p class="tableblock"><code class="blue">or</code></p></td> <td class="tableblock halign-center valign-top"><p class="tableblock"><code class="blue">or</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>Or</em></p></td> <td class="tableblock halign-center valign-top"><p class="tableblock"><em>Or</em></p></td>
@ -2179,19 +2177,6 @@ These operators have a high priority, in particular higher than the operator <co
<td class="tableblock halign-center valign-top"><p class="tableblock"><em>boolean</em> <code>||</code> <em>boolean</em> &#8594; <em>boolean</em></p></td> <td class="tableblock halign-center valign-top"><p class="tableblock"><em>boolean</em> <code>||</code> <em>boolean</em> &#8594; <em>boolean</em></p></td>
</tr> </tr>
<tr> <tr>
<td class="tableblock halign-center valign-top" rowspan="2"><p class="tableblock"><strong>INSERT</strong></p></td>
<td class="tableblock halign-center valign-top"><p class="tableblock"><code class="blue">+&gt;</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>Prepend</em></p></td>
<td class="tableblock halign-center valign-top"><p class="tableblock"><em>any</em> <code>+&gt;</code> <em>list</em> &#8594; <em>list</em></p></td>
</tr>
<tr>
<td class="tableblock halign-center valign-top"><p class="tableblock"><code class="blue">&lt;+</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>Append</em></p></td>
<td class="tableblock halign-center valign-top"><p class="tableblock"><em>list</em> <code>&lt;+</code> <em>any</em> &#8594; <em>list</em></p></td>
</tr>
<tr>
<td class="tableblock halign-center valign-top" rowspan="3"><p class="tableblock"><strong>ASSIGN</strong></p></td> <td class="tableblock halign-center valign-top" rowspan="3"><p class="tableblock"><strong>ASSIGN</strong></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"><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>
@ -2476,7 +2461,7 @@ g(@p):any{}`
</div> </div>
<div id="footer"> <div id="footer">
<div id="footer-text"> <div id="footer-text">
Last updated 2024-12-28 09:13:00 +0100 Last updated 2024-12-23 07:20:48 +0100
</div> </div>
</div> </div>
</body> </body>

View File

@ -11,7 +11,7 @@ func newBinNotTerm(tk *Token) (inst *term) {
tk: *tk, tk: *tk,
children: make([]*term, 0, 1), children: make([]*term, 0, 1),
position: posPrefix, position: posPrefix,
priority: priBinNot, priority: priBinary,
evalFunc: evalBinaryNot, evalFunc: evalBinaryNot,
} }
} }
@ -39,7 +39,7 @@ func newBinAndTerm(tk *Token) (inst *term) {
tk: *tk, tk: *tk,
children: make([]*term, 0, 2), children: make([]*term, 0, 2),
position: posInfix, position: posInfix,
priority: priBinAnd, priority: priBinary,
evalFunc: evalBinaryAnd, evalFunc: evalBinaryAnd,
} }
} }
@ -71,7 +71,7 @@ func newBinOrTerm(tk *Token) (inst *term) {
tk: *tk, tk: *tk,
children: make([]*term, 0, 2), children: make([]*term, 0, 2),
position: posInfix, position: posInfix,
priority: priBinOr, priority: priBinary,
evalFunc: evalBinaryOr, evalFunc: evalBinaryOr,
} }
} }

View File

@ -4,15 +4,15 @@
// operator-insert.go // operator-insert.go
package expr package expr
//-------- prepend term //-------- insert term
func newPrependTerm(tk *Token) (inst *term) { func newInsertTerm(tk *Token) (inst *term) {
return &term{ return &term{
tk: *tk, tk: *tk,
children: make([]*term, 0, 2), children: make([]*term, 0, 2),
position: posInfix, position: posInfix,
priority: priInsert, priority: priAssign,
evalFunc: evalPrepend, evalFunc: evalInsert,
} }
} }
@ -21,12 +21,12 @@ func newAppendTerm(tk *Token) (inst *term) {
tk: *tk, tk: *tk,
children: make([]*term, 0, 2), children: make([]*term, 0, 2),
position: posInfix, position: posInfix,
priority: priInsert, priority: priAssign,
evalFunc: evalAppend, evalFunc: evalAppend,
} }
} }
func evalPrepend(ctx ExprContext, opTerm *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 = opTerm.evalInfix(ctx); err != nil { if leftValue, rightValue, err = opTerm.evalInfix(ctx); err != nil {
@ -40,6 +40,10 @@ func evalPrepend(ctx ExprContext, opTerm *term) (v any, err error) {
if opTerm.children[1].symbol() == SymVariable { if opTerm.children[1].symbol() == SymVariable {
ctx.UnsafeSetVar(opTerm.children[1].source(), v) ctx.UnsafeSetVar(opTerm.children[1].source(), v)
} }
} else if IsInteger(leftValue) && IsInteger(rightValue) {
leftInt := leftValue.(int64)
rightInt := rightValue.(int64)
v = leftInt >> rightInt
} else { } else {
err = opTerm.errIncompatibleTypes(leftValue, rightValue) err = opTerm.errIncompatibleTypes(leftValue, rightValue)
} }
@ -60,6 +64,10 @@ func evalAppend(ctx ExprContext, opTerm *term) (v any, err error) {
if opTerm.children[0].symbol() == SymVariable { if opTerm.children[0].symbol() == SymVariable {
ctx.UnsafeSetVar(opTerm.children[0].source(), v) ctx.UnsafeSetVar(opTerm.children[0].source(), v)
} }
} else if IsInteger(leftValue) && IsInteger(rightValue) {
leftInt := leftValue.(int64)
rightInt := rightValue.(int64)
v = leftInt << rightInt
} else { } else {
err = opTerm.errIncompatibleTypes(leftValue, rightValue) err = opTerm.errIncompatibleTypes(leftValue, rightValue)
} }
@ -86,6 +94,6 @@ func evalAppend(ctx ExprContext, opTerm *term) (v any, err error) {
// init // init
func init() { func init() {
registerTermConstructor(SymPlusGreater, newPrependTerm) registerTermConstructor(SymInsert, newInsertTerm)
registerTermConstructor(SymLessPlus, newAppendTerm) registerTermConstructor(SymAppend, newAppendTerm)
} }

View File

@ -1,85 +0,0 @@
// Copyright (c) 2024 Celestino Amoroso (celestino.amoroso@gmail.com).
// All rights reserved.
// operator-shift.go
package expr
//-------- shift term
func newRightShiftTerm(tk *Token) (inst *term) {
return &term{
tk: *tk,
children: make([]*term, 0, 2),
position: posInfix,
priority: priBinShift,
evalFunc: evalRightShift,
}
}
func evalRightShift(ctx ExprContext, opTerm *term) (v any, err error) {
var leftValue, rightValue any
if leftValue, rightValue, err = opTerm.evalInfix(ctx); err != nil {
return
}
if IsInteger(leftValue) && IsInteger(rightValue) {
leftInt := leftValue.(int64)
rightInt := rightValue.(int64)
v = leftInt >> rightInt
} else {
err = opTerm.errIncompatibleTypes(leftValue, rightValue)
}
return
}
func newLeftShiftTerm(tk *Token) (inst *term) {
return &term{
tk: *tk,
children: make([]*term, 0, 2),
position: posInfix,
priority: priBinShift,
evalFunc: evalLeftShift,
}
}
func evalLeftShift(ctx ExprContext, opTerm *term) (v any, err error) {
var leftValue, rightValue any
if leftValue, rightValue, err = opTerm.evalInfix(ctx); err != nil {
return
}
if IsInteger(leftValue) && IsInteger(rightValue) {
leftInt := leftValue.(int64)
rightInt := rightValue.(int64)
v = leftInt << rightInt
} else {
err = opTerm.errIncompatibleTypes(leftValue, rightValue)
}
return
}
// func evalAssignAppend(ctx ExprContext, self *term) (v any, err error) {
// var leftValue, rightValue any
// if leftValue, rightValue, err = self.evalInfix(ctx); err != nil {
// return
// }
// if IsList(leftValue) {
// list, _ := leftValue.(*ListType)
// newList := append(*list, rightValue)
// v = &newList
// if
// } else {
// err = self.errIncompatibleTypes(leftValue, rightValue)
// }
// return
// }
// init
func init() {
registerTermConstructor(SymDoubleGreater, newRightShiftTerm)
registerTermConstructor(SymDoubleLess, newLeftShiftTerm)
}

View File

@ -124,8 +124,6 @@ func (scanner *scanner) fetchNextToken() (tk *Token) {
tk = scanner.moveOn(SymDoublePlus, ch, next) tk = scanner.moveOn(SymDoublePlus, ch, next)
} else if next == '=' { } else if next == '=' {
tk = scanner.moveOn(SymPlusEqual, ch, next) tk = scanner.moveOn(SymPlusEqual, ch, next)
} else if next == '>' {
tk = scanner.moveOn(SymPlusGreater, ch, next)
} else { } else {
tk = scanner.makeToken(SymPlus, ch) tk = scanner.makeToken(SymPlus, ch)
} }
@ -267,11 +265,9 @@ func (scanner *scanner) fetchNextToken() (tk *Token) {
if next, _ := scanner.peek(); next == '=' { if next, _ := scanner.peek(); next == '=' {
tk = scanner.moveOn(SymLessOrEqual, ch, next) tk = scanner.moveOn(SymLessOrEqual, ch, next)
} else if next == '<' { } else if next == '<' {
tk = scanner.moveOn(SymDoubleLess, ch, next) tk = scanner.moveOn(SymAppend, ch, next)
} else if next == '>' { } else if next == '>' {
tk = scanner.moveOn(SymLessGreater, ch, next) tk = scanner.moveOn(SymLessGreater, ch, next)
} else if next == '+' {
tk = scanner.moveOn(SymLessPlus, ch, next)
} else { } else {
tk = scanner.makeToken(SymLess, ch) tk = scanner.makeToken(SymLess, ch)
} }
@ -279,7 +275,7 @@ func (scanner *scanner) fetchNextToken() (tk *Token) {
if next, _ := scanner.peek(); next == '=' { if next, _ := scanner.peek(); next == '=' {
tk = scanner.moveOn(SymGreaterOrEqual, ch, next) tk = scanner.moveOn(SymGreaterOrEqual, ch, next)
} else if next == '>' { } else if next == '>' {
tk = scanner.moveOn(SymDoubleGreater, ch, next) tk = scanner.moveOn(SymInsert, ch, next)
} else { } else {
tk = scanner.makeToken(SymGreater, ch) tk = scanner.makeToken(SymGreater, ch)
} }

View File

@ -84,8 +84,8 @@ func init() {
SymQuestionExclam: {"?!", symClassOperator}, // 49: '?!' SymQuestionExclam: {"?!", symClassOperator}, // 49: '?!'
SymDoubleAt: {"@@", symClassOperator}, // 50: '@@' SymDoubleAt: {"@@", symClassOperator}, // 50: '@@'
SymDoubleColon: {"::", symClassOperator}, // 51: '::' SymDoubleColon: {"::", symClassOperator}, // 51: '::'
SymDoubleGreater: {">>", symClassOperator}, // 52: '>>' SymInsert: {">>", symClassOperator}, // 52: '>>'
SymDoubleLess: {"<<", symClassOperator}, // 53: '<<' SymAppend: {"<<", symClassOperator}, // 53: '<<'
SymCaret: {"^", symClassOperator}, // 54: '^' SymCaret: {"^", symClassOperator}, // 54: '^'
SymDollarRound: {"$(", symClassOperator}, // 55: '$(' SymDollarRound: {"$(", symClassOperator}, // 55: '$('
SymOpenClosedRound: {"()", symClassPostOp}, // 56: '()' SymOpenClosedRound: {"()", symClassPostOp}, // 56: '()'
@ -95,8 +95,6 @@ func init() {
SymStarEqual: {"*=", symClassOperator}, // 60: '*=' SymStarEqual: {"*=", symClassOperator}, // 60: '*='
SymSlashEqual: {"/=", symClassOperator}, // 61: '/=' SymSlashEqual: {"/=", symClassOperator}, // 61: '/='
SymPercEqual: {"%=", symClassOperator}, // 62: '%=' SymPercEqual: {"%=", symClassOperator}, // 62: '%='
SymPlusGreater: {"+>", symClassOperator}, // 63: '+>'
SymLessPlus: {"<+", symClassOperator}, // 64: '<+'
// SymChangeSign // SymChangeSign
// SymUnchangeSign // SymUnchangeSign
// SymIdentifier // SymIdentifier

View File

@ -60,8 +60,8 @@ const (
SymQuestionExclam // 49: '?!' SymQuestionExclam // 49: '?!'
SymDoubleAt // 50: '@@' SymDoubleAt // 50: '@@'
SymDoubleColon // 51: '::' SymDoubleColon // 51: '::'
SymDoubleGreater // 52: '>>' SymInsert // 52: '>>'
SymDoubleLess // 53: '<<' SymAppend // 53: '<<'
SymCaret // 54: '^' SymCaret // 54: '^'
SymDollarRound // 55: '$(' SymDollarRound // 55: '$('
SymOpenClosedRound // 56: '()' SymOpenClosedRound // 56: '()'
@ -71,8 +71,6 @@ const (
SymStarEqual // 60: '*=' SymStarEqual // 60: '*='
SymSlashEqual // 61: '/=' SymSlashEqual // 61: '/='
SymPercEqual // 62: '%=' SymPercEqual // 62: '%='
SymPlusGreater // 63: '+>'
SymLessPlus // 64: '<+'
SymChangeSign SymChangeSign
SymUnchangeSign SymUnchangeSign
SymIdentifier SymIdentifier

View File

@ -23,8 +23,8 @@ func TestListParser(t *testing.T) {
/* 9 */ {`mul([1,4,3.0,2])`, float64(24.0), nil}, /* 9 */ {`mul([1,4,3.0,2])`, float64(24.0), nil},
/* 10 */ {`add([1,"hello"])`, nil, `add(): param nr 2 (2 in 1) has wrong type string, number expected`}, /* 10 */ {`add([1,"hello"])`, nil, `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}, /* 11 */ {`[a=1,b=2,c=3] but a+b+c`, int64(6), nil},
/* 12 */ {`[1,2,3] <+ 2+2`, newListA(int64(1), int64(2), int64(3), int64(4)), nil}, /* 12 */ {`[1,2,3] << 2+2`, newListA(int64(1), int64(2), int64(3), int64(4)), nil},
/* 13 */ {`2-1 +> [2,3]`, newListA(int64(1), int64(2), int64(3)), nil}, /* 13 */ {`2-1 >> [2,3]`, newListA(int64(1), int64(2), int64(3)), nil},
/* 14 */ {`[1,2,3][1]`, int64(2), nil}, /* 14 */ {`[1,2,3][1]`, int64(2), nil},
/* 15 */ {`ls=[1,2,3] but ls[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}, /* 16 */ {`ls=[1,2,3] but ls[-1]`, int64(3), nil},
@ -33,8 +33,8 @@ func TestListParser(t *testing.T) {
/* 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}, /* 20 */ {`#["a", "b", "c"]`, int64(3), nil},
/* 21 */ {`"b" in ["a", "b", "c"]`, true, nil}, /* 21 */ {`"b" in ["a", "b", "c"]`, true, nil},
/* 22 */ {`a=[1,2]; (a)<+3`, newListA(int64(1), int64(2), int64(3)), nil}, /* 22 */ {`a=[1,2]; (a)<<3`, newListA(int64(1), int64(2), int64(3)), nil},
/* 23 */ {`a=[1,2]; (a)<+3; a`, newListA(int64(1), int64(2)), nil}, /* 23 */ {`a=[1,2]; (a)<<3; a`, newListA(int64(1), int64(2)), nil},
/* 24 */ {`["a","b","c","d"][1]`, "b", nil}, /* 24 */ {`["a","b","c","d"][1]`, "b", nil},
/* 25 */ {`["a","b","c","d"][1,1]`, nil, `[1:19] one index only is allowed`}, /* 25 */ {`["a","b","c","d"][1,1]`, nil, `[1:19] one index only is allowed`},
/* 26 */ {`[0,1,2,3,4][:]`, newListA(int64(0), int64(1), int64(2), int64(3), int64(4)), nil}, /* 26 */ {`[0,1,2,3,4][:]`, newListA(int64(0), int64(1), int64(2), int64(3), int64(4)), nil},
@ -42,16 +42,16 @@ func TestListParser(t *testing.T) {
/* 28 */ {`2 << 3;`, int64(16), nil}, /* 28 */ {`2 << 3;`, int64(16), nil},
/* 29 */ {`but >> ["a", "b", "c"]`, nil, `[1:6] infix operator ">>" requires two non-nil operands, got 0`}, /* 29 */ {`but >> ["a", "b", "c"]`, nil, `[1:6] infix operator ">>" requires two non-nil operands, got 0`},
/* 30 */ {`2 >> 3;`, int64(0), nil}, /* 30 */ {`2 >> 3;`, int64(0), nil},
/* 31 */ {`a=[1,2]; a<+3`, newListA(int64(1), int64(2), int64(3)), nil}, /* 31 */ {`a=[1,2]; a<<3`, newListA(int64(1), int64(2), int64(3)), nil},
/* 32 */ {`a=[1,2]; 5+>a`, newListA(int64(5), int64(1), int64(2)), nil}, /* 33 */ {`a=[1,2]; 5>>a`, newListA(int64(5), int64(1), int64(2)), nil},
/* 33 */ {`L=[1,2]; L[0]=9; L`, newListA(int64(9), int64(2)), nil}, /* 34 */ {`L=[1,2]; L[0]=9; L`, newListA(int64(9), int64(2)), nil},
/* 34 */ {`L=[1,2]; L[5]=9; L`, nil, `index 5 out of bounds (0, 1)`}, /* 35 */ {`L=[1,2]; L[5]=9; L`, nil, `index 5 out of bounds (0, 1)`},
/* 35 */ {`L=[1,2]; L[]=9; L`, nil, `[1:12] index/key specification expected, got [] [list]`}, /* 36 */ {`L=[1,2]; L[]=9; L`, nil, `[1:12] index/key specification expected, got [] [list]`},
/* 36 */ {`L=[1,2]; L[nil]=9;`, nil, `[1:12] index/key is nil`}, /* 37 */ {`L=[1,2]; L[nil]=9;`, nil, `[1:12] index/key is nil`},
/* 37 */ {`[0,1,2,3,4][2:3]`, newListA(int64(2)), nil}, /* 38 */ {`[0,1,2,3,4][2:3]`, newListA(int64(2)), nil},
/* 38 */ {`[0,1,2,3,4][3:-1]`, newListA(int64(3)), nil}, /* 39 */ {`[0,1,2,3,4][3:-1]`, newListA(int64(3)), nil},
/* 30 */ {`[0,1,2,3,4][-3:-1]`, newListA(int64(2), int64(3)), nil}, /* 40 */ {`[0,1,2,3,4][-3:-1]`, newListA(int64(2), int64(3)), nil},
/* 40 */ {`[0,1,2,3,4][0:]`, newListA(int64(0), int64(1), int64(2), int64(3), int64(4)), nil}, /* 41 */ {`[0,1,2,3,4][0:]`, newListA(int64(0), int64(1), int64(2), int64(3), int64(4)), nil},
} }
// t.Setenv("EXPR_PATH", ".") // t.Setenv("EXPR_PATH", ".")

View File

@ -15,19 +15,15 @@ const (
priRange priRange
priBut priBut
priAssign priAssign
priInsert
priOr priOr
priAnd priAnd
priNot priNot
priRelational priRelational
priBinOr priBinary
priBinAnd
priBinNot
priSum priSum
priProduct priProduct
priFraction priFraction
priSelector priSelector
priBinShift
priSign priSign
priFact priFact
priIterValue priIterValue