You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@nlpcraft.apache.org by ar...@apache.org on 2021/03/14 04:11:45 UTC

[incubator-nlpcraft] branch NLPCRAFT-206 updated (ccde124 -> 8958779)

This is an automated email from the ASF dual-hosted git repository.

aradzinski pushed a change to branch NLPCRAFT-206
in repository https://gitbox.apache.org/repos/asf/incubator-nlpcraft.git.


    from ccde124  WIP.
     new 7d7e6ac  WIP.
     new 8958779  WIP.

The 2 revisions listed above as "new" are entirely new to this
repository and will be described in separate emails.  The revisions
listed as "add" were already present in the repository and have only
been added to this reference.


Summary of changes:
 .../model/intent/compiler/NCDslCompiler.scala      |  16 +-
 .../model/intent/compiler/NCDslCompilerBase.scala  | 711 ++++++++++++---------
 .../model/intent/compiler/NCDslStackItem.scala     |   8 +-
 .../model/intent/compiler/antlr4/NCIntentDsl.g4    |   8 +-
 .../compiler/antlr4/NCIntentDslBaseListener.java   |  28 +-
 .../compiler/antlr4/NCIntentDslBaseVisitor.java    |  14 +-
 .../compiler/antlr4/NCIntentDslListener.java       |  56 +-
 .../intent/compiler/antlr4/NCIntentDslParser.java  | 146 ++---
 .../intent/compiler/antlr4/NCIntentDslVisitor.java |  28 +-
 9 files changed, 547 insertions(+), 468 deletions(-)


[incubator-nlpcraft] 02/02: WIP.

Posted by ar...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

aradzinski pushed a commit to branch NLPCRAFT-206
in repository https://gitbox.apache.org/repos/asf/incubator-nlpcraft.git

commit 8958779a9c7c7e11cd4ee2d50f82d023564a9897
Author: Aaron Radzinski <ar...@apache.org>
AuthorDate: Sat Mar 13 20:11:36 2021 -0800

    WIP.
---
 .../model/intent/compiler/NCDslCompiler.scala      |  16 +-
 .../model/intent/compiler/NCDslCompilerBase.scala  | 711 ++++++++++++---------
 .../model/intent/compiler/NCDslStackItem.scala     |   8 +-
 .../model/intent/compiler/antlr4/NCIntentDsl.g4    |   8 +-
 .../compiler/antlr4/NCIntentDslBaseListener.java   |  28 +-
 .../compiler/antlr4/NCIntentDslBaseVisitor.java    |  14 +-
 .../compiler/antlr4/NCIntentDslListener.java       |  56 +-
 .../intent/compiler/antlr4/NCIntentDslParser.java  | 146 ++---
 .../intent/compiler/antlr4/NCIntentDslVisitor.java |  28 +-
 9 files changed, 547 insertions(+), 468 deletions(-)

diff --git a/nlpcraft/src/main/scala/org/apache/nlpcraft/model/intent/compiler/NCDslCompiler.scala b/nlpcraft/src/main/scala/org/apache/nlpcraft/model/intent/compiler/NCDslCompiler.scala
index 18524a0..f3b09a5 100644
--- a/nlpcraft/src/main/scala/org/apache/nlpcraft/model/intent/compiler/NCDslCompiler.scala
+++ b/nlpcraft/src/main/scala/org/apache/nlpcraft/model/intent/compiler/NCDslCompiler.scala
@@ -97,11 +97,11 @@ object NCDslCompiler extends LazyLogging {
          * Shared/common implementation.
          */
         override def exitUnaryExpr(ctx: IDP.UnaryExprContext): Unit = instrs += parseUnaryExpr(ctx.MINUS(), ctx.NOT())(ctx)
-        override def exitMultExpr(ctx: IDP.MultExprContext): Unit = instrs += parseMultExpr(ctx.MULT(), ctx.MOD(), ctx.DIV())(ctx)
-        override def exitPlusExpr(ctx: IDP.PlusExprContext): Unit = instrs += parsePlusExpr(ctx.PLUS(), ctx.MINUS())(ctx)
+        override def exitMultDivModExpr(ctx: IDP.MultDivModExprContext): Unit = instrs += parseMultDivModExpr(ctx.MULT(), ctx.MOD(), ctx.DIV())(ctx)
+        override def exitPlusMinusExpr(ctx: IDP.PlusMinusExprContext): Unit = instrs += parsePlusMinusExpr(ctx.PLUS(), ctx.MINUS())(ctx)
         override def exitCompExpr(ctx: IDP.CompExprContext): Unit = instrs += parseCompExpr(ctx.LT(), ctx.GT(), ctx.LTEQ(), ctx.GTEQ())(ctx)
-        override def exitLogExpr(ctx: IDP.LogExprContext): Unit = instrs += parseLogExpr(ctx.AND, ctx.OR())(ctx)
-        override def exitEqExpr(ctx: IDP.EqExprContext): Unit = instrs += parseEqExpr(ctx.EQ, ctx.NEQ())(ctx)
+        override def exitAndOrExpr(ctx: IDP.AndOrExprContext): Unit = instrs += parseAndOrExpr(ctx.AND, ctx.OR())(ctx)
+        override def exitEqNeqExpr(ctx: IDP.EqNeqExprContext): Unit = instrs += parseEqNeqExpr(ctx.EQ, ctx.NEQ())(ctx)
         override def exitCallExpr(ctx: IDP.CallExprContext): Unit = instrs += parseCallExpr(ctx.FUN_NAME())(ctx)
         override def exitAtom(ctx: IDP.AtomContext): Unit = instrs += parseAtom(ctx.getText)(ctx)
 
@@ -271,7 +271,7 @@ object NCDslCompiler extends LazyLogging {
                     }
                     catch {
                         case e: Exception ⇒
-                            throw newRuntimeError(s"Failed to invoke custom intent term: $mdlCls.$mtdName", e)(ctx.mtdDecl())
+                            throw newRuntimeError(s"Failed to invoke custom intent term: $mdlCls.$mtdName", e, ctx.mtdDecl())
                     }
                 }
             }
@@ -314,10 +314,10 @@ object NCDslCompiler extends LazyLogging {
                 // Pop final result from stack.
                 val x = stack.pop()
 
-                if (!isBool(x.fun))
-                    throw newRuntimeError(s"$subj did not return boolean value: ${ctx.getText}")
+                if (!isBool(x.valFun))
+                    throw newRuntimeError(s"$subj did not return boolean value: ${ctx.getText}", ctx = ctx)
 
-                (asBool(x.fun), x.usedTok)
+                (asBool(x.valFun), x.usedTok)
             }
         }
 
diff --git a/nlpcraft/src/main/scala/org/apache/nlpcraft/model/intent/compiler/NCDslCompilerBase.scala b/nlpcraft/src/main/scala/org/apache/nlpcraft/model/intent/compiler/NCDslCompilerBase.scala
index b0f5756..d92ed6f 100644
--- a/nlpcraft/src/main/scala/org/apache/nlpcraft/model/intent/compiler/NCDslCompilerBase.scala
+++ b/nlpcraft/src/main/scala/org/apache/nlpcraft/model/intent/compiler/NCDslCompilerBase.scala
@@ -23,6 +23,7 @@ import org.apache.nlpcraft.model.NCToken
 import org.antlr.v4.runtime.{ParserRuleContext ⇒ PRC}
 import org.antlr.v4.runtime.tree.{TerminalNode ⇒ TN}
 import org.apache.nlpcraft.model.intent.NCDslContext
+import org.apache.nlpcraft.model.intent.compiler.NCDslStackItem.StackValue
 
 import java.lang.{Double ⇒ JDouble, Long ⇒ JLong}
 import java.time.LocalDate
@@ -50,6 +51,7 @@ trait NCDslCompilerBase {
     /**
      *
      * @param errMsg
+     * @param cause
      * @param ctx
      * @return
      */
@@ -80,14 +82,8 @@ trait NCDslCompilerBase {
     def asToken(v: Object): NCToken = v.asInstanceOf[NCToken]
     def asBool(v: Object): Boolean = v.asInstanceOf[Boolean]
 
-    def pushAny(v: () ⇒ Object, usedTok: Boolean)(implicit stack: StackType): Unit =
+    def push(v: StackValue, usedTok: Boolean)(implicit stack: StackType): Unit =
         stack.push(NCDslStackItem(v, usedTok))
-    def pushLong(v: () ⇒ Long, usedTok: Boolean)(implicit stack: StackType): Unit =
-        stack.push(NCDslStackItem(() ⇒ Long.box(v()), usedTok))
-    def pushDouble(v: () ⇒ Double, usedTok: Boolean)(implicit stack: StackType): Unit =
-        stack.push(NCDslStackItem(() ⇒ Double.box(v()), usedTok))
-    def pushBool(v: () ⇒ Boolean, usedTok: Boolean)(implicit stack: StackType): Unit =
-        stack.push(NCDslStackItem(() ⇒ Boolean.box(v()), usedTok))
 
     // Runtime errors.
     def rtUnaryOpError(op: String, v: Object)(implicit ctx: PRC): NCE =
@@ -108,14 +104,12 @@ trait NCDslCompilerBase {
      * @param stack
      * @return
      */
-    def pop2()(implicit stack: StackType): (() ⇒ Object, () ⇒ Object, Boolean, Boolean) = {
-        require(stack.size >= 2)
+    def pop1()(implicit stack: StackType): (() ⇒ Object, Boolean) = {
+        require(stack.nonEmpty)
 
-        // Stack pops in reverse order of push...
-        val NCDslStackItem(v2, f2) = stack.pop()
-        val NCDslStackItem(v1, f1) = stack.pop()
+        val NCDslStackItem(v, f) = stack.pop()
 
-        (v1, v2, f1, f2)
+        (v, f)
     }
 
     /**
@@ -123,10 +117,14 @@ trait NCDslCompilerBase {
      * @param stack
      * @return
      */
-    def pop2Values()(implicit stack: StackType): (Object, Object, Boolean, Boolean) = {
-        val (v1, v2, f1, f2) = pop2()
+    def pop2()(implicit stack: StackType): (() ⇒ Object, () ⇒ Object, Boolean, Boolean) = {
+        require(stack.size >= 2)
+
+        // Stack pops in reverse order of push...
+        val NCDslStackItem(v2, f2) = stack.pop()
+        val NCDslStackItem(v1, f1) = stack.pop()
 
-        (v1(), v2(), f1, f2)
+        (v1, v2, f1, f2)
     }
 
     /**
@@ -147,30 +145,6 @@ trait NCDslCompilerBase {
 
     /**
      *
-     * @param stack
-     * @return
-     */
-    def pop1()(implicit stack: StackType): (() ⇒ Object, Boolean) = {
-        require(stack.nonEmpty)
-
-        val NCDslStackItem(v, f) = stack.pop()
-
-        (v, f)
-    }
-
-    /**
-     *
-     * @param stack
-     * @return
-     */
-    def pop1Value()(implicit stack: StackType): (Object, Boolean) = {
-        val (v, f) = pop1()
-
-        (v(), f)
-    }
-
-    /**
-     *
      * @param lt
      * @param gt
      * @param lteq
@@ -179,59 +153,69 @@ trait NCDslCompilerBase {
     def parseCompExpr(lt: TN, gt: TN, lteq: TN, gteq: TN)(implicit ctx: PRC): Instr = (_, stack: StackType, _) ⇒ {
         implicit val s: StackType = stack
 
-        val (v1, v2, f1, f2) = pop2Values()
+        val (v1f, v2f, f1, f2) = pop2()
         val usedTok = f1 || f2
 
-        if (lt != null) {
-            if (isJLong(v1) && isJLong(v2))
-                pushBool(() ⇒ asJLong(v1) < asJLong(v2), usedTok)
-            else if (isJLong(v1) && isJDouble(v2))
-                pushBool(() ⇒ asJLong(v1) < asJDouble(v2), usedTok)
-            else if (isJDouble(v1) && isJLong(v2))
-                pushBool(() ⇒ asJDouble(v1) < asJLong(v2), usedTok)
-            else if (isJDouble(v1) && isJDouble(v2))
-                pushBool(() ⇒ asJDouble(v1) < asJDouble(v2), usedTok)
-            else
-                throw rtBinaryOpError("<", v1, v2)
-        }
-        else if (gt != null) {
-            if (isJLong(v1) && isJLong(v2))
-                pushBool(() ⇒ asJLong(v1) > asJLong(v2), usedTok)
-            else if (isJLong(v1) && isJDouble(v2))
-                pushBool(() ⇒ asJLong(v1) > asJDouble(v2), usedTok)
-            else if (isJDouble(v1) && isJLong(v2))
-                pushBool(() ⇒ asJDouble(v1) > asJLong(v2), usedTok)
-            else if (isJDouble(v1) && isJDouble(v2))
-                pushBool(() ⇒ asJDouble(v1) > asJDouble(v2), usedTok)
-            else
-                throw rtBinaryOpError(">", v1, v2)
-        }
-        else if (lteq != null) {
-            if (isJLong(v1) && isJLong(v2))
-                pushBool(() ⇒ asJLong(v1) <= asJLong(v2), usedTok)
-            else if (isJLong(v1) && isJDouble(v2))
-                pushBool(() ⇒ asJLong(v1) <= asJDouble(v2), usedTok)
-            else if (isJDouble(v1) && isJLong(v2))
-                pushBool(() ⇒ asJDouble(v1) <= asJLong(v2), usedTok)
-            else if (isJDouble(v1) && isJDouble(v2))
-                pushBool(() ⇒ asJDouble(v1) <= asJDouble(v2), usedTok)
-            else
-                throw rtBinaryOpError("<=", v1, v2)
-        }
-        else {
-            assert(gteq != null)
-
-            if (isJLong(v1) && isJLong(v2))
-                pushBool(() ⇒ asJLong(v1) >= asJLong(v2), usedTok)
-            else if (isJLong(v1) && isJDouble(v2))
-                pushBool(() ⇒ asJLong(v1) >= asJDouble(v2), usedTok)
-            else if (isJDouble(v1) && isJLong(v2))
-                pushBool(() ⇒ asJDouble(v1) >= asJLong(v2), usedTok)
-            else if (isJDouble(v1) && isJDouble(v2))
-                pushBool(() ⇒ asJDouble(v1) >= asJDouble(v2), usedTok)
-            else
-                throw rtBinaryOpError(">=", v1, v2)
-        }
+        if (lt != null)
+            push(
+                () ⇒ {
+                    val v1 = v1f()
+                    val v2 = v2f()
+
+                    if (isJLong(v1) && isJLong(v2)) asJLong(v1) < asJLong(v2)
+                    else if (isJLong(v1) && isJDouble(v2)) asJLong(v1) < asJDouble(v2)
+                    else if (isJDouble(v1) && isJLong(v2)) asJDouble(v1) < asJLong(v2)
+                    else if (isJDouble(v1) && isJDouble(v2)) asJDouble(v1) < asJDouble(v2)
+                    else
+                        throw rtBinaryOpError("<", v1, v2)
+                },
+                usedTok
+            )
+        else if (gt != null)
+            push(
+                () ⇒ {
+                    val v1 = v1f()
+                    val v2 = v2f()
+
+                    if (isJLong(v1) && isJLong(v2)) asJLong(v1) > asJLong(v2)
+                    else if (isJLong(v1) && isJDouble(v2)) asJLong(v1) > asJDouble(v2)
+                    else if (isJDouble(v1) && isJLong(v2)) asJDouble(v1) > asJLong(v2)
+                    else if (isJDouble(v1) && isJDouble(v2)) asJDouble(v1) > asJDouble(v2)
+                    else
+                        throw rtBinaryOpError(">", v1, v2)
+                },
+                usedTok
+            )
+        else if (lteq != null)
+            push(
+                () ⇒ {
+                    val v1 = v1f()
+                    val v2 = v2f()
+
+                    if (isJLong(v1) && isJLong(v2)) asJLong(v1) <= asJLong(v2)
+                    else if (isJLong(v1) && isJDouble(v2)) asJLong(v1) <= asJDouble(v2)
+                    else if (isJDouble(v1) && isJLong(v2)) asJDouble(v1) <= asJLong(v2)
+                    else if (isJDouble(v1) && isJDouble(v2)) asJDouble(v1) <= asJDouble(v2)
+                    else
+                        throw rtBinaryOpError("<=", v1, v2)
+                },
+                usedTok
+            )
+        else
+            push(
+                () ⇒ {
+                    val v1 = v1f()
+                    val v2 = v2f()
+
+                    if (isJLong(v1) && isJLong(v2)) asJLong(v1) >= asJLong(v2)
+                    else if (isJLong(v1) && isJDouble(v2)) asJLong(v1) >= asJDouble(v2)
+                    else if (isJDouble(v1) && isJLong(v2)) asJDouble(v1) >= asJLong(v2)
+                    else if (isJDouble(v1) && isJDouble(v2)) asJDouble(v1) >= asJDouble(v2)
+                    else
+                        throw rtBinaryOpError(">=", v1, v2)
+                },
+                usedTok
+            )
     }
 
     /**
@@ -240,43 +224,56 @@ trait NCDslCompilerBase {
      * @param mod
      * @param div
      */
-    def parseMultExpr(mult: TN, mod: TN, div: TN)(implicit ctx: PRC): Instr = (_, stack: StackType, _) ⇒ {
+    def parseMultDivModExpr(mult: TN, mod: TN, div: TN)(implicit ctx: PRC): Instr = (_, stack: StackType, _) ⇒ {
         implicit val s: StackType = stack
 
-        val (v1, v2, f1, f2) = pop2Values()
+        val (v1f, v2f, f1, f2) = pop2()
         val usedTok = f1 || f2
 
-        if (mult != null) {
-            if (isJLong(v1) && isJLong(v2))
-                pushLong(() ⇒ asJLong(v1) * asJLong(v2), usedTok)
-            else if (isJLong(v1) && isJDouble(v2))
-                pushDouble(() ⇒ asJLong(v1) * asJDouble(v2), usedTok)
-            else if (isJDouble(v1) && isJLong(v2))
-                pushDouble(() ⇒ asJDouble(v1) * asJLong(v2), usedTok)
-            else if (isJDouble(v1) && isJDouble(v2))
-                pushDouble(() ⇒ asJDouble(v1) * asJDouble(v2), usedTok)
-            else
-                throw rtBinaryOpError("*", v1, v2)
-        }
-        else if (mod != null) {
-            if (isJLong(v1) && isJLong(v2))
-                pushLong(() ⇒ asJLong(v1) % asJLong(v2), usedTok)
-            else
-                throw rtBinaryOpError("%", v1, v2)
-        }
+        if (mult != null)
+            push(
+                () ⇒ {
+                    val v1 = v1f()
+                    val v2 = v2f()
+
+                    if (isJLong(v1) && isJLong(v2)) asJLong(v1) * asJLong(v2)
+                    else if (isJLong(v1) && isJDouble(v2)) asJLong(v1) * asJDouble(v2)
+                    else if (isJDouble(v1) && isJLong(v2)) asJDouble(v1) * asJLong(v2)
+                    else if (isJDouble(v1) && isJDouble(v2)) asJDouble(v1) * asJDouble(v2)
+                    else
+                        throw rtBinaryOpError("*", v1, v2)
+                },
+                usedTok
+            )
+        else if (mod != null)
+            push(
+                () ⇒ {
+                    val v1 = v1f()
+                    val v2 = v2f()
+
+                    if (isJLong(v1) && isJLong(v2)) asJLong(v1) % asJLong(v2)
+                    else
+                        throw rtBinaryOpError("%", v1, v2)
+                },
+                usedTok
+            )
         else {
             assert(div != null)
 
-            if (isJLong(v1) && isJLong(v2))
-                pushLong(() ⇒ asJLong(v1) / asJLong(v2), usedTok)
-            else if (isJLong(v1) && isJDouble(v2))
-                pushDouble(() ⇒ asJLong(v1) / asJDouble(v2), usedTok)
-            else if (isJDouble(v1) && isJLong(v2))
-                pushDouble(() ⇒ asJDouble(v1) / asJLong(v2), usedTok)
-            else if (isJDouble(v1) && isJDouble(v2))
-                pushDouble(() ⇒ asJDouble(v1) / asJDouble(v2), usedTok)
-            else
-                throw rtBinaryOpError("/", v1, v2)
+            push(
+                () ⇒ {
+                    val v1 = v1f()
+                    val v2 = v2f()
+
+                    if (isJLong(v1) && isJLong(v2)) asJLong(v1) / asJLong(v2)
+                    else if (isJLong(v1) && isJDouble(v2)) asJLong(v1) / asJDouble(v2)
+                    else if (isJDouble(v1) && isJLong(v2)) asJDouble(v1) / asJLong(v2)
+                    else if (isJDouble(v1) && isJDouble(v2)) asJDouble(v1) / asJDouble(v2)
+                    else
+                        throw rtBinaryOpError("/", v1, v2)
+                },
+                usedTok
+            )
         }
     }
 
@@ -286,29 +283,33 @@ trait NCDslCompilerBase {
      * @param or
      * @return
      */
-    def parseLogExpr(and: TN, or: TN)(implicit ctx: PRC): Instr = (_, stack: StackType, _) ⇒ {
+    def parseAndOrExpr(and: TN, or: TN)(implicit ctx: PRC): Instr = (_, stack: StackType, _) ⇒ {
         implicit val s: StackType = stack
 
         val (v1f, v2f, f1, f2) = pop2()
-
         val (op, usedTok, flag) = if (and != null) ("&&", f1 || f2, false) else ("||", f1 && f2, true)
 
-        val v1 = v1f()
+        push(
+            () ⇒ {
+                val v1 = v1f()
 
-        if (!isBool(v1))
-            throw rtBinaryOpError(op, v1, v2f())
+                if (!isBool(v1))
+                    throw rtBinaryOpError(op, v1, v2f())
 
-        // NOTE: check v1 first and only if it is {true|false} check the v2.
-        if (asBool(v1) == flag)
-            pushBool(() ⇒ flag, usedTok)
-        else {
-            val v2 = v2f()
+                // NOTE: check v1 first and only if it is {true|false} check the v2.
+                if (asBool(v1) == flag)
+                    flag
+                else {
+                    val v2 = v2f()
 
-            if (!isBool(v2))
-                throw rtBinaryOpError(op, v2, v1)
+                    if (!isBool(v2))
+                        throw rtBinaryOpError(op, v2, v1)
 
-            pushBool(() ⇒ asBool(v2), usedTok)
-        }
+                    asBool(v2)
+                }
+            },
+            usedTok
+        )
     }
 
     /**
@@ -317,13 +318,13 @@ trait NCDslCompilerBase {
      * @param neq
      * @return
      */
-    def parseEqExpr(eq: TN, neq: TN)(implicit ctx: PRC): Instr = (_, stack: StackType, _) ⇒ {
+    def parseEqNeqExpr(eq: TN, neq: TN)(implicit ctx: PRC): Instr = (_, stack: StackType, _) ⇒ {
         implicit val s: StackType = stack
 
-        val (v1, v2, f1, f2) = pop2()
+        val (v1f, v2f, f1, f2) = pop2()
         val usedTok = f1 || f2
 
-        def doEq(op: String): Boolean = {
+        def doEq(op: String, v1: Object, v2: Object): Boolean = {
             if (v1 == null && v2 == null)
                 true
             else if ((v1 == null && v2 != null) || (v1 != null && v2 == null))
@@ -341,14 +342,22 @@ trait NCDslCompilerBase {
             else {
                 throw rtBinaryOpError(op, v1, v2)
             }}
-    
-        if (eq != null)
-            pushBool(() ⇒ doEq("=="), usedTok)
-        else {
-            assert(neq != null)
 
-            pushBool(() => !doEq("!='"), usedTok)
-        }
+        push(
+            () ⇒ {
+                val v1 = v1f()
+                val v2 = v2f()
+
+                if (eq != null)
+                    doEq("==", v1, v2)
+                else {
+                    assert(neq != null)
+
+                    !doEq("!='", v1, v2)
+                }
+            },
+            usedTok
+        )
     }
 
     /**
@@ -356,39 +365,45 @@ trait NCDslCompilerBase {
      * @param plus
      * @param minus
      */
-    def parsePlusExpr(plus: TN, minus: TN)(implicit ctx: PRC): Instr = (_, stack: StackType, _) ⇒ {
+    def parsePlusMinusExpr(plus: TN, minus: TN)(implicit ctx: PRC): Instr = (_, stack: StackType, _) ⇒ {
         implicit val s: StackType = stack
 
-        val (v1, v2, f1, f2) = pop2Values()
+        val (v1f, v2f, f1, f2) = pop2()
         val usedTok = f1 || f2
 
-        if (plus != null) {
-            if (isStr(v1) && isStr(v2))
-                pushAny(() ⇒ asStr(v1) + asStr(v2), usedTok)
-            else if (isJLong(v1) && isJLong(v2))
-                pushLong(() ⇒ asJLong(v1) + asJLong(v2), usedTok)
-            else if (isJLong(v1) && isJDouble(v2))
-                pushDouble(() ⇒ asJLong(v1) + asJDouble(v2), usedTok)
-            else if (isJDouble(v1) && isJLong(v2))
-                pushDouble(() ⇒ asJDouble(v1) + asJLong(v2), usedTok)
-            else if (isJDouble(v1) && isJDouble(v2))
-                pushDouble(() ⇒ asJDouble(v1) + asJDouble(v2), usedTok)
-            else
-                throw rtBinaryOpError("+", v1, v2)
-        }
+        if (plus != null)
+            push(
+                () ⇒ {
+                    val v1 = v1f()
+                    val v2 = v2f()
+
+                    if (isStr(v1) && isStr(v2)) asStr(v1) + asStr(v2)
+                    else if (isJLong(v1) && isJLong(v2)) asJLong(v1) + asJLong(v2)
+                    else if (isJLong(v1) && isJDouble(v2)) asJLong(v1) + asJDouble(v2)
+                    else if (isJDouble(v1) && isJLong(v2)) asJDouble(v1) + asJLong(v2)
+                    else if (isJDouble(v1) && isJDouble(v2)) asJDouble(v1) + asJDouble(v2)
+                    else
+                        throw rtBinaryOpError("+", v1, v2)
+                },
+                usedTok
+            )
         else {
             assert(minus != null)
 
-            if (isJLong(v1) && isJLong(v2))
-                pushLong(() ⇒ asJLong(v1) - asJLong(v2), usedTok)
-            else if (isJLong(v1) && isJDouble(v2))
-                pushDouble(() ⇒ asJLong(v1) - asJDouble(v2), usedTok)
-            else if (isJDouble(v1) && isJLong(v2))
-                pushDouble(() ⇒ asJDouble(v1) - asJLong(v2), usedTok)
-            else if (isJDouble(v1) && isJDouble(v2))
-                pushDouble(() ⇒ asJDouble(v1) - asJDouble(v2), usedTok)
-            else
-                throw rtBinaryOpError("-", v1, v2)
+            push(
+                () ⇒ {
+                    val v1 = v1f()
+                    val v2 = v2f()
+
+                    if (isJLong(v1) && isJLong(v2)) asJLong(v1) - asJLong(v2)
+                    else if (isJLong(v1) && isJDouble(v2)) asJLong(v1) - asJDouble(v2)
+                    else if (isJDouble(v1) && isJLong(v2)) asJDouble(v1) - asJLong(v2)
+                    else if (isJDouble(v1) && isJDouble(v2)) asJDouble(v1) - asJDouble(v2)
+                    else
+                        throw rtBinaryOpError("-", v1, v2)
+                },
+                usedTok
+            )
         }
     }
 
@@ -401,23 +416,33 @@ trait NCDslCompilerBase {
     def parseUnaryExpr(minus: TN, not: TN)(implicit ctx: PRC): Instr = (_, stack: StackType, _) ⇒ {
         implicit val s: StackType = stack
 
-        val (v, usedTok) = pop1Value()
+        val (vf, usedTok) = pop1()
 
-        if (minus != null) {
-            if (isJDouble(v))
-                pushDouble(() => -asJDouble(v), usedTok)
-            else if (isJLong(v))
-                pushLong(() => -asJLong(v), usedTok)
-            else
-                throw rtUnaryOpError("-", v)
-        }
+        if (minus != null)
+            push(
+                () ⇒ {
+                    val v = vf()
+
+                    if (isJDouble(v)) -asJDouble(v)
+                    else if (isJLong(v)) -asJLong(v)
+                    else
+                        throw rtUnaryOpError("-", v)
+                },
+                usedTok
+            )
         else {
             assert(not != null)
 
-            if (isBool(v))
-                pushBool(() => !asBool(v), usedTok)
-            else
-                throw rtUnaryOpError("!", v)
+            push(
+                () ⇒ {
+                    val v = vf()
+
+                    if (isBool(v)) !asBool(v)
+                    else
+                        throw rtUnaryOpError("!", v)
+                },
+                usedTok
+            )
         }
     }
 
@@ -448,7 +473,7 @@ trait NCDslCompilerBase {
                 }
             }
 
-        (_, stack, _) ⇒ pushAny(() ⇒ atom, false)(stack)
+        (_, stack, _) ⇒ push(() ⇒ atom, false)(stack)
     }
 
     /**
@@ -459,88 +484,151 @@ trait NCDslCompilerBase {
     def parseCallExpr(id: TN)(implicit ctx: PRC): Instr = (tok, stack: StackType, termCtx) ⇒ {
         val fun = id.getText
 
-        implicit val s2: StackType = stack
+        implicit val evidence: StackType = stack
 
         def ensureStack(min: Int): Unit =
             if (stack.size < min)
                 throw rtMinParamNumError(min, fun)
 
-        def get1[T](typ: String, is: Object ⇒ Boolean, as: Object ⇒ T): (() ⇒ T, Boolean) = {
-            val (vf, f) = pop1()
+//        def get1[T](typ: String, is: Object ⇒ Boolean, as: Object ⇒ T): (() ⇒ T, Boolean) = {
+//            val (vf, f) = pop1()
+//
+//            (
+//                () ⇒ {
+//                    val v = vf()
+//
+//                    if (!is(v))
+//                        throw rtParamTypeError(fun, v, typ)
+//
+//                    as(v)
+//                },
+//                f
+//            )
+//        }
+//        def get2[T](typ: String, is: Object ⇒ Boolean, as: Object ⇒ T): (() ⇒ T, () ⇒ T, Boolean) = {
+//            val (vf1, vf2, f1, f2) = pop2()
+//
+//            (
+//                () ⇒ {
+//                    val v = vf1()
+//
+//                    if (!is(v))
+//                        throw rtParamTypeError(fun, v, typ)
+//
+//                    as(v)
+//                },
+//                () ⇒ {
+//                    val v = vf2()
+//
+//                    if (!is(v))
+//                        throw rtParamTypeError(fun, v, typ)
+//
+//                    as(v)
+//                },
+//                f1 || f2
+//            )
+//        }
+//
+//        def get1Map(): (() ⇒ JMap[_, _], Boolean) = get1("map", isJMap, asJMap)
+//        def get1Double(): (() ⇒ JDouble, Boolean) = get1("double", isJDouble, asJDouble)
+//        def get1List(): (() ⇒ JList[_], Boolean) = get1("list", isJList, asJList)
+//        def get1Str(): (() ⇒ String, Boolean) = get1("string", isStr, asStr)
+//        def get2Doubles(): (() ⇒ JDouble, () ⇒ JDouble, Boolean) = get2("double", isJDouble, asJDouble)
+//        def get2Str(): (() ⇒ String, () ⇒ String, Boolean) = get2("string", isStr, asStr)
+//        def get1Tok1Str(): (() ⇒ NCToken, () ⇒ String, Boolean) = {
+//            val (vf1, vf2, f1, f2) = pop2()
+//
+//            (
+//                () ⇒ {
+//                    val v = vf1()
+//
+//                    if (!isToken(v))
+//                        throw rtParamTypeError(fun, v, "token")
+//
+//                    asToken(v)
+//                },
+//                () ⇒ {
+//                    val v = vf2()
+//
+//                    if (!isStr(v))
+//                        throw rtParamTypeError(fun, v, "string")
+//
+//                    asStr(v)
+//                },
+//                f1 || f2
+//            )
+//        }
+//        def get1Any(): (() ⇒ Any, Boolean) = {
+//            val (vf, f) = pop1()
+//
+//            (() ⇒ vf(), f)
+//        }
+
+        def toStr(v: () ⇒ Object): String = {
+            val s = v()
+
+            if (!isStr(s))
+                throw rtParamTypeError(fun, v, "string")
+
+            asStr(s)
+        }
 
-            (
-                () ⇒ {
-                    val v = vf()
+        def toJDouble(v: () ⇒ Object): JDouble = {
+            val d = v()
 
-                    if (!is(v))
-                        throw rtParamTypeError(fun, v, typ)
+            if (!isJDouble(d))
+                throw rtParamTypeError(fun, v, "double")
 
-                    as(v)
-                },
-                f
-            )
+            asJDouble(d)
         }
-        def get2[T](typ: String, is: Object ⇒ Boolean, as: Object ⇒ T): (() ⇒ T, () ⇒ T, Boolean) = {
-            val (vf1, vf2, f1, f2) = pop2()
 
-            (
-                () ⇒ {
-                    val v = vf1()
-
-                    if (!is(v))
-                        throw rtParamTypeError(fun, v, typ)
+        def optToken(): NCToken =
+            if (stack.nonEmpty && stack.top.isInstanceOf[NCToken]) stack.pop().asInstanceOf[NCToken] else tok
 
-                    as(v)
-                },
-                () ⇒ {
-                    val v = vf2()
 
-                    if (!is(v))
-                        throw rtParamTypeError(fun, v, typ)
+        def doSplit(): Unit = {
+            val (v1f, v2f, f1, f2) = pop2()
 
-                    as(v)
+            push(
+                () ⇒ {
+                   util.Arrays.asList(toStr(v1f).split(toStr(v2f)))
                 },
                 f1 || f2
             )
         }
-    
-        def get1Map(): (() ⇒ JMap[_, _], Boolean) = get1("map", isJMap, asJMap)
-        def get1Double(): (() ⇒ JDouble, Boolean) = get1("double", isJDouble, asJDouble)
-        def get1List(): (() ⇒ JList[_], Boolean) = get1("list", isJList, asJList)
-        def get1Str(): (() ⇒ String, Boolean) = get1("string", isStr, asStr)
-        def get2Doubles(): (() ⇒ JDouble, () ⇒ JDouble, Boolean) = get2("double", isJDouble, asJDouble)
-        def get2Str(): (() ⇒ String, () ⇒ String, Boolean) = get2("string", isStr, asStr)
-        def get1Tok1Str(): (() ⇒ NCToken, () ⇒ String, Boolean) = {
-            val (vf1, vf2, f1, f2) = pop2()
-
-            (
-                () ⇒ {
-                    val v = vf1()
 
-                    if (!isToken(v))
-                        throw rtParamTypeError(fun, v, "token")
+        def doSplitTrim(): Unit = {
+            val (v1f, v2f, f1, f2) = pop2()
 
-                    asToken(v)
-                },
+            push(
                 () ⇒ {
-                    val v = vf2()
-
-                    if (!isStr(v))
-                        throw rtParamTypeError(fun, v, "string")
-
-                    asStr(v)
+                    util.Arrays.asList(toStr(v1f).split(toStr(v2f)).toList.map(_.strip))
                 },
                 f1 || f2
             )
         }
-        def get1Any(): (() ⇒ Any, Boolean) = {
-            val (vf, f) = pop1()
 
-            (() ⇒ vf(), f)
-        }
 
-        def doSplit(): Unit = get2Str() match { case (s1, s2, f) ⇒ s1().split(s2()).foreach { s ⇒ pushAny(() ⇒ s, f)(stack) } }
-        def doSplitTrim(): Unit = get2Str() match { case (s1, s2, f) ⇒ s1().split(s2()).foreach { s ⇒ pushAny(() ⇒ s.strip, f)(stack) }}
+
+
+
+
+
+
+
+
+        // ----------------------------------------------------
+
+
+
+
+
+
+
+
+
+
+
 
         /*
          * Collection, statistical operations.
@@ -550,7 +638,7 @@ trait NCDslCompilerBase {
             var f = false
 
             stack.drain { x ⇒
-                jl.add(x.fun())
+                jl.add(x.valFun())
                 f = f || x.usedTok
             }
 
@@ -575,18 +663,6 @@ trait NCDslCompilerBase {
             }, f1 || f2)
         }
 
-
-
-
-
-        // ----------------------------------------------------
-
-
-
-
-
-
-
         def doGet(): Unit = {
             ensureStack(2)
 
@@ -618,7 +694,7 @@ trait NCDslCompilerBase {
             var idx = 0
 
             stack.drain { x ⇒
-                if (idx % 2 == 0) keys += x.fun else vals += x.fun
+                if (idx % 2 == 0) keys += x.valFun else vals += x.valFun
                 f = f || x.usedTok
 
                 idx += 1
@@ -663,9 +739,6 @@ trait NCDslCompilerBase {
                 pushAny(v3, f1 || f3)
         }
 
-        def token(): NCToken =
-            if (stack.nonEmpty && stack.top.isInstanceOf[NCToken]) stack.pop().asInstanceOf[NCToken] else tok
-
         def doPart(): Unit = {
             val (t, aliasId, f) = get1Tok1Str()
 
@@ -690,15 +763,15 @@ trait NCDslCompilerBase {
         fun match {
             // Metadata access.
             case "meta_part" ⇒ get1Tok1Str() match { case (t, s, f) ⇒  pushAny(t.meta(s), f) }
-            case "meta_token" ⇒ get1Str() match { case (s, _) ⇒ pushAny(tok.meta(s), true) }
-            case "meta_model" ⇒ get1Str() match { case (s, _) ⇒ pushAny(tok.getModel.meta(s), false) }
-            case "meta_intent" ⇒ get1Str() match { case (s, _) ⇒ pushAny(termCtx.intentMeta.get(s).orNull, false) }
-            case "meta_req" ⇒ get1Str() match { case (s, _) ⇒ pushAny(termCtx.req.getRequestData.get(s), false) }
-            case "meta_user" ⇒ get1Str() match { case (s, _) ⇒ pushAny(termCtx.req.getUser.getMetadata.get(s), false) }
-            case "meta_company" ⇒ get1Str() match { case (s, _) ⇒ pushAny(termCtx.req.getCompany.getMetadata.get(s), false) }
-            case "meta_sys" ⇒ get1Str() match { case (s, _) ⇒ pushAny(U.sysEnv(s).orNull, false) }
-            case "meta_conv" ⇒ get1Str() match { case (s, _) ⇒ pushAny(termCtx.convMeta.get(s).orNull, false) }
-            case "meta_frag" ⇒ get1Str() match { case (s, _) ⇒ pushAny(termCtx.fragMeta.get(s).orNull, false) }
+            case "meta_token" ⇒ pop1() match { case (s, _) ⇒ push(() ⇒ tok.meta(toStr(s)), true) }
+            case "meta_model" ⇒ pop1() match { case (s, _) ⇒ push(() ⇒ tok.getModel.meta(toStr(s)), false) }
+            case "meta_intent" ⇒ pop1() match { case (s, _) ⇒ push(() ⇒ termCtx.intentMeta.get(toStr(s)).orNull, false) }
+            case "meta_req" ⇒ pop1() match { case (s, _) ⇒ push(() ⇒ termCtx.req.getRequestData.get(toStr(s)), false) }
+            case "meta_user" ⇒ pop1() match { case (s, _) ⇒ push(() ⇒ termCtx.req.getUser.getMetadata.get(toStr(s)), false) }
+            case "meta_company" ⇒ pop1() match { case (s, _) ⇒ push(() ⇒ termCtx.req.getCompany.getMetadata.get(s), false) }
+            case "meta_sys" ⇒ pop1() match { case (s, _) ⇒ push(() ⇒ U.sysEnv(toStr(s)).orNull, false) }
+            case "meta_conv" ⇒ pop1() match { case (s, _) ⇒ push(() ⇒ termCtx.convMeta.get(toStr(s)).orNull, false) }
+            case "meta_frag" ⇒ pop1() match { case (s, _) ⇒ push(() ⇒ termCtx.fragMeta.get(toStr(s)).orNull, false) }
 
             // Converts JSON to map.
             case "json" ⇒ doJson()
@@ -707,27 +780,27 @@ trait NCDslCompilerBase {
             case "if" ⇒ doIf()
 
             // Token functions.
-            case "id" ⇒ pushAny(token().getId, true)
-            case "ancestors" ⇒ pushAny(token().getAncestors, true)
-            case "parent" ⇒ pushAny(token().getParentId, true)
-            case "groups" ⇒ pushAny(token().getGroups, true)
-            case "value" ⇒ pushAny(token().getValue, true)
-            case "aliases" ⇒ pushAny(token().getAliases, true)
-            case "start_idx" ⇒ pushLong(token().getStartCharIndex, true)
-            case "end_idx" ⇒ pushLong(token().getEndCharIndex, true)
-            case "this" ⇒ pushAny(() ⇒ tok, true)
+            case "id" ⇒ push(() ⇒ optToken().getId, true)
+            case "ancestors" ⇒ push(() ⇒ optToken().getAncestors, true)
+            case "parent" ⇒ push(() ⇒ optToken().getParentId, true)
+            case "groups" ⇒ push(() ⇒ optToken().getGroups, true)
+            case "value" ⇒ push(() ⇒ optToken().getValue, true)
+            case "aliases" ⇒ push(() ⇒ optToken().getAliases, true)
+            case "start_idx" ⇒ push(() ⇒ optToken().getStartCharIndex, true)
+            case "end_idx" ⇒ push(() ⇒ optToken().getEndCharIndex, true)
+            case "this" ⇒ push(() ⇒ tok, true)
             case "part" ⇒ doPart()
             case "parts" ⇒ doParts()
 
             // Request data.
-            case "req_id" ⇒ pushAny(termCtx.req.getServerRequestId, false)
+            case "req_id" ⇒ push(() ⇒ termCtx.req.getServerRequestId, false)
             case "req_normtext" ⇒
             case "req_tstamp" ⇒
             case "req_addr" ⇒
             case "req_agent" ⇒
 
             // User data.
-            case "user_id" ⇒ pushLong(termCtx.req.getUser.getId, false)
+            case "user_id" ⇒ push(() ⇒ termCtx.req.getUser.getId, false)
             case "user_fname" ⇒
             case "user_lname" ⇒
             case "user_email" ⇒
@@ -735,7 +808,7 @@ trait NCDslCompilerBase {
             case "user_signup_tstamp" ⇒
 
             // Company data.
-            case "comp_id" ⇒ pushLong(termCtx.req.getCompany.getId, false)
+            case "comp_id" ⇒ push(() ⇒ termCtx.req.getCompany.getId, false)
             case "comp_name" ⇒
             case "comp_website" ⇒
             case "comp_country" ⇒
@@ -745,17 +818,17 @@ trait NCDslCompilerBase {
             case "comp_postcode" ⇒
 
             // String functions.
-            case "trim" ⇒ get1Str() match { case (s, f) ⇒ pushAny(s.trim, f) }
-            case "strip" ⇒ get1Str() match { case (s, f) ⇒ pushAny(s.trim, f) }
-            case "uppercase" ⇒ get1Str() match { case (s, f) ⇒ pushAny(s.toUpperCase, f) }
-            case "lowercase" ⇒ get1Str() match { case (s, f) ⇒ pushAny(s.toLowerCase, f) }
-            case "is_alpha" ⇒ get1Str() match { case (s, f) ⇒ pushBool(StringUtils.isAlpha(asStr(s)), f) }
-            case "is_alphanum" ⇒ get1Str() match { case (s, f) ⇒ pushBool(StringUtils.isAlphanumeric(asStr(s)), f) }
-            case "is_whitespace" ⇒ get1Str() match { case (s, f) ⇒ pushBool(StringUtils.isWhitespace(asStr(s)), f) }
-            case "is_num" ⇒ get1Str() match { case (s, f) ⇒ pushBool(StringUtils.isNumeric(asStr(s)), f) }
-            case "is_numspace" ⇒ get1Str() match { case (s, f) ⇒ pushBool(StringUtils.isNumericSpace(asStr(s)), f) }
-            case "is_alphaspace" ⇒ get1Str() match { case (s, f) ⇒ pushBool(StringUtils.isAlphaSpace(asStr(s)), f) }
-            case "is_alphanumspace" ⇒ get1Str() match { case (s, f) ⇒ pushBool(StringUtils.isAlphanumericSpace(asStr(s)), f) }
+            case "trim" ⇒ pop1() match { case (s, f) ⇒ push(() ⇒ toStr(s).trim, f) }
+            case "strip" ⇒ pop1() match { case (s, f) ⇒ push(() ⇒ toStr(s).trim, f) }
+            case "uppercase" ⇒ pop1() match { case (s, f) ⇒ push(() ⇒ toStr(s).toUpperCase, f) }
+            case "lowercase" ⇒ pop1() match { case (s, f) ⇒ push(() ⇒ toStr(s).toLowerCase, f) }
+            case "is_alpha" ⇒ pop1() match { case (s, f) ⇒ push(() ⇒ StringUtils.isAlpha(toStr(s)), f) }
+            case "is_alphanum" ⇒ pop1() match { case (s, f) ⇒ push(() ⇒ StringUtils.isAlphanumeric(toStr(s)), f) }
+            case "is_whitespace" ⇒ pop1() match { case (s, f) ⇒ push(() ⇒ StringUtils.isWhitespace(toStr(s)), f) }
+            case "is_num" ⇒ pop1() match { case (s, f) ⇒ push(() ⇒ StringUtils.isNumeric(toStr(s)), f) }
+            case "is_numspace" ⇒ pop1() match { case (s, f) ⇒ push(() ⇒ StringUtils.isNumericSpace(toStr(s)), f) }
+            case "is_alphaspace" ⇒ pop1() match { case (s, f) ⇒ push(() ⇒ StringUtils.isAlphaSpace(toStr(s)), f) }
+            case "is_alphanumspace" ⇒ pop1() match { case (s, f) ⇒ push(() ⇒ StringUtils.isAlphanumericSpace(toStr(s)), f) }
             case "substring" ⇒
             case "charAt" ⇒
             case "regex" ⇒
@@ -766,35 +839,35 @@ trait NCDslCompilerBase {
 
             // Math functions.
             case "abs" ⇒ doAbs()
-            case "ceil" ⇒ get1Double() match { case (a: () ⇒ JDouble, f) ⇒ pushDouble(() ⇒ Math.ceil(a()), f) }
-            case "floor" ⇒ get1Double() match { case (a: () ⇒ JDouble, f) ⇒ pushDouble(() ⇒ Math.floor(a), f) }
-            case "rint" ⇒ get1Double() match { case (a: () ⇒ JDouble, f) ⇒ pushDouble(() ⇒ Math.rint(a), f) }
-            case "round" ⇒ get1Double() match { case (a: () ⇒ JDouble, f) ⇒ pushLong(() ⇒ Math.round(a), f) }
-            case "signum" ⇒ get1Double() match { case (a: () ⇒ JDouble, f) ⇒ pushDouble(() ⇒ Math.signum(a), f) }
-            case "sqrt" ⇒ get1Double() match { case (a: () ⇒ JDouble, f) ⇒ pushDouble(() ⇒ Math.sqrt(a), f) }
-            case "cbrt" ⇒ get1Double() match { case (a: () ⇒ JDouble, f) ⇒ pushDouble(() ⇒ Math.cbrt(a), f) }
-            case "pi" ⇒ pushDouble(() ⇒ Math.PI, false)
-            case "euler" ⇒ pushDouble(() ⇒ Math.E, false)
-            case "acos" ⇒ get1Double() match { case (a: () ⇒ JDouble, f) ⇒ pushDouble(() ⇒ Math.acos(a), f) }
-            case "asin" ⇒ get1Double() match { case (a: () ⇒ JDouble, f) ⇒ pushDouble(() ⇒ Math.asin(a), f) }
-            case "atan" ⇒ get1Double() match { case (a: () ⇒ JDouble, f) ⇒ pushDouble(() ⇒ Math.atan(a), f) }
-            case "cos" ⇒ get1Double() match { case (a: () ⇒ JDouble, f) ⇒ pushDouble(() ⇒ Math.cos(a), f) }
-            case "sin" ⇒ get1Double() match { case (a: () ⇒ JDouble, f) ⇒ pushDouble(() ⇒ Math.sin(a), f) }
-            case "tan" ⇒ get1Double() match { case (a: () ⇒ JDouble, f) ⇒ pushDouble(() ⇒ Math.tan(a), f) }
-            case "cosh" ⇒ get1Double() match { case (a: () ⇒ JDouble, f) ⇒ pushDouble(() ⇒ Math.cosh(a), f) }
-            case "sinh" ⇒ get1Double() match { case (a: () ⇒ JDouble, f) ⇒ pushDouble(() ⇒ Math.sinh(a), f) }
-            case "tanh" ⇒ get1Double() match { case (a: () ⇒ JDouble, f) ⇒ pushDouble(() ⇒ Math.tanh(a), f) }
-            case "atn2" ⇒ get2Doubles() match { case (a1: () ⇒ JDouble, a2: JDouble, f) ⇒ pushDouble(() ⇒ Math.atan2(a1, a2), f) }
-            case "degrees" ⇒ get1Double() match { case (a: () ⇒ JDouble, f) ⇒ pushDouble(() ⇒ Math.toDegrees(a), f) }
-            case "radians" ⇒ get1Double() match { case (a: () ⇒ JDouble, f) ⇒ pushDouble(() ⇒ Math.toRadians(a), f) }
-            case "exp" ⇒ get1Double() match { case (a: () ⇒ JDouble, f) ⇒ pushDouble(() ⇒ Math.exp(a), f) }
-            case "expm1" ⇒ get1Double() match { case (a: () ⇒ JDouble, f) ⇒ pushDouble(() ⇒ Math.expm1(a), f) }
-            case "hypot" ⇒ get2Doubles() match { case (a1: () ⇒ JDouble, a2: () ⇒ JDouble, f) ⇒ pushDouble(() ⇒ Math.hypot(a1, a2), f) }
-            case "log" ⇒ get1Double() match { case (a: () ⇒ JDouble, f) ⇒ pushDouble(() ⇒ Math.log(a), f) }
-            case "log10" ⇒ get1Double() match { case (a: () ⇒ JDouble, f) ⇒ pushDouble(() ⇒ Math.log10(a), f) }
-            case "log1p" ⇒ get1Double() match { case (a: () ⇒ JDouble, f) ⇒ pushDouble(() ⇒ Math.log1p(a), f) }
-            case "pow" ⇒ get2Doubles() match { case (a1: () ⇒ JDouble, a2: JDouble, f) ⇒ pushDouble(() ⇒ Math.pow(a1, a2), f) }
-            case "rand" ⇒ pushDouble(() ⇒ Math.random, false)
+            case "ceil" ⇒ pop1() match { case (a, f) ⇒ push(() ⇒ Math.ceil(toJDouble(a)), f) }
+            case "floor" ⇒ pop1() match { case (a, f) ⇒ push(() ⇒ Math.floor(toJDouble(a)), f) }
+            case "rint" ⇒ pop1() match { case (a, f) ⇒ push(() ⇒ Math.rint(toJDouble(a)), f) }
+            case "round" ⇒ pop1() match { case (a, f) ⇒ push(() ⇒ Math.round(toJDouble(a)), f) }
+            case "signum" ⇒ pop1() match { case (a, f) ⇒ push(() ⇒ Math.signum(toJDouble(a)), f) }
+            case "sqrt" ⇒ pop1() match { case (a, f) ⇒ push(() ⇒ Math.sqrt(toJDouble(a)), f) }
+            case "cbrt" ⇒ pop1() match { case (a, f) ⇒ push(() ⇒ Math.cbrt(toJDouble(a)), f) }
+            case "pi" ⇒ push(() ⇒ Math.PI, false)
+            case "euler" ⇒ push(() ⇒ Math.E, false)
+            case "acos" ⇒ pop1() match { case (a, f) ⇒ push(() ⇒ Math.acos(toJDouble(a)), f) }
+            case "asin" ⇒ pop1() match { case (a, f) ⇒ push(() ⇒ Math.asin(toJDouble(a)), f) }
+            case "atan" ⇒ pop1() match { case (a, f) ⇒ push(() ⇒ Math.atan(toJDouble(a)), f) }
+            case "cos" ⇒ pop1() match { case (a, f) ⇒ push(() ⇒ Math.cos(toJDouble(a)), f) }
+            case "sin" ⇒ pop1() match { case (a, f) ⇒ push(() ⇒ Math.sin(toJDouble(a)), f) }
+            case "tan" ⇒ pop1() match { case (a, f) ⇒ push(() ⇒ Math.tan(toJDouble(a)), f) }
+            case "cosh" ⇒ pop1() match { case (a, f) ⇒ push(() ⇒ Math.cosh(toJDouble(a)), f) }
+            case "sinh" ⇒ pop1() match { case (a, f) ⇒ push(() ⇒ Math.sinh(toJDouble(a)), f) }
+            case "tanh" ⇒ pop1() match { case (a, f) ⇒ push(() ⇒ Math.tanh(toJDouble(a)), f) }
+            case "atn2" ⇒ pop2() match { case (a1, a2, f1, f2) ⇒ push(() ⇒ Math.atan2(toJDouble(a1), toJDouble(a2)), f1 || f2) }
+            case "degrees" ⇒ pop1() match { case (a, f) ⇒ push(() ⇒ Math.toDegrees(toJDouble(a)), f) }
+            case "radians" ⇒ pop1() match { case (a, f) ⇒ push(() ⇒ Math.toRadians(toJDouble(a)), f) }
+            case "exp" ⇒ pop1() match { case (a, f) ⇒ push(() ⇒ Math.exp(toJDouble(a)), f) }
+            case "expm1" ⇒ pop1() match { case (a, f) ⇒ push(() ⇒ Math.expm1(toJDouble(a)), f) }
+            case "hypot" ⇒ pop2() match { case (a1, a2, f1, f2) ⇒ push(() ⇒ Math.hypot(toJDouble(a1), toJDouble(a2)), f1 || f2) }
+            case "log" ⇒ pop1() match { case (a, f) ⇒ push(() ⇒ Math.log(toJDouble(a)), f) }
+            case "log10" ⇒ pop1() match { case (a, f) ⇒ push(() ⇒ Math.log10(toJDouble(a)), f) }
+            case "log1p" ⇒ pop1() match { case (a, f) ⇒ push(() ⇒ Math.log1p(toJDouble(a)), f) }
+            case "pow" ⇒ pop2() match { case (a1, a2, f1, f2) ⇒ push(() ⇒ Math.pow(toJDouble(a1), toJDouble(a2)), f1 || f2) }
+            case "rand" ⇒ push(() ⇒ Math.random, false)
             case "square" ⇒ doSquare()
 
             // Collection functions.
diff --git a/nlpcraft/src/main/scala/org/apache/nlpcraft/model/intent/compiler/NCDslStackItem.scala b/nlpcraft/src/main/scala/org/apache/nlpcraft/model/intent/compiler/NCDslStackItem.scala
index 5dc96ee..82244a7 100644
--- a/nlpcraft/src/main/scala/org/apache/nlpcraft/model/intent/compiler/NCDslStackItem.scala
+++ b/nlpcraft/src/main/scala/org/apache/nlpcraft/model/intent/compiler/NCDslStackItem.scala
@@ -17,10 +17,16 @@
 
 package org.apache.nlpcraft.model.intent.compiler
 
+import org.apache.nlpcraft.model.intent.compiler.NCDslStackItem.StackValue
+
 /**
  *
  */
 case class NCDslStackItem(
-    fun: () ⇒ Object,
+    valFun: StackValue,
     usedTok: Boolean
 )
+
+object NCDslStackItem {
+    type StackValue = () ⇒ Object
+}
diff --git a/nlpcraft/src/main/scala/org/apache/nlpcraft/model/intent/compiler/antlr4/NCIntentDsl.g4 b/nlpcraft/src/main/scala/org/apache/nlpcraft/model/intent/compiler/antlr4/NCIntentDsl.g4
index 3fb7973..b88085c 100644
--- a/nlpcraft/src/main/scala/org/apache/nlpcraft/model/intent/compiler/antlr4/NCIntentDsl.g4
+++ b/nlpcraft/src/main/scala/org/apache/nlpcraft/model/intent/compiler/antlr4/NCIntentDsl.g4
@@ -81,11 +81,11 @@ expr
     // NOTE: order of productions defines precedence.
     : op=(MINUS | NOT) expr # unaryExpr
     | LPAR expr RPAR # parExpr
-    | expr op=(MULT | DIV | MOD) expr # multExpr
-    | expr op=(PLUS | MINUS) expr # plusExpr
+    | expr op=(MULT | DIV | MOD) expr # multDivModExpr
+    | expr op=(PLUS | MINUS) expr # plusMinusExpr
     | expr op=(LTEQ | GTEQ | LT | GT) expr # compExpr
-    | expr op=(EQ | NEQ) expr # eqExpr
-    | expr op=(AND | OR) expr # logExpr
+    | expr op=(EQ | NEQ) expr # eqNeqExpr
+    | expr op=(AND | OR) expr # andOrExpr
     | atom # atomExpr
     | FUN_NAME LPAR paramList? RPAR # callExpr
     ;
diff --git a/nlpcraft/src/main/scala/org/apache/nlpcraft/model/intent/compiler/antlr4/NCIntentDslBaseListener.java b/nlpcraft/src/main/scala/org/apache/nlpcraft/model/intent/compiler/antlr4/NCIntentDslBaseListener.java
index b8b858b..3f816cb 100644
--- a/nlpcraft/src/main/scala/org/apache/nlpcraft/model/intent/compiler/antlr4/NCIntentDslBaseListener.java
+++ b/nlpcraft/src/main/scala/org/apache/nlpcraft/model/intent/compiler/antlr4/NCIntentDslBaseListener.java
@@ -352,37 +352,37 @@ public class NCIntentDslBaseListener implements NCIntentDslListener {
 	 *
 	 * <p>The default implementation does nothing.</p>
 	 */
-	@Override public void enterEqExpr(NCIntentDslParser.EqExprContext ctx) { }
+	@Override public void enterUnaryExpr(NCIntentDslParser.UnaryExprContext ctx) { }
 	/**
 	 * {@inheritDoc}
 	 *
 	 * <p>The default implementation does nothing.</p>
 	 */
-	@Override public void exitEqExpr(NCIntentDslParser.EqExprContext ctx) { }
+	@Override public void exitUnaryExpr(NCIntentDslParser.UnaryExprContext ctx) { }
 	/**
 	 * {@inheritDoc}
 	 *
 	 * <p>The default implementation does nothing.</p>
 	 */
-	@Override public void enterUnaryExpr(NCIntentDslParser.UnaryExprContext ctx) { }
+	@Override public void enterCompExpr(NCIntentDslParser.CompExprContext ctx) { }
 	/**
 	 * {@inheritDoc}
 	 *
 	 * <p>The default implementation does nothing.</p>
 	 */
-	@Override public void exitUnaryExpr(NCIntentDslParser.UnaryExprContext ctx) { }
+	@Override public void exitCompExpr(NCIntentDslParser.CompExprContext ctx) { }
 	/**
 	 * {@inheritDoc}
 	 *
 	 * <p>The default implementation does nothing.</p>
 	 */
-	@Override public void enterCompExpr(NCIntentDslParser.CompExprContext ctx) { }
+	@Override public void enterPlusMinusExpr(NCIntentDslParser.PlusMinusExprContext ctx) { }
 	/**
 	 * {@inheritDoc}
 	 *
 	 * <p>The default implementation does nothing.</p>
 	 */
-	@Override public void exitCompExpr(NCIntentDslParser.CompExprContext ctx) { }
+	@Override public void exitPlusMinusExpr(NCIntentDslParser.PlusMinusExprContext ctx) { }
 	/**
 	 * {@inheritDoc}
 	 *
@@ -400,49 +400,49 @@ public class NCIntentDslBaseListener implements NCIntentDslListener {
 	 *
 	 * <p>The default implementation does nothing.</p>
 	 */
-	@Override public void enterCallExpr(NCIntentDslParser.CallExprContext ctx) { }
+	@Override public void enterMultDivModExpr(NCIntentDslParser.MultDivModExprContext ctx) { }
 	/**
 	 * {@inheritDoc}
 	 *
 	 * <p>The default implementation does nothing.</p>
 	 */
-	@Override public void exitCallExpr(NCIntentDslParser.CallExprContext ctx) { }
+	@Override public void exitMultDivModExpr(NCIntentDslParser.MultDivModExprContext ctx) { }
 	/**
 	 * {@inheritDoc}
 	 *
 	 * <p>The default implementation does nothing.</p>
 	 */
-	@Override public void enterMultExpr(NCIntentDslParser.MultExprContext ctx) { }
+	@Override public void enterAndOrExpr(NCIntentDslParser.AndOrExprContext ctx) { }
 	/**
 	 * {@inheritDoc}
 	 *
 	 * <p>The default implementation does nothing.</p>
 	 */
-	@Override public void exitMultExpr(NCIntentDslParser.MultExprContext ctx) { }
+	@Override public void exitAndOrExpr(NCIntentDslParser.AndOrExprContext ctx) { }
 	/**
 	 * {@inheritDoc}
 	 *
 	 * <p>The default implementation does nothing.</p>
 	 */
-	@Override public void enterPlusExpr(NCIntentDslParser.PlusExprContext ctx) { }
+	@Override public void enterCallExpr(NCIntentDslParser.CallExprContext ctx) { }
 	/**
 	 * {@inheritDoc}
 	 *
 	 * <p>The default implementation does nothing.</p>
 	 */
-	@Override public void exitPlusExpr(NCIntentDslParser.PlusExprContext ctx) { }
+	@Override public void exitCallExpr(NCIntentDslParser.CallExprContext ctx) { }
 	/**
 	 * {@inheritDoc}
 	 *
 	 * <p>The default implementation does nothing.</p>
 	 */
-	@Override public void enterLogExpr(NCIntentDslParser.LogExprContext ctx) { }
+	@Override public void enterEqNeqExpr(NCIntentDslParser.EqNeqExprContext ctx) { }
 	/**
 	 * {@inheritDoc}
 	 *
 	 * <p>The default implementation does nothing.</p>
 	 */
-	@Override public void exitLogExpr(NCIntentDslParser.LogExprContext ctx) { }
+	@Override public void exitEqNeqExpr(NCIntentDslParser.EqNeqExprContext ctx) { }
 	/**
 	 * {@inheritDoc}
 	 *
diff --git a/nlpcraft/src/main/scala/org/apache/nlpcraft/model/intent/compiler/antlr4/NCIntentDslBaseVisitor.java b/nlpcraft/src/main/scala/org/apache/nlpcraft/model/intent/compiler/antlr4/NCIntentDslBaseVisitor.java
index 117fd81..b25bd08 100644
--- a/nlpcraft/src/main/scala/org/apache/nlpcraft/model/intent/compiler/antlr4/NCIntentDslBaseVisitor.java
+++ b/nlpcraft/src/main/scala/org/apache/nlpcraft/model/intent/compiler/antlr4/NCIntentDslBaseVisitor.java
@@ -213,21 +213,21 @@ public class NCIntentDslBaseVisitor<T> extends AbstractParseTreeVisitor<T> imple
 	 * <p>The default implementation returns the result of calling
 	 * {@link #visitChildren} on {@code ctx}.</p>
 	 */
-	@Override public T visitEqExpr(NCIntentDslParser.EqExprContext ctx) { return visitChildren(ctx); }
+	@Override public T visitUnaryExpr(NCIntentDslParser.UnaryExprContext ctx) { return visitChildren(ctx); }
 	/**
 	 * {@inheritDoc}
 	 *
 	 * <p>The default implementation returns the result of calling
 	 * {@link #visitChildren} on {@code ctx}.</p>
 	 */
-	@Override public T visitUnaryExpr(NCIntentDslParser.UnaryExprContext ctx) { return visitChildren(ctx); }
+	@Override public T visitCompExpr(NCIntentDslParser.CompExprContext ctx) { return visitChildren(ctx); }
 	/**
 	 * {@inheritDoc}
 	 *
 	 * <p>The default implementation returns the result of calling
 	 * {@link #visitChildren} on {@code ctx}.</p>
 	 */
-	@Override public T visitCompExpr(NCIntentDslParser.CompExprContext ctx) { return visitChildren(ctx); }
+	@Override public T visitPlusMinusExpr(NCIntentDslParser.PlusMinusExprContext ctx) { return visitChildren(ctx); }
 	/**
 	 * {@inheritDoc}
 	 *
@@ -241,28 +241,28 @@ public class NCIntentDslBaseVisitor<T> extends AbstractParseTreeVisitor<T> imple
 	 * <p>The default implementation returns the result of calling
 	 * {@link #visitChildren} on {@code ctx}.</p>
 	 */
-	@Override public T visitCallExpr(NCIntentDslParser.CallExprContext ctx) { return visitChildren(ctx); }
+	@Override public T visitMultDivModExpr(NCIntentDslParser.MultDivModExprContext ctx) { return visitChildren(ctx); }
 	/**
 	 * {@inheritDoc}
 	 *
 	 * <p>The default implementation returns the result of calling
 	 * {@link #visitChildren} on {@code ctx}.</p>
 	 */
-	@Override public T visitMultExpr(NCIntentDslParser.MultExprContext ctx) { return visitChildren(ctx); }
+	@Override public T visitAndOrExpr(NCIntentDslParser.AndOrExprContext ctx) { return visitChildren(ctx); }
 	/**
 	 * {@inheritDoc}
 	 *
 	 * <p>The default implementation returns the result of calling
 	 * {@link #visitChildren} on {@code ctx}.</p>
 	 */
-	@Override public T visitPlusExpr(NCIntentDslParser.PlusExprContext ctx) { return visitChildren(ctx); }
+	@Override public T visitCallExpr(NCIntentDslParser.CallExprContext ctx) { return visitChildren(ctx); }
 	/**
 	 * {@inheritDoc}
 	 *
 	 * <p>The default implementation returns the result of calling
 	 * {@link #visitChildren} on {@code ctx}.</p>
 	 */
-	@Override public T visitLogExpr(NCIntentDslParser.LogExprContext ctx) { return visitChildren(ctx); }
+	@Override public T visitEqNeqExpr(NCIntentDslParser.EqNeqExprContext ctx) { return visitChildren(ctx); }
 	/**
 	 * {@inheritDoc}
 	 *
diff --git a/nlpcraft/src/main/scala/org/apache/nlpcraft/model/intent/compiler/antlr4/NCIntentDslListener.java b/nlpcraft/src/main/scala/org/apache/nlpcraft/model/intent/compiler/antlr4/NCIntentDslListener.java
index 72c1551..a9fb157 100644
--- a/nlpcraft/src/main/scala/org/apache/nlpcraft/model/intent/compiler/antlr4/NCIntentDslListener.java
+++ b/nlpcraft/src/main/scala/org/apache/nlpcraft/model/intent/compiler/antlr4/NCIntentDslListener.java
@@ -290,18 +290,6 @@ public interface NCIntentDslListener extends ParseTreeListener {
 	 */
 	void exitParExpr(NCIntentDslParser.ParExprContext ctx);
 	/**
-	 * Enter a parse tree produced by the {@code eqExpr}
-	 * labeled alternative in {@link NCIntentDslParser#expr}.
-	 * @param ctx the parse tree
-	 */
-	void enterEqExpr(NCIntentDslParser.EqExprContext ctx);
-	/**
-	 * Exit a parse tree produced by the {@code eqExpr}
-	 * labeled alternative in {@link NCIntentDslParser#expr}.
-	 * @param ctx the parse tree
-	 */
-	void exitEqExpr(NCIntentDslParser.EqExprContext ctx);
-	/**
 	 * Enter a parse tree produced by the {@code unaryExpr}
 	 * labeled alternative in {@link NCIntentDslParser#expr}.
 	 * @param ctx the parse tree
@@ -326,6 +314,18 @@ public interface NCIntentDslListener extends ParseTreeListener {
 	 */
 	void exitCompExpr(NCIntentDslParser.CompExprContext ctx);
 	/**
+	 * Enter a parse tree produced by the {@code plusMinusExpr}
+	 * labeled alternative in {@link NCIntentDslParser#expr}.
+	 * @param ctx the parse tree
+	 */
+	void enterPlusMinusExpr(NCIntentDslParser.PlusMinusExprContext ctx);
+	/**
+	 * Exit a parse tree produced by the {@code plusMinusExpr}
+	 * labeled alternative in {@link NCIntentDslParser#expr}.
+	 * @param ctx the parse tree
+	 */
+	void exitPlusMinusExpr(NCIntentDslParser.PlusMinusExprContext ctx);
+	/**
 	 * Enter a parse tree produced by the {@code atomExpr}
 	 * labeled alternative in {@link NCIntentDslParser#expr}.
 	 * @param ctx the parse tree
@@ -338,53 +338,53 @@ public interface NCIntentDslListener extends ParseTreeListener {
 	 */
 	void exitAtomExpr(NCIntentDslParser.AtomExprContext ctx);
 	/**
-	 * Enter a parse tree produced by the {@code callExpr}
+	 * Enter a parse tree produced by the {@code multDivModExpr}
 	 * labeled alternative in {@link NCIntentDslParser#expr}.
 	 * @param ctx the parse tree
 	 */
-	void enterCallExpr(NCIntentDslParser.CallExprContext ctx);
+	void enterMultDivModExpr(NCIntentDslParser.MultDivModExprContext ctx);
 	/**
-	 * Exit a parse tree produced by the {@code callExpr}
+	 * Exit a parse tree produced by the {@code multDivModExpr}
 	 * labeled alternative in {@link NCIntentDslParser#expr}.
 	 * @param ctx the parse tree
 	 */
-	void exitCallExpr(NCIntentDslParser.CallExprContext ctx);
+	void exitMultDivModExpr(NCIntentDslParser.MultDivModExprContext ctx);
 	/**
-	 * Enter a parse tree produced by the {@code multExpr}
+	 * Enter a parse tree produced by the {@code andOrExpr}
 	 * labeled alternative in {@link NCIntentDslParser#expr}.
 	 * @param ctx the parse tree
 	 */
-	void enterMultExpr(NCIntentDslParser.MultExprContext ctx);
+	void enterAndOrExpr(NCIntentDslParser.AndOrExprContext ctx);
 	/**
-	 * Exit a parse tree produced by the {@code multExpr}
+	 * Exit a parse tree produced by the {@code andOrExpr}
 	 * labeled alternative in {@link NCIntentDslParser#expr}.
 	 * @param ctx the parse tree
 	 */
-	void exitMultExpr(NCIntentDslParser.MultExprContext ctx);
+	void exitAndOrExpr(NCIntentDslParser.AndOrExprContext ctx);
 	/**
-	 * Enter a parse tree produced by the {@code plusExpr}
+	 * Enter a parse tree produced by the {@code callExpr}
 	 * labeled alternative in {@link NCIntentDslParser#expr}.
 	 * @param ctx the parse tree
 	 */
-	void enterPlusExpr(NCIntentDslParser.PlusExprContext ctx);
+	void enterCallExpr(NCIntentDslParser.CallExprContext ctx);
 	/**
-	 * Exit a parse tree produced by the {@code plusExpr}
+	 * Exit a parse tree produced by the {@code callExpr}
 	 * labeled alternative in {@link NCIntentDslParser#expr}.
 	 * @param ctx the parse tree
 	 */
-	void exitPlusExpr(NCIntentDslParser.PlusExprContext ctx);
+	void exitCallExpr(NCIntentDslParser.CallExprContext ctx);
 	/**
-	 * Enter a parse tree produced by the {@code logExpr}
+	 * Enter a parse tree produced by the {@code eqNeqExpr}
 	 * labeled alternative in {@link NCIntentDslParser#expr}.
 	 * @param ctx the parse tree
 	 */
-	void enterLogExpr(NCIntentDslParser.LogExprContext ctx);
+	void enterEqNeqExpr(NCIntentDslParser.EqNeqExprContext ctx);
 	/**
-	 * Exit a parse tree produced by the {@code logExpr}
+	 * Exit a parse tree produced by the {@code eqNeqExpr}
 	 * labeled alternative in {@link NCIntentDslParser#expr}.
 	 * @param ctx the parse tree
 	 */
-	void exitLogExpr(NCIntentDslParser.LogExprContext ctx);
+	void exitEqNeqExpr(NCIntentDslParser.EqNeqExprContext ctx);
 	/**
 	 * Enter a parse tree produced by {@link NCIntentDslParser#paramList}.
 	 * @param ctx the parse tree
diff --git a/nlpcraft/src/main/scala/org/apache/nlpcraft/model/intent/compiler/antlr4/NCIntentDslParser.java b/nlpcraft/src/main/scala/org/apache/nlpcraft/model/intent/compiler/antlr4/NCIntentDslParser.java
index 08638b0..cd7bcf7 100644
--- a/nlpcraft/src/main/scala/org/apache/nlpcraft/model/intent/compiler/antlr4/NCIntentDslParser.java
+++ b/nlpcraft/src/main/scala/org/apache/nlpcraft/model/intent/compiler/antlr4/NCIntentDslParser.java
@@ -1943,31 +1943,6 @@ public class NCIntentDslParser extends Parser {
 			else return visitor.visitChildren(this);
 		}
 	}
-	public static class EqExprContext extends ExprContext {
-		public Token op;
-		public List<ExprContext> expr() {
-			return getRuleContexts(ExprContext.class);
-		}
-		public ExprContext expr(int i) {
-			return getRuleContext(ExprContext.class,i);
-		}
-		public TerminalNode EQ() { return getToken(NCIntentDslParser.EQ, 0); }
-		public TerminalNode NEQ() { return getToken(NCIntentDslParser.NEQ, 0); }
-		public EqExprContext(ExprContext ctx) { copyFrom(ctx); }
-		@Override
-		public void enterRule(ParseTreeListener listener) {
-			if ( listener instanceof NCIntentDslListener ) ((NCIntentDslListener)listener).enterEqExpr(this);
-		}
-		@Override
-		public void exitRule(ParseTreeListener listener) {
-			if ( listener instanceof NCIntentDslListener ) ((NCIntentDslListener)listener).exitEqExpr(this);
-		}
-		@Override
-		public <T> T accept(ParseTreeVisitor<? extends T> visitor) {
-			if ( visitor instanceof NCIntentDslVisitor ) return ((NCIntentDslVisitor<? extends T>)visitor).visitEqExpr(this);
-			else return visitor.visitChildren(this);
-		}
-	}
 	public static class UnaryExprContext extends ExprContext {
 		public Token op;
 		public ExprContext expr() {
@@ -2017,48 +1992,51 @@ public class NCIntentDslParser extends Parser {
 			else return visitor.visitChildren(this);
 		}
 	}
-	public static class AtomExprContext extends ExprContext {
-		public AtomContext atom() {
-			return getRuleContext(AtomContext.class,0);
+	public static class PlusMinusExprContext extends ExprContext {
+		public Token op;
+		public List<ExprContext> expr() {
+			return getRuleContexts(ExprContext.class);
 		}
-		public AtomExprContext(ExprContext ctx) { copyFrom(ctx); }
+		public ExprContext expr(int i) {
+			return getRuleContext(ExprContext.class,i);
+		}
+		public TerminalNode PLUS() { return getToken(NCIntentDslParser.PLUS, 0); }
+		public TerminalNode MINUS() { return getToken(NCIntentDslParser.MINUS, 0); }
+		public PlusMinusExprContext(ExprContext ctx) { copyFrom(ctx); }
 		@Override
 		public void enterRule(ParseTreeListener listener) {
-			if ( listener instanceof NCIntentDslListener ) ((NCIntentDslListener)listener).enterAtomExpr(this);
+			if ( listener instanceof NCIntentDslListener ) ((NCIntentDslListener)listener).enterPlusMinusExpr(this);
 		}
 		@Override
 		public void exitRule(ParseTreeListener listener) {
-			if ( listener instanceof NCIntentDslListener ) ((NCIntentDslListener)listener).exitAtomExpr(this);
+			if ( listener instanceof NCIntentDslListener ) ((NCIntentDslListener)listener).exitPlusMinusExpr(this);
 		}
 		@Override
 		public <T> T accept(ParseTreeVisitor<? extends T> visitor) {
-			if ( visitor instanceof NCIntentDslVisitor ) return ((NCIntentDslVisitor<? extends T>)visitor).visitAtomExpr(this);
+			if ( visitor instanceof NCIntentDslVisitor ) return ((NCIntentDslVisitor<? extends T>)visitor).visitPlusMinusExpr(this);
 			else return visitor.visitChildren(this);
 		}
 	}
-	public static class CallExprContext extends ExprContext {
-		public TerminalNode FUN_NAME() { return getToken(NCIntentDslParser.FUN_NAME, 0); }
-		public TerminalNode LPAR() { return getToken(NCIntentDslParser.LPAR, 0); }
-		public TerminalNode RPAR() { return getToken(NCIntentDslParser.RPAR, 0); }
-		public ParamListContext paramList() {
-			return getRuleContext(ParamListContext.class,0);
+	public static class AtomExprContext extends ExprContext {
+		public AtomContext atom() {
+			return getRuleContext(AtomContext.class,0);
 		}
-		public CallExprContext(ExprContext ctx) { copyFrom(ctx); }
+		public AtomExprContext(ExprContext ctx) { copyFrom(ctx); }
 		@Override
 		public void enterRule(ParseTreeListener listener) {
-			if ( listener instanceof NCIntentDslListener ) ((NCIntentDslListener)listener).enterCallExpr(this);
+			if ( listener instanceof NCIntentDslListener ) ((NCIntentDslListener)listener).enterAtomExpr(this);
 		}
 		@Override
 		public void exitRule(ParseTreeListener listener) {
-			if ( listener instanceof NCIntentDslListener ) ((NCIntentDslListener)listener).exitCallExpr(this);
+			if ( listener instanceof NCIntentDslListener ) ((NCIntentDslListener)listener).exitAtomExpr(this);
 		}
 		@Override
 		public <T> T accept(ParseTreeVisitor<? extends T> visitor) {
-			if ( visitor instanceof NCIntentDslVisitor ) return ((NCIntentDslVisitor<? extends T>)visitor).visitCallExpr(this);
+			if ( visitor instanceof NCIntentDslVisitor ) return ((NCIntentDslVisitor<? extends T>)visitor).visitAtomExpr(this);
 			else return visitor.visitChildren(this);
 		}
 	}
-	public static class MultExprContext extends ExprContext {
+	public static class MultDivModExprContext extends ExprContext {
 		public Token op;
 		public List<ExprContext> expr() {
 			return getRuleContexts(ExprContext.class);
@@ -2069,22 +2047,22 @@ public class NCIntentDslParser extends Parser {
 		public TerminalNode MULT() { return getToken(NCIntentDslParser.MULT, 0); }
 		public TerminalNode DIV() { return getToken(NCIntentDslParser.DIV, 0); }
 		public TerminalNode MOD() { return getToken(NCIntentDslParser.MOD, 0); }
-		public MultExprContext(ExprContext ctx) { copyFrom(ctx); }
+		public MultDivModExprContext(ExprContext ctx) { copyFrom(ctx); }
 		@Override
 		public void enterRule(ParseTreeListener listener) {
-			if ( listener instanceof NCIntentDslListener ) ((NCIntentDslListener)listener).enterMultExpr(this);
+			if ( listener instanceof NCIntentDslListener ) ((NCIntentDslListener)listener).enterMultDivModExpr(this);
 		}
 		@Override
 		public void exitRule(ParseTreeListener listener) {
-			if ( listener instanceof NCIntentDslListener ) ((NCIntentDslListener)listener).exitMultExpr(this);
+			if ( listener instanceof NCIntentDslListener ) ((NCIntentDslListener)listener).exitMultDivModExpr(this);
 		}
 		@Override
 		public <T> T accept(ParseTreeVisitor<? extends T> visitor) {
-			if ( visitor instanceof NCIntentDslVisitor ) return ((NCIntentDslVisitor<? extends T>)visitor).visitMultExpr(this);
+			if ( visitor instanceof NCIntentDslVisitor ) return ((NCIntentDslVisitor<? extends T>)visitor).visitMultDivModExpr(this);
 			else return visitor.visitChildren(this);
 		}
 	}
-	public static class PlusExprContext extends ExprContext {
+	public static class AndOrExprContext extends ExprContext {
 		public Token op;
 		public List<ExprContext> expr() {
 			return getRuleContexts(ExprContext.class);
@@ -2092,24 +2070,46 @@ public class NCIntentDslParser extends Parser {
 		public ExprContext expr(int i) {
 			return getRuleContext(ExprContext.class,i);
 		}
-		public TerminalNode PLUS() { return getToken(NCIntentDslParser.PLUS, 0); }
-		public TerminalNode MINUS() { return getToken(NCIntentDslParser.MINUS, 0); }
-		public PlusExprContext(ExprContext ctx) { copyFrom(ctx); }
+		public TerminalNode AND() { return getToken(NCIntentDslParser.AND, 0); }
+		public TerminalNode OR() { return getToken(NCIntentDslParser.OR, 0); }
+		public AndOrExprContext(ExprContext ctx) { copyFrom(ctx); }
 		@Override
 		public void enterRule(ParseTreeListener listener) {
-			if ( listener instanceof NCIntentDslListener ) ((NCIntentDslListener)listener).enterPlusExpr(this);
+			if ( listener instanceof NCIntentDslListener ) ((NCIntentDslListener)listener).enterAndOrExpr(this);
 		}
 		@Override
 		public void exitRule(ParseTreeListener listener) {
-			if ( listener instanceof NCIntentDslListener ) ((NCIntentDslListener)listener).exitPlusExpr(this);
+			if ( listener instanceof NCIntentDslListener ) ((NCIntentDslListener)listener).exitAndOrExpr(this);
 		}
 		@Override
 		public <T> T accept(ParseTreeVisitor<? extends T> visitor) {
-			if ( visitor instanceof NCIntentDslVisitor ) return ((NCIntentDslVisitor<? extends T>)visitor).visitPlusExpr(this);
+			if ( visitor instanceof NCIntentDslVisitor ) return ((NCIntentDslVisitor<? extends T>)visitor).visitAndOrExpr(this);
 			else return visitor.visitChildren(this);
 		}
 	}
-	public static class LogExprContext extends ExprContext {
+	public static class CallExprContext extends ExprContext {
+		public TerminalNode FUN_NAME() { return getToken(NCIntentDslParser.FUN_NAME, 0); }
+		public TerminalNode LPAR() { return getToken(NCIntentDslParser.LPAR, 0); }
+		public TerminalNode RPAR() { return getToken(NCIntentDslParser.RPAR, 0); }
+		public ParamListContext paramList() {
+			return getRuleContext(ParamListContext.class,0);
+		}
+		public CallExprContext(ExprContext ctx) { copyFrom(ctx); }
+		@Override
+		public void enterRule(ParseTreeListener listener) {
+			if ( listener instanceof NCIntentDslListener ) ((NCIntentDslListener)listener).enterCallExpr(this);
+		}
+		@Override
+		public void exitRule(ParseTreeListener listener) {
+			if ( listener instanceof NCIntentDslListener ) ((NCIntentDslListener)listener).exitCallExpr(this);
+		}
+		@Override
+		public <T> T accept(ParseTreeVisitor<? extends T> visitor) {
+			if ( visitor instanceof NCIntentDslVisitor ) return ((NCIntentDslVisitor<? extends T>)visitor).visitCallExpr(this);
+			else return visitor.visitChildren(this);
+		}
+	}
+	public static class EqNeqExprContext extends ExprContext {
 		public Token op;
 		public List<ExprContext> expr() {
 			return getRuleContexts(ExprContext.class);
@@ -2117,20 +2117,20 @@ public class NCIntentDslParser extends Parser {
 		public ExprContext expr(int i) {
 			return getRuleContext(ExprContext.class,i);
 		}
-		public TerminalNode AND() { return getToken(NCIntentDslParser.AND, 0); }
-		public TerminalNode OR() { return getToken(NCIntentDslParser.OR, 0); }
-		public LogExprContext(ExprContext ctx) { copyFrom(ctx); }
+		public TerminalNode EQ() { return getToken(NCIntentDslParser.EQ, 0); }
+		public TerminalNode NEQ() { return getToken(NCIntentDslParser.NEQ, 0); }
+		public EqNeqExprContext(ExprContext ctx) { copyFrom(ctx); }
 		@Override
 		public void enterRule(ParseTreeListener listener) {
-			if ( listener instanceof NCIntentDslListener ) ((NCIntentDslListener)listener).enterLogExpr(this);
+			if ( listener instanceof NCIntentDslListener ) ((NCIntentDslListener)listener).enterEqNeqExpr(this);
 		}
 		@Override
 		public void exitRule(ParseTreeListener listener) {
-			if ( listener instanceof NCIntentDslListener ) ((NCIntentDslListener)listener).exitLogExpr(this);
+			if ( listener instanceof NCIntentDslListener ) ((NCIntentDslListener)listener).exitEqNeqExpr(this);
 		}
 		@Override
 		public <T> T accept(ParseTreeVisitor<? extends T> visitor) {
-			if ( visitor instanceof NCIntentDslVisitor ) return ((NCIntentDslVisitor<? extends T>)visitor).visitLogExpr(this);
+			if ( visitor instanceof NCIntentDslVisitor ) return ((NCIntentDslVisitor<? extends T>)visitor).visitEqNeqExpr(this);
 			else return visitor.visitChildren(this);
 		}
 	}
@@ -2242,15 +2242,15 @@ public class NCIntentDslParser extends Parser {
 					switch ( getInterpreter().adaptivePredict(_input,25,_ctx) ) {
 					case 1:
 						{
-						_localctx = new MultExprContext(new ExprContext(_parentctx, _parentState));
+						_localctx = new MultDivModExprContext(new ExprContext(_parentctx, _parentState));
 						pushNewRecursionContext(_localctx, _startState, RULE_expr);
 						setState(276);
 						if (!(precpred(_ctx, 7))) throw new FailedPredicateException(this, "precpred(_ctx, 7)");
 						setState(277);
-						((MultExprContext)_localctx).op = _input.LT(1);
+						((MultDivModExprContext)_localctx).op = _input.LT(1);
 						_la = _input.LA(1);
 						if ( !((((_la) & ~0x3f) == 0 && ((1L << _la) & ((1L << MULT) | (1L << DIV) | (1L << MOD))) != 0)) ) {
-							((MultExprContext)_localctx).op = (Token)_errHandler.recoverInline(this);
+							((MultDivModExprContext)_localctx).op = (Token)_errHandler.recoverInline(this);
 						}
 						else {
 							if ( _input.LA(1)==Token.EOF ) matchedEOF = true;
@@ -2263,15 +2263,15 @@ public class NCIntentDslParser extends Parser {
 						break;
 					case 2:
 						{
-						_localctx = new PlusExprContext(new ExprContext(_parentctx, _parentState));
+						_localctx = new PlusMinusExprContext(new ExprContext(_parentctx, _parentState));
 						pushNewRecursionContext(_localctx, _startState, RULE_expr);
 						setState(279);
 						if (!(precpred(_ctx, 6))) throw new FailedPredicateException(this, "precpred(_ctx, 6)");
 						setState(280);
-						((PlusExprContext)_localctx).op = _input.LT(1);
+						((PlusMinusExprContext)_localctx).op = _input.LT(1);
 						_la = _input.LA(1);
 						if ( !(_la==MINUS || _la==PLUS) ) {
-							((PlusExprContext)_localctx).op = (Token)_errHandler.recoverInline(this);
+							((PlusMinusExprContext)_localctx).op = (Token)_errHandler.recoverInline(this);
 						}
 						else {
 							if ( _input.LA(1)==Token.EOF ) matchedEOF = true;
@@ -2305,15 +2305,15 @@ public class NCIntentDslParser extends Parser {
 						break;
 					case 4:
 						{
-						_localctx = new EqExprContext(new ExprContext(_parentctx, _parentState));
+						_localctx = new EqNeqExprContext(new ExprContext(_parentctx, _parentState));
 						pushNewRecursionContext(_localctx, _startState, RULE_expr);
 						setState(285);
 						if (!(precpred(_ctx, 4))) throw new FailedPredicateException(this, "precpred(_ctx, 4)");
 						setState(286);
-						((EqExprContext)_localctx).op = _input.LT(1);
+						((EqNeqExprContext)_localctx).op = _input.LT(1);
 						_la = _input.LA(1);
 						if ( !(_la==EQ || _la==NEQ) ) {
-							((EqExprContext)_localctx).op = (Token)_errHandler.recoverInline(this);
+							((EqNeqExprContext)_localctx).op = (Token)_errHandler.recoverInline(this);
 						}
 						else {
 							if ( _input.LA(1)==Token.EOF ) matchedEOF = true;
@@ -2326,15 +2326,15 @@ public class NCIntentDslParser extends Parser {
 						break;
 					case 5:
 						{
-						_localctx = new LogExprContext(new ExprContext(_parentctx, _parentState));
+						_localctx = new AndOrExprContext(new ExprContext(_parentctx, _parentState));
 						pushNewRecursionContext(_localctx, _startState, RULE_expr);
 						setState(288);
 						if (!(precpred(_ctx, 3))) throw new FailedPredicateException(this, "precpred(_ctx, 3)");
 						setState(289);
-						((LogExprContext)_localctx).op = _input.LT(1);
+						((AndOrExprContext)_localctx).op = _input.LT(1);
 						_la = _input.LA(1);
 						if ( !(_la==AND || _la==OR) ) {
-							((LogExprContext)_localctx).op = (Token)_errHandler.recoverInline(this);
+							((AndOrExprContext)_localctx).op = (Token)_errHandler.recoverInline(this);
 						}
 						else {
 							if ( _input.LA(1)==Token.EOF ) matchedEOF = true;
diff --git a/nlpcraft/src/main/scala/org/apache/nlpcraft/model/intent/compiler/antlr4/NCIntentDslVisitor.java b/nlpcraft/src/main/scala/org/apache/nlpcraft/model/intent/compiler/antlr4/NCIntentDslVisitor.java
index 332235a..9de16bc 100644
--- a/nlpcraft/src/main/scala/org/apache/nlpcraft/model/intent/compiler/antlr4/NCIntentDslVisitor.java
+++ b/nlpcraft/src/main/scala/org/apache/nlpcraft/model/intent/compiler/antlr4/NCIntentDslVisitor.java
@@ -180,26 +180,26 @@ public interface NCIntentDslVisitor<T> extends ParseTreeVisitor<T> {
 	 */
 	T visitParExpr(NCIntentDslParser.ParExprContext ctx);
 	/**
-	 * Visit a parse tree produced by the {@code eqExpr}
+	 * Visit a parse tree produced by the {@code unaryExpr}
 	 * labeled alternative in {@link NCIntentDslParser#expr}.
 	 * @param ctx the parse tree
 	 * @return the visitor result
 	 */
-	T visitEqExpr(NCIntentDslParser.EqExprContext ctx);
+	T visitUnaryExpr(NCIntentDslParser.UnaryExprContext ctx);
 	/**
-	 * Visit a parse tree produced by the {@code unaryExpr}
+	 * Visit a parse tree produced by the {@code compExpr}
 	 * labeled alternative in {@link NCIntentDslParser#expr}.
 	 * @param ctx the parse tree
 	 * @return the visitor result
 	 */
-	T visitUnaryExpr(NCIntentDslParser.UnaryExprContext ctx);
+	T visitCompExpr(NCIntentDslParser.CompExprContext ctx);
 	/**
-	 * Visit a parse tree produced by the {@code compExpr}
+	 * Visit a parse tree produced by the {@code plusMinusExpr}
 	 * labeled alternative in {@link NCIntentDslParser#expr}.
 	 * @param ctx the parse tree
 	 * @return the visitor result
 	 */
-	T visitCompExpr(NCIntentDslParser.CompExprContext ctx);
+	T visitPlusMinusExpr(NCIntentDslParser.PlusMinusExprContext ctx);
 	/**
 	 * Visit a parse tree produced by the {@code atomExpr}
 	 * labeled alternative in {@link NCIntentDslParser#expr}.
@@ -208,33 +208,33 @@ public interface NCIntentDslVisitor<T> extends ParseTreeVisitor<T> {
 	 */
 	T visitAtomExpr(NCIntentDslParser.AtomExprContext ctx);
 	/**
-	 * Visit a parse tree produced by the {@code callExpr}
+	 * Visit a parse tree produced by the {@code multDivModExpr}
 	 * labeled alternative in {@link NCIntentDslParser#expr}.
 	 * @param ctx the parse tree
 	 * @return the visitor result
 	 */
-	T visitCallExpr(NCIntentDslParser.CallExprContext ctx);
+	T visitMultDivModExpr(NCIntentDslParser.MultDivModExprContext ctx);
 	/**
-	 * Visit a parse tree produced by the {@code multExpr}
+	 * Visit a parse tree produced by the {@code andOrExpr}
 	 * labeled alternative in {@link NCIntentDslParser#expr}.
 	 * @param ctx the parse tree
 	 * @return the visitor result
 	 */
-	T visitMultExpr(NCIntentDslParser.MultExprContext ctx);
+	T visitAndOrExpr(NCIntentDslParser.AndOrExprContext ctx);
 	/**
-	 * Visit a parse tree produced by the {@code plusExpr}
+	 * Visit a parse tree produced by the {@code callExpr}
 	 * labeled alternative in {@link NCIntentDslParser#expr}.
 	 * @param ctx the parse tree
 	 * @return the visitor result
 	 */
-	T visitPlusExpr(NCIntentDslParser.PlusExprContext ctx);
+	T visitCallExpr(NCIntentDslParser.CallExprContext ctx);
 	/**
-	 * Visit a parse tree produced by the {@code logExpr}
+	 * Visit a parse tree produced by the {@code eqNeqExpr}
 	 * labeled alternative in {@link NCIntentDslParser#expr}.
 	 * @param ctx the parse tree
 	 * @return the visitor result
 	 */
-	T visitLogExpr(NCIntentDslParser.LogExprContext ctx);
+	T visitEqNeqExpr(NCIntentDslParser.EqNeqExprContext ctx);
 	/**
 	 * Visit a parse tree produced by {@link NCIntentDslParser#paramList}.
 	 * @param ctx the parse tree


[incubator-nlpcraft] 01/02: WIP.

Posted by ar...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

aradzinski pushed a commit to branch NLPCRAFT-206
in repository https://gitbox.apache.org/repos/asf/incubator-nlpcraft.git

commit 7d7e6ac523700e01167888eea718c6bfaecd37ce
Author: Aaron Radzinski <ar...@apache.org>
AuthorDate: Sat Mar 13 00:29:45 2021 -0800

    WIP.
---
 .../scala/org/apache/nlpcraft/model/intent/compiler/NCDslCompiler.scala | 2 +-
 .../org/apache/nlpcraft/model/intent/compiler/NCDslCompilerBase.scala   | 2 +-
 2 files changed, 2 insertions(+), 2 deletions(-)

diff --git a/nlpcraft/src/main/scala/org/apache/nlpcraft/model/intent/compiler/NCDslCompiler.scala b/nlpcraft/src/main/scala/org/apache/nlpcraft/model/intent/compiler/NCDslCompiler.scala
index 7bdd183..18524a0 100644
--- a/nlpcraft/src/main/scala/org/apache/nlpcraft/model/intent/compiler/NCDslCompiler.scala
+++ b/nlpcraft/src/main/scala/org/apache/nlpcraft/model/intent/compiler/NCDslCompiler.scala
@@ -315,7 +315,7 @@ object NCDslCompiler extends LazyLogging {
                 val x = stack.pop()
 
                 if (!isBool(x.fun))
-                    throw newRuntimeError(s"$subj does not return boolean value: ${ctx.getText}")
+                    throw newRuntimeError(s"$subj did not return boolean value: ${ctx.getText}")
 
                 (asBool(x.fun), x.usedTok)
             }
diff --git a/nlpcraft/src/main/scala/org/apache/nlpcraft/model/intent/compiler/NCDslCompilerBase.scala b/nlpcraft/src/main/scala/org/apache/nlpcraft/model/intent/compiler/NCDslCompilerBase.scala
index bc82d7c..b0f5756 100644
--- a/nlpcraft/src/main/scala/org/apache/nlpcraft/model/intent/compiler/NCDslCompilerBase.scala
+++ b/nlpcraft/src/main/scala/org/apache/nlpcraft/model/intent/compiler/NCDslCompilerBase.scala
@@ -664,7 +664,7 @@ trait NCDslCompilerBase {
         }
 
         def token(): NCToken =
-            if (stack.nonEmpty && stack.top.isInstanceOf[NCToken]) stack.top.asInstanceOf[NCToken] else tok
+            if (stack.nonEmpty && stack.top.isInstanceOf[NCToken]) stack.pop().asInstanceOf[NCToken] else tok
 
         def doPart(): Unit = {
             val (t, aliasId, f) = get1Tok1Str()