287 lines
7.5 KiB
C++
287 lines
7.5 KiB
C++
#include "Operand.h"
|
|
#include "Exception.h"
|
|
#include <format>
|
|
#include <iostream>
|
|
#include <time.h>
|
|
|
|
namespace jet {
|
|
|
|
Operand::Operand(coreutils::ZString &in) {
|
|
|
|
doubleValue = 0;
|
|
|
|
in.skipWhitespace();
|
|
|
|
if(in.ifNext("(")) {
|
|
Operand op(in);
|
|
string = op.string;
|
|
doubleValue = op.doubleValue;
|
|
if(!in.ifNext(")"))
|
|
throw coreutils::Exception("expected ) in expression.");
|
|
}
|
|
|
|
if(in.ifNextIgnoreCase("SUBSTRING")) {
|
|
if(!in.ifNext("("))
|
|
throw coreutils::Exception("Expecting ( for SUBSTRING parameters.");
|
|
Operand parm1(in);
|
|
if(!in.ifNext(","))
|
|
throw coreutils::Exception("Expecting , in SUBSTRING expression.");
|
|
Operand parm2(in);
|
|
if(in.ifNext(")")) {
|
|
string = parm1.string.substring(parm2.string.asInteger());
|
|
}
|
|
else if(!in.ifNext(","))
|
|
throw coreutils::Exception("Expecting , in SUBSTRING expression.");
|
|
Operand parm3(in);
|
|
if(in.ifNext(")")) {
|
|
string = parm1.string.substring(parm2.string.asInteger(), parm3.string.asInteger());
|
|
}
|
|
else
|
|
throw coreutils::Exception("Expecting ) at end of substring expression.");
|
|
} else if(in.ifNextIgnoreCase("LEFT")) {
|
|
if(!in.ifNext("("))
|
|
throw coreutils::Exception("Expecting ( for LEFT parameters.");
|
|
Operand parm1(in);
|
|
if(!in.ifNext(","))
|
|
throw coreutils::Exception("Expecting , in LEFT expression.");
|
|
Operand parm2(in);
|
|
if(in.ifNext(")")) {
|
|
string = parm1.string.substring(0, parm2.string.asInteger());
|
|
}
|
|
else
|
|
throw coreutils::Exception("Expecting ) at end of LEFT expression.");
|
|
} else if(in.ifNextIgnoreCase("RIGHT")) {
|
|
|
|
} else if(in.ifNextIgnoreCase("TRIM")) {
|
|
|
|
} else if(in.ifNextIgnoreCase("TOUPPER")) {
|
|
|
|
} else if(in.ifNextIgnoreCase("TOLOWER")) {
|
|
|
|
} else if(in.ifNextIgnoreCase("REVERSE")) {
|
|
|
|
} else if(in.ifNextIgnoreCase("CONCAT")) {
|
|
|
|
} else if(in.ifNextIgnoreCase("INTEGER")) {
|
|
|
|
} else if(in.ifNextIgnoreCase("ROUND")) {
|
|
|
|
} else if(in.ifNextIgnoreCase("RANDOM")) {
|
|
unsigned int seed = (unsigned int)clock();
|
|
doubleValue = (double) rand_r(&seed) / (RAND_MAX + 1.0);
|
|
isNumber = true;
|
|
string = std::format("{:.12f}", doubleValue);
|
|
string.removeTrailingZeros();
|
|
} else if(in.ifNextIgnoreCase("true")) {
|
|
boolean = true;
|
|
string = "true";
|
|
} else if(in.ifNextIgnoreCase("false")) {
|
|
boolean = false;
|
|
string = "false";
|
|
} else if(in.startsWithNumber()) {
|
|
doubleValue = in.asDouble();
|
|
string = std::format("{:.12f}", doubleValue);
|
|
isNumber = true;
|
|
} else if(in.ifNext("'")) {
|
|
string = in.getTokenExclude("'");
|
|
in.ifNext("'");
|
|
isNumber = false;
|
|
}
|
|
|
|
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("<>")) {
|
|
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("+")) {
|
|
if(isNumber) {
|
|
Operand op(in);
|
|
if(op.isNumber) {
|
|
doubleValue += op.doubleValue;
|
|
string = std::format("{:.12f}", doubleValue);
|
|
string.removeTrailingZeros();
|
|
} 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("{:.12f}", doubleValue);
|
|
string.removeTrailingZeros();
|
|
} 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("{:.12f}", doubleValue);
|
|
string.removeTrailingZeros();
|
|
} 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("{:.12f}", doubleValue);
|
|
string.removeTrailingZeros();
|
|
} else
|
|
throw coreutils::Exception("operand is not a number.");
|
|
} else
|
|
throw coreutils::Exception("operand is not a number.");
|
|
} else
|
|
return;
|
|
|
|
}
|
|
|
|
}
|