From 839f7e2eb8592368419cd084cc704db5519d953c Mon Sep 17 00:00:00 2001 From: brad Arant Date: Sat, 16 Nov 2024 10:23:16 -0800 Subject: [PATCH] OPerand now does its own expression parsing. --- Operand.cpp | 200 ++++++++++++++++++++++---------------------- Operand.h | 3 +- __header.cpp | 2 +- __if.cpp | 2 +- __set.cpp | 7 +- __until.cpp | 2 +- __while.cpp | 6 +- tests/test1.jet | 2 +- tests/testdb.jet | 2 +- tests/testtag.jet | 7 +- tests/testwhile.jet | 2 +- 11 files changed, 120 insertions(+), 115 deletions(-) diff --git a/Operand.cpp b/Operand.cpp index 68a0fa0..aee75f0 100644 --- a/Operand.cpp +++ b/Operand.cpp @@ -6,50 +6,54 @@ namespace jet { - Operand::Operand(coreutils::ZString &in) { + Operand::Operand(coreutils::ZString &in, Global &global, std::map &lvariables) { doubleValue = 0; in.skipWhitespace(); - if(in.ifNext("(")) { - Operand op(in); + 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."); - } - - if(in.ifNextIgnoreCase("SUBSTRING")) { + } else if(in.ifNextIgnoreCase("SUBSTRING")) { if(!in.ifNext("(")) throw coreutils::Exception("Expecting ( for SUBSTRING parameters."); - Operand parm1(in); + Operand parm1(in, global, lvariables); if(!in.ifNext(",")) throw coreutils::Exception("Expecting , in SUBSTRING expression."); - Operand parm2(in); + Operand parm2(in, global, lvariables); if(in.ifNext(")")) { string = parm1.string.substring(parm2.string.asInteger()); - } - else if(!in.ifNext(",")) + } else if(!in.ifNext(",")) throw coreutils::Exception("Expecting , in SUBSTRING expression."); - Operand parm3(in); + Operand parm3(in, global, lvariables); if(in.ifNext(")")) { string = parm1.string.substring(parm2.string.asInteger(), parm3.string.asInteger()); - } - else + } 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); + Operand parm1(in, global, lvariables); if(!in.ifNext(",")) throw coreutils::Exception("Expecting , in LEFT expression."); - Operand parm2(in); + Operand parm2(in, global, lvariables); if(in.ifNext(")")) { string = parm1.string.substring(0, parm2.string.asInteger()); - } - else + } else throw coreutils::Exception("Expecting ) at end of LEFT expression."); + } else if(in.ifNextIgnoreCase("EXPR")) { + } else if(in.ifNextIgnoreCase("RIGHT")) { } else if(in.ifNextIgnoreCase("TRIM")) { @@ -88,82 +92,10 @@ namespace jet { 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"; - } - } - } + in.skipWhitespace(); + if(in.ifNext("!=") || in.ifNext("<>")) { - Operand op(in); + Operand op(in, global, lvariables); if(isNumber && op.isNumber) { if(doubleValue != op.doubleValue) { boolean = true; @@ -187,7 +119,7 @@ namespace jet { } } if(in.ifNext("<=")) { - Operand op(in); + Operand op(in, global, lvariables); if(isNumber && op.isNumber) { if(doubleValue <= op.doubleValue) { boolean = true; @@ -211,7 +143,7 @@ namespace jet { } } if(in.ifNext(">=")) { - Operand op(in); + Operand op(in, global, lvariables); if(isNumber && op.isNumber) { if(doubleValue >= op.doubleValue) { 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(isNumber) { - Operand op(in); + Operand op(in, global, lvariables); if(op.isNumber) { doubleValue += op.doubleValue; string = std::format("{:.12f}", doubleValue); @@ -247,7 +251,7 @@ namespace jet { throw coreutils::Exception("operand is not a number."); } else if(in.ifNext("-")) { if(isNumber) { - Operand op(in); + Operand op(in, global, lvariables); if(op.isNumber) { doubleValue -= op.doubleValue; string = std::format("{:.12f}", doubleValue); @@ -258,7 +262,7 @@ namespace jet { throw coreutils::Exception("operand is not a number."); } else if(in.ifNext("*")) { if(isNumber) { - Operand op(in); + Operand op(in, global, lvariables); if(op.isNumber) { doubleValue *= op.doubleValue; string = std::format("{:.12f}", doubleValue); @@ -269,7 +273,7 @@ namespace jet { throw coreutils::Exception("operand is not a number."); } else if(in.ifNext("/")) { if(isNumber) { - Operand op(in); + Operand op(in, global, lvariables); if(op.isNumber) { doubleValue /= op.doubleValue; string = std::format("{:.12f}", doubleValue); diff --git a/Operand.h b/Operand.h index d6550a7..b9aeeb4 100644 --- a/Operand.h +++ b/Operand.h @@ -2,13 +2,14 @@ #define __Operand_h__ #include "MString.h" +#include "Global.h" namespace jet { class Operand { public: - Operand(coreutils::ZString &in); + Operand(coreutils::ZString &in, Global &global, std::map &lvariables); bool isNumber; diff --git a/__header.cpp b/__header.cpp index 13e9d71..6cf0c05 100644 --- a/__header.cpp +++ b/__header.cpp @@ -21,7 +21,7 @@ namespace jet { if(variableDefined("expr")) { if(variableDefined("eval")) 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) { processContainer(container); if(evaluate) { diff --git a/__if.cpp b/__if.cpp index d59de3f..59902cb 100644 --- a/__if.cpp +++ b/__if.cpp @@ -36,7 +36,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."); - booleanResult = Operand(variables["expr"]).boolean; + booleanResult = Operand(variables["expr"], global, parent->variables).boolean; } if(booleanResult) processContainer(container); diff --git a/__set.cpp b/__set.cpp index 707ada9..c7e2114 100644 --- a/__set.cpp +++ b/__set.cpp @@ -24,13 +24,12 @@ namespace jet { resolveKeyword("name"); if(variableDefined("expr")) { - resolveKeyword("expr"); 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") - parent->variables[variables["name"]] = Operand(variables["expr"]).string; + parent->variables[variables["name"]] = Operand(variables["expr"], global, parent->variables).string; 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) { processContainer(container); if(evaluate) { diff --git a/__until.cpp b/__until.cpp index e0e2e9b..ceb575d 100644 --- a/__until.cpp +++ b/__until.cpp @@ -47,7 +47,7 @@ namespace jet { variables["expr"].reset(); variables["expr"] = exprSaved; resolveKeyword("expr"); - booleanResult = Operand(variables["expr"]).boolean; + booleanResult = Operand(variables["expr"], global, parent->variables).boolean; } else { booleanResult = false; int rc = variables["value1"].compare(variables["value2"]); diff --git a/__while.cpp b/__while.cpp index c10829f..13fecaa 100644 --- a/__while.cpp +++ b/__while.cpp @@ -39,8 +39,7 @@ namespace jet { throw coreutils::Exception("type should not be specified with expr."); exprMethod = true; exprSaved = variables["expr"]; - resolveKeyword("expr"); - booleanResult = Operand(variables["expr"]).boolean; + booleanResult = Operand(variables["expr"], global, parent->variables).boolean; } while(booleanResult) { processContainer(container); @@ -48,8 +47,7 @@ namespace jet { if(exprMethod) { variables["expr"].reset(); variables["expr"] = exprSaved; - resolveKeyword("expr"); - booleanResult = Operand(variables["expr"]).boolean; + booleanResult = Operand(variables["expr"], global, parent->variables).boolean; } else { booleanResult = false; int rc = variables["value1"].compare(variables["value2"]); diff --git a/tests/test1.jet b/tests/test1.jet index bddbd46..13a6d83 100755 --- a/tests/test1.jet +++ b/tests/test1.jet @@ -1,4 +1,4 @@ -#!./jet-2.0 +#!../jet-2.0 This is output diff --git a/tests/testdb.jet b/tests/testdb.jet index ccfa8bf..ba6ab88 100755 --- a/tests/testdb.jet +++ b/tests/testdb.jet @@ -1,4 +1,4 @@ -#!./jet-2.0 +#!../jet-2.0 select * from testdata diff --git a/tests/testtag.jet b/tests/testtag.jet index a4c69e9..578376b 100755 --- a/tests/testtag.jet +++ b/tests/testtag.jet @@ -1,13 +1,16 @@ -#!./jet-2.0 +#!../jet-2.0 + x $[ix] + z - + y + \ No newline at end of file diff --git a/tests/testwhile.jet b/tests/testwhile.jet index ad8f82e..a3c3628 100755 --- a/tests/testwhile.jet +++ b/tests/testwhile.jet @@ -1,7 +1,7 @@ #!../jet-2.0 - + -->$[ix]<--