Fixed expressions to be able to do math with nested expressions.

This commit is contained in:
Brad Arant 2024-09-30 14:20:59 -07:00
parent 0b9f2354a3
commit aa090c8a73
11 changed files with 86 additions and 98 deletions

View File

@ -1,51 +0,0 @@
#include "Expression.h"
#include "Operand.h"
#include "Exception.h"
#include <iostream>
namespace jet {
Expression::Expression(coreutils::ZString &in) : MString() {
std::cout << "Expression construction:" << in << std::endl;
Operand op1(in);
boolean = op1.boolean;
string = op1.string;
if(in.unparsed().getLength() > 0) {
std::cout << "1)" << in.unparsed() << "(" << std::endl;
if(in.ifNext("+"))
operation = (char *)"+";
else if(in.ifNext("-"))
operation = (char *)"-";
else
throw coreutils::Exception("Expecting operator.");
in.skipWhitespace();
if(in.unparsed().getLength() == 0)
throw coreutils::Exception("Expecting operand.");
Operand op2(in);
std::cout << op1.string << ":" << operation << ":" << op2.string << std::endl;
}
std::cout << "Leaving expression string: " << string << std::endl;
std::cout << "Unparsed: [" << in.unparsed() << "]" << std::endl;
}
Expression::~Expression() {}
bool Expression::getBooleanResult() {
return boolean;
}
double Expression::getNumericResult() {
return 0;
}
coreutils::ZString Expression::getStringResult() {
return coreutils::ZString();
}
}

View File

@ -1,24 +0,0 @@
#ifndef __Expression_h__
#define __Expression_h__
#include "MString.h"
namespace jet {
class Expression : public coreutils::MString {
public:
Expression(coreutils::ZString &in);
virtual ~Expression();
bool getBooleanResult();
double getNumericResult();
coreutils::ZString getStringResult();
bool boolean;
coreutils::MString string;
char *operation;
};
}
#endif

View File

@ -7,8 +7,22 @@ namespace jet {
Operand::Operand(coreutils::ZString &in) {
doubleValue = 0;
in.skipWhitespace();
std::cout << "op: [" << in.unparsed() << "]" << std::endl;
// std::cout << "op: [" << in.unparsed() << "]" << std::endl;
if(in.ifNext("(")) {
// std::cout << "(" << in.unparsed() << std::endl;
Operand op(in);
string = op.string;
doubleValue = op.doubleValue;
if(!in.ifNext(")"))
throw coreutils::Exception("expected ) in expression.");
// std::cout << ")" << in.unparsed() << std::endl;
}
if(in.ifNext("SUBSTRING")) {
if(!in.ifNext("("))
throw coreutils::Exception("Expecting ( for SUBSTRING parameters.");
@ -44,21 +58,66 @@ namespace jet {
} else if(in.ifNext("true")) {
boolean = true;
string = "true";
return;
} else if(in.ifNext("false")) {
boolean = false;
string = "false";
return;
} else if(in.startsWithNumber()) {
doubleValue = in.asDouble();
string = std::format("{}", doubleValue);
return;
isNumber = true;
} else if(in.ifNext("'")) {
string = in.getTokenExclude("'");
in.ifNext("'");
isNumber = false;
}
in.skipWhitespace();
if(in.ifNext("+")) {
if(isNumber) {
Operand op(in);
if(op.isNumber) {
doubleValue += op.doubleValue;
string = std::format("{}", doubleValue);
} else
throw coreutils::Exception("operand is not a number.");
} else
throw coreutils::Exception("operand is not a number.");
} else if(in.ifNext("-")) {
if(isNumber) {
Operand op(in);
if(op.isNumber) {
doubleValue -= op.doubleValue;
string = std::format("{}", doubleValue);
} else
throw coreutils::Exception("operand is not a number.");
} else
throw coreutils::Exception("operand is not a number.");
} else if(in.ifNext("*")) {
if(isNumber) {
Operand op(in);
if(op.isNumber) {
doubleValue *= op.doubleValue;
string = std::format("{}", doubleValue);
} else
throw coreutils::Exception("operand is not a number.");
} else
throw coreutils::Exception("operand is not a number.");
} else if(in.ifNext("/")) {
if(isNumber) {
Operand op(in);
if(op.isNumber) {
doubleValue /= op.doubleValue;
string = std::format("{}", doubleValue);
} else
throw coreutils::Exception("operand is not a number.");
} else
throw coreutils::Exception("operand is not a number.");
} else {
// std::cout << ">" << string << std::endl;
return;
}
}
}

View File

@ -10,8 +10,7 @@ namespace jet {
public:
Operand(coreutils::ZString &in);
bool isNumber();
bool isString();
bool isNumber;
///
/// boolean is set by internal processes to return the boolean
@ -21,8 +20,6 @@ namespace jet {
bool boolean;
coreutils::MString string;
private:
// dataType enum ={};
double doubleValue;

View File

@ -18,7 +18,6 @@ namespace jet {
if(variableDefined(coreutils::ZString("step"))) {
step = variables["step"].asDouble();
}
std::cout << "start: " << counter << "; end: " << end << "; step: " << step << std::endl;
for(double ix = counter; ix <= end; ix += step) {
if(nameDefined)
variables[variables["name"]] = ix;

View File

@ -1,6 +1,6 @@
#include "__header.h"
#include "Exception.h"
#include "Expression.h"
#include "Operand.h"
#include <iostream>
namespace jet {
@ -20,7 +20,7 @@ namespace jet {
if(variableDefined("expr")) {
if(variableDefined("eval"))
throw coreutils::Exception("Cannot use eval with expr.");
global.headers[variables["name"]] = Expression(variables["expr"]).string;
global.headers[variables["name"]] = Operand(variables["expr"]).string;
} else if(hasContainer) {
processContainer(container);
if(evaluate) {

View File

@ -1,7 +1,7 @@
#include "__if.h"
#include "Exception.h"
#include <iostream>
#include "Expression.h"
#include "Operand.h"
namespace jet {
@ -15,7 +15,7 @@ namespace jet {
throw coreutils::Exception("Either value1 or expr can be specified but not both.");
if(variableDefined("value2")) {
if(variableDefined("type")) {
result = Expression(variables["expr"]);
} else
throw coreutils::Exception("type expected if value1 and value2 specified.");
} else
@ -37,8 +37,7 @@ namespace jet {
throw coreutils::Exception("value2 should not be specified with expr.");
if(variableDefined("type"))
throw coreutils::Exception("type should not be specified with expr.");
result = Expression(variables["expr"]);
booleanResult = true;
booleanResult = Operand(variables["expr"]).boolean;
}
if(booleanResult)
processContainer(container);

View File

@ -1,6 +1,6 @@
#include "__set.h"
#include "Exception.h"
#include "Expression.h"
#include "Operand.h"
#include <iostream>
namespace jet {
@ -21,7 +21,7 @@ namespace jet {
if(variableDefined("expr")) {
if(variableDefined("eval"))
throw coreutils::Exception("Cannot use eval with expr.");
global.variables[variables["name"]] = Expression(variables["expr"]).string;
global.variables[variables["name"]] = Operand(variables["expr"]).string;
} else if(hasContainer) {
processContainer(container);
if(evaluate) {

View File

@ -1,6 +1,6 @@
#include "__write.h"
#include "Exception.h"
#include "Expression.h"
#include "Operand.h"
#include <iostream>
#include <fcntl.h>
#include <unistd.h>

BIN
jet-2.0

Binary file not shown.

View File

@ -13,10 +13,19 @@
</mysql>
</comment>
<set name="ix" value="1" />
<set name="theexpr" expr="SUBSTRING('abcdefg', 1, 3)" />
<set name="theexpr2" expr="5+3" />
theexpr=($[theexpr])
theexpr2($[theexpr2])
<set name="theexpr" expr="SUBSTRING('abcdefg', 5 - 4, 20 - 17)" />
<set name="addition" expr="5+3" />
<set name="subtraction" expr="5-3" />
<set name="multiplication" expr="5*3" />
<set name="division" expr="5/3" />
<set name="divisor" value="8" />
<set name="nested" expr="(2*(4+4)/$[divisor])*32" />
$[nested]
substring('abcdefg', 1, 3)=[$[theexpr]]
5+3=($[addition])
5-3($[subtraction])
5*3($[multiplication])
5/3($[division])
<set name="varname$[ix]" value="vardata" scope="global" />
<set name="noeval" eval="no">this is the value store in #[name].</set>
<set name="thename" eval="yes">this is the value store in #[name].</set>