JetCore/Operand.cpp
2024-11-26 16:57:03 -08:00

300 lines
8.6 KiB
C++

#include "Operand.h"
#include "Exception.h"
#include <format>
#include <iostream>
#include <time.h>
namespace jet {
Operand::Operand(coreutils::ZString &in, Global &global, std::map<coreutils::MString, coreutils::MString> &lvariables) {
doubleValue = 0;
in.skipWhitespace();
if(in.startsWith("$[") || in.startsWith("#[")) {
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;
doubleValue = op.doubleValue;
if(!in.ifNext(")"))
throw coreutils::Exception("expected ) in expression.");
} else if(in.ifNextIgnoreCase("SUBSTRING")) {
if(!in.ifNext("("))
throw coreutils::Exception("Expecting ( for SUBSTRING parameters.");
Operand parm1(in, global, lvariables);
if(!in.ifNext(","))
throw coreutils::Exception("Expecting , in SUBSTRING expression.");
Operand parm2(in, global, lvariables);
if(in.ifNext(")")) {
string = parm1.string.substring(parm2.string.asInteger());
} else if(!in.ifNext(","))
throw coreutils::Exception("Expecting , in SUBSTRING expression.");
Operand parm3(in, global, lvariables);
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, global, lvariables);
if(!in.ifNext(","))
throw coreutils::Exception("Expecting , in LEFT expression.");
Operand parm2(in, global, lvariables);
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("EXPR")) {
if(!in.ifNext("("))
throw coreutils::Exception("Expecting ( for EXPR parameters.");
Operand parm1(in, global, lvariables);
if(in.ifNext(")")) {
Operand op(parm1.string, global, lvariables);
string = op.string;
isNumber = op.isNumber;
boolean = op.boolean;
} else
throw coreutils::Exception("Expecting ) at end of EXPR 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;
} else
throw coreutils::Exception("operand is not valid.");
in.skipWhitespace();
if(in.ifNext("!=") || 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("=")) {
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(isNumber) {
Operand op(in, global, lvariables);
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, global, lvariables);
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, global, lvariables);
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, global, lvariables);
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;
}
}