OPerand now does its own expression parsing.

This commit is contained in:
brad Arant 2024-11-16 10:23:16 -08:00
parent 4d016197d2
commit 839f7e2eb8
11 changed files with 120 additions and 115 deletions

View File

@ -6,50 +6,54 @@
namespace jet { namespace jet {
Operand::Operand(coreutils::ZString &in) { Operand::Operand(coreutils::ZString &in, Global &global, std::map<coreutils::ZString, coreutils::MString> &lvariables) {
doubleValue = 0; doubleValue = 0;
in.skipWhitespace(); in.skipWhitespace();
if(in.ifNext("(")) { if(in.startsWith("$[") || in.startsWith("#[")) {
Operand op(in); string = global.getVariable(in, lvariables);
doubleValue = string.asDouble();
isNumber = string.eod();
string.reset();
if((string == "false") || (string == "true"))
boolean = true;
} else if(in.ifNext("(")) {
Operand op(in, global, lvariables);
string = op.string; string = op.string;
doubleValue = op.doubleValue; doubleValue = op.doubleValue;
if(!in.ifNext(")")) if(!in.ifNext(")"))
throw coreutils::Exception("expected ) in expression."); throw coreutils::Exception("expected ) in expression.");
} } else if(in.ifNextIgnoreCase("SUBSTRING")) {
if(in.ifNextIgnoreCase("SUBSTRING")) {
if(!in.ifNext("(")) if(!in.ifNext("("))
throw coreutils::Exception("Expecting ( for SUBSTRING parameters."); throw coreutils::Exception("Expecting ( for SUBSTRING parameters.");
Operand parm1(in); Operand parm1(in, global, lvariables);
if(!in.ifNext(",")) if(!in.ifNext(","))
throw coreutils::Exception("Expecting , in SUBSTRING expression."); throw coreutils::Exception("Expecting , in SUBSTRING expression.");
Operand parm2(in); Operand parm2(in, global, lvariables);
if(in.ifNext(")")) { if(in.ifNext(")")) {
string = parm1.string.substring(parm2.string.asInteger()); string = parm1.string.substring(parm2.string.asInteger());
} } else if(!in.ifNext(","))
else if(!in.ifNext(","))
throw coreutils::Exception("Expecting , in SUBSTRING expression."); throw coreutils::Exception("Expecting , in SUBSTRING expression.");
Operand parm3(in); Operand parm3(in, global, lvariables);
if(in.ifNext(")")) { if(in.ifNext(")")) {
string = parm1.string.substring(parm2.string.asInteger(), parm3.string.asInteger()); string = parm1.string.substring(parm2.string.asInteger(), parm3.string.asInteger());
} } else
else
throw coreutils::Exception("Expecting ) at end of substring expression."); throw coreutils::Exception("Expecting ) at end of substring expression.");
} else if(in.ifNextIgnoreCase("LEFT")) { } else if(in.ifNextIgnoreCase("LEFT")) {
if(!in.ifNext("(")) if(!in.ifNext("("))
throw coreutils::Exception("Expecting ( for LEFT parameters."); throw coreutils::Exception("Expecting ( for LEFT parameters.");
Operand parm1(in); Operand parm1(in, global, lvariables);
if(!in.ifNext(",")) if(!in.ifNext(","))
throw coreutils::Exception("Expecting , in LEFT expression."); throw coreutils::Exception("Expecting , in LEFT expression.");
Operand parm2(in); Operand parm2(in, global, lvariables);
if(in.ifNext(")")) { if(in.ifNext(")")) {
string = parm1.string.substring(0, parm2.string.asInteger()); string = parm1.string.substring(0, parm2.string.asInteger());
} } else
else
throw coreutils::Exception("Expecting ) at end of LEFT expression."); throw coreutils::Exception("Expecting ) at end of LEFT expression.");
} else if(in.ifNextIgnoreCase("EXPR")) {
} else if(in.ifNextIgnoreCase("RIGHT")) { } else if(in.ifNextIgnoreCase("RIGHT")) {
} else if(in.ifNextIgnoreCase("TRIM")) { } else if(in.ifNextIgnoreCase("TRIM")) {
@ -88,82 +92,10 @@ namespace jet {
isNumber = false; isNumber = false;
} }
in.skipWhitespace(); in.skipWhitespace();
if(in.ifNext("=")) {
Operand op(in);
if(isNumber && op.isNumber) {
if(doubleValue == op.doubleValue) {
boolean = true;
isNumber = false;
string = "true";
} else {
boolean = false;
isNumber = false;
string = "false";
}
} else if(!isNumber && !op.isNumber) {
if(string == op.string) {
boolean = true;
isNumber = false;
string = "true";
} else {
boolean = false;
isNumber = false;
string = "false";
}
}
}
if(in.ifNext("<")) {
Operand op(in);
if(isNumber && op.isNumber) {
if(doubleValue < op.doubleValue) {
boolean = true;
isNumber = false;
string = "true";
} else {
boolean = false;
isNumber = false;
string = "false";
}
} else if(!isNumber && !op.isNumber) {
if(string < op.string) {
boolean = true;
isNumber = false;
string = "true";
} else {
boolean = false;
isNumber = false;
string = "false";
}
}
}
if(in.ifNext(">")) {
Operand op(in);
if(isNumber && op.isNumber) {
if(doubleValue > op.doubleValue) {
boolean = true;
isNumber = false;
string = "true";
} else {
boolean = false;
isNumber = false;
string = "false";
}
} else if(!isNumber && !op.isNumber) {
if(string > op.string) {
boolean = true;
isNumber = false;
string = "true";
} else {
boolean = false;
isNumber = false;
string = "false";
}
}
}
if(in.ifNext("!=") || in.ifNext("<>")) { if(in.ifNext("!=") || in.ifNext("<>")) {
Operand op(in); Operand op(in, global, lvariables);
if(isNumber && op.isNumber) { if(isNumber && op.isNumber) {
if(doubleValue != op.doubleValue) { if(doubleValue != op.doubleValue) {
boolean = true; boolean = true;
@ -187,7 +119,7 @@ namespace jet {
} }
} }
if(in.ifNext("<=")) { if(in.ifNext("<=")) {
Operand op(in); Operand op(in, global, lvariables);
if(isNumber && op.isNumber) { if(isNumber && op.isNumber) {
if(doubleValue <= op.doubleValue) { if(doubleValue <= op.doubleValue) {
boolean = true; boolean = true;
@ -211,7 +143,7 @@ namespace jet {
} }
} }
if(in.ifNext(">=")) { if(in.ifNext(">=")) {
Operand op(in); Operand op(in, global, lvariables);
if(isNumber && op.isNumber) { if(isNumber && op.isNumber) {
if(doubleValue >= op.doubleValue) { if(doubleValue >= op.doubleValue) {
boolean = true; boolean = true;
@ -234,9 +166,81 @@ namespace jet {
} }
} }
} }
if(in.ifNext("=")) {
Operand op(in, global, lvariables);
if(isNumber && op.isNumber) {
if(doubleValue == op.doubleValue) {
boolean = true;
isNumber = false;
string = "true";
} else {
boolean = false;
isNumber = false;
string = "false";
}
} else if(!isNumber && !op.isNumber) {
if(string == op.string) {
boolean = true;
isNumber = false;
string = "true";
} else {
boolean = false;
isNumber = false;
string = "false";
}
}
}
if(in.ifNext("<")) {
Operand op(in, global, lvariables);
if(isNumber && op.isNumber) {
if(doubleValue < op.doubleValue) {
boolean = true;
isNumber = false;
string = "true";
} else {
boolean = false;
isNumber = false;
string = "false";
}
} else if(!isNumber && !op.isNumber) {
if(string < op.string) {
boolean = true;
isNumber = false;
string = "true";
} else {
boolean = false;
isNumber = false;
string = "false";
}
}
}
if(in.ifNext(">")) {
Operand op(in, global, lvariables);
if(isNumber && op.isNumber) {
if(doubleValue > op.doubleValue) {
boolean = true;
isNumber = false;
string = "true";
} else {
boolean = false;
isNumber = false;
string = "false";
}
} else if(!isNumber && !op.isNumber) {
if(string > op.string) {
boolean = true;
isNumber = false;
string = "true";
} else {
boolean = false;
isNumber = false;
string = "false";
}
}
}
if(in.ifNext("+")) { if(in.ifNext("+")) {
if(isNumber) { if(isNumber) {
Operand op(in); Operand op(in, global, lvariables);
if(op.isNumber) { if(op.isNumber) {
doubleValue += op.doubleValue; doubleValue += op.doubleValue;
string = std::format("{:.12f}", doubleValue); string = std::format("{:.12f}", doubleValue);
@ -247,7 +251,7 @@ namespace jet {
throw coreutils::Exception("operand is not a number."); throw coreutils::Exception("operand is not a number.");
} else if(in.ifNext("-")) { } else if(in.ifNext("-")) {
if(isNumber) { if(isNumber) {
Operand op(in); Operand op(in, global, lvariables);
if(op.isNumber) { if(op.isNumber) {
doubleValue -= op.doubleValue; doubleValue -= op.doubleValue;
string = std::format("{:.12f}", doubleValue); string = std::format("{:.12f}", doubleValue);
@ -258,7 +262,7 @@ namespace jet {
throw coreutils::Exception("operand is not a number."); throw coreutils::Exception("operand is not a number.");
} else if(in.ifNext("*")) { } else if(in.ifNext("*")) {
if(isNumber) { if(isNumber) {
Operand op(in); Operand op(in, global, lvariables);
if(op.isNumber) { if(op.isNumber) {
doubleValue *= op.doubleValue; doubleValue *= op.doubleValue;
string = std::format("{:.12f}", doubleValue); string = std::format("{:.12f}", doubleValue);
@ -269,7 +273,7 @@ namespace jet {
throw coreutils::Exception("operand is not a number."); throw coreutils::Exception("operand is not a number.");
} else if(in.ifNext("/")) { } else if(in.ifNext("/")) {
if(isNumber) { if(isNumber) {
Operand op(in); Operand op(in, global, lvariables);
if(op.isNumber) { if(op.isNumber) {
doubleValue /= op.doubleValue; doubleValue /= op.doubleValue;
string = std::format("{:.12f}", doubleValue); string = std::format("{:.12f}", doubleValue);

View File

@ -2,13 +2,14 @@
#define __Operand_h__ #define __Operand_h__
#include "MString.h" #include "MString.h"
#include "Global.h"
namespace jet { namespace jet {
class Operand { class Operand {
public: public:
Operand(coreutils::ZString &in); Operand(coreutils::ZString &in, Global &global, std::map<coreutils::ZString, coreutils::MString> &lvariables);
bool isNumber; bool isNumber;

View File

@ -21,7 +21,7 @@ namespace jet {
if(variableDefined("expr")) { if(variableDefined("expr")) {
if(variableDefined("eval")) if(variableDefined("eval"))
throw coreutils::Exception("Cannot use eval with expr."); throw coreutils::Exception("Cannot use eval with expr.");
global.headers[variables["name"]] = Operand(variables["expr"]).string; global.headers[variables["name"]] = Operand(variables["expr"], global, parent->variables).string;
} else if(hasContainer) { } else if(hasContainer) {
processContainer(container); processContainer(container);
if(evaluate) { if(evaluate) {

View File

@ -36,7 +36,7 @@ namespace jet {
throw coreutils::Exception("value2 should not be specified with expr."); throw coreutils::Exception("value2 should not be specified with expr.");
if(variableDefined("type")) if(variableDefined("type"))
throw coreutils::Exception("type should not be specified with expr."); throw coreutils::Exception("type should not be specified with expr.");
booleanResult = Operand(variables["expr"]).boolean; booleanResult = Operand(variables["expr"], global, parent->variables).boolean;
} }
if(booleanResult) if(booleanResult)
processContainer(container); processContainer(container);

View File

@ -24,13 +24,12 @@ namespace jet {
resolveKeyword("name"); resolveKeyword("name");
if(variableDefined("expr")) { if(variableDefined("expr")) {
resolveKeyword("expr");
if(!variableDefined("scope") || (variables["scope"] == "global")) if(!variableDefined("scope") || (variables["scope"] == "global"))
global.variables[variables["name"]] = Operand(variables["expr"]).string; global.variables[variables["name"]] = Operand(variables["expr"], global, parent->variables).string;
else if(variables["scope"] == "local") else if(variables["scope"] == "local")
parent->variables[variables["name"]] = Operand(variables["expr"]).string; parent->variables[variables["name"]] = Operand(variables["expr"], global, parent->variables).string;
else if(variables["scope"] == "parent") else if(variables["scope"] == "parent")
parent->parent->variables[variables["name"]] = Operand(variables["expr"]).string; parent->parent->variables[variables["name"]] = Operand(variables["expr"], global, parent->variables).string;
} else if(hasContainer) { } else if(hasContainer) {
processContainer(container); processContainer(container);
if(evaluate) { if(evaluate) {

View File

@ -47,7 +47,7 @@ namespace jet {
variables["expr"].reset(); variables["expr"].reset();
variables["expr"] = exprSaved; variables["expr"] = exprSaved;
resolveKeyword("expr"); resolveKeyword("expr");
booleanResult = Operand(variables["expr"]).boolean; booleanResult = Operand(variables["expr"], global, parent->variables).boolean;
} else { } else {
booleanResult = false; booleanResult = false;
int rc = variables["value1"].compare(variables["value2"]); int rc = variables["value1"].compare(variables["value2"]);

View File

@ -39,8 +39,7 @@ namespace jet {
throw coreutils::Exception("type should not be specified with expr."); throw coreutils::Exception("type should not be specified with expr.");
exprMethod = true; exprMethod = true;
exprSaved = variables["expr"]; exprSaved = variables["expr"];
resolveKeyword("expr"); booleanResult = Operand(variables["expr"], global, parent->variables).boolean;
booleanResult = Operand(variables["expr"]).boolean;
} }
while(booleanResult) { while(booleanResult) {
processContainer(container); processContainer(container);
@ -48,8 +47,7 @@ namespace jet {
if(exprMethod) { if(exprMethod) {
variables["expr"].reset(); variables["expr"].reset();
variables["expr"] = exprSaved; variables["expr"] = exprSaved;
resolveKeyword("expr"); booleanResult = Operand(variables["expr"], global, parent->variables).boolean;
booleanResult = Operand(variables["expr"]).boolean;
} else { } else {
booleanResult = false; booleanResult = false;
int rc = variables["value1"].compare(variables["value2"]); int rc = variables["value1"].compare(variables["value2"]);

View File

@ -1,4 +1,4 @@
#!./jet-2.0 #!../jet-2.0
<jet> <jet>
This is output This is output
</jet> </jet>

View File

@ -1,4 +1,4 @@
#!./jet-2.0 #!../jet-2.0
<jet cgi="true" name1="localname" filterblanklines="true" trimlines="true"> <jet cgi="true" name1="localname" filterblanklines="true" trimlines="true">
<mysql host="localhost" database="barant" user="barant" password="uversa" sessionid="1"> <mysql host="localhost" database="barant" user="barant" password="uversa" sessionid="1">
<sql sessionid="1">select * from testdata</sql> <sql sessionid="1">select * from testdata</sql>

View File

@ -1,13 +1,16 @@
#!./jet-2.0 #!../jet-2.0
<jet filterblanklines="true" trimlines="true"> <jet filterblanklines="true" trimlines="true">
<tag name="test"> <tag name="test">
x
<set name="ix" expr="$[ix]+1" /> <set name="ix" expr="$[ix]+1" />
<container /> <container />
$[ix] $[ix]
z
</tag> </tag>
<set name="ix" value="1" /> <set name="ix" value="1" />
<test> <test>
<set name="ix" expr="$[ix]+1" /> y
<set name="ix" expr="$[ix]+3" />
</test> </test>
<test /> <test />
</jet> </jet>

View File

@ -1,7 +1,7 @@
#!../jet-2.0 #!../jet-2.0
<jet cgi="false" name1="localname" filterblanklines="true" trimlines="true"> <jet cgi="false" name1="localname" filterblanklines="true" trimlines="true">
<set name="ix" value="1" /> <set name="ix" value="1" />
<while expr="$[ix]<10"> <while expr="$[ix]<=11">
-->$[ix]<-- -->$[ix]<--
<set name="ix" expr="$[ix]+1" /> <set name="ix" expr="$[ix]+1" />
</while> </while>