diff --git a/src/aux/aux_compile_line.cpp b/src/aux/aux_compile_line.cpp index 748ff57..69a9bda 100644 --- a/src/aux/aux_compile_line.cpp +++ b/src/aux/aux_compile_line.cpp @@ -5,6 +5,8 @@ // | TODO: comment and format this file properly | // +---------------------------------------------+ +#include "../ldpl.h" + // Compiles line per line void compile_line(vector &tokens, compiler_state &state) { @@ -442,6 +444,24 @@ void compile_line(vector &tokens, compiler_state &state) state.where); return; } + if (line_like("FOR $num-var FROM $num-expr TO $num-expr INCLUSIVE STEP $num-expr DO", tokens, state)) + { + if (!in_procedure_section(state)) + badcode("FOR outside PROCEDURE section", state.where); + state.open_loop(); + string var = get_c_variable(state, tokens[1]); + string from = get_c_expression(state, tokens[3]); + string to = get_c_expression(state, tokens[5]); + string step = get_c_expression(state, tokens[7]); + string init = var + " = " + from; + string condition = + step + " >= 0 ? " + var + " <= " + to + " : " + var + " >= " + to; + string increment = var + " += " + step; + // C++ Code + state.add_code("for (" + init + "; " + condition + "; " + increment + ") {", + state.where); + return; + } if (line_like("FOR EACH $anyVar IN $collection DO", tokens, state)) { if (!in_procedure_section(state)) diff --git a/src/aux/aux_state.cpp b/src/aux/aux_state.cpp index 5fadd80..6e17e5a 100644 --- a/src/aux/aux_state.cpp +++ b/src/aux/aux_state.cpp @@ -1,39 +1,50 @@ /* This file contains auxiliary functions that check the current compilation * state */ -bool is_num_map(string &token, compiler_state &state) { +#include "../ldpl.h" + +bool is_num_map(string &token, compiler_state &state) +{ // -- Returns if the variable is a NUMBER MAP or an access to a multicontainer // that results in a NUMBER MAP -- vector type = variable_type(token, state); - if (type.size() == 2 && type[0] == 1 && type[1] == 4) return true; + if (type.size() == 2 && type[0] == 1 && type[1] == 4) + return true; return false; } -bool is_txt_map(string &token, compiler_state &state) { +bool is_txt_map(string &token, compiler_state &state) +{ // -- Returns if the variable is a TEXT MAP or an access to a multicontainer // that results in a TEXT MAP -- vector type = variable_type(token, state); - if (type.size() == 2 && type[0] == 2 && type[1] == 4) return true; + if (type.size() == 2 && type[0] == 2 && type[1] == 4) + return true; return false; } -bool is_num_list(string &token, compiler_state &state) { +bool is_num_list(string &token, compiler_state &state) +{ // -- Returns if the variable is a NUMBER LIST or an access to a // multicontainer that results in a NUMBER LIST -- vector type = variable_type(token, state); - if (type.size() == 2 && type[0] == 1 && type[1] == 3) return true; + if (type.size() == 2 && type[0] == 1 && type[1] == 3) + return true; return false; } -bool is_txt_list(string &token, compiler_state &state) { +bool is_txt_list(string &token, compiler_state &state) +{ // -- Returns if the variable is a TEXT MAP or an access to a multicontainer // that results in a TEXT MAP -- vector type = variable_type(token, state); - if (type.size() == 2 && type[0] == 2 && type[1] == 3) return true; + if (type.size() == 2 && type[0] == 2 && type[1] == 3) + return true; return false; } -bool is_list_list(string &token, compiler_state &state) { +bool is_list_list(string &token, compiler_state &state) +{ // -- Returns if the variable is a NUMBER/TEXT LIST LIST multicontainer or a // multicontainer access that results in a LIST of LISTs -- vector type = variable_type(token, state); @@ -42,7 +53,8 @@ bool is_list_list(string &token, compiler_state &state) { return false; } -bool is_map_list(string &token, compiler_state &state) { +bool is_map_list(string &token, compiler_state &state) +{ // -- Returns if the variable is a multicontainer NUMBER/TEXT LIST MAP or a // multicontainer access that results in a LIST of MAPs -- vector type = variable_type(token, state); @@ -51,7 +63,8 @@ bool is_map_list(string &token, compiler_state &state) { return false; } -bool is_scalar_map(string &token, compiler_state &state) { +bool is_scalar_map(string &token, compiler_state &state) +{ // -- Returns if the variable is a NUMBER MAP or an access to a multicontainer // that results in a NUMBER MAP -- // -- or if the variable is a TEXT MAP or an access to a multicontainer that @@ -59,7 +72,8 @@ bool is_scalar_map(string &token, compiler_state &state) { return is_num_map(token, state) || is_txt_map(token, state); } -bool is_map_map(string &token, compiler_state &state) { +bool is_map_map(string &token, compiler_state &state) +{ // -- Returns if the variable is a NUMBER/TEXT MAP MAP multicontainer or a // multicontainer access that results in a MAP of MAPs -- vector type = variable_type(token, state); @@ -68,14 +82,16 @@ bool is_map_map(string &token, compiler_state &state) { return false; } -bool is_map(string &token, compiler_state &state) { +bool is_map(string &token, compiler_state &state) +{ // -- Returns true if the variable is a MAP, regardless of a map of what // (multicontainer or not) -- vector type = variable_type(token, state); return type.back() == 4; } -bool is_scalar_list(string &token, compiler_state &state) { +bool is_scalar_list(string &token, compiler_state &state) +{ // -- Returns if the variable is a NUMBER LIST or an access to a // multicontainer that results in a NUMBER LIST -- // -- or if the variable is a TEXT LIST or an access to a multicontainer that @@ -83,65 +99,77 @@ bool is_scalar_list(string &token, compiler_state &state) { return is_num_list(token, state) || is_txt_list(token, state); } -bool is_num_var(string &token, compiler_state &state) { +bool is_num_var(string &token, compiler_state &state) +{ // -- Checks if token is a NUMBER variable (or an access to a container that // results in a NUMBER variable) -- return (variable_type(token, state) == vector{1}); } -bool is_txt_var(string &token, compiler_state &state) { +bool is_txt_var(string &token, compiler_state &state) +{ // -- Checks if token is a TEXT variable (or an access to a container that // results in a TEXT variable) -- return (variable_type(token, state) == vector{2}); } -bool is_scalar_variable(string &token, compiler_state &state) { +bool is_scalar_variable(string &token, compiler_state &state) +{ // -- Returns is an identifier is a valid scalar variable or an access that // results in one -- return is_num_var(token, state) || is_txt_var(token, state); } -bool is_num_expr(string &token, compiler_state &state) { +bool is_num_expr(string &token, compiler_state &state) +{ // -- Returns is an identifier is a valid scalar variable or number or an // access that results in one -- return is_num_var(token, state) || is_number(token); } -bool is_txt_expr(string &token, compiler_state &state) { +bool is_txt_expr(string &token, compiler_state &state) +{ // -- Returns is an identifier is a valid scalar variable or text or an access // that results in one -- return is_txt_var(token, state) || is_string(token); } -bool is_expression(string &token, compiler_state &state) { +bool is_expression(string &token, compiler_state &state) +{ // -- Returns is an identifier is a valid scalar variable or text or number or // an access that results in one -- return is_num_expr(token, state) || is_txt_expr(token, state); } -bool is_external(string &token, compiler_state &state) { +bool is_external(string &token, compiler_state &state) +{ // -- Returns if an identifier maps to an external variable -- return state.externals[token]; } -bool variable_exists(string &token, compiler_state &state) { +bool variable_exists(string &token, compiler_state &state) +{ // -- Returns if a variable has been declared or not -- // (Bear in mind that myList is a variable, myList:0 is not, that's an access // for all this function is concerned) return variable_type(token, state) != vector{0}; } -bool is_subprocedure(string &token, compiler_state &state) { +bool is_subprocedure(string &token, compiler_state &state) +{ // -- Returns if an identifier maps to a valid, existing sub-procedure -- for (auto &subprocedure : state.subprocedures) - if (subprocedure.first == token) return true; + if (subprocedure.first == token) + return true; return false; } -bool in_procedure_section(compiler_state &state) { +bool in_procedure_section(compiler_state &state) +{ // -- Returns if the compiler is currently compiling a procedure section or // not -- - if (state.section_state == 3) { + if (state.section_state == 3) + { // We're inside a SUB-PROCEDURE procedure with no sections state.section_state = 2; open_subprocedure_code(state); @@ -149,7 +177,8 @@ bool in_procedure_section(compiler_state &state) { return state.section_state == 2; } -vector variable_type(string &token, compiler_state &state) { +vector variable_type(string &token, compiler_state &state) +{ // -- Returns the LDPL internal representation of the type of a variable -- // // Return the number of the type or {0} if the variable doesn't exist. This @@ -192,13 +221,17 @@ vector variable_type(string &token, compiler_state &state) { // to discard those indexes that access the other containers and not the one // we are trying to get the types of. size_t tokensToSkip = 0; - for (size_t i = 1; i < tokens.size(); ++i) { + for (size_t i = 1; i < tokens.size(); ++i) + { // If the current token is a scalar literal, we can skip it safely. - if (is_number(tokens[i]) || is_string(tokens[i])) { - if (tokensToSkip > 0) tokensToSkip--; + if (is_number(tokens[i]) || is_string(tokens[i])) + { + if (tokensToSkip > 0) + tokensToSkip--; } // If it's not, then it must be a variable name. - else { + else + { // If the variable doesn't exist in the current context, we rise an error. if (state.variables[state.current_subprocedure].count(tokens[i]) == 0 && state.variables[""].count(tokens[i]) == 0) @@ -211,13 +244,16 @@ vector variable_type(string &token, compiler_state &state) { tokensToSkip += cvar_types.size() - 1; else // If the variable exists and is a scalar, we can skip it - if (tokensToSkip > 0) tokensToSkip--; + if (tokensToSkip > 0) + tokensToSkip--; } - if (tokensToSkip == 0) types.pop_back(); + if (tokensToSkip == 0) + types.pop_back(); } // We return {0} if there is an incomplete container access // that must be complete to resolve as a scalar index - if (tokensToSkip > 0) return {0}; + if (tokensToSkip > 0) + return {0}; // Now we have the types and can return them. return types; } \ No newline at end of file diff --git a/src/ldpl.h b/src/ldpl.h index 6ae1e7a..13f701c 100644 --- a/src/ldpl.h +++ b/src/ldpl.h @@ -1,3 +1,5 @@ +#ifndef LDPL_H +#define LDPL_H /* --- STD Includes --- */ #include #include @@ -97,4 +99,5 @@ void open_subprocedure_code(compiler_state &state); void add_call_code(string &subprocedure, vector ¶meters, compiler_state &state); string current_os(); bool is_map(string &token, compiler_state &state); -void badcode(const string &msg, const code_location where); \ No newline at end of file +void badcode(const string &msg, const code_location where); +#endif \ No newline at end of file