diff --git a/src/aux/aux_c_format.cpp b/src/aux/aux_c_format.cpp index 14b2cfb..f3d7abb 100644 --- a/src/aux/aux_c_format.cpp +++ b/src/aux/aux_c_format.cpp @@ -7,323 +7,379 @@ // Given a full variable (with accesses and everything, like foo:0:'hi there' or // bar) returns the C++ representation of said variable in order to be accessed. -string get_c_variable(compiler_state &state, string &variable) { - // We want to get two things in order to create the correct C++ representation - // of a 'full variable': the variable name and all the indexess we are trying - // to access that correspond to this particular variable (because we could - // have foo number list list and bar number list and try to access - // foo:bar:0:1. In this case, we would be interested in getting 'foo', 'bar:0' - // and '1'. - string var_name; - vector indexes; - // We use the split_vector function to get these values into our variables. - split_vector(variable, var_name, indexes, state); - // We 'fix' the variable name, turning all characters not accepted by C++ into - // LDPL codes that C++ does accept. - var_name = fix_identifier(var_name, true, state); - // If split_vector didn't return any indexes, then we are dealing with a - // scalar variable. We just return the C++ variable name and we are done. - if (indexes.empty()) return var_name; - // If our indexes vector is not empty, however, we recreate the correct C++ - // container access, with one dimension for each value in our indexes vector. - for (size_t i = 0; i < indexes.size(); ++i) - var_name += '[' + get_c_expression(state, indexes[i]) + ']'; - // Once we are done, we return the variable name. - return var_name; +string get_c_variable(compiler_state &state, string &variable) +{ + // We want to get two things in order to create the correct C++ representation + // of a 'full variable': the variable name and all the indexess we are trying + // to access that correspond to this particular variable (because we could + // have foo number list list and bar number list and try to access + // foo:bar:0:1. In this case, we would be interested in getting 'foo', 'bar:0' + // and '1'. + string var_name; + vector indexes; + // We use the split_vector function to get these values into our variables. + split_vector(variable, var_name, indexes, state); + // We 'fix' the variable name, turning all characters not accepted by C++ into + // LDPL codes that C++ does accept. + var_name = fix_identifier(var_name, true, state); + // If split_vector didn't return any indexes, then we are dealing with a + // scalar variable. We just return the C++ variable name and we are done. + if (indexes.empty()) + return var_name; + // If our indexes vector is not empty, however, we recreate the correct C++ + // container access, with one dimension for each value in our indexes vector. + for (size_t i = 0; i < indexes.size(); ++i) + var_name += "[" + get_c_expression(state, indexes[i]) + "]"; + // Once we are done, we return the variable name. + return var_name; } -string get_c_expression(compiler_state &state, string &expression) { - if (is_scalar_variable(expression, state) || - variable_exists(expression, state)) - return get_c_variable(state, expression); - is_number(expression); // We fix the expression should it be a number literal - return expression; +string get_c_expression(compiler_state &state, string &expression) +{ + if (is_scalar_variable(expression, state) || variable_exists(expression, state)) + return get_c_variable(state, expression); + is_number(expression); // We fix the expression should it be a number literal + return expression; } // text must be a TEXT or a TEXT variable -string get_c_char_array(compiler_state &state, string &text) { - if (is_txt_var(text, state)) - return get_c_variable(state, text) + ".str_rep().c_str()"; - return text; +string get_c_char_array(compiler_state &state, string &text) +{ + if (is_txt_var(text, state)) + return get_c_variable(state, text) + ".str_rep().c_str()"; + return text; } -string get_c_string(compiler_state &state, string &expression) { - string c_expression = get_c_expression(state, expression); - if (is_num_expr(expression, state)) - return "to_ldpl_string(" + c_expression + ")"; - return c_expression; +string get_c_string(compiler_state &state, string &expression) +{ + string c_expression = get_c_expression(state, expression); + if (is_num_expr(expression, state)) + return "to_ldpl_string(" + c_expression + ")"; + return c_expression; } -string get_c_number(compiler_state &state, string &expression) { - string c_expression = get_c_expression(state, expression); - if (is_txt_expr(expression, state)) return "to_number(" + c_expression + ")"; - return c_expression; +string get_c_number(compiler_state &state, string &expression) +{ + string c_expression = get_c_expression(state, expression); + if (is_txt_expr(expression, state)) + return "to_number(" + c_expression + ")"; + return c_expression; } // Returns [ERROR] if invalid condtion, otherwise returns C++ condition -string get_c_condition(compiler_state &state, vector tokens) { - unsigned int ct = 0; - string condition = get_c_condition(state, tokens, ct); - if (ct < tokens.size()) return "[ERROR]"; - return condition; +string get_c_condition(compiler_state &state, vector tokens) +{ + unsigned int ct = 0; + string condition = get_c_condition(state, tokens, ct); + if (ct < tokens.size()) + return "[ERROR]"; + return condition; } -#define MATCH(x) \ - if (ct < tokens.size() && tokens[ct] == x) \ - ct++; \ - else \ - return "[ERROR]"; +#define MATCH(x) \ + if (ct < tokens.size() && tokens[ct] == x) \ + ct++; \ + else \ + return "[ERROR]"; string get_c_condition(compiler_state &state, vector tokens, - unsigned int &ct) { - if (ct >= tokens.size()) return "[ERROR]"; - string condition; - if (tokens[ct] == "(") { - MATCH("("); - condition = get_c_condition(state, tokens, ct); - if (condition == "[ERROR]") return condition; - MATCH(")"); - condition = "(" + condition + ")"; - } else { - string first_value = tokens[ct]; - string second_value; - string rel_op; - ct++; // We validate the token after we get the second value - if (tokens[ct] == "IS") { - MATCH("IS"); - if (tokens[ct] == "EQUAL") { - MATCH("EQUAL"); - MATCH("TO"); - rel_op = "EQUAL TO"; - } else if (tokens[ct] == "NOT") { - MATCH("NOT"); - MATCH("EQUAL"); - MATCH("TO"); - rel_op = "NOT EQUAL TO"; - } else if (tokens[ct] == "GREATER") { - MATCH("GREATER"); - MATCH("THAN"); - if (ct + 1 < tokens.size() && tokens[ct + 1] == "EQUAL") { - // We check the next token instead of the curent one - // because "OR" could be a variable after "GREATER THAN" - MATCH("OR"); - MATCH("EQUAL"); - MATCH("TO"); - rel_op = "GREATER THAN OR EQUAL TO"; - } else { - rel_op = "GREATER THAN"; - } - } else if (tokens[ct] == "LESS") { - MATCH("LESS"); - MATCH("THAN"); - if (ct + 1 < tokens.size() && tokens[ct + 1] == "EQUAL") { - // We check the next token instead of the curent one - // because "OR" could be a variable after "LESS THAN" - MATCH("OR"); - MATCH("EQUAL"); - MATCH("TO"); - rel_op = "LESS THAN OR EQUAL TO"; - } else { - rel_op = "LESS THAN"; - } - } else { + unsigned int &ct) +{ + if (ct >= tokens.size()) return "[ERROR]"; - } + string condition; + if (tokens[ct] == "(") + { + MATCH("("); + condition = get_c_condition(state, tokens, ct); + if (condition == "[ERROR]") + return condition; + MATCH(")"); + condition = "(" + condition + ")"; + } + else + { + string first_value = tokens[ct]; + string second_value; + string rel_op; + ct++; // We validate the token after we get the second value + if (tokens[ct] == "IS") + { + MATCH("IS"); + if (tokens[ct] == "EQUAL") + { + MATCH("EQUAL"); + MATCH("TO"); + rel_op = "EQUAL TO"; + } + else if (tokens[ct] == "NOT") + { + MATCH("NOT"); + MATCH("EQUAL"); + MATCH("TO"); + rel_op = "NOT EQUAL TO"; + } + else if (tokens[ct] == "GREATER") + { + MATCH("GREATER"); + MATCH("THAN"); + if (ct + 1 < tokens.size() && tokens[ct + 1] == "EQUAL") + { + // We check the next token instead of the curent one + // because "OR" could be a variable after "GREATER THAN" + MATCH("OR"); + MATCH("EQUAL"); + MATCH("TO"); + rel_op = "GREATER THAN OR EQUAL TO"; + } + else + { + rel_op = "GREATER THAN"; + } + } + else if (tokens[ct] == "LESS") + { + MATCH("LESS"); + MATCH("THAN"); + if (ct + 1 < tokens.size() && tokens[ct + 1] == "EQUAL") + { + // We check the next token instead of the curent one + // because "OR" could be a variable after "LESS THAN" + MATCH("OR"); + MATCH("EQUAL"); + MATCH("TO"); + rel_op = "LESS THAN OR EQUAL TO"; + } + else + { + rel_op = "LESS THAN"; + } + } + else + { + return "[ERROR]"; + } - second_value = tokens[ct]; - ++ct; + second_value = tokens[ct]; + ++ct; - string type; - if (is_num_expr(first_value, state) && is_num_expr(second_value, state)) - type = "NUMBER"; - else if (is_txt_expr(first_value, state) && - is_txt_expr(second_value, state)) - type = "TEXT"; - else if (is_num_map(first_value, state) && - is_num_map(second_value, state)) - type = "NUMBER MAP"; - else if (is_txt_map(first_value, state) && - is_txt_map(second_value, state)) - type = "TEXT MAP"; - else if (is_num_list(first_value, state) && - is_num_list(second_value, state)) - type = "NUMBER LIST"; - else if (is_txt_list(first_value, state) && - is_txt_list(second_value, state)) - type = "TEXT LIST"; - else if (is_list_list(first_value, state) && - is_list_list(second_value, state) && - variable_type(first_value, state) == - variable_type(second_value, state)) - type = "LIST LIST"; - else if (is_map_map(first_value, state) && - is_map_map(second_value, state) && - variable_type(first_value, state) == - variable_type(second_value, state)) - type = "MAP MAP"; - else - return "[ERROR]"; + string type; + if (is_num_expr(first_value, state) && is_num_expr(second_value, state)) + type = "NUMBER"; + else if (is_txt_expr(first_value, state) && + is_txt_expr(second_value, state)) + type = "TEXT"; + else if (is_num_map(first_value, state) && + is_num_map(second_value, state)) + type = "NUMBER MAP"; + else if (is_txt_map(first_value, state) && + is_txt_map(second_value, state)) + type = "TEXT MAP"; + else if (is_num_list(first_value, state) && + is_num_list(second_value, state)) + type = "NUMBER LIST"; + else if (is_txt_list(first_value, state) && + is_txt_list(second_value, state)) + type = "TEXT LIST"; + else if (is_list_list(first_value, state) && + is_list_list(second_value, state) && + variable_type(first_value, state) == + variable_type(second_value, state)) + type = "LIST LIST"; + else if (is_map_map(first_value, state) && + is_map_map(second_value, state) && + variable_type(first_value, state) == + variable_type(second_value, state)) + type = "MAP MAP"; + else + return "[ERROR]"; - first_value = get_c_expression(state, first_value); - second_value = get_c_expression(state, second_value); - if (type == "NUMBER") { - if (rel_op == "EQUAL TO") - condition = "num_equal(" + first_value + ", " + second_value + ")"; - else if (rel_op == "NOT EQUAL TO") - condition = "!num_equal(" + first_value + ", " + second_value + ")"; - else if (rel_op == "GREATER THAN") - condition = first_value + " > " + second_value; - else if (rel_op == "LESS THAN") - condition = first_value + " < " + second_value; - else if (rel_op == "GREATER THAN OR EQUAL TO") - condition = "(" + first_value + " > " + second_value + - " || num_equal(" + first_value + ", " + second_value + - "))"; - else - condition = "(" + first_value + " < " + second_value + - " || num_equal(" + first_value + ", " + second_value + - "))"; - } else if (type == "TEXT") { - if (rel_op == "EQUAL TO") - condition = "str_cmp(" + first_value + ", " + second_value + ") == 0"; - else if (rel_op == "NOT EQUAL TO") - condition = "str_cmp(" + first_value + ", " + second_value + ") != 0"; - else if (rel_op == "GREATER THAN") - condition = "str_cmp(" + first_value + ", " + second_value + ") > 0"; - else if (rel_op == "LESS THAN") - condition = "str_cmp(" + first_value + ", " + second_value + ") < 0"; - else if (rel_op == "GREATER THAN OR EQUAL TO") - condition = "str_cmp(" + first_value + ", " + second_value + ") >= 0"; - else if (rel_op == "LESS THAN OR EQUAL TO") - condition = "str_cmp(" + first_value + ", " + second_value + ") <= 0"; + first_value = get_c_expression(state, first_value); + second_value = get_c_expression(state, second_value); + if (type == "NUMBER") + { + if (rel_op == "EQUAL TO") + condition = "num_equal(" + first_value + ", " + second_value + ")"; + else if (rel_op == "NOT EQUAL TO") + condition = "!num_equal(" + first_value + ", " + second_value + ")"; + else if (rel_op == "GREATER THAN") + condition = first_value + " > " + second_value; + else if (rel_op == "LESS THAN") + condition = first_value + " < " + second_value; + else if (rel_op == "GREATER THAN OR EQUAL TO") + condition = "(" + first_value + " > " + second_value + + " || num_equal(" + first_value + ", " + second_value + + "))"; + else + condition = "(" + first_value + " < " + second_value + + " || num_equal(" + first_value + ", " + second_value + + "))"; + } + else if (type == "TEXT") + { + if (rel_op == "EQUAL TO") + condition = "str_cmp(" + first_value + ", " + second_value + ") == 0"; + else if (rel_op == "NOT EQUAL TO") + condition = "str_cmp(" + first_value + ", " + second_value + ") != 0"; + else if (rel_op == "GREATER THAN") + condition = "str_cmp(" + first_value + ", " + second_value + ") > 0"; + else if (rel_op == "LESS THAN") + condition = "str_cmp(" + first_value + ", " + second_value + ") < 0"; + else if (rel_op == "GREATER THAN OR EQUAL TO") + condition = "str_cmp(" + first_value + ", " + second_value + ") >= 0"; + else if (rel_op == "LESS THAN OR EQUAL TO") + condition = "str_cmp(" + first_value + ", " + second_value + ") <= 0"; + else + return "[ERROR]"; + } + else + { + first_value += ".inner_collection"; + second_value += ".inner_collection"; + if (rel_op == "EQUAL TO") + condition = first_value + " == " + second_value; + else if (rel_op == "NOT EQUAL TO") + condition = first_value + " != " + second_value; + else // >, >, <= and >= are only valid in NUMBER and TEXT + return "[ERROR]"; + } + } else - return "[ERROR]"; - } else { - first_value += ".inner_collection"; - second_value += ".inner_collection"; - if (rel_op == "EQUAL TO") - condition = first_value + " == " + second_value; - else if (rel_op == "NOT EQUAL TO") - condition = first_value + " != " + second_value; - else // >, >, <= and >= are only valid in NUMBER and TEXT - return "[ERROR]"; - } - } else { - if (tokens[ct] == "IN") { - MATCH("IN"); - rel_op = "IN"; - } else if (tokens[ct] == "NOT") { - MATCH("NOT"); - MATCH("IN"); - rel_op = "NOT IN"; - } + { + if (tokens[ct] == "IN") + { + MATCH("IN"); + rel_op = "IN"; + } + else if (tokens[ct] == "NOT") + { + MATCH("NOT"); + MATCH("IN"); + rel_op = "NOT IN"; + } - second_value = tokens[ct]; - ++ct; - string type; - if (is_num_expr(first_value, state) && is_num_list(second_value, state)) - type = "NUM-IN-NUM-LIST"; - else if (is_num_expr(first_value, state) && - is_txt_list(second_value, state)) - type = "NUM-IN-TEXT-LIST"; - else if (is_txt_expr(first_value, state) && - is_num_list(second_value, state)) - type = "TEXT-IN-NUM-LIST"; - else if (is_txt_expr(first_value, state) && - is_txt_list(second_value, state)) - type = "TEXT-IN-TEXT-LIST"; - else if (is_num_expr(first_value, state) && is_map(second_value, state)) - type = "NUM-IN-MAP"; - else if (is_string(first_value) && is_map(second_value, state)) - type = "STR-IN-MAP"; - else if (is_txt_var(first_value, state) && is_map(second_value, state)) - type = "TEXTVAR-IN-MAP"; - else - return "[ERROR]"; + second_value = tokens[ct]; + ++ct; + string type; + if (is_num_expr(first_value, state) && is_num_list(second_value, state)) + type = "NUM-IN-NUM-LIST"; + else if (is_num_expr(first_value, state) && + is_txt_list(second_value, state)) + type = "NUM-IN-TEXT-LIST"; + else if (is_txt_expr(first_value, state) && + is_num_list(second_value, state)) + type = "TEXT-IN-NUM-LIST"; + else if (is_txt_expr(first_value, state) && + is_txt_list(second_value, state)) + type = "TEXT-IN-TEXT-LIST"; + else if (is_num_expr(first_value, state) && is_map(second_value, state)) + type = "NUM-IN-MAP"; + else if (is_string(first_value) && is_map(second_value, state)) + type = "STR-IN-MAP"; + else if (is_txt_var(first_value, state) && is_map(second_value, state)) + type = "TEXTVAR-IN-MAP"; + else + return "[ERROR]"; - first_value = get_c_expression(state, first_value); - second_value = get_c_expression(state, second_value); - if (type == "NUM-IN-NUM-LIST") { - if (rel_op == "IN") - condition = "find(" + second_value + ".inner_collection.begin(), " + - second_value + ".inner_collection.end(), (ldpl_number) " + - first_value + ") != " + second_value + - ".inner_collection.end()"; - else if (rel_op == "NOT IN") - condition = "find(" + second_value + ".inner_collection.begin(), " + - second_value + ".inner_collection.end(), (ldpl_number) " + - first_value + ") == " + second_value + - ".inner_collection.end()"; - } else if (type == "TEXT-IN-NUM-LIST") { - if (rel_op == "IN") - condition = "find(" + second_value + ".inner_collection.begin(), " + - second_value + ".inner_collection.end(), to_number(" + - first_value + ")) != " + second_value + - ".inner_collection.end()"; - else if (rel_op == "NOT IN") - condition = "find(" + second_value + ".inner_collection.begin(), " + - second_value + ".inner_collection.end(), to_number(" + - first_value + ")) == " + second_value + - ".inner_collection.end()"; - } else if (type == "NUM-IN-TEXT-LIST") { - if (rel_op == "IN") - condition = "find(" + second_value + ".inner_collection.begin(), " + - second_value + - ".inner_collection.end(), to_ldpl_string(" + first_value + - ")) != " + second_value + ".inner_collection.end()"; - else if (rel_op == "NOT IN") - condition = "find(" + second_value + ".inner_collection.begin(), " + - second_value + - ".inner_collection.end(), to_ldpl_string(" + first_value + - ")) == " + second_value + ".inner_collection.end()"; - } else if (type == "TEXT-IN-TEXT-LIST") { - if (rel_op == "IN") - condition = "find(" + second_value + ".inner_collection.begin(), " + - second_value + ".inner_collection.end(), " + first_value + - ") != " + second_value + ".inner_collection.end()"; - else if (rel_op == "NOT IN") - condition = "find(" + second_value + ".inner_collection.begin(), " + - second_value + ".inner_collection.end(), " + first_value + - ") == " + second_value + ".inner_collection.end()"; - } else if (type == "NUM-IN-MAP") { - if (rel_op == "IN") - condition = second_value + ".inner_collection.find(to_ldpl_string(" + - first_value + ").str_rep()) != " + second_value + - ".inner_collection.end()"; - else if (rel_op == "NOT IN") - condition = second_value + ".inner_collection.find(to_ldpl_string(" + - first_value + ").str_rep()) == " + second_value + - ".inner_collection.end()"; - } else if (type == "STR-IN-MAP") { - if (rel_op == "IN") - condition = second_value + ".inner_collection.find(" + first_value + - ") != " + second_value + ".inner_collection.end()"; - else if (rel_op == "NOT IN") - condition = second_value + ".inner_collection.find(" + first_value + - ") == " + second_value + ".inner_collection.end()"; - } else if (type == "TEXTVAR-IN-MAP") { - if (rel_op == "IN") - condition = second_value + ".inner_collection.find(" + first_value + - ".str_rep()) != " + second_value + - ".inner_collection.end()"; - else if (rel_op == "NOT IN") - condition = second_value + ".inner_collection.find(" + first_value + - ".str_rep()) == " + second_value + - ".inner_collection.end()"; - } else - return "[ERROR]"; - } + first_value = get_c_expression(state, first_value); + second_value = get_c_expression(state, second_value); + if (type == "NUM-IN-NUM-LIST") + { + if (rel_op == "IN") + condition = "find(" + second_value + ".inner_collection.begin(), " + + second_value + ".inner_collection.end(), (ldpl_number) " + + first_value + ") != " + second_value + + ".inner_collection.end()"; + else if (rel_op == "NOT IN") + condition = "find(" + second_value + ".inner_collection.begin(), " + + second_value + ".inner_collection.end(), (ldpl_number) " + + first_value + ") == " + second_value + + ".inner_collection.end()"; + } + else if (type == "TEXT-IN-NUM-LIST") + { + if (rel_op == "IN") + condition = "find(" + second_value + ".inner_collection.begin(), " + + second_value + ".inner_collection.end(), to_number(" + + first_value + ")) != " + second_value + + ".inner_collection.end()"; + else if (rel_op == "NOT IN") + condition = "find(" + second_value + ".inner_collection.begin(), " + + second_value + ".inner_collection.end(), to_number(" + + first_value + ")) == " + second_value + + ".inner_collection.end()"; + } + else if (type == "NUM-IN-TEXT-LIST") + { + if (rel_op == "IN") + condition = "find(" + second_value + ".inner_collection.begin(), " + + second_value + + ".inner_collection.end(), to_ldpl_string(" + first_value + + ")) != " + second_value + ".inner_collection.end()"; + else if (rel_op == "NOT IN") + condition = "find(" + second_value + ".inner_collection.begin(), " + + second_value + + ".inner_collection.end(), to_ldpl_string(" + first_value + + ")) == " + second_value + ".inner_collection.end()"; + } + else if (type == "TEXT-IN-TEXT-LIST") + { + if (rel_op == "IN") + condition = "find(" + second_value + ".inner_collection.begin(), " + + second_value + ".inner_collection.end(), " + first_value + + ") != " + second_value + ".inner_collection.end()"; + else if (rel_op == "NOT IN") + condition = "find(" + second_value + ".inner_collection.begin(), " + + second_value + ".inner_collection.end(), " + first_value + + ") == " + second_value + ".inner_collection.end()"; + } + else if (type == "NUM-IN-MAP") + { + if (rel_op == "IN") + condition = second_value + ".inner_collection.find(to_ldpl_string(" + + first_value + ").str_rep()) != " + second_value + + ".inner_collection.end()"; + else if (rel_op == "NOT IN") + condition = second_value + ".inner_collection.find(to_ldpl_string(" + + first_value + ").str_rep()) == " + second_value + + ".inner_collection.end()"; + } + else if (type == "STR-IN-MAP") + { + if (rel_op == "IN") + condition = second_value + ".inner_collection.find(" + first_value + + ") != " + second_value + ".inner_collection.end()"; + else if (rel_op == "NOT IN") + condition = second_value + ".inner_collection.find(" + first_value + + ") == " + second_value + ".inner_collection.end()"; + } + else if (type == "TEXTVAR-IN-MAP") + { + if (rel_op == "IN") + condition = second_value + ".inner_collection.find(" + first_value + + ".str_rep()) != " + second_value + + ".inner_collection.end()"; + else if (rel_op == "NOT IN") + condition = second_value + ".inner_collection.find(" + first_value + + ".str_rep()) == " + second_value + + ".inner_collection.end()"; + } + else + return "[ERROR]"; + } - if (ct < tokens.size() && (tokens[ct] == "AND" || tokens[ct] == "OR")) { - if (tokens[ct] == "AND") - condition += " && "; - else if (tokens[ct] == "OR") - condition += " || "; - ++ct; - string next_condition = get_c_condition(state, tokens, ct); - if (next_condition == "[ERROR]") return next_condition; - condition += next_condition; + if (ct < tokens.size() && (tokens[ct] == "AND" || tokens[ct] == "OR")) + { + if (tokens[ct] == "AND") + condition += " && "; + else if (tokens[ct] == "OR") + condition += " || "; + ++ct; + string next_condition = get_c_condition(state, tokens, ct); + if (next_condition == "[ERROR]") + return next_condition; + condition += next_condition; + } } - } - return condition; + return condition; } \ No newline at end of file diff --git a/src/ldpl_lib/ldpl_lib.cpp b/src/ldpl_lib/ldpl_lib.cpp index 71e14ca..e98f5ea 100644 --- a/src/ldpl_lib/ldpl_lib.cpp +++ b/src/ldpl_lib/ldpl_lib.cpp @@ -59,6 +59,11 @@ class LdplNumber integerValue = v; isInteger = true; } + LdplNumber(size_t v) + { + integerValue = v; + isInteger = true; + } LdplNumber(long long v) { integerValue = v; @@ -465,7 +470,7 @@ class LdplNumber } else if (!isInteger && !other.isInteger) { - return floatingValue > other.floatingValue; + return floatingValue < other.floatingValue; } else { @@ -487,28 +492,57 @@ class LdplNumber bool operator<=(const LdplNumber &other) const { - return (*this < other || *this == other); + return *this < other || *this == other; } bool operator>=(const LdplNumber &other) const { - return (*this > other || *this == other); + return *this > other || *this == other; } - // Stream insertion operator - friend std::ostream &operator<<(std::ostream &os, const LdplNumber &num) + friend bool operator<(int lhs, const LdplNumber &rhs) { - if (num.isInteger) - { - os << num.integerValue; - } - else - { - os << num.floatingValue; - } - return os; + return LdplNumber(lhs) < rhs; + } + + friend bool operator>(int lhs, const LdplNumber &rhs) + { + return LdplNumber(lhs) > rhs; + } + + friend bool operator<=(int lhs, const LdplNumber &rhs) + { + return LdplNumber(lhs) <= rhs; + } + + friend bool operator>=(int lhs, const LdplNumber &rhs) + { + return LdplNumber(lhs) >= rhs; } + friend bool operator<(double lhs, const LdplNumber &rhs) + { + return LdplNumber(lhs) < rhs; + } + + friend bool operator>(double lhs, const LdplNumber &rhs) + { + return LdplNumber(lhs) > rhs; + } + + friend bool operator<=(double lhs, const LdplNumber &rhs) + { + return LdplNumber(lhs) <= rhs; + } + + friend bool operator>=(double lhs, const LdplNumber &rhs) + { + return LdplNumber(lhs) >= rhs; + } + + // Stream insertion operator + friend std::ostream &operator<<(std::ostream &os, const LdplNumber &num); + // Stream extraction operator friend std::istream &operator>>(std::istream &is, LdplNumber &num) { @@ -589,6 +623,46 @@ class LdplNumber { return floatingValue; } + + friend LdplNumber operator*(int lhs, const LdplNumber &rhs) { + return LdplNumber(lhs) * rhs; + } + + friend LdplNumber operator+(int lhs, const LdplNumber &rhs) { + return LdplNumber(lhs) + rhs; + } + + friend LdplNumber operator-(int lhs, const LdplNumber &rhs) { + return LdplNumber(lhs) - rhs; + } + + friend LdplNumber operator/(int lhs, const LdplNumber &rhs) { + return LdplNumber(lhs) / rhs; + } + + friend LdplNumber operator%(int lhs, const LdplNumber &rhs) { + return LdplNumber(lhs) % rhs; + } + + friend LdplNumber operator*(double lhs, const LdplNumber &rhs) { + return LdplNumber(lhs) * rhs; + } + + friend LdplNumber operator+(double lhs, const LdplNumber &rhs) { + return LdplNumber(lhs) + rhs; + } + + friend LdplNumber operator-(double lhs, const LdplNumber &rhs) { + return LdplNumber(lhs) - rhs; + } + + friend LdplNumber operator/(double lhs, const LdplNumber &rhs) { + return LdplNumber(lhs) / rhs; + } + + friend LdplNumber operator%(double lhs, const LdplNumber &rhs) { + return LdplNumber(lhs) % rhs; + } }; LdplNumber floor(LdplNumber a) @@ -636,12 +710,12 @@ class graphemedText string str_rep() const; graphemedText(); graphemedText(const string &x); - graphemedText(const double &f); + explicit graphemedText(const double &f); graphemedText &operator=(const string &x); graphemedText(const char *x); graphemedText &operator=(const char *x); graphemedText(const char *x, size_t len); - graphemedText(char x); + explicit graphemedText(char x); graphemedText &operator=(char x); string operator[](size_t i); // string operator[](int i); @@ -692,7 +766,7 @@ bool operator==(const graphemedText &ch1, const char c2); bool operator<(const graphemedText &c1, const graphemedText &c2); bool operator>(const graphemedText &c1, const graphemedText &c2); bool operator!=(const graphemedText &ch1, const graphemedText &ch2); -graphemedText to_ldpl_string(double x); +graphemedText to_ldpl_string(ldpl_number x); #endif void graphemedText::regenerateGraphemeIndex() @@ -1148,11 +1222,10 @@ ifstream file_loading_stream; ofstream file_writing_stream; string file_loading_line; ldpl_number VAR_ERRORCODE = 0; -graphemedText VAR_ERRORTEXT = ""; +graphemedText VAR_ERRORTEXT = (string) ""; ldpl_text joinvar; // Generic temporary use text variable (used by join but can be // Forward declarations -graphemedText to_ldpl_string(ldpl_number x); graphemedText trimCopy(graphemedText _line); #ifndef LDPLMAP @@ -1163,6 +1236,7 @@ struct ldpl_map unordered_map inner_collection; T &operator[](graphemedText i); T &operator[](ldpl_number i); + T &operator[](int i); bool operator==(const ldpl_map &map2) const; }; #endif @@ -1179,6 +1253,12 @@ T &ldpl_map::operator[](graphemedText i) return inner_collection[i.str_rep()]; } +template +T &ldpl_map::operator[](int i) +{ + return inner_collection[to_ldpl_string(i).str_rep()]; +} + template T &ldpl_map::operator[](ldpl_number i) { @@ -1212,7 +1292,7 @@ T &ldpl_list::operator[](ldpl_number i) << inner_collection.size() << ")" << endl; exit(1); } - return inner_collection[i]; + return inner_collection[i.to_size_t()]; } template @@ -1343,10 +1423,10 @@ ldpl_number get_char_num(graphemedText chr) graphemedText getAsciiChar(ldpl_number value) { if (value < 0) - return "?"; + return (string) "?"; if (value > 127) - return "?"; - return (char)value; + return (string) "?"; + return graphemedText((char)(value.to_int())); } void join(const graphemedText &a, const graphemedText &b, graphemedText &c) @@ -1365,13 +1445,19 @@ graphemedText charat(graphemedText &s, ldpl_number pos) // https://stackoverflow.com/questions/13686482/ graphemedText to_ldpl_string(ldpl_number x) { - ostringstream out; - out.precision(10); - out << fixed << x; - string str = out.str(); - str.erase(str.find_last_not_of('0') + 1, string::npos); - str.erase(str.find_last_not_of('.') + 1, string::npos); - return str; + if (x.IsInteger()) + { + return x.internalIntegerValue().to_string(); + } + else + { + ostringstream out; + out << fixed << setprecision(5) << x.to_double(); + string str = out.str(); + str.erase(str.find_last_not_of('0') + 1, string::npos); + str.erase(str.find_last_not_of('.') + 1, string::npos); + return str; + } } #include @@ -1677,3 +1763,17 @@ void utf8_split_list(ldpl_list &result, graphemedText haystack, g result.inner_collection.push_back(charat(haystack, i)); } } + +// Stream insertion operator +std::ostream &operator<<(std::ostream &os, const LdplNumber &num) +{ + if (num.isInteger) + { + os << num.integerValue.to_string(); + } + else + { + os << to_ldpl_string(num.floatingValue); + } + return os; +}