#include "Operand.h" #include "Exception.h" #include #include #include namespace jet { Operand::Operand(coreutils::ZString &in, Global &global, std::map &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; } }