/* * @DESC: Lee dos bytes desde el pc del tcb, efectua operacion con ambos y los guarda en registro 'a'. * Cada byte es una letra de un registro. * Busca el valor del registro. */ resultado_t _funcion_operacion(tcb_t* tcb, int32_t operacion(int32_t, int32_t), int32_t condicion(int32_t), char* nombre) { char registro1, registro2; if (leer_registro(tcb, ®istro1) == FALLO_LECTURA_DE_MEMORIA) return ERROR_EN_EJECUCION; if (leer_registro(tcb, ®istro2) == FALLO_LECTURA_DE_MEMORIA) return ERROR_EN_EJECUCION; ansisop_ejecucion_instruccion6(nombre, registro1, registro2); int32_t valor_del_registro_1, valor_del_registro_2; if (obtener_valor_del_registro(tcb, registro1, &valor_del_registro_1) == EXCEPCION_NO_ENCONTRO_EL_REGISTRO) return ERROR_EN_EJECUCION; if (obtener_valor_del_registro(tcb, registro2, &valor_del_registro_2) == EXCEPCION_NO_ENCONTRO_EL_REGISTRO) return ERROR_EN_EJECUCION; if (condicion(valor_del_registro_2)) return ERROR_EN_EJECUCION; actualizar_registro_a(tcb, operacion(valor_del_registro_1, valor_del_registro_2)); return OK; }
/* * void sentencia(void) * Analiza un bloque de sentencias */ void sentencia(void) { int im1, im2, im3, im4; int dir, from, to, step; while (pieza >= p_return) { test_buffer(&mem, &imem_max, imem); switch (pieza) { case p_return: inicio_sentencia(); lexico(); if (pieza == p_abrir) { lexico(); if (pieza != p_cerrar) { expresion(); if (pieza != p_cerrar) error(3, 18); /* esperando ')' */ g1(lrtf); } else { g1(lret); } lexico(); } else { g1(lret); } if (!free_sintax) if (pieza != p_ptocoma) error(3, 9); /* esperando ';' */ while (pieza == p_ptocoma || pieza == p_coma) lexico(); final_sentencia(); grabar_sentencia(); break; case p_if: telseif[itelseif++] = 0; inicio_sentencia(); lexico(); if (!free_sintax) if (pieza != p_abrir) error(3, 22); /* esperando '(' */ if (pieza == p_abrir) lexico(); condicion(); if (!free_sintax) if (pieza != p_cerrar) error(3, 18); /* esperando ')' */ if (pieza == p_cerrar) lexico(); g2(ljpf, 0); im1 = imem - 1; final_sentencia(); grabar_sentencia(); if1: sentencia(); if (pieza == p_else) { inicio_sentencia(); lexico(); g2(ljmp, 0); mem[im1] = imem; im1 = imem - 1; final_sentencia(); grabar_sentencia(); sentencia(); } else if (pieza == p_elseif) { if (itelseif == 0) error(0, 73); /* elseif fuera de bloque if */ inicio_sentencia(); g2(ljmp, 0); telseif[itelseif++] = imem - 1; mem[im1] = imem; lexico(); if (!free_sintax) if (pieza != p_abrir) error(3, 22); /* esperando '(' */ if (pieza == p_abrir) lexico(); condicion(); if (!free_sintax) if (pieza != p_cerrar) error(3, 18); /* esperando ')' */ if (pieza == p_cerrar) lexico(); g2(ljpf, 0); im1 = imem - 1; final_sentencia(); grabar_sentencia(); goto if1; } mem[im1] = imem; if (pieza != p_end) error(0, 57); lexico(); /* esperando END */ while (telseif[--itelseif] != 0) mem[telseif[itelseif]] = imem; break; case p_loop: tbreak[itbreak++] = 0; tcont[itcont++] = 0; lexico(); im1 = imem; sentencia(); if (pieza != p_end) error(0, 57); /* esperando END */ inicio_sentencia(); lexico(); g2(ljmp, im1); while (tbreak[--itbreak] != 0) mem[tbreak[itbreak]] = imem; while (tcont[--itcont] != 0) mem[tcont[itcont]] = im1; final_sentencia(); grabar_sentencia(); break; case p_while: inicio_sentencia(); tbreak[itbreak++] = 0; tcont[itcont++] = 0; im1 = imem; lexico(); if (!free_sintax) if (pieza != p_abrir) error(3, 22); /* esperando '(' */ if (pieza == p_abrir) lexico(); condicion(); if (!free_sintax) if (pieza != p_cerrar) error(3, 18); /* esperando ')' */ if (pieza == p_cerrar) lexico(); g2(ljpf, 0); im2 = imem - 1; final_sentencia(); grabar_sentencia(); sentencia(); if (pieza != p_end) error(0, 57); inicio_sentencia(); /* esperando END */ lexico(); g2(ljmp, im1); mem[im2] = imem; while (tbreak[--itbreak] != 0) mem[tbreak[itbreak]] = imem; while (tcont[--itcont] != 0) mem[tcont[itcont]] = im1; final_sentencia(); grabar_sentencia(); break; case p_repeat: tbreak[itbreak++] = 0; tcont[itcont++] = 0; lexico(); im1 = imem; sentencia(); if (pieza != p_until) error(0, 58); /* esperando UNTIL */ inicio_sentencia(); lexico(); if (!free_sintax) if (pieza != p_abrir) error(3, 22); /* esperando '(' */ if (pieza == p_abrir) lexico(); condicion(); if (!free_sintax) if (pieza != p_cerrar) error(3, 18); /* esperando ')' */ if (pieza == p_cerrar) lexico(); g2(ljpf, im1); while (tbreak[--itbreak] != 0) mem[tbreak[itbreak]] = imem; while (tcont[--itcont] != 0) mem[tcont[itcont]] = im1; final_sentencia(); grabar_sentencia(); break; case p_from: inicio_sentencia(); tbreak[itbreak++] = 0; tcont[itcont++] = 0; lexico(); if (pieza != p_id) error(0, 59); /* esperando una variable */ if (o->tipo == tvglo) { dir = o->vglo.offset; g2(lcar, dir); } else if (o->tipo == tvloc && (!o->bloque || o->bloque == bloque_actual)) { dir = -o->vloc.offset; g2(lcar, -dir); g1(laid); } else error(0, 59); /* esperando una variable */ lexico(); if (pieza != p_asig) error(3, 7); lexico(); /* esperando '=' */ from = constante(); if (pieza != p_to) error(1, 60); lexico(); /* esperando TO */ to = constante(); if (from == to) error(4, 61); /* sentencia FROM incorrecta */ if (pieza == p_step) { lexico(); step = constante(); if (from < to && step <= 0) error(4, 62); /* el valor step no es válido */ if (from > to && step >= 0) error(4, 62); } else { if (from < to) step = 1; else step = -1; } g2(lcar, from); /* Asignación del from */ g1(lasi); g1(lasp); im1 = imem; /* Inicio del bucle */ if (dir >= 0) { /* Comparación de la condición de permanencia */ g2(lcar, dir); } else { g2(lcar, -dir); g1(laid); } g1(lptr); g2(lcar, to); if (step > 0) g1(lmei); else g1(lmai); g2(ljpf, 0); im2 = imem - 1; final_sentencia(); grabar_sentencia(); if (!free_sintax) if (pieza != p_ptocoma) error(3, 9); /* esperando ';' */ while (pieza == p_ptocoma || pieza == p_coma) lexico(); sentencia(); if (pieza != p_end) error(0, 57); inicio_sentencia(); /* esperando END */ lexico(); im3 = imem; /* Posición del continue */ if (dir >= 0) { /* Incremento y vuelta al inicio del bucle */ g2(lcar, dir); } else { g2(lcar, -dir); g1(laid); } g2(lcar, step); g1(lada); g1(lasp); g2(ljmp, im1); mem[im2] = imem; while (tbreak[--itbreak] != 0) mem[tbreak[itbreak]] = imem; while (tcont[--itcont] != 0) mem[tcont[itcont]] = im3; final_sentencia(); grabar_sentencia(); break; case p_for: inicio_sentencia(); tbreak[itbreak++] = 0; tcont[itcont++] = 0; lexico(); if (pieza != p_abrir) error(3, 22); lexico(); /* esperando '(' */ if (pieza != p_ptocoma) { expresion(); g1(lasp); while (pieza == p_coma) { lexico(); expresion(); g1(lasp); } } im1 = imem; if (pieza != p_ptocoma) error(3, 9); lexico(); /* esperando ';' */ if (pieza == p_ptocoma) { g2(lcar, 1); } else expresion(); g2(ljpf, 0); im2 = imem - 1; while (pieza == p_coma) { lexico(); expresion(); g2(ljpf, im2); im2 = imem - 1; } g2(ljmp, 0); im3 = imem - 1; if (pieza != p_ptocoma) error(3, 9); lexico(); /* esperando ';' */ if (pieza != p_cerrar) { expresion(); g1(lasp); while (pieza == p_coma) { lexico(); expresion(); g1(lasp); } } g2(ljmp, im1); if (pieza != p_cerrar) error(3, 18); lexico(); /* esperando ')' */ final_sentencia(); grabar_sentencia(); mem[im3++] = imem; sentencia(); if (pieza != p_end) error(0, 57); /* esperando END */ inicio_sentencia(); lexico(); g2(ljmp, im3); do { im1 = mem[im2]; mem[im2] = imem; im2 = im1; } while (im2); while (tbreak[--itbreak] != 0) mem[tbreak[itbreak]] = imem; while (tcont[--itcont] != 0) mem[tcont[itcont]] = im3; final_sentencia(); grabar_sentencia(); break; case p_switch: inicio_sentencia(); lexico(); if (!free_sintax) if (pieza != p_abrir) error(3, 22); /* esperando '(' */ if (pieza == p_abrir) lexico(); condicion(); if (!free_sintax) if (pieza != p_cerrar) error(3, 18); /* esperando ')' */ if (pieza == p_cerrar) lexico(); while (pieza == p_ptocoma) { lexico(); } final_sentencia(); grabar_sentencia(); im1 = 0; im2 = 0; while (pieza != p_end) { inicio_sentencia(); if (pieza == p_case) { im3 = 0; do { lexico(); if (im1) mem[im1] = imem; expresion(); if (pieza != p_rango) { g2(lcse, 0); im1 = imem - 1; } else { lexico(); expresion(); g2(lcsr, 0); im1 = imem - 1; } if (pieza == p_coma) { g2(ljmp, im3); im3 = imem - 1; } } while (pieza == p_coma); while (im3) { im4 = mem[im3]; mem[im3] = imem; im3 = im4; } } else if (pieza == p_default) { lexico(); if (im1) mem[im1] = imem; im1 = 0; } else error(0, 63); /* esperando case, default o end */ if (!free_sintax) if (pieza != p_ptocoma) error(3, 64); /* esperando ':' */ while (pieza == p_ptocoma || pieza == p_coma) lexico(); g1(lasp); final_sentencia(); grabar_sentencia(); sentencia(); if (pieza != p_end) error(0, 57); /* esperando END */ inicio_sentencia(); g2(ljmp, im2); im2 = imem - 1; pasa_ptocoma(); final_sentencia(); grabar_sentencia(); } inicio_sentencia(); if (im1) mem[im1] = imem; g1(lasp); while (im2) { im1 = mem[im2]; mem[im2] = imem; im2 = im1; } lexico(); final_sentencia(); grabar_sentencia(); break; case p_frame: inicio_sentencia(); lexico(); if (pieza == p_abrir) { lexico(); if (pieza != p_cerrar) { expresion(); if (pieza != p_cerrar) error(3, 18); /* esperando ')' */ g1(lfrf); } else { g1(lfrm); } lexico(); } else { g1(lfrm); } if (!free_sintax) if (pieza != p_ptocoma) error(3, 9); /* esperando ';' */ while (pieza == p_ptocoma || pieza == p_coma) lexico(); final_sentencia(); grabar_sentencia(); break; case p_debug: inicio_sentencia(); g1(ldbg); lexico(); if (!free_sintax) if (pieza != p_ptocoma) error(3, 9); /* esperando ';' */ while (pieza == p_ptocoma || pieza == p_coma) lexico(); final_sentencia(); grabar_sentencia(); break; case p_break: inicio_sentencia(); if (itbreak == 0) error(0, 65); lexico(); /* break fuera de un bucle */ if (!free_sintax) if (pieza != p_ptocoma) error(3, 9); /* esperando ';' */ while (pieza == p_ptocoma || pieza == p_coma) lexico(); g2(ljmp, 0); tbreak[itbreak++] = imem - 1; final_sentencia(); grabar_sentencia(); break; case p_continue: inicio_sentencia(); if (itcont == 0) error(0, 66); lexico(); /* continue fuera de un bucle */ if (!free_sintax) if (pieza != p_ptocoma) error(3, 9); /* esperando ';' */ while (pieza == p_ptocoma || pieza == p_coma) lexico(); g2(ljmp, 0); tcont[itcont++] = imem - 1; final_sentencia(); grabar_sentencia(); break; case p_clone: inicio_sentencia(); lexico(); g2(lclo, 0); im1 = imem - 1; final_sentencia(); grabar_sentencia(); sentencia(); if (pieza != p_end) error(0, 57); lexico(); /* esperando END */ mem[im1] = imem; break; case p_ptocoma: lexico(); break; default: inicio_sentencia(); error_25 = 67; expresion(); do { _exp--; } while ((*_exp).tipo == eoper && (*_exp).token == p_string); error_25 = 25; switch ((*_exp).tipo) { case ecall: break; case efext: break; case eoper: switch ((*_exp).token) { case p_asig: case p_inc: case p_suma: case p_dec: case p_resta: case p_add_asig: case p_sub_asig: case p_mul_asig: case p_div_asig: case p_mod_asig: case p_and_asig: case p_or_asig: case p_xor_asig: case p_shr_asig: case p_shl_asig: case p_asigword: case p_incword: case p_sumaword: case p_decword: case p_restaword: case p_add_asigword: case p_sub_asigword: case p_mul_asigword: case p_div_asigword: case p_mod_asigword: case p_and_asigword: case p_or_asigword: case p_xor_asigword: case p_shr_asigword: case p_shl_asigword: case p_asigchar: case p_incchar: case p_sumachar: case p_decchar: case p_restachar: case p_add_asigchar: case p_sub_asigchar: case p_mul_asigchar: case p_div_asigchar: case p_mod_asigchar: case p_and_asigchar: case p_or_asigchar: case p_xor_asigchar: case p_shr_asigchar: case p_shl_asigchar: case p_strcpy: case p_strcat: case p_strsub: break; default: error(4, 68); break; /* expresion sin sentido */ } break; default: error(4, 68); /* expresion sin sentido */ } if (!free_sintax) if (pieza != p_ptocoma) error(3, 9); /* esperando ';' */ while (pieza == p_ptocoma || pieza == p_coma) lexico(); g1(lasp); final_sentencia(); grabar_sentencia(); break; } } }
//instruccion void instruccion(int toksig[]) { int i; int setpaso[NOTOKENS]; //conjunto de paso por valor int vacio[NOTOKENS]; //conjunto vacío init_set(vacio); if (token==ident) { if (esFuncion()) { copia_set(setpaso,toksig); funcion(setpaso); } else { //ve a buscarlo a la tabla de símbolos i=posicion(); if (i==0) { error(11); //error 11: identificador no declarado } else if (buscarElemento(i) -> tipo != VARIABLE) error(12); //error 12: no están permitidas las asignaciones a constantes o a procedimientos obtoken(); if (token==asignacion) obtoken(); else error(13); //error 13: se esperaba el operador de asignación copia_set(setpaso,toksig); expresion(setpaso); } } else if (token==calltok) { obtoken(); if (token!=ident) error(14); //error 14: "CALL" debe ir seguido de un identificador else { //buscar el nombre del procedimiento en la tabla de símbolos i=posicion(); if (i==0) error(11); //error 11: Identificador no declarado else if (buscarElemento(i) -> tipo!=PROCEDIMIENTO) error(15); //error 15 : No tiene sentido llamar a una constante o a una variable obtoken(); } } else if (token==iftok) { obtoken(); copia_set(setpaso,toksig); setpaso[thentok]=setpaso[dotok]=1; //setpaso=thentok+dotok+toksig condicion(setpaso); if (token==thentok) obtoken(); else error(16); //error 16: Se esperaba un "THEN" copia_set(setpaso,toksig); instruccion(toksig); } else if (token==begintok) { obtoken(); copia_set(setpaso,toksig); setpaso[puntoycoma]=setpaso[endtok]=1; //setpaso=puntoycoma+endtok+toksig instruccion(setpaso); while (token==puntoycoma || token==calltok || token==begintok || token==iftok || token==whiletok || token == fortok) { //aquí el while 'inserta' el punto y coma para continuar compilando cuando no lo encuentre //el compilador detecta la omisión clásica del punto y coma if (token==puntoycoma) obtoken(); else error(10); //error 10: Falta un punto y coma entre instrucciones copia_set(setpaso,toksig); setpaso[puntoycoma]=setpaso[endtok]=1; //setpaso=puntoycoma+endtok+toksig instruccion(setpaso); } if (token==endtok) obtoken(); else error(17); //error 17: Se esperaba un "END" o un punto y coma } else if (token==whiletok) { obtoken(); copia_set(setpaso,toksig); setpaso[dotok]=1;//setpaso=dotok+toksig condicion(setpaso); if (token==dotok) obtoken(); else error(18); //error 18: Se esperaba un "DO" copia_set(setpaso,toksig); instruccion(setpaso); } else if (token == fortok) { obtoken(); copia_set(setpaso,toksig); setpaso[dotok]=1;//setpaso=dotok+toksig if (token == ident) { i = posicion(); if (i == 0) { // no se encontro el identificador error(11); // identificador no declarado } else if (buscarElemento(i) -> tipo==PROCEDIMIENTO) { error(21); //error 21: identificador de procedimiento } else { // era un identificador valido obtoken(); if (token == intok) { obtoken(); if (token == entero) { obtoken(); if (token == dospuntos) { obtoken(); if (token == entero) { obtoken(); if (token == dotok) { obtoken(); copia_set(setpaso,toksig); instruccion(setpaso); } else { error(18); } } else { error(38); // se esperaba un numero entero } } else { error(39); // se esperaban dos puntos } } else { error(38); // se esperaba un numero entero } } else { error(29); // se esperaba un IN despues del FOR } } } else error(28); } else if (token == booleantok) { obtoken(); declaracionboolean(); } else if (token == codigoptok) { obtoken(); declaracioninline(); } //comprobación explícita de que los tokens que viene son sucesores de instrucción copia_set(setpaso,toksig); test(setpaso,vacio,19); //error(19): Un simbolo incorrecto sigue a una instrucción }
//instruccion void instruccion() { int i; if (token==ident) { //ve a buscarlo a la tabla de símbolos i=posicion() ; if (i==0) error(11); //error 11: identificador no declarado else if (tabla[i].tipo != VARIABLE) error(12); //error 12: no están permitidas las asignaciones a constantes o a procedimientos obtoken(); if (token==asignacion) obtoken(); else error(13) ; //error 13: se esperaba el operador de asignación expresion(); } else if (token==calltok) { obtoken(); if (token!=ident) error(14); //error 14: "CALL" debe ir seguido de un identificador else { //buscar el nombre del procedimiento en la tabla de símbolos i=posicion(); if (i==0) error(11); //error 11: Identificador no declarado else if (tabla[i].tipo!=PROCEDIMIENTO) error(15); //error 15 : No tiene sentido llamar a una constante o a una variable obtoken(); } } else if (token==iftok) { obtoken(); condicion(); if (token==thentok) obtoken(); else error(16); //error 16: Se esperaba un "THEN" instruccion(); } else if (token==begintok) { obtoken(); instruccion(); while (token==puntoycoma) { obtoken(); instruccion(); } if (token==endtok) obtoken(); else error(17); //error 17: Se esperaba un "END" o un punto y coma } else if (token==whiletok) { obtoken(); condicion(); if (token==dotok) obtoken(); else error(18); //error 18: Se esperaba un "DO" instruccion(); } }