Skip to content

Commit

Permalink
Add FOR ... INCLUSIVE
Browse files Browse the repository at this point in the history
  • Loading branch information
Lartu committed Jun 13, 2024
1 parent 27f5453 commit a3ef4dc
Show file tree
Hide file tree
Showing 3 changed files with 94 additions and 35 deletions.
20 changes: 20 additions & 0 deletions src/aux/aux_compile_line.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,8 @@
// | TODO: comment and format this file properly |
// +---------------------------------------------+

#include "../ldpl.h"

// Compiles line per line
void compile_line(vector<string> &tokens, compiler_state &state)
{
Expand Down Expand Up @@ -442,6 +444,24 @@ void compile_line(vector<string> &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))
Expand Down
104 changes: 70 additions & 34 deletions src/aux/aux_state.cpp
Original file line number Diff line number Diff line change
@@ -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<unsigned int> 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<unsigned int> 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<unsigned int> 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<unsigned int> 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<unsigned int> type = variable_type(token, state);
Expand All @@ -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<unsigned int> type = variable_type(token, state);
Expand All @@ -51,15 +63,17 @@ 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
// results in a TEXT MAP --
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<unsigned int> type = variable_type(token, state);
Expand All @@ -68,88 +82,103 @@ 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<unsigned int> 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
// results in a TEXT LIST --
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<unsigned int>{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<unsigned int>{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<unsigned int>{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);
}
return state.section_state == 2;
}

vector<unsigned int> variable_type(string &token, compiler_state &state) {
vector<unsigned int> 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
Expand Down Expand Up @@ -192,13 +221,17 @@ vector<unsigned int> 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)
Expand All @@ -211,13 +244,16 @@ vector<unsigned int> 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;
}
5 changes: 4 additions & 1 deletion src/ldpl.h
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
#ifndef LDPL_H
#define LDPL_H
/* --- STD Includes --- */
#include <algorithm>
#include <array>
Expand Down Expand Up @@ -97,4 +99,5 @@ void open_subprocedure_code(compiler_state &state);
void add_call_code(string &subprocedure, vector<string> &parameters, compiler_state &state);
string current_os();
bool is_map(string &token, compiler_state &state);
void badcode(const string &msg, const code_location where);
void badcode(const string &msg, const code_location where);
#endif

0 comments on commit a3ef4dc

Please sign in to comment.