Descripción de la estructuras - PabloNaranjo78/Proyecto_1_Datos_2 GitHub Wiki

La base de todo, la lista enlazada simple

Como una breve descripción de la estructura de datos de la lista enlazada simple, esta estructura presenta múltiples nodo vinculados entre sí por medio de referencias de memoria hacia el nodo siguiente, para este caso. Dichos nodos almacenan valores y se accede a los mismos por medio de la lista.

Con el fin de facilitar el manejo de datos y la amplia cantidad de atributos que debe poseer cada variable, se decidió manejar por medio de una lista enlazada simple genérica, cuyo nodo puede almacenar cualquier tipo de dato o de referencia. Esto facilita muchísimo la disposición de la memoria de forma ordenada y bastante simplificada por el hecho de trabajar sobre listas de genéricos. Además, al utilizar lista completamente personalizadas, se mejora bastante los procesos como la agregación de datos, direcciones de memoria, indicadores de referencia, niveles del código desde los que se accede, entre otros.

template <class T>
class Node {
public:
    T * dir;
    bool init = false;
    string identifier;
    struct Node * next = NULL;
    ReferenceList * refs = new ReferenceList();
    T data;
    T * data_ref;
    bool ref;
};

(Clase Nodo)

void add(string id, T data, bool ref) {
    cout << "Agregando data" << endl;
    Node<T> * newNode = new Node<T>;
    if (this->head == NULL){
        this->head = newNode;
    }else{
        Node<T> * tmp = head;
        while(tmp->next != NULL){
            cout << "buscando..." << endl;
            tmp = tmp->next;
        }
        tmp->next = newNode;
    }

    if (!ref){
        newNode->dir = (T*)malloc(sizeof(data));
        newNode->data = data;
        * newNode->dir = newNode->data;
    }else{
        cout << "Here 2" << endl;
        newNode->dir = (T*)malloc(sizeof(data));
        newNode->data_ref = NULL;
    }
    newNode->ref = ref;
    newNode->identifier = id;
}

(Operacion de agregacion personalizada)

Unificando el acceso a la lista

En este proyecta se busca realizar un mapeo de memoria (consultar sección de algoritmos) bastante subdivido internamente pero con una interfaz simplificada. La forma en que se unifican las listas que contienen cada tipo permitido se puede observar en la clase "MemoryLayout", en la que se unen los 5 tipos de listas, contenidas en cada gestor de memoria, en otra lista enlazada que representa el total de la memoria. Esta estructura lleva referencias a los niveles o capas de memoria generadas por la declaración de scopes en el código. De esta forma, la clase MemoryLayout, con referencia al nivel en el que se quiere operar, envía los datos al gestor de memoria específico para que este seleccione la lista apropiada, según el tipo de dato, y que en esta se genere la salida esperada.

MemoryManager * MemoryLayout::addLevel() {
    this->lvl ++;
    MemoryManager * tmp = this->head;
    MemoryManager * to_return = NULL;
    if (tmp == NULL){
        tmp = new MemoryManager(this->lvl);
        this->head = tmp;
        this->head->lvl = this->lvl;
        to_return = tmp;
    }else{
        while (tmp->next != NULL){
            tmp = tmp->next;
        }
        tmp->next = new MemoryManager(this->lvl);
        tmp->next->lvl = this->lvl;
        to_return = tmp->next;
    }
    cout << "Level added lvl: " << this->lvl << endl;
    return to_return;
}

(Agregación de un nivel/capa de memoria)

Manejo de información por medio de Json

Al momento de enviar información por medio de los sockets, se emplea la estructura de un json, esto facilita la obteción de la información de forma específica cuando el IDE requiere leer una parte u otra, esto porque el resultado del análisis del código por parte del Intérprete(Servidor) se obtienen diferentes parámetros, como la cantidad de líneas leídas, la dirección de memoria en la que se guardó, el valor que guarda esta dirección, la etiqueta asignada, el conteo de referencias y las salidas a consola estándar. La estructura que sigue el json es la siguiente:

JsonManager::JsonManager() {

    list["lineCounter"];
    list["ramDir"]={};
    list["ramValue"] = {};
    list["ramTag"] = {};
    list["ramRef"] = {};
    list["stdOutText"] = {};
    list["logText"] = {};
}

De esta forma, se crea un json con esa estructura y luego se van concatenando los demás resultados de las otras líneas que se van leyendo mediante el siguiente método:

void JsonManager::addDatatoJson(int _counter, string ramDir, string ramValue, string ramTag, string ramRef,
                                  string logText, string stdoutText) {

    counter+= _counter;
    list["ramDir"]+= ramDir;
    list["ramValue"] += ramValue;
    list["ramTag"] += ramTag;
    list["ramRef"] += ramRef;
    list["stdOutText"] += stdoutText;
    list["logText"] += logText;
}

Así luego el IDE(Cliente) va leyendo las líneas con sus respectivos resultados, un ejemplo de ello, es cuando se da al botón "Run", que lee todas las líneas y muestra todos los resultados, este lee el json de la siguiente forma:

void CodeEditor::jsonInterpreter(string inData) {

    json inDataJson = json::parse(inData);
    int counter= inDataJson["lineCounter"];
    for (int i = 0; i < counter;i++){
        setRamText(inDataJson["ramDir"][i],inDataJson["ramValue"][i],inDataJson["ramTag"][i],inDataJson["ramRef"][i]);
        setLogText(inDataJson["logText"][i]);
        setSTDOutText(inDataJson["stdOutText"][i]);

    }

}

Este ya recibe un string desde el resultado del envío del Cliente(IDE), por lo que realiza un parseo del dato en forma de string a un json, entonces, luego obtiene el dato de cuantas líneas se leyeron y mediante un ciclo for va agregando todos los resultados de las líneas, de esta misma manera funcionaría el botón de Debug, solo que en vez de correr todas las líneas, va consultando y analizando de forma individual.

⚠️ **GitHub.com Fallback** ⚠️