From 4f482df658604ccbbb72155376b5705ecea10ce7c950cea8f03def1767f4eace Mon Sep 17 00:00:00 2001 From: Victor Roman Archidona Date: Thu, 17 Oct 2002 01:17:48 +0000 Subject: [PATCH] Eliminados archivos dentro del STUB que no se utilizaban (parser.* y compiler.*) --- ediv/src/stub/compiler.c | 1065 ----------- ediv/src/stub/compiler.h | 44 - ediv/src/stub/parser.c | 3609 -------------------------------------- ediv/src/stub/parser.h | 185 -- 4 files changed, 4903 deletions(-) delete mode 100644 ediv/src/stub/compiler.c delete mode 100644 ediv/src/stub/compiler.h delete mode 100644 ediv/src/stub/parser.c delete mode 100644 ediv/src/stub/parser.h diff --git a/ediv/src/stub/compiler.c b/ediv/src/stub/compiler.c deleted file mode 100644 index b4b97e5..0000000 --- a/ediv/src/stub/compiler.c +++ /dev/null @@ -1,1065 +0,0 @@ -/* - * eDiv Compiler - * Copyleft (C) 2000-2002 Sion Entertainment - * http://www.sion-e.com - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - */ - - -#include -#include -#include -#ifdef __linux__ -# include -#endif - -#include - -#include "compiler.h" -#include "parser.h" -#include "lower.h" -#include "expresion.h" -#include "extern.h" -#include "modulos.h" -#include "encrypt.h" -#include "listados.h" - -void analiza_ltlex(void); // en ltlex.c - - -void prepara_compilacion() -{ - int n; - - vnom=NULL; - - mem_ory=NULL; - frm=NULL; - mem=NULL; - loc=NULL; - - itbreak=0; itcont=0; itelseif=0; - coment=0; cero=0; error_25=25; - - memset(vhash,0,256*sizeof(byte*)); - - inicializa_lower(); - - // Inicializamos la tabla de objetos - memset(obj,0,sizeof(obj[0])*max_obj); - iobj=obj; - num_obj=0; - - // Inicializamos la tabla de símbolos - memset(lex_simb,0,sizeof(lex_simb)); - ilex_simb=lex_simb; - num_nodos=0; - - - // Inicializamos los caracteres básicos en lex_case - for (n=0;n<256;n++) - if (lower[n]) { - if (n>='0' && n<='9') - lex_case[n]=(struct lex_ele *)l_num; - else - lex_case[n]=(struct lex_ele *)l_id; - } - else - lex_case[n]=(struct lex_ele *)l_err; - - - // Inicializamos el vector de nombres - vnom=(byte *) e_malloc(max_obj*long_med_id+1024); - ivnom.b=vnom; - - - // Leemos los símbolos y palabras reservadas de ltlex.def - analiza_ltlex(); - - - // Terminamos de inicializar lex_case - lex_case[' ']=(struct lex_ele *)l_spc; - lex_case[tab]=(struct lex_ele *)l_spc; - lex_case[cr]=(struct lex_ele *)l_cr; - lex_case[lf]=(struct lex_ele *)l_cr; - lex_case[0]=(struct lex_ele *)l_eof; - - // Buffer para el bytecode - imem_max=default_buffer; imem=0; - mem_ory=mem=(int*)e_malloc(imem_max*sizeof(int)); - memset(mem,0,imem_max*sizeof(int)); - - // Buffer para variables locales y privadas - iloc_max=default_buffer/2; iloc=0; iloc_len=0; - loc=(int*)e_malloc(iloc_max*sizeof(int)); - memset(loc,0,iloc_max*sizeof(int)); - - // No se lo que es - ifrm_max=default_buffer/2; - frm=(int*)e_malloc(ifrm_max*sizeof(int)); - memset(frm,0,ifrm_max*sizeof(int)); - - imem=long_header; - - *(prog+progsize)=0; - - _source=NULL; -} - -void compila() -{ - struct objeto * i; - FILE *f; - int n,l; - unsigned long m; - byte * q, * p; - int start_lin, start_dbg; - - ultima_linea=prog; - acceso_remoto=0; parametros=0; linea=1; - linf=NULL; - - printf("Precompilando...\n"); - - itxt=inicio_textos=imem; - psintactico(); // Para obtener "longitud_textos" - imem+=longitud_textos; - #ifdef _DEBUG - printf("longitud_textos: %d\n",longitud_textos); - #endif - - test_buffer(&mem,&imem_max,imem); - - if(n_errors>0) return; - - num_obj_predefinidos=num_obj; - - ultima_linea=source; //fwrite(&cero,1,1,lprg); - acceso_remoto=0; parametros=0; linea=1; - - sintactico(); - - i=obj; - while (iusado) { - linea=i->linea; - ierror=i->ierror; - error(0,34,i->name); // nombre desconocido - } - i++; - } - - if(n_errors>0) return; - - // Borra todo y comienza de nuevo :P - - printf("Compilando...\n"); - - if (frm!=NULL) { free(frm); frm=NULL; } - if (loc!=NULL) { free(loc); loc=NULL; } - if (mem!=NULL) { free(mem); mem=mem_ory=NULL; } - if (vnom!=NULL) { free(vnom); vnom=NULL; } - - prepara_compilacion(); - source=prog; - - dll_func2(); // recarga sólo las dlls necesarias - - if(debug) { - if((linf=tmpfile())==NULL) { - printf("Error creando archivo de intercambio\n"); - exit(1); - } - } - - itxt=inicio_textos=imem; - imem+=longitud_textos; - test_buffer(&mem,&imem_max,imem); - num_obj_predefinidos=num_obj; - acceso_remoto=0; parametros=0; linea=1; - - sintactico(); - - // Ahora que estamos en el final del bytecode, añadiremos la rutina que carga - // las DLLs. Lo primero es guardar las cadenas con los nombres: - for(n=0;n2*1000*1000) errormem(); - - if (n>*maximo-security_distance) { - max=*maximo; - *maximo=n+buffer_grow; - max=*maximo-max; - if (*buffer==mem) { - if ((*buffer=mem_ory=(int *)realloc(*buffer,*maximo*sizeof(int)))==NULL) - errormem(); - } else { - if ((*buffer=(int *)realloc(*buffer,*maximo*sizeof(int)))==NULL) - errormem(); - } - memset((byte*)*buffer+(*maximo-max)*sizeof(int),0,max*sizeof(int)); - } -} - - -//----------------------------------------------------------------------------- -// Analisis de un bloque de sentencias -//----------------------------------------------------------------------------- - -void sentencia() { - - 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 (fromto && step>=0) error(4,62); - } else { - if (from=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 efunc: 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; - } - } -} - - -//----------------------------------------------------------------------------- -// Funciones de generación de código -//----------------------------------------------------------------------------- - -// void g1(int op) { mem[imem++]=op; } -// void g2(int op, int pa) { mem[imem++]=op; mem[imem++]=pa; } - -//----------------------------------------------------------------------------- -// Optimización peephole de código intermedio EML -//----------------------------------------------------------------------------- - -// *** OJO!!! *** quizá se pueda quitar "dir" y esa comprobación absurda ... - -//struct { // Peephole, "mirilla" de optimizacion -// int dir; // Dirección -// int param; // Indica el número de parametros de la instruccion -// int op; // Opcode -//} code[16]; // En code[15] debe quedar siempre la última instrucción generada - -void gen(int param, int op, int pa); -void remove_code(int i); -void delete_code(void); -void add_code(int dir, int param, int op); - -void g1(int op) { - if (optimizar) gen(0,op,0); else mem[imem++]=op; -} - -void g2(int op, int pa) { - if (optimizar) gen(1,op,pa); else { mem[imem++]=op; mem[imem++]=pa; } -} - -int optimizado; - -void gen(int param, int op, int pa) { -// int n; - - optimizado=0; - - switch(op) { - case lcar: - if (code[15].op==lcar) { - code[15].op=mem[imem-2]=lcar2; - code[15].param=2; - mem[imem++]=pa; optimizado=1; - } else if (code[15].op==lcar2) { - code[15].op=mem[imem-3]=lcar3; - code[15].param=3; - mem[imem++]=pa; optimizado=1; - } else if (code[15].op==lcar3) { - code[15].op=mem[imem-4]=lcar4; - code[15].param=4; - mem[imem++]=pa; optimizado=1; - } break; - case lasp: - if (code[15].op==lasi) { - if (code[14].op==lcar) { - remove_code(1); - code[15].op=mem[imem-2]=lcarasiasp; - } else { - code[15].op=mem[imem-1]=lasiasp; - optimizado=1; - } - } else if (code[15].op==lfun) { - code[15].op=mem[imem-2]=lfunasp; - optimizado=1; - } break; - case laid: - if (code[15].op==lcar) { - code[15].op=mem[imem-2]=lcaraid; - optimizado=1; - } break; - case lptr: - if (code[15].op==lcar) { - code[15].op=mem[imem-2]=lcarptr; - optimizado=1; - } else if (code[15].op==lcaradd) { - code[15].op=mem[imem-2]=lcaraddptr; - optimizado=1; - } else if (code[15].op==laid) { - code[15].op=mem[imem-1]=laidptr; - optimizado=1; - } else if (code[15].op==ladd) { - code[15].op=mem[imem-1]=laddptr; - optimizado=1; - } else if (code[15].op==lcaraid) { - code[15].op=mem[imem-2]=lcaraidptr; - optimizado=1; - } break; - case lcpa: - if (code[15].op==lcaraid) { - code[15].op=mem[imem-2]=lcaraidcpa; - optimizado=1; - } break; - case ladd: - if (code[15].op==lcar2){ - code[15].op=mem[imem-3]=lcar; - code[15].param=1; - mem[imem-2]+=mem[imem-1]; - imem--; optimizado=1; - } else if (code[15].op==lcar3){ - code[15].op=mem[imem-4]=lcar2; - code[15].param=2; - mem[imem-2]+=mem[imem-1]; - imem--; optimizado=1; - } else if (code[15].op==lcar4){ - code[15].op=mem[imem-5]=lcar3; - code[15].param=3; - mem[imem-2]+=mem[imem-1]; - imem--; optimizado=1; - } else if (code[15].op==lcar){ - if (mem[imem-1]==0) remove_code(1); else { - code[15].op=mem[imem-2]=lcaradd; - optimizado=1; - } - } else if (code[15].op==lcarmul){ - code[15].op=mem[imem-2]=lcarmuladd; - optimizado=1; - } break; - case lmul: - if (code[15].op==lcar2){ - code[15].op=mem[imem-3]=lcar; - code[15].param=1; - mem[imem-2]*=mem[imem-1]; - imem--; optimizado=1; - } else if (code[15].op==lcar3){ - code[15].op=mem[imem-4]=lcar2; - code[15].param=2; - mem[imem-2]*=mem[imem-1]; - imem--; optimizado=1; - } else if (code[15].op==lcar4){ - code[15].op=mem[imem-5]=lcar3; - code[15].param=3; - mem[imem-2]*=mem[imem-1]; - imem--; optimizado=1; - } else if (code[15].op==lcar){ - if (mem[imem-1]==1) remove_code(1); else { - code[15].op=mem[imem-2]=lcarmul; - optimizado=1; - } - } break; - case lsub: - if (code[15].op==lcar2){ - code[15].op=mem[imem-3]=lcar; - code[15].param=1; - mem[imem-2]-=mem[imem-1]; - imem--; optimizado=1; - } else if (code[15].op==lcar3){ - code[15].op=mem[imem-4]=lcar2; - code[15].param=2; - mem[imem-2]-=mem[imem-1]; - imem--; optimizado=1; - } else if (code[15].op==lcar4){ - code[15].op=mem[imem-5]=lcar3; - code[15].param=3; - mem[imem-2]-=mem[imem-1]; - imem--; optimizado=1; - } else if (code[15].op==lcar){ - if (mem[imem-1]==0) remove_code(1); else { - code[15].op=mem[imem-2]=lcarsub; - optimizado=1; - } - } break; - case ldiv: - if (code[15].op==lcar2){ - if (mem[imem-1]!=0) { - code[15].op=mem[imem-3]=lcar; - code[15].param=1; - mem[imem-2]/=mem[imem-1]; - imem--; optimizado=1; - } - } else if (code[15].op==lcar3){ - if (mem[imem-1]!=0) { - code[15].op=mem[imem-4]=lcar2; - code[15].param=2; - mem[imem-2]/=mem[imem-1]; - imem--; optimizado=1; - } - } else if (code[15].op==lcar4){ - if (mem[imem-1]!=0) { - code[15].op=mem[imem-5]=lcar3; - code[15].param=3; - mem[imem-2]/=mem[imem-1]; - imem--; optimizado=1; - } - } else if (code[15].op==lcar){ - if (mem[imem-1]==1) remove_code(1); - else if (mem[imem-1]!=0) { - code[15].op=mem[imem-2]=lcardiv; // Un cardiv nunca será "cardiv 0" - optimizado=1; - } - } break; - case lneg: - if (code[15].op==lcar || code[15].op==lcar2 || code[15].op==lcar3 || code[15].op==lcar4) { - mem[imem-1]=-mem[imem-1]; optimizado=1; - } - break; - case lnot: - if (code[15].op==lcar || code[15].op==lcar2 || code[15].op==lcar3 || code[15].op==lcar4) { - mem[imem-1]=mem[imem-1]^-1; optimizado=1; - } - break; - } - - if (!optimizado) { - if (imem-code[15].dir>2) delete_code(); - add_code(imem,param,op); - if (param) { mem[imem++]=op; mem[imem++]=pa; } else mem[imem++]=op; - } - -} - -void remove_code(int i) { - int n; - optimizado=1; - while (i--) { - imem-=code[15].param+1; - for (n=15;n>0;n--) { - code[n].dir=code[n-1].dir; - code[n].param=code[n-1].param; - code[n].op=code[n-1].op; - } code[0].dir=0; code[0].param=0; code[0].op=0; - } -} - -void delete_code(void) { - int n; - for (n=0;n<16;n++) { - code[n].dir=0; code[n].param=0; code[n].op=0; - } -} - -void add_code(int dir, int param, int op) { - int n; - for (n=0;n<15;n++) { - code[n].dir=code[n+1].dir; - code[n].param=code[n+1].param; - code[n].op=code[n+1].op; - } code[15].dir=dir; code[15].param=param; code[15].op=op; -} - - -//----------------------------------------------------------------------------- -// Con el primer token leido guarda el inicio de una sentencia -//----------------------------------------------------------------------------- - -void inicio_sentencia(void) -{ - byte * p=ierror-1; - inicio=imem; - linea1=linea; - columna1=0; - while (*p!=cr && *p!=lf && p>_source) { - columna1++; p--; - } -} - -//----------------------------------------------------------------------------- -// Con el primer token que no es de la sentecia guarda el fin de una sentencia -//----------------------------------------------------------------------------- - -void final_sentencia(void) -{ - byte * p=old_ierror_end-1; - final=imem-1; - linea2=old_linea; - columna2=0; - while (*p!=cr && *p!=lf && p>=_source) { - columna2++; p--; - } -} - -//----------------------------------------------------------------------------- -// Guarda un registro (inicio,final,linea1,...) en el temporal (linf) -//----------------------------------------------------------------------------- - -void grabar_sentencia(void) -{ - if(debug && linf!=NULL) { - fwrite(&inicio,4,1,linf); - fwrite(&final,4,1,linf); - fwrite(&linea1,4,1,linf); - fwrite(&columna1,4,1,linf); - fwrite(&linea2,4,1,linf); - fwrite(&columna2,4,1,linf); - } -} - -//----------------------------------------------------------------------------- -// Agrega información de depurado al ejecutable -//----------------------------------------------------------------------------- - -void escribe_lin(FILE* f) -{ - int b; - - #ifdef WIN32 - // Resuelve la ruta del PRG - char resolved_path[_MAX_PATH]; - _fullpath(resolved_path,fichero_prg,_MAX_PATH); - #else - // Lo mismo pero en Linux - char resolved_path[PATH_MAX]; - realpath(fichero_prg,resolved_path); - #endif - - // Escribe la ruta resuelta - fputs(resolved_path,f); - fputc(0,f); - - // Escribe la información LIN (offset de cada sentencia en el prg y en el bytecode) - fseek(linf,0,SEEK_SET); - while((b=fgetc(linf))!=EOF) - fputc(b,f); - - fclose(linf); -} - - -// Escribe información sobre los objetos - -void escribe_dbg(FILE* f) -{ - int n; - - // Datos comunes de cada objeto - struct { - int tipo; - int nombre; - int bloque; - int miembro; - int v0,v1,v2,v3,v4,v5; - } ob; - - // Cabecera de sección DBG - fwrite(&num_obj,4,1,f); - fwrite(&num_obj_predefinidos,4,1,f); - n=(int)&obj[0]; - fwrite(&n,4,1,f); - n=sizeof(struct objeto); - fwrite(&n,4,1,f); - - // Escribe los datos de cada objeto - for (n=0;n -#include "main.h" -#include "parser.h" -#include "compiler.h" -#include "lower.h" -//#include "expresion.h" -#include "extern.h" - -// Para los objetos predefinidos (DLL) - -int crea_objeto(byte * nombre) -{ - struct objeto * * ptr_o; - byte ** ptr, * _ivnom, h; - - _ivnom=ivnom.b; *ivnom.p++=0; *ivnom.p++=0; h=0; - while (*ivnom.b=lower[*nombre++]) h=((byte)(h<<1)+(h>>7))^(*ivnom.b++); - ivnom.b++; if (ivnom.b-vnom>max_obj*long_med_id) return 1; // error "sobrepasado buffer de nombres de objeto" - ptr=&vhash[h]; - while (*ptr && strcmp((char *)(ptr+2),(char *)_ivnom+8)) ptr=(byte**)*ptr; - if (!strcmp((byte *)(ptr+2),_ivnom+8)) { // id encontrado - ivnom.b=_ivnom; // lo saca de vnom - return 2; // genera un error "el nombre no es nuevo" - } else { - *ptr=_ivnom; ptr_o=(void*)(_ivnom+4); *ptr_o=o=iobj++; // id nuevo - (*o).name=(byte*)_ivnom+8; - (*o).member=member; - if (num_obj++==max_obj) return 3; // error "demasiados objetos" - } - - (*o).dll=numdlls; -// (*o).usado_dll=0; - - return 0; -} - - -//////////////////// -// PRECOMPILACIÓN // -//////////////////// - -void psintactico(void) -{ - byte * _ivnom=ivnom.b; - - longitud_textos=0; - source=prog; - - do { - plexico(); - } while (pieza!=p_ultima); - - ivnom.b=_ivnom; - source=prog; - _source=source; - coment=0; -} - -void plexico(void) -{ - byte ** ptr, * _ivnom, h, * _source=source; - struct lex_ele * e; - - if (!coment) { - old_linea=linea; - old_ierror=ierror; - old_ierror_end=ierror_end; - } - -lex_scan: - - ierror=_source; - - switch ((int)lex_case[*_source]) { // Puntero a un lex_ele o l_??? - - case l_err: - if (coment) { pieza=p_rem; _source++; } - else error(0,5); // carácter no reconocido - _source++; - break; - - case l_eof: - pieza=p_ultima; - if (coment) error(0,1); // llegó el final dentro de un comentario - break; - - case l_cr: - linea++; - if (*_source==cr && *(_source+1)==lf) _source+=2; - else _source++; - - ultima_linea=_source; - goto lex_scan; - - case l_id : - if (coment) { pieza=p_rem; _source++; break; } - - _ivnom=ivnom.b; - *ivnom.p++=0; - *ivnom.p++=0; - h=0; - - while (*ivnom.b=lower[*_source++]) - h=((byte)(h<<1)+(h>>7))^(*ivnom.b++); - - ivnom.b++; - _source--; - if (ivnom.b-vnom>max_obj*long_med_id) error(0,2); // Excedida la capacidad del vector de nombres - - ptr=&vhash[h]; - while (*ptr && strcmp((byte *)(ptr+2),_ivnom+8)) - ptr=(void*)*ptr; - - if (!strcmp((byte *)(ptr+2),_ivnom+8)) { // id encontrado - ivnom.b=_ivnom; // lo saca de vnom - pieza=(int)*(ptr+1); - if (pieza<256 && pieza>=0) { // palabra reservada (token) - if (pieza==p_rem) { - while (*_source!=cr && *_source!=lf) _source++; - goto lex_scan; - } - } else { // objeto (id anterior) - pieza=p_id; - } - } - else { // id nuevo - ivnom.b=_ivnom; // lo saca de vnom - pieza=p_id; - } - - break; - - case l_spc: - while ((*++_source)==' '); - goto lex_scan; - - case l_lit: - if (coment) { pieza=p_rem; _source++; break; } - - pieza=p_lit; // Literal entre dos h - h=*_source; - _ivnom=ivnom.b; - - do { - _source++; - - if (*_source==cr || *_source==lf) { - error(0,3); // literal sin cerrar - break; - } - - if (*_source==h) { - if (*(_source+1)==h) *_ivnom=*++_source; - else *_ivnom=0; - } - else - *_ivnom=*_source; - - } while (*_ivnom++); - - _source++; - longitud_textos+=(strlen(ivnom.b)+4)/4; - ivnom.b=_ivnom; // lo saca de vnom - break; - - case l_num: - if (coment) { pieza=p_rem; _source++; break; } - - pieza=p_num; - pieza_num=0; - - if (*_source=='0' && lower[*(_source+1)]=='x') { - _source+=2; - while ((int)lex_case[*_source]==l_num || - (lower[*_source]>='a' && lower[*_source]<='f')) { - if ((int)lex_case[*_source]==l_num) - pieza_num=pieza_num*16+*_source++-0x30; - else - pieza_num=pieza_num*16+lower[*_source++]-'a'+10; - } - } - else - do { - pieza_num=pieza_num*10+*_source++-0x30; - } while ((int)lex_case[*_source]==l_num); - - break; - - default: // puntero a un lex_ele - e=lex_case[*_source++]; - _ivnom=_source; - pieza=(*e).token; - - while (e=(*e).siguiente) { - while (*_source!=(*e).caracter && (*e).alternativa) - e=(*e).alternativa; - - if (*_source++==(*e).caracter && (*e).token) { - pieza=(*e).token; - _ivnom=_source; - } - } - _source=_ivnom; - - if (pieza==p_rem && !coment) { - while (*_source!=cr && *_source!=lf) _source++; - goto lex_scan; - } - - if (pieza==p_ini_rem) { - coment++; - do { - source=_source; - plexico(); - _source=source; - } while (pieza!=p_end_rem); - coment--; - goto lex_scan; - } - - if (pieza==p_ultima) { - if (coment) error(0,1); // llegó el final dentro de un comentario - else error(0,4); // símbolo no reconocido (¡¡creo!!) - } - - break; - - } - - source=_source; - ierror_end=_source-1; -} - - -////////////////////////////////////// -// ANÁLISIS SINTÁCTICO DEL PROGRAMA // -////////////////////////////////////// - -void sintactico(void) -{ - struct objeto * ob, * member2; - int _imem,_imem_old,num_par,n; - byte *oimemptr; - int _itxt,dup; - byte * old_source,*nombre_dll; - char cWork[256]; - int num_extern; - - lexico(); - - // - // Opciones de compilacion - // - // p_compiler_options {opcion} {;} - // - - max_process=0; // Valores de las opciones por defecto - ignore_errors=0; - free_sintax=0; - extended_conditions=0; - simple_conditions=0; - comprueba_rango=1; - comprueba_id=1; - comprueba_null=1; - hacer_strfix=1; - optimizar=1; - - if (pieza==p_compiler_options) { - lexico(); - do { - if (pieza==p_ptocoma) { lexico(); break; } - if (pieza==p_coma) lexico(); - if (pieza==p_id && (*o).tipo==tcons) { - switch((*o).cons.valor) { - case 0: // _max_process - lexico(); - if (pieza!=p_asig) error(3,7); // se esperaba '=' - lexico(); - max_process=constante(); - if (max_process<0) max_process=0; - #ifdef _DEBUG - printf("dbg: max_process=%d\n",max_process); - #endif - break; - case 1: // _extended_conditions - lexico(); - extended_conditions=1; - break; - case 2: // _simple_conditions - lexico(); - simple_conditions=1; - break; - case 3: // _case_sensitive - lexico(); - memcpy(lower+129,"üéâäàåçêëèïîìäåéææôöòûùÿöü¢£¥áíóú",35); - memcpy(lower+'A',"ABCDEFGHIJKLMNOPQRSTUVWXYZ",26); - lower['Ñ']='Ñ'; - break; - case 4: // _ignore_errors - lexico(); - ignore_errors=1; - break; - case 5: // _free_sintax - lexico(); - free_sintax=1; - break; - case 6: // _no_check - lexico(); - comprueba_rango=0; - comprueba_id=0; - comprueba_null=0; - break; - case 7: // _no_strfix - lexico(); - hacer_strfix=0; - break; - case 8: // _no_optimization - lexico(); - optimizar=0; - break; - case 9: // _no_range_check - lexico(); - comprueba_rango=0; - break; - case 10: // _no_id_check - lexico(); - comprueba_id=0; - break; - case 11: // _no_null_check - lexico(); - comprueba_null=0; - break; - default: - error(0,8); // se esperaba una opción de compilación - break; - } - } else { - if (!free_sintax) { - if (pieza==p_program) { - error(3,9); // se esperaba ';' (¡creo!) - //lexico(); - break; - } - else { - error(0,8); // se esperaba una opción de compilación - //lexico(); - // puede ser peligroso - while(pieza!=p_coma && pieza!=p_ptocoma && pieza!=p_program) - lexico(); - } - } else break; - } - } while (1); - } - - // - // Cabecera - // - // p_program p_id {;} - // - - save_error(0); - if (pieza!=p_program && pieza!=p_setup_program) error(4,44); // esperando PROGRAM - - if (pieza==p_setup_program) - warning(1); // característica desfasada - - //if ((lins=fopen(cWork,"wb"))==NULL) c_error(0,0); // cWork="system\exec.ins" - - inicio_sentencia(); lexico(); - if (pieza!=p_id) error(1,45); // esperando el nombre del programa - - ob=o; - if ((*ob).tipo!=tnone) error(0,30); // el nombre no es nuevo - (*ob).tipo=tproc; - (*ob).proc.bloque=bloque_actual=ob; - (*ob).proc.offset=0; - (*ob).proc.num_par=0; - lexico(); - if (!free_sintax) if (pieza!=p_ptocoma) error(3,9); // esperando ';' - while (pieza==p_ptocoma || pieza==p_coma) lexico(); - final_sentencia(); - - // - // Import (DESFASADO), se ignora - // - // {p_import p_lit {;}} - // - - while (pieza==p_import) { - warning(2); // sintaxis antigua - lexico(); - if (pieza!=p_lit && !(pieza==p_id && (*o).tipo==tcons && (*o).cons.literal)) - error(1,46); // se esperaba un literal - lexico(); - if (!free_sintax) if (pieza!=p_ptocoma) error(3,9); // esperando ';' - while (pieza==p_ptocoma || pieza==p_coma) lexico(); - } - - // - // Zona de constantes - // - // [ p_const {;} { p_id p_asig {; | ,} } ] - // - - if (pieza==p_const) { - pasa_ptocoma(); - while (pieza==p_id) { - ob=o; - if ((*ob).tipo!=tnone && (*ob).tipo!=tcons) error(0,30); // el nombre no es nuevo - (*ob).tipo=tcons; - lexico(); if (pieza!=p_asig) error(3,7); // esperando '=' - - lexico(); - if (pieza==p_lit || (pieza==p_id && (*o).tipo==tcons && (*o).cons.literal)) - (*ob).cons.literal=1; - else - (*ob).cons.literal=0; - - (*ob).cons.valor=constante(); - if (!free_sintax) if (pieza!=p_ptocoma && pieza!=p_coma) error(3,9); // esperando ';' - while (pieza==p_ptocoma || pieza==p_coma) lexico(); - } - } - - // - // Variables globales, pueden usarse en expresiones constantes - // - // := p_id [ p_asig ] {;} - // - // := p_id p_corab ( p_corce p_asig - // | p_corce [ p_asig ] ) {;} - // - // := ( | [ [p_dup] p_abrir p_cerrar ] ) - // [ p_coma ] - // - - if (pieza==p_global) { - pasa_ptocoma(); - while (pieza==p_id || pieza==p_int || pieza==p_pointer || pieza==p_struct || pieza==p_string || pieza==p_byte || pieza==p_word) { - - if (pieza==p_struct) { // Struct global - - lexico(); - - if (pieza==p_pointer) { // Se define un puntero a struct - - lexico(); if (pieza!=p_id) error(1,27); ob=o; // esperando el nombre de la estructura - if ((*ob).tipo==tnone) error(0,28); // No se define el pointer así - if ((*ob).tipo!=tsglo && (*ob).tipo!=tsloc) error(0,28); - lexico(); - puntero_a_struct: - analiza_pointer_struct(tpsgl,imem,ob); - if (pieza==p_asig) { lexico(); mem[imem]=constante(); } - test_buffer(&mem,&imem_max,imem++); - - if (pieza==p_coma) { - lexico(); - if (pieza==p_pointer) lexico(); - goto puntero_a_struct; - } else { - if (!free_sintax) if (pieza!=p_ptocoma) error(3,9); // esperando ';' - while (pieza==p_ptocoma || pieza==p_coma) lexico(); - } - - } else { - - if (pieza!=p_id) error(1,27); // esperando el nombre de la estructura - ob=o; member=ob; lexico(); - - if ((*ob).tipo!=tnone) error(2,30); // el nombre no es nuevo - - (*ob).tipo=tsglo; (*ob).sglo.offset=_imem=imem; - if (pieza==p_corab) { - member2=member; member=NULL; lexico(); - if (((*ob).sglo.items1=constante())<0) error(4,43); // estructura de longitud negativa - if (pieza==p_coma) { - lexico(); - if (((*ob).sglo.items2=constante())<0) error(4,43); // idem - if (pieza==p_coma) { - lexico(); - if (((*ob).sglo.items3=constante())<0) error(4,43); // reidem - } else (*ob).sglo.items3=-1; - } else { (*ob).sglo.items2=-1; (*ob).sglo.items3=-1; } - member=member2; - (*ob).sglo.totalitems=(*ob).sglo.items1+1; - if ((*ob).sglo.items2>-1) (*ob).sglo.totalitems*=(*ob).sglo.items2+1; - if ((*ob).sglo.items3>-1) (*ob).sglo.totalitems*=(*ob).sglo.items3+1; - if (pieza!=p_corce) error(3,19); lexico(); // espernado ']' - } else { - (*ob).sglo.totalitems=1; - (*ob).sglo.items1=0; (*ob).sglo.items2=-1; (*ob).sglo.items3=-1; - } - if (((*ob).sglo.len_item=analiza_struct(_imem))==0) error(0,47); // estructua vacia - member=NULL; lexico(); - imem=(*ob).sglo.offset; dup=(*ob).sglo.totalitems+1; - if (dup>1) { - test_buffer(&mem,&imem_max,imem+(*ob).sglo.len_item*(*ob).sglo.totalitems); - test_buffer(&frm,&ifrm_max,imem+(*ob).sglo.len_item*(*ob).sglo.totalitems); - while (--dup) { - memcpy(&mem[imem],&mem[_imem],(*ob).sglo.len_item<<2); - memcpy(&frm[imem],&frm[_imem],(*ob).sglo.len_item<<2); - imem+=(*ob).sglo.len_item; - } - } imem=_imem; - if (pieza==p_asig) { - save_error(1); - lexico(); tglo_init(0); - if (imem-_imem-1>=(*ob).sglo.len_item*(*ob).sglo.totalitems) error(4,55); // demasiados valores para la estructura - } while (pieza==p_ptocoma) lexico(); - - imem=_imem+(*ob).sglo.len_item*(*ob).sglo.totalitems; - test_buffer(&mem,&imem_max,imem); - } - - } else if (pieza==p_string) { // Cadena global - - lexico(); - - if (pieza==p_pointer) { // Puntero a byte - - lexico(); puntero1: - ob=analiza_pointer(tpcgl,imem); - if (pieza==p_asig) { lexico(); mem[imem]=constante(); } - test_buffer(&mem,&imem_max,++imem); - if (pieza==p_coma) { - lexico(); if (pieza==p_pointer) lexico(); - goto puntero1; - } - - } else { - - if (pieza!=p_id) error(1,29); // esperando el nombre de la cadena - ob=o; if ((*ob).tipo!=tnone) error(0,30); lexico(); // el nombre no es nuevo - (*ob).tipo=tcglo; - _imem=imem; - (*ob).cglo.offset=_imem+1; - if (pieza==p_corab) { - lexico(); - if (pieza==p_corce) { - lexico(); - (*ob).cglo.totalen=255; - } else { - if (((*ob).cglo.totalen=constante())<0) error(4,31); // cadena de long. negativa - if ((*ob).cglo.totalen>0xFFFFF) error(4,32); // cadena demasiado larga - if (pieza!=p_corce) error(3,19); // esperando ']' - lexico(); - } - } else (*ob).cglo.totalen=255; - if (pieza==p_asig) { - save_error(1); - _itxt=itxt; - lexico(); - if (pieza!=p_lit && !(pieza==p_id && (*o).tipo==tcons && (*o).cons.literal)) - error(3,46); // se esperaba un literal - if (strlen((char*)&mem[pieza_num])>(*ob).cglo.totalen+1) - error(4,49); // literal demasiado largo - imem=_imem+1+((*ob).cglo.totalen+5)/4; // ej. c[32] -> c[0]..c[32],NUL - test_buffer(&mem,&imem_max,imem); - strcpy((char*)&mem[_imem+1],(char*)&mem[pieza_num]); - itxt=_itxt; // Saca la cadena del segmento de textos - lexico(); - } else { - imem=_imem+1+((*ob).cglo.totalen+5)/4; - test_buffer(&mem,&imem_max,imem); - } mem[_imem]=0xDAD00000|(*ob).cglo.totalen; - } - - if (pieza==p_coma) pieza=p_string; else { - if (!free_sintax) if (pieza!=p_ptocoma) error(3,9); // esperando ';' - while (pieza==p_ptocoma || pieza==p_coma) lexico(); - } - - } else if (pieza==p_byte) { // Tabla Byte global - - lexico(); - - if (pieza==p_pointer) { // Puntero a byte - - lexico(); puntero2: - ob=analiza_pointer(tpbgl,imem); - if (pieza==p_asig) { lexico(); mem[imem]=constante(); } - test_buffer(&mem,&imem_max,++imem); - if (pieza==p_coma) { - lexico(); if (pieza==p_pointer) lexico(); - goto puntero2; - } - - } else { - - if (pieza!=p_id) error(1,23); // esperando un nombre - ob=o; if ((*ob).tipo!=tnone) error(0,30); lexico(); // el nombre no es nuevo - (*ob).tipo=tbglo; (*ob).bglo.offset=_imem=imem; - if (pieza==p_corab) { - lexico(); - if (pieza==p_corce) { - lexico(); if (pieza!=p_asig) error(3,7); lexico(); // esperando '=' - oimemptr=(byte*)&mem[imem]; - tglo_init(2); - (*ob).bglo.len1=imemptr-oimemptr-1; - (*ob).bglo.len2=-1; - (*ob).bglo.len3=-1; - (*ob).bglo.totalen=((*ob).bglo.len1+4)/4; - } else { - if (((*ob).bglo.len1=constante())<0) error(4,40); // tabla de longitud negativa - if (pieza==p_coma) { - lexico(); - if (((*ob).bglo.len2=constante())<0) error(4,40); // idem - if (pieza==p_coma) { - lexico(); - if (((*ob).bglo.len3=constante())<0) error(4,40); // reidem - } else (*ob).bglo.len3=-1; - } else { (*ob).bglo.len2=-1; (*ob).bglo.len3=-1; } - - (*ob).bglo.totalen=(*ob).bglo.len1+1; - if ((*ob).bglo.len2>-1) (*ob).bglo.totalen*=(*ob).bglo.len2+1; - if ((*ob).bglo.len3>-1) (*ob).bglo.totalen*=(*ob).bglo.len3+1; - if (pieza!=p_corce) error(3,19); lexico(); // esperando ']' - if (pieza==p_asig) { - save_error(1); - lexico(); - oimemptr=(byte*)&mem[imem]; - tglo_init(2); - if (imemptr-oimemptr>(*ob).bglo.totalen) error(4,48); // demasiados valores para la tabla - } (*ob).bglo.totalen=((*ob).bglo.totalen+3)/4; - } - } else { // Byte global - (*ob).tipo=tbglo; (*ob).bglo.offset=imem; - (*ob).bglo.len1=0; - (*ob).bglo.len2=-1; - (*ob).bglo.len3=-1; - (*ob).bglo.totalen=1; // 1 int - if (pieza==p_asig) { - save_error(1); - lexico(); - mem[imem]=constante(); - if (mem[imem]<0 || mem[imem]>255) error(4,50); // valor byte fuera de rango - } - } imem=_imem+(*ob).bglo.totalen; test_buffer(&mem,&imem_max,imem); - } - - if (pieza==p_coma) pieza=p_byte; else { - if (!free_sintax) if (pieza!=p_ptocoma) error(3,9); // esperando ';' - while (pieza==p_ptocoma || pieza==p_coma) lexico(); - } - - } else if (pieza==p_word) { // Tabla Word global - - lexico(); - - if (pieza==p_pointer) { // Puntero a word - - lexico(); puntero3: - ob=analiza_pointer(tpwgl,imem); - if (pieza==p_asig) { lexico(); mem[imem]=constante(); } - test_buffer(&mem,&imem_max,++imem); - if (pieza==p_coma) { - lexico(); if (pieza==p_pointer) lexico(); - goto puntero3; - } - - } else { - - if (pieza!=p_id) error(1,23); // esperando un nombre - ob=o; if ((*ob).tipo!=tnone) error(0,30); lexico(); // el nombre no es nuevo - (*ob).tipo=twglo; (*ob).wglo.offset=_imem=imem; - if (pieza==p_corab) { - lexico(); - if (pieza==p_corce) { - lexico(); if (pieza!=p_asig) error(3,7); lexico(); // esperando '=' - oimemptr=(byte*)&mem[imem]; - tglo_init(1); - (*ob).wglo.len1=(imemptr-oimemptr)/2-1; - (*ob).wglo.len2=-1; - (*ob).wglo.len3=-1; - (*ob).wglo.totalen=((*ob).wglo.len1+2)/2; - } else { - if (((*ob).wglo.len1=constante())<0) error(4,40); // tabla de longitud negativa - if (pieza==p_coma) { - lexico(); - if (((*ob).wglo.len2=constante())<0) error(4,40); // idem - if (pieza==p_coma) { - lexico(); - if (((*ob).wglo.len3=constante())<0) error(4,40); // reidem - } else (*ob).wglo.len3=-1; - } else { (*ob).wglo.len2=-1; (*ob).wglo.len3=-1; } - - (*ob).wglo.totalen=(*ob).wglo.len1+1; - if ((*ob).wglo.len2>-1) (*ob).wglo.totalen*=(*ob).wglo.len2+1; - if ((*ob).wglo.len3>-1) (*ob).wglo.totalen*=(*ob).wglo.len3+1; - if (pieza!=p_corce) error(3,19); lexico(); // esperando ']' - if (pieza==p_asig) { - save_error(1); - lexico(); - oimemptr=(byte*)&mem[imem]; - tglo_init(1); - if (imemptr-oimemptr>(*ob).wglo.totalen*2) error(4,48); // demasiados valores para la tabla - } (*ob).wglo.totalen=((*ob).wglo.totalen+1)/2; - } - } else { // Word global - (*ob).tipo=twglo; (*ob).wglo.offset=imem; - (*ob).wglo.len1=0; - (*ob).wglo.len2=-1; - (*ob).wglo.len3=-1; - (*ob).wglo.totalen=1; // 1 int - if (pieza==p_asig) { - save_error(1); - lexico(); - mem[imem]=constante(); - if (mem[imem]<0 || mem[imem]>65535) error(4,51); // valor word fuera de rango - } - } imem=_imem+(*ob).wglo.totalen; test_buffer(&mem,&imem_max,imem); - } - - if (pieza==p_coma) pieza=p_word; else { - if (!free_sintax) if (pieza!=p_ptocoma) error(3,9); // esperando ';' - while (pieza==p_ptocoma || pieza==p_coma) lexico(); - } - - } else if (pieza==p_int || pieza==p_id || pieza==p_pointer) { - - if (pieza==p_int) { - lexico(); - if (pieza!=p_id && pieza!=p_pointer) error(1,23); // esperando un nombre - } - - if (pieza==p_pointer) { // Puntero a int - - lexico(); puntero4: - ob=analiza_pointer(tpigl,imem); - if (pieza==p_asig) { lexico(); mem[imem]=constante(); } - test_buffer(&mem,&imem_max,++imem); - if (pieza==p_coma) { - lexico(); if (pieza==p_pointer) lexico(); - goto puntero4; - } - - } else { - - ob=o; if ((*ob).tipo!=tnone) error(0,30); lexico(); // el nombre no es nuevo - if (pieza==p_corab) { // Tabla global - lexico(); - (*ob).tipo=ttglo; (*ob).tglo.offset=_imem=imem; - if (pieza==p_corce) { - lexico(); if (pieza!=p_asig) error(3,7); lexico(); // esperando '=' - tglo_init(3); - (*ob).tglo.len1=imem-_imem-1; - (*ob).tglo.len2=-1; - (*ob).tglo.len3=-1; - (*ob).tglo.totalen=imem-_imem; - } else { - if (((*ob).tglo.len1=constante())<0) error(4,40); // tabla de longitud negativa - if (pieza==p_coma) { - lexico(); - if (((*ob).tglo.len2=constante())<0) error(4,40); // idem - if (pieza==p_coma) { - lexico(); - if (((*ob).tglo.len3=constante())<0) error(4,40); // reidem - } else (*ob).tglo.len3=-1; - } else { (*ob).tglo.len2=-1; (*ob).tglo.len3=-1; } - (*ob).tglo.totalen=(*ob).tglo.len1+1; - if ((*ob).tglo.len2>-1) (*ob).tglo.totalen*=(*ob).tglo.len2+1; - if ((*ob).tglo.len3>-1) (*ob).tglo.totalen*=(*ob).tglo.len3+1; - if (pieza!=p_corce) error(3,19); lexico(); // esperando ']' - if (pieza==p_asig) { - save_error(1); - lexico(); tglo_init(3); - if (imem-_imem>(*ob).tglo.totalen) error(4,48); // demasiados valores para la tabla - } - } - imem=_imem+(*ob).tglo.totalen; - test_buffer(&mem,&imem_max,imem); - - } else { // Variable global - - (*ob).tipo=tvglo; (*ob).vglo.offset=imem; - if (pieza==p_asig) { lexico(); mem[imem]=constante(); } - test_buffer(&mem,&imem_max,++imem); - - } - } - if (!free_sintax) if (pieza!=p_ptocoma && pieza!=p_coma) error(3,9); // esperando ';' - while (pieza==p_ptocoma || pieza==p_coma) lexico(); - } - } - } - - // - // Variables locales, no se pueden usar en expresiones constantes - // - // := p_id [ p_asig ] {;} - // - // := p_id p_corab ( p_corce p_asig - // | p_corce [ p_asig ] ) {;} - // - - if (pieza==p_local) { - pasa_ptocoma(); - while (pieza==p_id || pieza==p_int || pieza==p_pointer || pieza==p_struct || pieza==p_string || pieza==p_byte || pieza==p_word) { - - if (pieza==p_struct) { - - lexico(); - - if (pieza==p_pointer) { // Se define un puntero a struct - - lexico(); if (pieza!=p_id) error(1,27); ob=o; // esperando el nombre de la estructura - if ((*ob).tipo==tnone) error(0,28); // No se define el pointer así - if ((*ob).tipo!=tsglo && (*ob).tipo!=tsloc) error(0,28); - lexico(); - puntero_a_struct_local: - analiza_pointer_struct(tpslo,iloc,ob); - if (pieza==p_asig) { lexico(); loc[iloc]=constante(); } - test_buffer(&loc,&iloc_max,iloc++); - - if (pieza==p_coma) { - lexico(); - if (pieza==p_pointer) lexico(); - goto puntero_a_struct_local; - } else { - if (!free_sintax) if (pieza!=p_ptocoma) error(3,9); // esperando ';' - while (pieza==p_ptocoma || pieza==p_coma) lexico(); - } - - } else { - - if (pieza!=p_id) error(1,27); // esperando el nombre de la estructura - ob=o; member=ob; lexico(); - - if ((*ob).tipo!=tnone) error(2,30); // el nombre no es nuevo - - (*ob).tipo=tsloc; (*ob).sloc.offset=_imem=iloc; - if (pieza==p_corab) { - member2=member; member=NULL; lexico(); - if (((*ob).sloc.items1=constante())<0) error(4,43); // estructura de longitud negativa - if (pieza==p_coma) { - lexico(); - if (((*ob).sloc.items2=constante())<0) error(4,43); // idem - if (pieza==p_coma) { - lexico(); - if (((*ob).sloc.items3=constante())<0) error(4,43); // reidem - } else (*ob).sloc.items3=-1; - } else { (*ob).sloc.items2=-1; (*ob).sloc.items3=-1; } - member=member2; - (*ob).sloc.totalitems=(*ob).sloc.items1+1; - if ((*ob).sloc.items2>-1) (*ob).sloc.totalitems*=(*ob).sloc.items2+1; - if ((*ob).sloc.items3>-1) (*ob).sloc.totalitems*=(*ob).sloc.items3+1; - if (pieza!=p_corce) error(3,19); lexico(); // esperando ']' - } else { - (*ob).sloc.totalitems=1; - (*ob).sloc.items1=0; (*ob).sloc.items2=-1; (*ob).sloc.items3=-1; - } - if (((*ob).sloc.len_item=analiza_struct_local(_imem))==0) error(0,47); // estructura vacia - member=NULL; lexico(); - iloc=(*ob).sloc.offset; dup=(*ob).sloc.totalitems+1; - if (dup>1) { - test_buffer(&loc,&iloc_max,iloc+(*ob).sloc.len_item*(*ob).sloc.totalitems); - test_buffer(&frm,&ifrm_max,imem+(*ob).sloc.len_item*(*ob).sloc.totalitems); - while (--dup) { - memcpy(&loc[iloc],&loc[_imem],(*ob).sloc.len_item<<2); - memcpy(&frm[iloc],&frm[_imem],(*ob).sloc.len_item<<2); - iloc+=(*ob).sloc.len_item; - } - } iloc=_imem; - if (pieza==p_asig) { - save_error(1); lexico(); tloc_init(0); - if (iloc-_imem-1>=(*ob).sloc.len_item*(*ob).sloc.totalitems) error(4,55); // demasiados valores para la estructura - } while (pieza==p_ptocoma) lexico(); - iloc=_imem+(*ob).sloc.len_item*(*ob).sloc.totalitems; - test_buffer(&loc,&iloc_max,iloc); - } - - } else if (pieza==p_string) { // Cadena local - - lexico(); - - if (pieza==p_pointer) { // Puntero a byte - - lexico(); puntero5: - ob=analiza_pointer(tpclo,iloc); - if (pieza==p_asig) { lexico(); loc[iloc]=constante(); } - test_buffer(&loc,&iloc_max,++iloc); - if (pieza==p_coma) { - lexico(); if (pieza==p_pointer) lexico(); - goto puntero5; - } - - } else { - - if (pieza!=p_id) error(1,29); // esperando el nombre de la cadena - ob=o; if ((*ob).tipo!=tnone) error(0,30); lexico(); // el nombre no es nuevo - (*ob).tipo=tcloc; - _imem=iloc; - (*ob).cloc.offset=_imem+1; - if (pieza==p_corab) { - lexico(); - if (pieza==p_corce) { - lexico(); - (*ob).cloc.totalen=255; - } else { - if (((*ob).cloc.totalen=constante())<0) error(4,31); // cadena de long. negativa - if ((*ob).cloc.totalen>0xFFFFF) error(4,32); // cadena demasiado larga - if (pieza!=p_corce) error(3,19); // esperando ']' - lexico(); - } - } else (*ob).cloc.totalen=255; - if (pieza==p_asig) { - save_error(1); - _itxt=itxt; - lexico(); - if (pieza!=p_lit && !(pieza==p_id && (*o).tipo==tcons && (*o).cons.literal)) - error(3,46); // se esperaba un literal - if (strlen((char*)&mem[pieza_num])>(*ob).cloc.totalen+1) - error(4,49); // literal demasiado largo - iloc=_imem+1+((*ob).cloc.totalen+5)/4; // ej. c[32] -> c[0]..c[32],NUL - test_buffer(&loc,&iloc_max,iloc); - strcpy((char*)&loc[_imem+1],(char*)&mem[pieza_num]); - itxt=_itxt; // Saca la cadena del segmento de textos - lexico(); - } else { - iloc=_imem+1+((*ob).cloc.totalen+5)/4; - test_buffer(&loc,&iloc_max,iloc); - } loc[_imem]=0xDAD00000|(*ob).cloc.totalen; - } - - if (pieza==p_coma) pieza=p_string; else { - if (!free_sintax) if (pieza!=p_ptocoma) error(3,9); // esperando ';' - while (pieza==p_ptocoma || pieza==p_coma) lexico(); - } - - } else if (pieza==p_byte) { // Tabla Byte local - - lexico(); - - if (pieza==p_pointer) { // Puntero a byte - - lexico(); puntero6: - ob=analiza_pointer(tpblo,iloc); - if (pieza==p_asig) { lexico(); loc[iloc]=constante(); } - test_buffer(&loc,&iloc_max,++iloc); - if (pieza==p_coma) { - lexico(); if (pieza==p_pointer) lexico(); - goto puntero6; - } - - } else { - - if (pieza!=p_id) error(1,23); // esperando un nombre - ob=o; if ((*ob).tipo!=tnone) error(0,30); lexico(); // el nombre no es nuevo - (*ob).tipo=tbloc; (*ob).bloc.offset=_imem=iloc; - if (pieza==p_corab) { - lexico(); - if (pieza==p_corce) { - lexico(); if (pieza!=p_asig) error(3,7); lexico(); // esperando '=' - oimemptr=(byte*)&loc[iloc]; - tloc_init(2); - (*ob).bloc.len1=imemptr-oimemptr-1; - (*ob).bloc.len2=-1; - (*ob).bloc.len3=-1; - (*ob).bloc.totalen=((*ob).bloc.len1+4)/4; - } else { - if (((*ob).bloc.len1=constante())<0) error(4,40); // tabla de long. negativa - if (pieza==p_coma) { - lexico(); - if (((*ob).bloc.len2=constante())<0) error(4,40); // idem - if (pieza==p_coma) { - lexico(); - if (((*ob).bloc.len3=constante())<0) error(4,40); // reidem - } else (*ob).bloc.len3=-1; - } else { (*ob).bloc.len2=-1; (*ob).bloc.len3=-1; } - - (*ob).bloc.totalen=(*ob).bloc.len1+1; - if ((*ob).bloc.len2>-1) (*ob).bloc.totalen*=(*ob).bloc.len2+1; - if ((*ob).bloc.len3>-1) (*ob).bloc.totalen*=(*ob).bloc.len3+1; - if (pieza!=p_corce) error(3,19); lexico(); // esperando ']' - if (pieza==p_asig) { - save_error(1); - lexico(); - oimemptr=(byte*)&loc[iloc]; - tloc_init(2); - if (imemptr-oimemptr>(*ob).bloc.totalen) error(4,48); // demasiados valores para la tabla - } (*ob).bloc.totalen=((*ob).bloc.totalen+3)/4; - } - } else { // Byte local - (*ob).tipo=tbloc; (*ob).bloc.offset=iloc; - (*ob).bloc.len1=0; - (*ob).bloc.len2=-1; - (*ob).bloc.len3=-1; - (*ob).bloc.totalen=1; // 1 int - if (pieza==p_asig) { - save_error(1); - lexico(); - loc[iloc]=constante(); - if (loc[iloc]<0 || loc[iloc]>255) error(4,50); // valor byte fuera de rango - } - } iloc=_imem+(*ob).bloc.totalen; test_buffer(&loc,&iloc_max,iloc); - } - - if (pieza==p_coma) pieza=p_byte; else { - if (!free_sintax) if (pieza!=p_ptocoma) error(3,9); // esperando ';' - while (pieza==p_ptocoma || pieza==p_coma) lexico(); - } - - } else if (pieza==p_word) { // Tabla Word local - - lexico(); - - if (pieza==p_pointer) { // Puntero a byte - - lexico(); puntero7: - ob=analiza_pointer(tpwlo,iloc); - if (pieza==p_asig) { lexico(); loc[iloc]=constante(); } - test_buffer(&loc,&iloc_max,++iloc); - if (pieza==p_coma) { - lexico(); if (pieza==p_pointer) lexico(); - goto puntero7; - } - - } else { - - if (pieza!=p_id) error(1,23); // esperando un nombre - ob=o; if ((*ob).tipo!=tnone) error(0,30); lexico(); // el nombre no es nuevo - (*ob).tipo=twloc; (*ob).wloc.offset=_imem=iloc; - if (pieza==p_corab) { - lexico(); - if (pieza==p_corce) { - lexico(); if (pieza!=p_asig) error(3,7); lexico(); // esperando '=' - oimemptr=(byte*)&loc[iloc]; - tloc_init(1); - (*ob).wloc.len1=(imemptr-oimemptr)/2-1; - (*ob).wloc.len2=-1; - (*ob).wloc.len3=-1; - (*ob).wloc.totalen=((*ob).wloc.len1+2)/2; - } else { - if (((*ob).wloc.len1=constante())<0) error(4,40); // tabla de long. negativa - if (pieza==p_coma) { - lexico(); - if (((*ob).wloc.len2=constante())<0) error(4,40); // idem - if (pieza==p_coma) { - lexico(); - if (((*ob).wloc.len3=constante())<0) error(4,40); // reidem - } else (*ob).wloc.len3=-1; - } else { (*ob).wloc.len2=-1; (*ob).wloc.len3=-1; } - - (*ob).wloc.totalen=(*ob).wloc.len1+1; - if ((*ob).wloc.len2>-1) (*ob).wloc.totalen*=(*ob).wloc.len2+1; - if ((*ob).wloc.len3>-1) (*ob).wloc.totalen*=(*ob).wloc.len3+1; - if (pieza!=p_corce) error(3,19); lexico(); // esperando ']' - if (pieza==p_asig) { - save_error(1); - lexico(); - oimemptr=(byte*)&loc[iloc]; - tloc_init(1); - if (imemptr-oimemptr>(*ob).wloc.totalen*2) error(4,48); // demasiados valores para la tabla - } (*ob).wloc.totalen=((*ob).wloc.totalen+1)/2; - } - } else { // Word local - (*ob).tipo=twloc; (*ob).wloc.offset=iloc; - (*ob).wloc.len1=0; - (*ob).wloc.len2=-1; - (*ob).wloc.len3=-1; - (*ob).wloc.totalen=1; // 1 int - if (pieza==p_asig) { - save_error(1); - lexico(); - loc[iloc]=constante(); - if (loc[iloc]<0 || loc[iloc]>65535) error(4,51); // valor word fuera de rango - } - } iloc=_imem+(*ob).wloc.totalen; test_buffer(&loc,&iloc_max,iloc); - } - - if (pieza==p_coma) pieza=p_word; else { - if (!free_sintax) if (pieza!=p_ptocoma) error(3,9); // esperando ';' - while (pieza==p_ptocoma || pieza==p_coma) lexico(); - } - - } else if (pieza==p_int || pieza==p_id || pieza==p_pointer) { - - if (pieza==p_int) { - lexico(); - if (pieza!=p_id && pieza!=p_pointer) error(1,23); // esperando un nombre - } - - if (pieza==p_pointer) { // Miembro puntero a int - - lexico(); puntero8: - ob=analiza_pointer(tpilo,iloc); - if (pieza==p_asig) { lexico(); loc[iloc]=constante(); } - test_buffer(&loc,&iloc_max,++iloc); - if (pieza==p_coma) { - lexico(); if (pieza==p_pointer) lexico(); - goto puntero8; - } - - } else { - - ob=o; if ((*ob).tipo!=tnone) error(0,30); lexico(); // el nombre no es nuevo - if (pieza==p_corab) { // Tabla local - lexico(); - (*ob).tipo=ttloc; (*ob).tloc.offset=_imem=iloc; - if (pieza==p_corce) { - lexico(); if (pieza!=p_asig) error(3,7); lexico(); // esperando '=' - tloc_init(3); - (*ob).tloc.len1=iloc-_imem-1; - (*ob).tloc.len2=-1; - (*ob).tloc.len3=-1; - (*ob).tloc.totalen=iloc-_imem; - } else { - if (((*ob).tloc.len1=constante())<0) error(4,40); // tabla de long. negativa - if (pieza==p_coma) { - lexico(); - if (((*ob).tloc.len2=constante())<0) error(4,40); // idem - if (pieza==p_coma) { - lexico(); - if (((*ob).tloc.len3=constante())<0) error(4,40); // reidem - } else (*ob).tloc.len3=-1; - } else { (*ob).tloc.len2=-1; (*ob).tloc.len3=-1; } - (*ob).tloc.totalen=(*ob).tloc.len1+1; - if ((*ob).tloc.len2>-1) (*ob).tloc.totalen*=(*ob).tloc.len2+1; - if ((*ob).tloc.len3>-1) (*ob).tloc.totalen*=(*ob).tloc.len3+1; - if (pieza!=p_corce) error(3,19); lexico(); // esperando ']' - if (pieza==p_asig) { - save_error(1); - lexico(); tloc_init(3); - if (iloc-_imem>(*ob).tloc.totalen) error(4,48); } // demasiados valores para la tabla - } - iloc=_imem+(*ob).tloc.totalen; - test_buffer(&loc,&iloc_max,iloc); - - } else { // Variable local - - (*ob).tipo=tvloc; (*ob).vloc.offset=iloc; - if (pieza==p_asig) { lexico(); loc[iloc]=constante(); } - test_buffer(&loc,&iloc_max,++iloc); - - } - } - if (!free_sintax) if (pieza!=p_ptocoma && pieza!=p_coma) error(3,9); // esperando ';' - while (pieza==p_ptocoma || pieza==p_coma) lexico(); - } - } - } - - // - // Código principal - // - - // Genera el salto al inicio del código (long_header) - - mem[0]=0; mem[1]=imem; iloc_len=iloc; - - g2(ltyp,(int)bloque_actual); - g2(lcbp,0); - inicio=0; final=imem-1; - grabar_sentencia(); - - // otra vez import... se ha usado sintaxis de DIV 1. - // de nuevo le decimos k se lo meta por las narices... - - if (pieza==p_import) { - warning(2); // sintaxis antigua - lexico(); - if (pieza!=p_lit && !(pieza==p_id && (*o).tipo==tcons && (*o).cons.literal)) - error(1,46); // se esperaba un literal - lexico(); - if (!free_sintax) if (pieza!=p_ptocoma) error(3,9); // esperando ';' - while (pieza==p_ptocoma || pieza==p_coma) lexico(); - } - - // esta instrucción realiza un salto a la rutina donde están los limp - // (importación de DLLs). Como esta la colocaremos al final (porque, hasta - // que lleguemos al final no sabremos qué dlls hay que importar), dejamos - // el parámetro de ljmp de momento a 0 y guardamos el offset en - // salto_import, donde al final sustituiremos el 0 por el offset adecuado. - - salto_import=imem+1; - g2(ljmp,0); - - // El primer FRAME, y la carga de variables PRIVATE, se ejecutan - // conjuntamente en el BEGIN del programa principal. - - final=imem; - - parametros=-1; - bloque_lexico=bloque_actual; - n=iloc; - analiza_private(); - if (iloc>iloc_len) iloc_len=iloc; - iloc=n; - parametros=0; - - g1(lfrm); - - if (pieza!=p_begin) error(0,56); - inicio_sentencia(); inicio=final; - lexico(); final_sentencia(); grabar_sentencia(); - - sentencia(); - - if (pieza!=p_end) error(0,57); inicio_sentencia(); - g1(lret); - pasa_ptocoma(); final_sentencia(); grabar_sentencia(); - - - // - // Procesos - // - // p_process p_id p_abrir [ id { , id } ] p_cerrar { ; } p_begin ... p_end - // - - save_error(0); - while (pieza==p_process || pieza==p_function) { - n=pieza; inicio_sentencia(); lexico(); - if (pieza!=p_id) error(1,70); // esperando el nombre del proceso o funcion - ob=o; lexico(); - if ((*ob).tipo==tproc && (*ob).usado) { - num_par=(*ob).proc.num_par; bloque_lexico=bloque_actual=ob; - _imem=(*ob).proc.offset; while(_imem) { - _imem_old=mem[_imem]; mem[_imem]=imem; _imem=_imem_old; } - } else if ((*ob).tipo==tnone) { - (*ob).usado=0; (*ob).tipo=tproc; - (*ob).proc.bloque=bloque_lexico=bloque_actual=ob; - } else error(2,30); // el nombre no es nuevo - (*ob).proc.offset=imem; (*ob).proc.num_par=0; - - g2(ltyp,(int)bloque_actual); - if (n==p_function) g1(lnop); - g2(lcbp,0); _imem=imem-1; - if (pieza!=p_abrir) error(3,22); // esperando '(' - - parametros=1; n=iloc; lexico(); - - while (pieza!=p_cerrar) { - (*ob).proc.num_par++; expresion_cpa(); - if (pieza!=p_cerrar) if (pieza!=p_coma) error(3,35); // se esperaba una coma - else { lexico(); if (pieza==p_cerrar) error(3,36); } // se esperaba otro parámetro - } - if ((*ob).usado) { - if (num_par==(*ob).proc.num_par) (*ob).usado=0; else error(0,38); // nº de parametros incorrecto - } - pasa_ptocoma(); final_sentencia(); - - if (parametros>1) { - g2(lpar,parametros-1); - } - - parametros=-1; // Para que los parámetros se puedan repetir como PRIVATE - - num_par=mem[_imem]=(*ob).proc.num_par; - - analiza_private(); parametros=0; - - if (iloc>iloc_len) iloc_len=iloc; iloc=n; - - if (pieza!=p_begin) error(0,56); lexico(); // esperando BEGIN - final=imem-1; grabar_sentencia(); - sentencia(); - if (pieza!=p_end) error(0,57); // esperando END - inicio_sentencia(); - g1(lret); - pasa_ptocoma(); final_sentencia(); grabar_sentencia(); - - save_error(0); - } - - if (pieza!=p_ultima) error(4,71); // esperando PROCESS o FUNCTION - -} - -//----------------------------------------------------------------------------- -// Lexico (lee una nueva pieza del *source) -//----------------------------------------------------------------------------- - -void lexico(void) -{ - struct objeto * * ptr_o; - byte ** ptr, * _ivnom, h, * _source=source; - struct lex_ele * e; - - int n; - - if (!coment) { - old_linea=linea; - old_ierror=ierror; - old_ierror_end=ierror_end; - } - -lex_scan: - - ierror=_source; - - switch ((int)lex_case[*_source]) { // Puntero a un lex_ele o l_??? - - case l_err: - if (coment) { pieza=p_rem; _source++; } - else error(0,5); // carácter no reconocido - _source++; - break; - - case l_eof: - pieza=p_ultima; - break; - - case l_cr: - linea++; - if (*_source==cr && *(_source+1)==lf) _source+=2; - else _source++; - - ultima_linea=_source; - goto lex_scan; - - case l_id : - if (coment) { pieza=p_rem; _source++; break; } - - _ivnom=ivnom.b; - *ivnom.p++=0; - *ivnom.p++=0; - h=0; - - while (*ivnom.b=lower[*_source++]) - h=((byte)(h<<1)+(h>>7))^(*ivnom.b++); - - ivnom.b++; - _source--; - if (ivnom.b-vnom>max_obj*long_med_id) error(0,2); // Excedida la capacidad del vector de nombres - - ptr=&vhash[h]; - - while (*ptr && strcmp((char *)(ptr+2),(char *)_ivnom+8)) - ptr=(byte**)*ptr; - - if (!strcmp((byte *)(ptr+2),_ivnom+8)) { // id encontrado - ivnom.b=_ivnom; // lo saca de vnom - pieza=(int)*(ptr+1); - - if (pieza<256 && pieza>=0) { // palabra reservada (token) - - if (pieza==p_rem) { - while (*_source!=cr && *_source!=lf) _source++; - goto lex_scan; - } - - } - else { // objeto (id anterior) - - ptr_o=(void*)(ptr+1); - o=*ptr_o; - pieza=p_id; - - while(o!=NULL && ( ((*o).bloque && bloque_lexico!=(*o).bloque) || - ((*o).member!=member) )) - o=(*o).anterior; - - if(o==NULL) { // No encontrado - o=iobj++; (*o).anterior=*ptr_o; *ptr_o=o; - (*o).name=(byte*)(ptr_o+1); - (*o).member=member; - (*o).param=0; - (*o).dll=-1; - if (parametros) (*o).bloque=bloque_actual; - if (num_obj++==max_obj) - error(0,6); // excedida la capacidad de la tabla de objetos - } - else { - //printf("->->-> %s\n",(char*)_ivnom+8); - if ((*o).tipo==tcons) - pieza_num=(*o).cons.valor; - if((*o).dll!=-1) - dlls[(*o).dll].usado=1; - } - } - } - else { // id nuevo - *ptr=_ivnom; - ptr_o=(void*)(_ivnom+4); - *ptr_o=o=iobj++; - pieza=p_id; - - (*o).name=(byte*)_ivnom+8; - (*o).member=member; - (*o).dll=-1; - if (parametros) (*o).bloque=bloque_actual; - if (num_obj++==max_obj) - error(0,6); // excedida la capacidad de la tabla de objetos - } - - break; - - case l_spc: - while ((*++_source)==' '); - goto lex_scan; - - case l_lit: - if (coment) { pieza=p_rem; _source++; break; } - - pieza=p_lit; // Literal entre dos h - h=*_source; - _ivnom=ivnom.b; - - do { - _source++; - if (*_source==cr || *_source==lf) { - error(0,3); // literal sin cerrar - break; - } - - if (*_source==h) { - if (*(_source+1)==h) *_ivnom=*++_source; - else *_ivnom=0; - } else *_ivnom=*_source; - - } while (*_ivnom++); - - _source++; - next_lexico(_source,0,0); - - while (next_pieza==p_lit) { - next_lexico(_source,0,linea); - linea=next_linea; - _source=next_source; - h=*_source; _ivnom--; - do { - _source++; - if (*_source==cr || *_source==lf) { - error(0,3); // literal sin cerrar - break; - } - - if (*_source==h) { - if (*(_source+1)==h) *_ivnom=*++_source; - else *_ivnom=0; - } else *_ivnom=*_source; - - } while (*_ivnom++); - - _source++; - next_lexico(_source,0,0); - } - - n=(strlen(ivnom.b)+4)/4; - memcpy(&mem_ory[itxt],ivnom.b,strlen(ivnom.b)+1); - - pieza_num=itxt; - itxt+=n; - - break; - - case l_num: - - if (coment) { pieza=p_rem; _source++; break; } - - pieza=p_num; - pieza_num=0; - - // Número hexadecimal - if (*_source=='0' && lower[*(_source+1)]=='x') { - _source+=2; - while ((int)lex_case[*_source]==l_num || - (lower[*_source]>='a' && lower[*_source]<='f')) { - if ((int)lex_case[*_source]==l_num) - pieza_num=pieza_num*16+*_source++-0x30; - else - pieza_num=pieza_num*16+lower[*_source++]-'a'+10; - } - } - else do { - pieza_num=pieza_num*10+*_source++-0x30; - } while ((int)lex_case[*_source]==l_num); - - break; - - default: // puntero a un lex_ele - - e=lex_case[*_source++]; - _ivnom=_source; - pieza=(*e).token; - - while (e=(*e).siguiente) { - - while (*_source!=(*e).caracter && (*e).alternativa) - e=(*e).alternativa; - - if (*_source++==(*e).caracter && (*e).token) { - pieza=(*e).token; - _ivnom=_source; - } - } - - _source=_ivnom; - - if (pieza==p_rem && !coment) { - while (*_source!=cr && *_source!=lf) _source++; - goto lex_scan; - } - - if (pieza==p_ini_rem) { - coment++; - do { - source=_source; - lexico(); - _source=source; - } while (pieza!=p_end_rem); - coment--; - goto lex_scan; - } - - if (pieza==p_ultima) { - if (coment) error(0,1); // llegó el final dentro de un comentario - else error(0,4); // símbolo no reconocido (¡¡creo!!) - } - - break; - - } - - source=_source; - ierror_end=_source-1; -} - - -//----------------------------------------------------------------------------- -// Adivina cual será la siguiente pieza lexica leida (y donde estará) -//----------------------------------------------------------------------------- - -// No genera nunca errores - -byte * next_lexico(byte * _source, int coment, int linea) -{ - byte ** ptr, * _ivnom, h; - struct lex_ele * e; - - if (!coment && linea) { - old_linea=linea; - old_ierror=ierror; - old_ierror_end=ierror_end; - } - -lex_scan: - - if (linea) ierror=_source; - next_source=_source; - - switch ((int)lex_case[*_source]) { - - case l_err: - if (coment) { _source++; goto lex_scan; } - next_pieza=0; - break; - - case l_cr : - if (linea) { - - linea++; - if (*_source==cr && *(_source+1)==lf) _source+=2; - else _source++; - - ultima_linea=_source; - goto lex_scan; - - } - else { - - if (*_source==cr && *(_source+1)==lf) _source+=2; - else _source++; - - goto lex_scan; - - } - - case l_eof: - next_pieza=0; - break; - - case l_id : - if (coment) { _source++; goto lex_scan; } - - _ivnom=ivnom.b; - *ivnom.p++=0; - *ivnom.p++=0; - h=0; - - while (*ivnom.b=lower[*_source++]) - h=((byte)(h<<1)+(h>>7))^(*ivnom.b++); - - ivnom.b++; - _source--; - ptr=&vhash[h]; - - while (*ptr && strcmp((char *)(ptr+2),(char *)_ivnom+8)) - ptr=(unsigned char **)*ptr; - - if (!strcmp((char *)(ptr+2),(char *)_ivnom+8)) { // id encontrado - ivnom.b=_ivnom; // lo saca de vnom - next_pieza=(int)*(ptr+1); - if (next_pieza<256 && next_pieza>=0) { // palabra reservada (token) - if (next_pieza==p_rem) { - while (*_source!=cr) _source++; - goto lex_scan; - } - } else { // objeto (id anterior) - next_pieza=p_id; - } - } else { - ivnom.b=_ivnom; // lo saca de vnom - next_pieza=p_id; // id nuevo - } - - break; - - case l_spc: - while ((*++_source)==' '); - goto lex_scan; - - case l_lit: - if (coment) { _source++; goto lex_scan; } - next_pieza=p_lit; - break; - - case l_num: - if (coment) { _source++; goto lex_scan; } - next_pieza=p_num; - break; - - default: // puntero a un lex_ele - e=lex_case[*_source++]; - next_pieza=(*e).token; - _ivnom=_source; - - while (e=(*e).siguiente) { - while (*_source!=(*e).caracter && (*e).alternativa) - e=(*e).alternativa; - - if (*_source++==(*e).caracter && (*e).token) { - next_pieza=(*e).token; - _ivnom=_source; - } - } - - _source=_ivnom; - - if (next_pieza==p_rem && !coment) { - while (*_source!=cr && *_source!=lf) _source++; - goto lex_scan; - } - - if (next_pieza==p_ini_rem) { - coment++; - do { - _source=next_lexico(_source,coment,linea); - linea=next_linea; - } while (next_pieza!=p_end_rem); - coment--; - goto lex_scan; - } - - break; - - } - - next_linea=linea; - return(_source); -} - - -//----------------------------------------------------------------------------- -// Pasa varias comas o puntos y coma seguidos -//----------------------------------------------------------------------------- - -void pasa_ptocoma(void) -{ - do { - lexico(); - } while (pieza==p_ptocoma); -} - - - // - // Analiza las variables privadas de un bloque, como las locales - // - - // *** OJO *** No se debe permitir #id.tvpri - // pues fallaría a no ser que #id fuera del mismo tipo que el - // proceso actual (hermano) - -void analiza_private(void) { - struct objeto * ob, * member2; - int _imem,_imem_old,_itxt,dup; - byte *oimemptr; - - if (pieza==p_private) { - pasa_ptocoma(); - - g2(lpri,0); _imem_old=imem-1; - - while (pieza==p_id || pieza==p_int || pieza==p_pointer || pieza==p_struct || pieza==p_string || pieza==p_byte || pieza==p_word) { - - if (pieza==p_struct) { - - lexico(); - - if (pieza==p_pointer) { // Se define un puntero a struct - - lexico(); if (pieza!=p_id) error(1,27); ob=o; // esperando el nombre de la estructura - if ((*ob).tipo==tnone) error(0,28); // No se define el pointer así - if ((*ob).tipo!=tsglo && (*ob).tipo!=tsloc) error(0,28); - lexico(); - puntero_a_struct: - if (analiza_pointer_struct(tpslo,iloc,ob)==1) { - iloc++; - if (pieza==p_asig) { lexico(); mem[imem]=constante(); } - test_buffer(&mem,&imem_max,++imem); - } - - if (pieza==p_coma) { - lexico(); - if (pieza==p_pointer) lexico(); - goto puntero_a_struct; - } else { - if (!free_sintax) if (pieza!=p_ptocoma) error(3,9); // esperando ';' - while (pieza==p_ptocoma || pieza==p_coma) lexico(); - } - - } else { - - if (pieza!=p_id) error(1,27); // esperando el nombre de la estructura - ob=o; member=ob; lexico(); - - if ((*ob).tipo!=tnone) error(2,30); // el nombre no es nuevo - - (*ob).tipo=tsloc; (*ob).sloc.offset=_imem=imem; - if (pieza==p_corab) { - member2=member; member=NULL; lexico(); - if (((*ob).sloc.items1=constante())<0) error(4,43); // estructura de long. negativa - if (pieza==p_coma) { - lexico(); - if (((*ob).sloc.items2=constante())<0) error(4,43); // idem - if (pieza==p_coma) { - lexico(); - if (((*ob).sloc.items3=constante())<0) error(4,43); // reidem - } else (*ob).sloc.items3=-1; - } else { (*ob).sloc.items2=-1; (*ob).sloc.items3=-1; } - member=member2; - (*ob).sloc.totalitems=(*ob).sloc.items1+1; - if ((*ob).sloc.items2>-1) (*ob).sloc.totalitems*=(*ob).sloc.items2+1; - if ((*ob).sloc.items3>-1) (*ob).sloc.totalitems*=(*ob).sloc.items3+1; - if (pieza!=p_corce) error(3,19); lexico(); // esperando ']' - } else { - (*ob).sloc.totalitems=1; - (*ob).sloc.items1=0; (*ob).sloc.items2=-1; (*ob).sloc.items3=-1; - } - if (((*ob).sloc.len_item=analiza_struct_private(_imem))==0) error(0,47); // estructura vacia - - member=NULL; lexico(); - - imem=(*ob).sloc.offset; dup=(*ob).sloc.totalitems+1; - if (dup>1) { - test_buffer(&mem,&imem_max,imem+(*ob).sloc.len_item*(*ob).sloc.totalitems); - test_buffer(&frm,&ifrm_max,imem+(*ob).sloc.len_item*(*ob).sloc.totalitems); - while (--dup) { - memcpy(&mem[imem],&mem[_imem],(*ob).sloc.len_item<<2); - memcpy(&frm[imem],&frm[_imem],(*ob).sloc.len_item<<2); - imem+=(*ob).sloc.len_item; - } - } imem=_imem; - - if (pieza==p_asig) { - save_error(1); lexico(); tglo_init(0); - if (imem-_imem-1>=(*ob).sloc.len_item*(*ob).sloc.totalitems) error(4,55); // demasiados valores para la estructura - } while (pieza==p_ptocoma) lexico(); - - imem=_imem+(*ob).sloc.len_item*(*ob).sloc.totalitems; - (*ob).sloc.offset=iloc; iloc+=(*ob).sloc.len_item*(*ob).sloc.totalitems; - test_buffer(&mem,&imem_max,imem); - } - - } else if (pieza==p_string) { // Cadena privada - - lexico(); - - if (pieza==p_pointer) { // Puntero a byte - - lexico(); puntero1: - ob=analiza_pointer(tpclo,iloc); - if (ob==NULL) continue; else iloc++; - if (pieza==p_asig) { lexico(); mem[imem]=constante(); } - test_buffer(&mem,&imem_max,++imem); - if (pieza==p_coma) { - lexico(); if (pieza==p_pointer) lexico(); - goto puntero1; - } - - } else { - - if (pieza!=p_id) error(1,29); // esperando el nombre de la cadena - ob=o; if ((*ob).tipo!=tnone) { // Mira si se repite un parámetro ... - if (parametros==-1 && (*ob).param==1 && (*ob).bloque==bloque_actual) { - if ((*ob).tipo==tcloc) { // Se repite un string - save_error(0); - lexico(); - if (pieza==p_corab) { - lexico(); - if (pieza==p_corce) { - lexico(); - dup=255; - } else { - dup=constante(); - if (pieza!=p_corce) error(3,19); // esperando ']' - lexico(); - } - } else dup=255; - if (dup!=(*ob).cloc.totalen) error(4,41); // la longitud no coincide con la declaración anterior - else if (pieza==p_asig) error(0,42); // no se puede inicializar un parámetro - else { - while (pieza==p_ptocoma || pieza==p_coma) lexico(); - (*ob).param++; - continue; - } - } else error(0,30); // el nombre no es nuevo - } else error(0,30); - } else lexico(); - - (*ob).tipo=tcloc; - _imem=imem; - if (pieza==p_corab) { - lexico(); - if (pieza==p_corce) { - lexico(); - (*ob).cloc.totalen=255; - } else { - if (((*ob).cloc.totalen=constante())<0) error(4,31); // cadena de long. negativa - if ((*ob).cloc.totalen>0xFFFFF) error(4,32); // cadena demasiado larga - if (pieza!=p_corce) error(3,19); // esperando ']' - lexico(); - } - } else (*ob).cloc.totalen=255; - if (pieza==p_asig) { - save_error(1); - _itxt=itxt; - lexico(); - if (pieza!=p_lit && !(pieza==p_id && (*o).tipo==tcons && (*o).cons.literal)) - error(3,46); // se esperaba un literal - if (strlen((char*)&mem[pieza_num])>(*ob).cloc.totalen+1) - error(4,49); // literal demasiado largo - imem=_imem+1+((*ob).cloc.totalen+5)/4; // ej. c[32] -> c[0]..c[32],NUL - test_buffer(&mem,&imem_max,imem); - strcpy((char*)&mem[_imem+1],(char*)&mem[pieza_num]); - itxt=_itxt; // Saca la cadena del segmento de textos - lexico(); - } else { - imem=_imem+1+((*ob).cloc.totalen+5)/4; - test_buffer(&mem,&imem_max,imem); - } mem[_imem]=0xDAD00000|(*ob).cloc.totalen; - (*ob).cloc.offset=iloc+1; - iloc+=1+((*ob).cloc.totalen+5)/4; - } - - if (pieza==p_coma) pieza=p_string; else { - if (!free_sintax) if (pieza!=p_ptocoma) error(3,9); // esperando ';' - while (pieza==p_ptocoma || pieza==p_coma) lexico(); - } - - } else if (pieza==p_byte) { // Tabla Byte privado - - lexico(); - - if (pieza==p_pointer) { // Puntero a byte - - lexico(); puntero2: - ob=analiza_pointer(tpblo,iloc); - if (ob==NULL) continue; else iloc++; - if (pieza==p_asig) { lexico(); mem[imem]=constante(); } - test_buffer(&mem,&imem_max,++imem); - if (pieza==p_coma) { - lexico(); if (pieza==p_pointer) lexico(); - goto puntero2; - } - - } else { - - if (pieza!=p_id) error(1,23); // esperando un nombre - ob=o; if ((*ob).tipo!=tnone) { - if (parametros==-1 && (*ob).param==1 && (*ob).bloque==bloque_actual) { - if ((*ob).tipo==tbloc) { // Se repite un byte parámetro - lexico(); - if (pieza==p_corab) error(2,33); // no se puede pasar una tabla como parámetro - else if (pieza==p_asig) error(0,42); // no se puede inicializar un parámetro - else { - while (pieza==p_ptocoma || pieza==p_coma) { - lexico(); - } - (*ob).param++; - continue; - } - } else error(0,30); // el nombre no es nuevo - } else error(0,30); - } else lexico(); - - (*ob).tipo=tbloc; _imem=imem; - if (pieza==p_corab) { - lexico(); - if (pieza==p_corce) { - lexico(); if (pieza!=p_asig) error(3,7); lexico(); // esperando '=' - oimemptr=(byte*)&mem[imem]; - tglo_init(2); - (*ob).bloc.len1=imemptr-oimemptr-1; - (*ob).bloc.len2=-1; - (*ob).bloc.len3=-1; - (*ob).bloc.totalen=((*ob).bloc.len1+4)/4; - } else { - if (((*ob).bloc.len1=constante())<0) error(4,40); // tabla de long. negativa - if (pieza==p_coma) { - lexico(); - if (((*ob).bloc.len2=constante())<0) error(4,40); // idem - if (pieza==p_coma) { - lexico(); - if (((*ob).bloc.len3=constante())<0) error(4,40); // reidem - } else (*ob).bloc.len3=-1; - } else { (*ob).bloc.len2=-1; (*ob).bloc.len3=-1; } - - (*ob).bloc.totalen=(*ob).bloc.len1+1; - if ((*ob).bloc.len2>-1) (*ob).bloc.totalen*=(*ob).bloc.len2+1; - if ((*ob).bloc.len3>-1) (*ob).bloc.totalen*=(*ob).bloc.len3+1; - if (pieza!=p_corce) error(3,19); lexico(); // esperando ']' - if (pieza==p_asig) { - save_error(1); - lexico(); - oimemptr=(byte*)&mem[imem]; - tglo_init(2); - if (imemptr-oimemptr>(*ob).bloc.totalen) error(4,48); // demasiados valores para la tabla - } (*ob).bloc.totalen=((*ob).bloc.totalen+3)/4; - } - } else { // Byte privado - (*ob).tipo=tbloc; (*ob).bloc.offset=imem; - (*ob).bloc.len1=0; - (*ob).bloc.len2=-1; - (*ob).bloc.len3=-1; - (*ob).bloc.totalen=1; // 1 int - if (pieza==p_asig) { - save_error(1); - lexico(); - mem[imem]=constante(); - if (mem[imem]<0 || mem[imem]>255) error(4,50); // valor byte fuera de rango - } - } - imem=_imem+(*ob).bloc.totalen; test_buffer(&mem,&imem_max,imem); - (*ob).bloc.offset=iloc; iloc+=(*ob).bloc.totalen; - } - - if (pieza==p_coma) pieza=p_byte; else { - if (!free_sintax) if (pieza!=p_ptocoma) error(3,9); // esperando ';' - while (pieza==p_ptocoma || pieza==p_coma) lexico(); - } - - } else if (pieza==p_word) { // Tabla Word privada - - lexico(); - - if (pieza==p_pointer) { // Puntero a word - - lexico(); puntero3: - ob=analiza_pointer(tpwlo,iloc); - if (ob==NULL) continue; else iloc++; - if (pieza==p_asig) { lexico(); mem[imem]=constante(); } - test_buffer(&mem,&imem_max,++imem); - if (pieza==p_coma) { - lexico(); if (pieza==p_pointer) lexico(); - goto puntero3; - } - - } else { - - if (pieza!=p_id) error(1,23); // esperando un nombre - ob=o; if ((*ob).tipo!=tnone) { - if (parametros==-1 && (*ob).param==1 && (*ob).bloque==bloque_actual) { - if ((*ob).tipo==twloc) { // Se repite un word parámetro - lexico(); - if (pieza==p_corab) error(2,33); // no se puede pasar una tabla como parámetro - else if (pieza==p_asig) error(0,42); // no se puede inicializar un parámetro - else { - while (pieza==p_ptocoma || pieza==p_coma) { - lexico(); - } - (*ob).param++; - continue; - } - } else error(0,30); // el nombre no es nuevo - } else error(0,30); - } else lexico(); - - (*ob).tipo=twloc; _imem=imem; - if (pieza==p_corab) { - lexico(); - if (pieza==p_corce) { - lexico(); if (pieza!=p_asig) error(3,7); lexico(); // esperando '=' - oimemptr=(byte*)&mem[imem]; - tglo_init(1); - (*ob).wloc.len1=(imemptr-oimemptr)/2-1; - (*ob).wloc.len2=-1; - (*ob).wloc.len3=-1; - (*ob).wloc.totalen=((*ob).wloc.len1+2)/2; - } else { - if (((*ob).wloc.len1=constante())<0) error(4,40); // tabla de long. negativa - if (pieza==p_coma) { - lexico(); - if (((*ob).wloc.len2=constante())<0) error(4,40); // idem - if (pieza==p_coma) { - lexico(); - if (((*ob).wloc.len3=constante())<0) error(4,40); // reidem - } else (*ob).wloc.len3=-1; - } else { (*ob).wloc.len2=-1; (*ob).wloc.len3=-1; } - - (*ob).wloc.totalen=(*ob).wloc.len1+1; - if ((*ob).wloc.len2>-1) (*ob).wloc.totalen*=(*ob).wloc.len2+1; - if ((*ob).wloc.len3>-1) (*ob).wloc.totalen*=(*ob).wloc.len3+1; - if (pieza!=p_corce) error(3,19); lexico(); // esperando ']' - if (pieza==p_asig) { - save_error(1); - lexico(); - oimemptr=(byte*)&mem[imem]; - tglo_init(1); - if (imemptr-oimemptr>(*ob).wloc.totalen*2) error(4,48); // demasiados valores para la tabla - } (*ob).wloc.totalen=((*ob).wloc.totalen+1)/2; - } - } else { // Word privado - (*ob).tipo=twloc; (*ob).wloc.offset=imem; - (*ob).wloc.len1=0; - (*ob).wloc.len2=-1; - (*ob).wloc.len3=-1; - (*ob).wloc.totalen=1; // 1 int - if (pieza==p_asig) { - save_error(1); - lexico(); - mem[imem]=constante(); - if (mem[imem]<0 || mem[imem]>65535) error(4,51); // valor word fuera de rango - } - } - imem=_imem+(*ob).wloc.totalen; test_buffer(&mem,&imem_max,imem); - (*ob).wloc.offset=iloc; iloc+=(*ob).wloc.totalen; - } - - if (pieza==p_coma) pieza=p_word; else { - if (!free_sintax) if (pieza!=p_ptocoma) error(3,9); // esperando ';' - while (pieza==p_ptocoma || pieza==p_coma) lexico(); - } - - } else if (pieza==p_int || pieza==p_id || pieza==p_pointer) { - - if (pieza==p_int) { - lexico(); - if (pieza!=p_id && pieza!=p_pointer) error(1,23); // esperando un nombre - } - - if (pieza==p_pointer) { // Miembro puntero a int - - lexico(); puntero4: - ob=analiza_pointer(tpilo,iloc); - if (ob==NULL) continue; else iloc++; - if (pieza==p_asig) { lexico(); mem[imem]=constante(); } - test_buffer(&mem,&imem_max,++imem); - if (pieza==p_coma) { - lexico(); if (pieza==p_pointer) lexico(); - goto puntero4; - } - - } else { - - // Si el objeto no es tnone, se repite un parámetro o bien es un error - - ob=o; if ((*ob).tipo!=tnone) { - if (parametros==-1 && (*ob).param==1 && (*ob).bloque==bloque_actual) { - if ((*ob).tipo==tvloc) { // Se repite una variable local - lexico(); - if (pieza==p_corab) error(2,33); // no se puede pasar una tabla como parámetro - else if (pieza==p_asig) error(0,42); // no se puede inicializar un parámetro - else { - while (pieza==p_ptocoma || pieza==p_coma) { - lexico(); - } - (*ob).param++; - continue; - } - } else error(0,30); // el nombre no es nuevo - } else error(0,30); - } else lexico(); - - if (pieza==p_corab) { // Tabla privada - lexico(); - (*ob).tipo=ttloc; _imem=imem; - if (pieza==p_corce) { - lexico(); if (pieza!=p_asig) error(3,7); lexico(); // esperando '=' - tglo_init(3); - (*ob).tloc.len1=imem-_imem-1; - (*ob).tloc.len2=-1; - (*ob).tloc.len3=-1; - (*ob).tloc.totalen=imem-_imem; - } else { - if (((*ob).tloc.len1=constante())<0) error(4,40); // tabla de long. negativa - if (pieza==p_coma) { - lexico(); - if (((*ob).tloc.len2=constante())<0) error(4,40); // idem - if (pieza==p_coma) { - lexico(); - if (((*ob).tloc.len3=constante())<0) error(4,40); // reidem - } else (*ob).tloc.len3=-1; - } else { (*ob).tloc.len2=-1; (*ob).tloc.len3=-1; } - (*ob).tloc.totalen=(*ob).tloc.len1+1; - if ((*ob).tloc.len2>-1) (*ob).tloc.totalen*=(*ob).tloc.len2+1; - if ((*ob).tloc.len3>-1) (*ob).tloc.totalen*=(*ob).tloc.len3+1; - if (pieza!=p_corce) error(3,19); lexico(); // esperando ']' - if (pieza==p_asig) { - save_error(1); lexico(); tglo_init(3); - if (imem-_imem>(*ob).tloc.totalen) error(4,48); } // demasiados valores para la tabla - } - imem=_imem+(*ob).tloc.totalen; - test_buffer(&mem,&imem_max,imem); - (*ob).tloc.offset=iloc; iloc+=(*ob).tloc.totalen; - - } else { // Variable privada - - (*ob).tipo=tvloc; (*ob).vloc.offset=iloc++; - if (pieza==p_asig) { lexico(); mem[imem]=constante(); } - test_buffer(&mem,&imem_max,++imem); - } - } - if (!free_sintax) if (pieza!=p_ptocoma && pieza!=p_coma) error(3,9); // esperando ';' - while (pieza==p_ptocoma || pieza==p_coma) lexico(); - } (*ob).bloque=bloque_actual; - } - - mem[_imem_old]=imem; - - }; - -} - -//----------------------------------------------------------------------------- -// Análisis de una declaración pointer (int, word o byte) -//----------------------------------------------------------------------------- - -struct objeto * analiza_pointer(int tipo, int offset) -{ - struct objeto * ob; - int len1,len2,len3; - - if (pieza!=p_id) error(1,23); // esperando un nombre - ob=o; if ((*ob).tipo!=tnone) { - if (parametros==-1 && (*ob).param==1 && (*ob).bloque==bloque_actual) { - if ((*ob).tipo==tipo) { // Se repite un pointer parámetro como private - save_error(0); lexico(); - len1=-1; len2=-1; len3=-1; - if (pieza==p_corab) { lexico(); - if ((len1=constante())<0) error(4,40); // tabla de longitud negativa - if (pieza==p_coma) { - lexico(); - if ((len2=constante())<0) error(4,40); // tabla de longitud negativa - if (pieza==p_coma) { - lexico(); - if ((len3=constante())<0) error(4,40); // tabla de longitud negativa - } - } if (pieza!=p_corce) error(3,19); lexico(); // esperando ']' - } - if (len1!=(*ob).pilo.len1 || len2!=(*ob).pilo.len2 || len3!=(*ob).pilo.len3) error(4,41); // la longitud no coincide con la declaración anterior - else if (pieza==p_asig) error(0,42); // no se puede inicializar un parámetro - else { - while (pieza==p_ptocoma || pieza==p_coma) lexico(); - (*ob).param++; // No permite volver a redeclararlo - return(NULL); - } - } else error(0,30); // el nombre no es nuevo - } else error(0,30); - } else lexico(); - if (parametros==-1) (*ob).bloque=bloque_actual; - (*ob).pilo.len1=-1; (*ob).pilo.len2=-1; (*ob).pilo.len3=-1; - if (pieza==p_corab) { lexico(); - if (((*ob).pilo.len1=constante())<0) error(4,40); // tabla de longitud negativa - if (pieza==p_coma) { - lexico(); - if (((*ob).pilo.len2=constante())<0) error(4,40); // tabla de longitud negativa - if (pieza==p_coma) { - lexico(); - if (((*ob).pilo.len3=constante())<0) error(4,40); // tabla de longitud negativa - } - } - if (pieza!=p_corce) error(3,19); lexico(); // esperando ']' - } (*ob).pilo.totalen=0; - if ((*ob).pilo.len1>-1) (*ob).pilo.totalen=(*ob).pilo.len1+1; - if ((*ob).pilo.len2>-1) (*ob).pilo.totalen*=(*ob).pilo.len2+1; - if ((*ob).pilo.len3>-1) (*ob).pilo.totalen*=(*ob).pilo.len3+1; - - (*ob).tipo=tipo; (*ob).pilo.offset=offset; - - return(ob); -} - -//----------------------------------------------------------------------------- - -int analiza_struct(int offstruct) { // tras " struct id [ ] " // idðmember - int len=0,dup,i,_itxt,_imem; - struct objeto * ob; - struct objeto * old_member,* member2; - byte * oimemptr; - - while (pieza==p_ptocoma) lexico(); - - while (pieza!=p_end) { - - if (pieza==p_struct) { // Miembro struct - - lexico(); - - if (pieza==p_pointer) { // Se define un puntero a struct - - old_member=member; member=NULL; lexico(); member=old_member; - if (pieza!=p_id) error(1,27); ob=o; // esperando el nombre de la estructura - - if ((*ob).tipo==tnone) error(0,28); // No se define el pointer así - if ((*ob).tipo!=tsglo && (*ob).tipo!=tsloc) error(0,28); - lexico(); - puntero_a_struct: - analiza_pointer_struct(tpsgl,len,ob); - test_buffer(&mem,&imem_max,offstruct+len); - if (pieza==p_asig) { - lexico(); mem[offstruct+len]=constante(); - } len+=1; - - if (pieza==p_coma) { - lexico(); - if (pieza==p_pointer) lexico(); - goto puntero_a_struct; - } else { - if (!free_sintax) if (pieza!=p_ptocoma) error(3,9); // esperando ';' - while (pieza==p_ptocoma || pieza==p_coma) lexico(); - } - - } else { - - if (pieza!=p_id) error(1,27); // esperando el nombre de la estructura - ob=o; - old_member=member; member=ob; lexico(); - if ((*ob).tipo!=tnone) error(2,30); // el nombre no es nuevo - - (*ob).tipo=tsglo; (*ob).sglo.offset=len; - if (pieza==p_corab) { - member2=member; member=NULL; lexico(); - if (((*ob).sglo.items1=constante())<0) error(4,43); // estructura de longitud negativa - if (pieza==p_coma) { - lexico(); - if (((*ob).sglo.items2=constante())<0) error(4,43); // idem - if (pieza==p_coma) { - lexico(); - if (((*ob).sglo.items3=constante())<0) error(4,43); // reidem - } else (*ob).sglo.items3=-1; - } else { (*ob).sglo.items2=-1; (*ob).sglo.items3=-1; } - member=member2; - (*ob).sglo.totalitems=(*ob).sglo.items1+1; - if ((*ob).sglo.items2>-1) (*ob).sglo.totalitems*=(*ob).sglo.items2+1; - if ((*ob).sglo.items3>-1) (*ob).sglo.totalitems*=(*ob).sglo.items3+1; - if (pieza!=p_corce) error(3,19); lexico(); // esperando ']' - } else { - (*ob).sglo.totalitems=1; - (*ob).sglo.items1=0; (*ob).sglo.items2=-1; (*ob).sglo.items3=-1; - } - if (((*ob).sglo.len_item=analiza_struct(offstruct+len))==0) error(0,47); // estructura vacia - i=offstruct+len; dup=(*ob).sglo.totalitems+1; - if (dup>1) { - test_buffer(&mem,&imem_max,i+(*ob).sglo.len_item*(*ob).sglo.totalitems); - test_buffer(&frm,&ifrm_max,i+(*ob).sglo.len_item*(*ob).sglo.totalitems); - while (--dup) { - memcpy(&mem[i],&mem[offstruct+len],(*ob).sglo.len_item<<2); - memcpy(&frm[i],&frm[offstruct+len],(*ob).sglo.len_item<<2); - i+=(*ob).sglo.len_item; - } - } - len+=(*ob).sglo.len_item*(*ob).sglo.totalitems; - member=old_member; lexico(); - while (pieza==p_ptocoma) lexico(); - } - } else if (pieza==p_string) { // Miembro cadena - - lexico(); - - if (pieza==p_pointer) { // Miembro puntero a byte - - lexico(); puntero1: - ob=analiza_pointer(tpcgl,len); - test_buffer(&mem,&imem_max,offstruct+len); - if (pieza==p_asig) { - lexico(); mem[offstruct+len]=constante(); - } len+=1; - - if (pieza==p_coma) { - lexico(); if (pieza==p_pointer) lexico(); - goto puntero1; - } - - } else { - - if (pieza!=p_id) error(1,29); // esperando el nombre de la cadena - ob=o; if ((*ob).tipo!=tnone) error(0,30); lexico(); // el nombre no es nuevo - (*ob).tipo=tcglo; (*ob).cglo.offset=len+1; - if (pieza==p_corab) { - lexico(); - if (pieza==p_corce) { - lexico(); - (*ob).cglo.totalen=255; - } else { - if (((*ob).cglo.totalen=constante())<0) error(4,31); // cadena de longitud negativa - if ((*ob).cglo.totalen>0xFFFFF) error(4,32); // cadena demasiado larga - if (pieza!=p_corce) error(3,19); // esperando ']' - lexico(); - } - } else (*ob).cglo.totalen=255; - - test_buffer(&frm,&ifrm_max,offstruct+len); - frm[offstruct+len]=0xDAD00000; - - if (pieza==p_asig) { - save_error(1); - _itxt=itxt; - lexico(); - if (pieza!=p_lit && !(pieza==p_id && (*o).tipo==tcons && (*o).cons.literal)) - error(3,46); // se esperaba un literal - if (strlen((char*)&mem[pieza_num])>(*ob).cglo.totalen+1) - error(4,49); // literal demasiado largo - test_buffer(&mem,&imem_max,offstruct+len); - mem[offstruct+len]=0xDAD00000|(*ob).cglo.totalen; - strcpy((char*)&mem[offstruct+len+1],(char*)&mem[pieza_num]); - len+=1+((*ob).cglo.totalen+5)/4; - itxt=_itxt; // Saca la cadena del segmento de textos - lexico(); - } else { - test_buffer(&mem,&imem_max,offstruct+len); - mem[offstruct+len]=0xDAD00000|(*ob).cglo.totalen; - len+=1+((*ob).cglo.totalen+5)/4; - } - } - - if (pieza==p_coma) pieza=p_string; else { - if (!free_sintax) if (pieza!=p_ptocoma) error(3,9); // esperando ';' - while (pieza==p_ptocoma || pieza==p_coma) lexico(); - } - - } else if (pieza==p_byte) { // Miembro byte - - lexico(); - - if (pieza==p_pointer) { // Miembro puntero a byte - - lexico(); puntero2: - ob=analiza_pointer(tpbgl,len); - test_buffer(&mem,&imem_max,offstruct+len); - if (pieza==p_asig) { - lexico(); mem[offstruct+len]=constante(); - } len+=1; - - if (pieza==p_coma) { - lexico(); if (pieza==p_pointer) lexico(); - goto puntero2; - } - - } else { - - if (pieza!=p_id) error(1,23); // esperando un nombre - ob=o; if ((*ob).tipo!=tnone) error(0,30); lexico(); // el nombre no es nuevo - (*ob).tipo=tbglo; (*ob).bglo.offset=len; - if (pieza==p_corab) { lexico(); - if (((*ob).bglo.len1=constante())<0) error(4,40); // tabla de longitud negativa - if (pieza==p_coma) { - lexico(); - if (((*ob).bglo.len2=constante())<0) error(4,40); // idem - if (pieza==p_coma) { - lexico(); - if (((*ob).bglo.len3=constante())<0) error(4,40); // reidem - } else (*ob).bglo.len3=-1; - } else { (*ob).bglo.len2=-1; (*ob).bglo.len3=-1; } - (*ob).bglo.totalen=(*ob).bglo.len1+1; - if ((*ob).bglo.len2>-1) (*ob).bglo.totalen*=(*ob).bglo.len2+1; - if ((*ob).bglo.len3>-1) (*ob).bglo.totalen*=(*ob).bglo.len3+1; - if (pieza!=p_corce) error(3,19); lexico(); // esperando ']' - test_buffer(&mem,&imem_max,offstruct+len+((*ob).bglo.totalen+3)/4); - - test_buffer(&frm,&ifrm_max,offstruct+len+((*ob).bglo.totalen+3)/4); - memset(&frm[offstruct+len],2,(*ob).bglo.totalen); - - if (pieza==p_asig) { - _imem=imem; imem=offstruct+len; - save_error(1); lexico(); - oimemptr=(byte*)&mem[imem]; - tglo_init(2); - if (imemptr-oimemptr>(*ob).bglo.totalen) error(4,48); // demasiados valores para la tabla - imem=_imem; - } (*ob).bglo.totalen=((*ob).bglo.totalen+3)/4; - } else { - (*ob).tipo=tbglo; (*ob).bglo.offset=len; - (*ob).bglo.len1=0; - (*ob).bglo.len2=-1; - (*ob).bglo.len3=-1; - (*ob).bglo.totalen=1; // 1 int - - test_buffer(&frm,&ifrm_max,offstruct+len); - frm[offstruct+len]=2; - - if (pieza==p_asig) { - save_error(1); - lexico(); - test_buffer(&mem,&imem_max,offstruct+len); - mem[offstruct+len]=constante(); - if (mem[offstruct+len]<0 || mem[offstruct+len]>255) error(4,50); // valor byte fuera de rango - } - } len+=(*ob).bglo.totalen; - } - - if (pieza==p_coma) pieza=p_byte; else { - if (!free_sintax) if (pieza!=p_ptocoma) error(3,9); // esperando ';' - while (pieza==p_ptocoma || pieza==p_coma) lexico(); - } - - } else if (pieza==p_word) { // Miembro word - - lexico(); - - if (pieza==p_pointer) { // Miembro puntero a word - - lexico(); puntero3: - ob=analiza_pointer(tpwgl,len); - test_buffer(&mem,&imem_max,offstruct+len); - if (pieza==p_asig) { - lexico(); mem[offstruct+len]=constante(); - } len+=1; - if (pieza==p_coma) { - lexico(); if (pieza==p_pointer) lexico(); - goto puntero3; - } - - } else { - - if (pieza!=p_id) error(1,23); // esperando un nombre - ob=o; if ((*ob).tipo!=tnone) error(0,30); lexico(); // el nombre no es nuevo - (*ob).tipo=twglo; (*ob).wglo.offset=len; - if (pieza==p_corab) { lexico(); - if (((*ob).wglo.len1=constante())<0) error(4,40); // tabla de longitud negativa - if (pieza==p_coma) { - lexico(); - if (((*ob).wglo.len2=constante())<0) error(4,40); // idem - if (pieza==p_coma) { - lexico(); - if (((*ob).wglo.len3=constante())<0) error(4,40); // idem - } else (*ob).wglo.len3=-1; - } else { (*ob).wglo.len2=-1; (*ob).wglo.len3=-1; } - (*ob).wglo.totalen=(*ob).wglo.len1+1; - if ((*ob).wglo.len2>-1) (*ob).wglo.totalen*=(*ob).wglo.len2+1; - if ((*ob).wglo.len3>-1) (*ob).wglo.totalen*=(*ob).wglo.len3+1; - if (pieza!=p_corce) error(3,19); lexico(); // esperando ']' - test_buffer(&mem,&imem_max,offstruct+len+((*ob).wglo.totalen+1)/2); - - test_buffer(&frm,&ifrm_max,offstruct+len+((*ob).wglo.totalen+1)/2); - memset(&frm[offstruct+len],1,(*ob).wglo.totalen*2); - - if (pieza==p_asig) { - _imem=imem; imem=offstruct+len; - save_error(1); lexico(); - oimemptr=(byte*)&mem[imem]; - tglo_init(1); - if (imemptr-oimemptr>(*ob).wglo.totalen*2) error(4,48); // demasiados valores para la tabla - imem=_imem; - } (*ob).wglo.totalen=((*ob).wglo.totalen+1)/2; - } else { - (*ob).tipo=twglo; (*ob).wglo.offset=len; - (*ob).wglo.len1=0; - (*ob).wglo.len2=-1; - (*ob).wglo.len3=-1; - (*ob).wglo.totalen=1; // 1 int - - test_buffer(&frm,&ifrm_max,offstruct+len); - frm[offstruct+len]=1; - - if (pieza==p_asig) { - save_error(1); - lexico(); - test_buffer(&mem,&imem_max,offstruct+len); - mem[offstruct+len]=constante(); - if (mem[offstruct+len]<0 || mem[offstruct+len]>65535) error(4,51); // valor word fuera de rango - } - } len+=(*ob).wglo.totalen; - } - - if (pieza==p_coma) pieza=p_word; else { - if (!free_sintax) if (pieza!=p_ptocoma) error(3,9); // esperando ';' - while (pieza==p_ptocoma || pieza==p_coma) lexico(); - } - - } else if (pieza==p_int || pieza==p_id || pieza==p_pointer) { - - if (pieza==p_int) { - lexico(); - if (pieza!=p_id && pieza!=p_pointer) error(1,23); // esperando un nombre - } - - if (pieza==p_pointer) { // Miembro puntero a int - - lexico(); puntero4: - ob=analiza_pointer(tpigl,len); - test_buffer(&mem,&imem_max,offstruct+len); - if (pieza==p_asig) { - lexico(); mem[offstruct+len]=constante(); - } len+=1; - if (pieza==p_coma) { - lexico(); if (pieza==p_pointer) lexico(); - goto puntero4; - } - - } else { - - ob=o; if ((*ob).tipo!=tnone) error(0,30); lexico(); // el nombre no es nuevo - if (pieza==p_corab) { lexico(); // Miembro tabla - (*ob).tipo=ttglo; (*ob).tglo.offset=len; - if (((*ob).tglo.len1=constante())<0) error(4,40); // tabla de longitud negativa - if (pieza==p_coma) { - lexico(); - if (((*ob).tglo.len2=constante())<0) error(4,40); // idem - if (pieza==p_coma) { - lexico(); - if (((*ob).tglo.len3=constante())<0) error(4,40); // idem - } else (*ob).tglo.len3=-1; - } else { (*ob).tglo.len2=-1; (*ob).tglo.len3=-1; } - (*ob).tglo.totalen=(*ob).tglo.len1+1; - if ((*ob).tglo.len2>-1) (*ob).tglo.totalen*=(*ob).tglo.len2+1; - if ((*ob).tglo.len3>-1) (*ob).tglo.totalen*=(*ob).tglo.len3+1; - if (pieza!=p_corce) error(3,19); lexico(); // esperando ']' - - test_buffer(&mem,&imem_max,offstruct+len+(*ob).tglo.totalen); - if (pieza==p_asig) { - _imem=imem; imem=offstruct+len; - save_error(1); lexico(); tglo_init(0); - if (imem-(offstruct+len)>(*ob).tglo.totalen) error(4,48); // demasiados valores para la tabla - imem=_imem; - } len+=(*ob).tglo.totalen; - - } else { // Miembro variable - - (*ob).tipo=tvglo; (*ob).vglo.offset=len; - test_buffer(&mem,&imem_max,offstruct+len); - if (pieza==p_asig) { - lexico(); mem[offstruct+len]=constante(); - } len+=1; - - } - } - if (!free_sintax) if (pieza!=p_ptocoma && pieza!=p_coma) error(3,9); // esperando ';' - while (pieza==p_ptocoma || pieza==p_coma) lexico(); - } else { error(0,39); do lexico(); while (pieza==p_ptocoma); } // esperando un elemento de la estructura - } return(len); -} - -// - -int analiza_struct_local(int offstruct) { // tras " struct id [ ] " // idðmember - int len=0,dup,i,_itxt,_iloc; - struct objeto * ob; - struct objeto * old_member,* member2; - byte * oimemptr; - - while (pieza==p_ptocoma) lexico(); - - while (pieza!=p_end) { - - if (pieza==p_struct) { // Miembro struct - - lexico(); - - if (pieza==p_pointer) { // Se define un puntero a struct - - old_member=member; member=NULL; lexico(); member=old_member; - if (pieza!=p_id) error(1,27); ob=o; // esperando el nombre de la estructura - - if ((*ob).tipo==tnone) error(0,28); // No se define el pointer así - if ((*ob).tipo!=tsglo && (*ob).tipo!=tsloc) error(0,28); - lexico(); - puntero_a_struct: - analiza_pointer_struct(tpslo,len,ob); - test_buffer(&loc,&iloc_max,offstruct+len); - if (pieza==p_asig) { - lexico(); loc[offstruct+len]=constante(); - } len+=1; - - if (pieza==p_coma) { - lexico(); - if (pieza==p_pointer) lexico(); - goto puntero_a_struct; - } else { - if (!free_sintax) if (pieza!=p_ptocoma) error(3,9); // esperando ';' - while (pieza==p_ptocoma || pieza==p_coma) lexico(); - } - - } else { - - if (pieza!=p_id) error(1,27); // esperando el nombre de la estructura - ob=o; - - old_member=member; member=ob; lexico(); - if ((*ob).tipo!=tnone) error(2,30); // el nombre no es nuevo - - (*ob).tipo=tsloc; (*ob).sloc.offset=len; - if (pieza==p_corab) { - member2=member; member=NULL; lexico(); - if (((*ob).sloc.items1=constante())<0) error(4,43); // estructura de long. negativa - if (pieza==p_coma) { - lexico(); - if (((*ob).sloc.items2=constante())<0) error(4,43); // idem - if (pieza==p_coma) { - lexico(); - if (((*ob).sloc.items3=constante())<0) error(4,43); // reidem - } else (*ob).sloc.items3=-1; - } else { (*ob).sloc.items2=-1; (*ob).sloc.items3=-1; } - member=member2; - (*ob).sloc.totalitems=(*ob).sloc.items1+1; - if ((*ob).sloc.items2>-1) (*ob).sloc.totalitems*=(*ob).sloc.items2+1; - if ((*ob).sloc.items3>-1) (*ob).sloc.totalitems*=(*ob).sloc.items3+1; - if (pieza!=p_corce) error(3,19); lexico(); // esperando ']' - } else { - (*ob).sloc.totalitems=1; - (*ob).sloc.items1=0; (*ob).sloc.items2=-1; (*ob).sloc.items3=-1; - } - if (((*ob).sloc.len_item=analiza_struct_local(offstruct+len))==0) error(0,47); // estructura vacia - i=offstruct+len; dup=(*ob).sloc.totalitems+1; - if (dup>1) { - test_buffer(&loc,&iloc_max,i+(*ob).sloc.len_item*(*ob).sloc.totalitems); - test_buffer(&frm,&ifrm_max,i+(*ob).sloc.len_item*(*ob).sloc.totalitems); - while (--dup) { - memcpy(&loc[i],&loc[offstruct+len],(*ob).sloc.len_item<<2); - memcpy(&frm[i],&frm[offstruct+len],(*ob).sloc.len_item<<2); - i+=(*ob).sloc.len_item; - } - } - len+=(*ob).sloc.len_item*(*ob).sloc.totalitems; - member=old_member; lexico(); - while (pieza==p_ptocoma) lexico(); - } - - } else if (pieza==p_string) { // Miembro cadena - - lexico(); - - if (pieza==p_pointer) { // Miembro puntero a byte - - lexico(); puntero1: - ob=analiza_pointer(tpclo,len); - test_buffer(&loc,&iloc_max,offstruct+len); - if (pieza==p_asig) { - lexico(); loc[offstruct+len]=constante(); - } len+=1; - if (pieza==p_coma) { - lexico(); if (pieza==p_pointer) lexico(); - goto puntero1; - } - - } else { - - if (pieza!=p_id) error(1,29); // esperando el nombre de la cadena - ob=o; if ((*ob).tipo!=tnone) error(0,30); lexico(); // el nombre no es nuevo - (*ob).tipo=tcloc; (*ob).cloc.offset=len+1; - if (pieza==p_corab) { - lexico(); - if (pieza==p_corce) { - lexico(); - (*ob).cloc.totalen=255; - } else { - if (((*ob).cloc.totalen=constante())<0) error(4,31); // cadena de long. negativa - if ((*ob).cloc.totalen>0xFFFFF) error(4,32); // cadena demasiado larga - if (pieza!=p_corce) error(3,19); // esperando ']' - lexico(); - } - } else (*ob).cloc.totalen=255; - - test_buffer(&frm,&ifrm_max,offstruct+len); - frm[offstruct+len]=0xDAD00000; - - if (pieza==p_asig) { - save_error(1); - _itxt=itxt; - lexico(); - if (pieza!=p_lit && !(pieza==p_id && (*o).tipo==tcons && (*o).cons.literal)) - error(3,46); // se esperaba un literal - if (strlen((char*)&mem[pieza_num])>(*ob).cloc.totalen+1) - error(4,49); // literal demasiado largo - test_buffer(&loc,&iloc_max,offstruct+len); - loc[offstruct+len]=0xDAD00000|(*ob).cloc.totalen; - strcpy((char*)&loc[offstruct+len+1],(char*)&mem[pieza_num]); - len+=1+((*ob).cloc.totalen+5)/4; - itxt=_itxt; // Saca la cadena del segmento de textos - lexico(); - } else { - test_buffer(&loc,&iloc_max,offstruct+len); - loc[offstruct+len]=0xDAD00000|(*ob).cloc.totalen; - len+=1+((*ob).cloc.totalen+5)/4; - } - } - - if (pieza==p_coma) pieza=p_string; else { - if (!free_sintax) if (pieza!=p_ptocoma) error(3,9); // esperando ';' - while (pieza==p_ptocoma || pieza==p_coma) lexico(); - } - - } else if (pieza==p_byte) { // Miembro byte - - lexico(); - - if (pieza==p_pointer) { // Miembro puntero a byte - - lexico(); puntero2: - ob=analiza_pointer(tpblo,len); - test_buffer(&loc,&iloc_max,offstruct+len); - if (pieza==p_asig) { - lexico(); loc[offstruct+len]=constante(); - } len+=1; - if (pieza==p_coma) { - lexico(); if (pieza==p_pointer) lexico(); - goto puntero2; - } - - } else { - - if (pieza!=p_id) error(1,23); // esperando un nombre - ob=o; if ((*ob).tipo!=tnone) error(0,30); lexico(); // el nombre no es nuevo - (*ob).tipo=tbloc; (*ob).bloc.offset=len; - if (pieza==p_corab) { lexico(); - if (((*ob).bloc.len1=constante())<0) error(4,40); // tabla de long. negativa - if (pieza==p_coma) { - lexico(); - if (((*ob).bloc.len2=constante())<0) error(4,40); // idem - if (pieza==p_coma) { - lexico(); - if (((*ob).bloc.len3=constante())<0) error(4,40); // reidem - } else (*ob).bloc.len3=-1; - } else { (*ob).bloc.len2=-1; (*ob).bloc.len3=-1; } - (*ob).bloc.totalen=(*ob).bloc.len1+1; - if ((*ob).bloc.len2>-1) (*ob).bloc.totalen*=(*ob).bloc.len2+1; - if ((*ob).bloc.len3>-1) (*ob).bloc.totalen*=(*ob).bloc.len3+1; - if (pieza!=p_corce) error(3,19); lexico(); // esperando ']' - - test_buffer(&loc,&iloc_max,offstruct+len+((*ob).bloc.totalen+3)/4); - - test_buffer(&frm,&ifrm_max,offstruct+len+((*ob).bloc.totalen+3)/4); - memset(&frm[offstruct+len],2,(*ob).bloc.totalen); - - if (pieza==p_asig) { - _iloc=iloc; iloc=offstruct+len; - save_error(1); lexico(); - oimemptr=(byte*)&loc[iloc]; - tloc_init(2); - if (imemptr-oimemptr>(*ob).bloc.totalen) error(4,48); // demasiados valores para la tabla - iloc=_iloc; - } (*ob).bloc.totalen=((*ob).bloc.totalen+3)/4; - } else { - (*ob).tipo=tbloc; (*ob).bloc.offset=len; - (*ob).bloc.len1=0; - (*ob).bloc.len2=-1; - (*ob).bloc.len3=-1; - (*ob).bloc.totalen=1; // 1 int - - test_buffer(&frm,&ifrm_max,offstruct+len); - frm[offstruct+len]=2; - - if (pieza==p_asig) { - save_error(1); - lexico(); - test_buffer(&loc,&iloc_max,offstruct+len); - loc[offstruct+len]=constante(); - if (loc[offstruct+len]<0 || loc[offstruct+len]>255) error(4,51); // valor byte fuera de rango - } - } len+=(*ob).bloc.totalen; - } - - if (pieza==p_coma) pieza=p_byte; else { - if (!free_sintax) if (pieza!=p_ptocoma) error(3,9); // esperando ; - while (pieza==p_ptocoma || pieza==p_coma) lexico(); - } - - } else if (pieza==p_word) { // Miembro word - - lexico(); - - if (pieza==p_pointer) { // Miembro puntero a word - - lexico(); puntero3: - ob=analiza_pointer(tpwlo,len); - test_buffer(&loc,&iloc_max,offstruct+len); - if (pieza==p_asig) { - lexico(); loc[offstruct+len]=constante(); - } len+=1; - if (pieza==p_coma) { - lexico(); if (pieza==p_pointer) lexico(); - goto puntero3; - } - - } else { - - if (pieza!=p_id) error(1,23); // esperando un nombre - ob=o; if ((*ob).tipo!=tnone) error(0,30); lexico(); // el nombre no es nuevo - (*ob).tipo=twloc; (*ob).wloc.offset=len; - if (pieza==p_corab) { lexico(); - if (((*ob).wloc.len1=constante())<0) error(4,40); // tabla de long. negativa - if (pieza==p_coma) { - lexico(); - if (((*ob).wloc.len2=constante())<0) error(4,40); // idem - if (pieza==p_coma) { - lexico(); - if (((*ob).wloc.len3=constante())<0) error(4,40); // reidem - } else (*ob).wloc.len3=-1; - } else { (*ob).wloc.len2=-1; (*ob).wloc.len3=-1; } - (*ob).wloc.totalen=(*ob).wloc.len1+1; - if ((*ob).wloc.len2>-1) (*ob).wloc.totalen*=(*ob).wloc.len2+1; - if ((*ob).wloc.len3>-1) (*ob).wloc.totalen*=(*ob).wloc.len3+1; - if (pieza!=p_corce) error(3,19); lexico(); // esperando ']' - - test_buffer(&loc,&iloc_max,offstruct+len+((*ob).wloc.totalen+1)/2); - - test_buffer(&frm,&ifrm_max,offstruct+len+((*ob).wloc.totalen+1)/2); - memset(&frm[offstruct+len],1,(*ob).wloc.totalen*2); - - if (pieza==p_asig) { - _iloc=iloc; iloc=offstruct+len; - save_error(1); lexico(); - oimemptr=(byte*)&loc[iloc]; - tloc_init(1); - if (imemptr-oimemptr>(*ob).wloc.totalen*2) error(4,48); // demasiados valores para la tabla - iloc=_iloc; - } (*ob).wloc.totalen=((*ob).wloc.totalen+1)/2; - } else { - (*ob).tipo=twloc; (*ob).wloc.offset=len; - (*ob).wloc.len1=0; - (*ob).wloc.len2=-1; - (*ob).wloc.len3=-1; - (*ob).wloc.totalen=1; // 1 int - - test_buffer(&frm,&ifrm_max,offstruct+len); - frm[offstruct+len]=1; - - if (pieza==p_asig) { - save_error(1); - lexico(); - test_buffer(&loc,&iloc_max,offstruct+len); - loc[offstruct+len]=constante(); - if (loc[offstruct+len]<0 || loc[offstruct+len]>65535) error(4,51); // valor word fuera de rango - } - } len+=(*ob).wloc.totalen; - } - - if (pieza==p_coma) pieza=p_word; else { - if (!free_sintax) if (pieza!=p_ptocoma) error(3,9); // esperando ';' - while (pieza==p_ptocoma || pieza==p_coma) lexico(); - } - - } else if (pieza==p_int || pieza==p_id || pieza==p_pointer) { - - if (pieza==p_int) { - lexico(); - if (pieza!=p_id && pieza!=p_pointer) error(1,23); // esperando un nombre - } - - if (pieza==p_pointer) { // Miembro puntero a int - - lexico(); puntero4: - ob=analiza_pointer(tpilo,len); - test_buffer(&loc,&iloc_max,offstruct+len); - if (pieza==p_asig) { - lexico(); loc[offstruct+len]=constante(); - } len+=1; - if (pieza==p_coma) { - lexico(); if (pieza==p_pointer) lexico(); - goto puntero4; - } - - } else { - - ob=o; if ((*ob).tipo!=tnone) error(0,30); lexico(); // el nombre no es nuevo - if (pieza==p_corab) { lexico(); // Miembro tabla - (*ob).tipo=ttloc; (*ob).tloc.offset=len; - if (((*ob).tloc.len1=constante())<0) error(4,40); // tabla de long. negativa - if (pieza==p_coma) { - lexico(); - if (((*ob).tloc.len2=constante())<0) error(4,40); // idem - if (pieza==p_coma) { - lexico(); - if (((*ob).tloc.len3=constante())<0) error(4,40); // reidem - } else (*ob).tloc.len3=-1; - } else { (*ob).tloc.len2=-1; (*ob).tloc.len3=-1; } - (*ob).tloc.totalen=(*ob).tloc.len1+1; - if ((*ob).tloc.len2>-1) (*ob).tloc.totalen*=(*ob).tloc.len2+1; - if ((*ob).tloc.len3>-1) (*ob).tloc.totalen*=(*ob).tloc.len3+1; - if (pieza!=p_corce) error(3,19); lexico(); // esperando ']' - - test_buffer(&loc,&iloc_max,offstruct+len+(*ob).tloc.totalen); - if (pieza==p_asig) { - _iloc=iloc; iloc=offstruct+len; - save_error(1); lexico(); tloc_init(0); - if (iloc-(offstruct+len)>(*ob).tloc.totalen) error(4,48); // demasiados valores para la tabla - iloc=_iloc; - } len+=(*ob).tloc.totalen; - - } else { // Miembro variable - - (*ob).tipo=tvloc; (*ob).vloc.offset=len; - test_buffer(&loc,&iloc_max,offstruct+len); - if (pieza==p_asig) { - lexico(); loc[offstruct+len]=constante(); - } len+=1; - - } - } - if (!free_sintax) if (pieza!=p_ptocoma && pieza!=p_coma) error(3,9); // esperando ';' - while (pieza==p_ptocoma || pieza==p_coma) lexico(); - } else { error(0,39); do lexico(); while (pieza==p_ptocoma); } // esperando un elemento de la estructura - (*ob).bloque=bloque_lexico; - } return(len); -} - - -// - -int analiza_struct_private(int offstruct) { // tras " struct id [ ] " // idðmember - int len=0,dup,i,_itxt,_imem; - struct objeto * ob; - struct objeto * old_member,* member2; - byte * oimemptr; - - while (pieza==p_ptocoma) lexico(); - - while (pieza!=p_end) { - - if (pieza==p_struct) { // Miembro struct - - lexico(); - - if (pieza==p_pointer) { // Se define un puntero a struct - - old_member=member; member=NULL; lexico(); member=old_member; - if (pieza!=p_id) error(1,27); ob=o; // esperando el nombre de la estructura - - if ((*ob).tipo==tnone) error(0,28); // No se define el pointer así - if ((*ob).tipo!=tsglo && (*ob).tipo!=tsloc) error(0,28); - lexico(); - puntero_a_struct: - analiza_pointer_struct(tpslo,len,ob); - test_buffer(&mem,&imem_max,offstruct+len); - if (pieza==p_asig) { - lexico(); mem[offstruct+len]=constante(); - } len+=1; - - if (pieza==p_coma) { - lexico(); - if (pieza==p_pointer) lexico(); - goto puntero_a_struct; - } else { - if (!free_sintax) if (pieza!=p_ptocoma) error(3,9); // esperando ';' - while (pieza==p_ptocoma || pieza==p_coma) lexico(); - } - - } else { - - if (pieza!=p_id) error(1,27); // esperando el nombre de la estructura - ob=o; - - old_member=member; member=ob; lexico(); - if ((*ob).tipo!=tnone) error(2,30); // el nombre no es nuevo - - (*ob).tipo=tsloc; (*ob).sloc.offset=len; - if (pieza==p_corab) { - member2=member; member=NULL; lexico(); - if (((*ob).sloc.items1=constante())<0) error(4,43); // estructura de long. negativa - if (pieza==p_coma) { - lexico(); - if (((*ob).sloc.items2=constante())<0) error(4,43); // idem - if (pieza==p_coma) { - lexico(); - if (((*ob).sloc.items3=constante())<0) error(4,43); // reidem - } else (*ob).sloc.items3=-1; - } else { (*ob).sloc.items2=-1; (*ob).sloc.items3=-1; } - member=member2; - (*ob).sloc.totalitems=(*ob).sloc.items1+1; - if ((*ob).sloc.items2>-1) (*ob).sloc.totalitems*=(*ob).sloc.items2+1; - if ((*ob).sloc.items3>-1) (*ob).sloc.totalitems*=(*ob).sloc.items3+1; - if (pieza!=p_corce) error(3,19); lexico(); // esperando ']' - } else { - (*ob).sloc.totalitems=1; - (*ob).sloc.items1=0; (*ob).sloc.items2=-1; (*ob).sloc.items3=-1; - } - if (((*ob).sloc.len_item=analiza_struct_private(offstruct+len))==0) error(0,55); // demasiados valores para la estructura - i=offstruct+len; dup=(*ob).sloc.totalitems+1; - if (dup>1) { - test_buffer(&mem,&imem_max,i+(*ob).sloc.len_item*(*ob).sloc.totalitems); - test_buffer(&frm,&ifrm_max,i+(*ob).sloc.len_item*(*ob).sloc.totalitems); - while (--dup) { - memcpy(&mem[i],&mem[offstruct+len],(*ob).sloc.len_item<<2); - memcpy(&frm[i],&frm[offstruct+len],(*ob).sloc.len_item<<2); - i+=(*ob).sloc.len_item; - } - } - len+=(*ob).sloc.len_item*(*ob).sloc.totalitems; - member=old_member; lexico(); - while (pieza==p_ptocoma) lexico(); - } - - } else if (pieza==p_string) { // Miembro cadena - - lexico(); - - if (pieza==p_pointer) { // Miembro puntero a byte - - lexico(); puntero1: - ob=analiza_pointer(tpclo,len); - test_buffer(&mem,&imem_max,offstruct+len); - if (pieza==p_asig) { - lexico(); mem[offstruct+len]=constante(); - } len+=1; - if (pieza==p_coma) { - lexico(); if (pieza==p_pointer) lexico(); - goto puntero1; - } - - } else { - - if (pieza!=p_id) error(1,23); // esperando un nombre - ob=o; if ((*ob).tipo!=tnone) error(0,30); lexico(); // el nombre no es nuevo - (*ob).tipo=tcloc; (*ob).cloc.offset=len+1; - if (pieza==p_corab) { - lexico(); - if (pieza==p_corce) { - lexico(); - (*ob).cloc.totalen=255; - } else { - if (((*ob).cloc.totalen=constante())<0) error(4,31); // cadena de long. negativa - if ((*ob).cloc.totalen>0xFFFFF) error(4,32); // cadena demasiado larga - if (pieza!=p_corce) error(3,19); // esperando ']' - lexico(); - } - } else (*ob).cloc.totalen=255; - - test_buffer(&frm,&ifrm_max,offstruct+len); - frm[offstruct+len]=0xDAD00000; - - if (pieza==p_asig) { - save_error(1); - _itxt=itxt; - lexico(); - if (pieza!=p_lit && !(pieza==p_id && (*o).tipo==tcons && (*o).cons.literal)) - error(3,46); // se esperaba un literal - if (strlen((char*)&mem[pieza_num])>(*ob).cloc.totalen+1) - error(4,49); // literal demasiado largo - test_buffer(&mem,&imem_max,offstruct+len); - mem[offstruct+len]=0xDAD00000|(*ob).cloc.totalen; - strcpy((char*)&mem[offstruct+len+1],(char*)&mem[pieza_num]); - len+=1+((*ob).cloc.totalen+5)/4; - itxt=_itxt; // Saca la cadena del segmento de textos - lexico(); - } else { - test_buffer(&mem,&imem_max,offstruct+len); - mem[offstruct+len]=0xDAD00000|(*ob).cloc.totalen; - len+=1+((*ob).cloc.totalen+5)/4; - } - } - - if (pieza==p_coma) pieza=p_string; else { - if (!free_sintax) if (pieza!=p_ptocoma) error(3,9); // esperando ';' - while (pieza==p_ptocoma || pieza==p_coma) lexico(); - } - - } else if (pieza==p_byte) { // Miembro byte - - lexico(); - - if (pieza==p_pointer) { // Miembro puntero a byte - - lexico(); puntero2: - ob=analiza_pointer(tpblo,len); - test_buffer(&mem,&imem_max,offstruct+len); - if (pieza==p_asig) { - lexico(); mem[offstruct+len]=constante(); - } len+=1; - if (pieza==p_coma) { - lexico(); if (pieza==p_pointer) lexico(); - goto puntero2; - } - - } else { - - if (pieza!=p_id) error(1,23); // esperando un nombre - ob=o; if ((*ob).tipo!=tnone) error(0,30); lexico(); // el nombre no es nuevo - (*ob).tipo=tbloc; (*ob).bloc.offset=len; - if (pieza==p_corab) { lexico(); - if (((*ob).bloc.len1=constante())<0) error(4,40); // tabla de long. negativa - if (pieza==p_coma) { - lexico(); - if (((*ob).bloc.len2=constante())<0) error(4,40); // idem - if (pieza==p_coma) { - lexico(); - if (((*ob).bloc.len3=constante())<0) error(4,40); // reidem - } else (*ob).bloc.len3=-1; - } else { (*ob).bloc.len2=-1; (*ob).bloc.len3=-1; } - (*ob).bloc.totalen=(*ob).bloc.len1+1; - if ((*ob).bloc.len2>-1) (*ob).bloc.totalen*=(*ob).bloc.len2+1; - if ((*ob).bloc.len3>-1) (*ob).bloc.totalen*=(*ob).bloc.len3+1; - if (pieza!=p_corce) error(3,19); lexico(); // esperando ']' - test_buffer(&mem,&imem_max,offstruct+len+((*ob).bloc.totalen+3)/4); - - test_buffer(&frm,&ifrm_max,offstruct+len+((*ob).bloc.totalen+3)/4); - memset(&frm[offstruct+len],2,(*ob).bloc.totalen); - - if (pieza==p_asig) { - _imem=imem; imem=offstruct+len; - save_error(1); lexico(); - oimemptr=(byte*)&mem[imem]; - tglo_init(2); - if (imemptr-oimemptr>(*ob).bloc.totalen) error(4,48); // demasiados valores para la tabla - imem=_imem; - } (*ob).bloc.totalen=((*ob).bloc.totalen+3)/4; - } else { - (*ob).tipo=tbloc; (*ob).bloc.offset=len; - (*ob).bloc.len1=0; - (*ob).bloc.len2=-1; - (*ob).bloc.len3=-1; - (*ob).bloc.totalen=1; // 1 int - - test_buffer(&frm,&ifrm_max,offstruct+len); - frm[offstruct+len]=2; - - if (pieza==p_asig) { - save_error(1); - lexico(); - test_buffer(&mem,&imem_max,offstruct+len); - mem[offstruct+len]=constante(); - if (mem[offstruct+len]<0 || mem[offstruct+len]>255) error(4,50); // valor byte fuera de rango - } - } len+=(*ob).bloc.totalen; - } - - if (pieza==p_coma) pieza=p_byte; else { - if (!free_sintax) if (pieza!=p_ptocoma) error(3,9); // esperando ';' - while (pieza==p_ptocoma || pieza==p_coma) lexico(); - } - - } else if (pieza==p_word) { // Miembro word - - lexico(); - - if (pieza==p_pointer) { // Miembro puntero a word - - lexico(); puntero3: - ob=analiza_pointer(tpwlo,len); - test_buffer(&mem,&imem_max,offstruct+len); - if (pieza==p_asig) { - lexico(); mem[offstruct+len]=constante(); - } len+=1; - if (pieza==p_coma) { - lexico(); if (pieza==p_pointer) lexico(); - goto puntero3; - } - - } else { - - if (pieza!=p_id) error(1,23); // esperando un nombre - ob=o; if ((*ob).tipo!=tnone) error(0,30); lexico(); // el nombre no es nuevo - (*ob).tipo=twloc; (*ob).wloc.offset=len; - if (pieza==p_corab) { lexico(); - if (((*ob).wloc.len1=constante())<0) error(4,40); // tabla de long. negativa - if (pieza==p_coma) { - lexico(); - if (((*ob).wloc.len2=constante())<0) error(4,40); // idem - if (pieza==p_coma) { - lexico(); - if (((*ob).wloc.len3=constante())<0) error(4,40); // reidem - } else (*ob).wloc.len3=-1; - } else { (*ob).wloc.len2=-1; (*ob).wloc.len3=-1; } - (*ob).wloc.totalen=(*ob).wloc.len1+1; - if ((*ob).wloc.len2>-1) (*ob).wloc.totalen*=(*ob).wloc.len2+1; - if ((*ob).wloc.len3>-1) (*ob).wloc.totalen*=(*ob).wloc.len3+1; - if (pieza!=p_corce) error(3,19); lexico(); // esperando ']' - test_buffer(&mem,&imem_max,offstruct+len+((*ob).wloc.totalen+1)/2); - - test_buffer(&frm,&ifrm_max,offstruct+len+((*ob).wloc.totalen+1)/2); - memset(&frm[offstruct+len],1,(*ob).wloc.totalen*2); - - if (pieza==p_asig) { - _imem=imem; imem=offstruct+len; - save_error(1); lexico(); - oimemptr=(byte*)&mem[imem]; - tglo_init(1); - if (imemptr-oimemptr>(*ob).wloc.totalen*2) error(4,48); // demasiados valores para la tabla - imem=_imem; - } (*ob).wloc.totalen=((*ob).wloc.totalen+1)/2; - } else { - (*ob).tipo=twloc; (*ob).wloc.offset=len; - (*ob).wloc.len1=0; - (*ob).wloc.len2=-1; - (*ob).wloc.len3=-1; - (*ob).wloc.totalen=1; // 1 int - - test_buffer(&frm,&ifrm_max,offstruct+len); - frm[offstruct+len]=1; - - if (pieza==p_asig) { - save_error(1); - lexico(); - test_buffer(&mem,&imem_max,offstruct+len); - mem[offstruct+len]=constante(); - if (mem[offstruct+len]<0 || mem[offstruct+len]>65535) error(4,51); // valor word fuera de rango - } - } len+=(*ob).wloc.totalen; - } - - if (pieza==p_coma) pieza=p_word; else { - if (!free_sintax) if (pieza!=p_ptocoma) error(3,9); // esperando ';' - while (pieza==p_ptocoma || pieza==p_coma) lexico(); - } - - } else if (pieza==p_int || pieza==p_id || pieza==p_pointer) { - - if (pieza==p_int) { - lexico(); - if (pieza!=p_id && pieza!=p_pointer) error(1,23); // esperando un nombre - } - - if (pieza==p_pointer) { // Miembro puntero a int - - lexico(); puntero4: - ob=analiza_pointer(tpilo,len); - test_buffer(&mem,&imem_max,offstruct+len); - if (pieza==p_asig) { - lexico(); mem[offstruct+len]=constante(); - } len+=1; - if (pieza==p_coma) { - lexico(); if (pieza==p_pointer) lexico(); - goto puntero4; - } - - } else { - - ob=o; if ((*ob).tipo!=tnone) error(0,30); lexico(); // el nombre no es nuevo - if (pieza==p_corab) { lexico(); // Miembro tabla - (*ob).tipo=ttloc; (*ob).tloc.offset=len; - if (((*ob).tloc.len1=constante())<0) error(4,40); // tabla de long. negativa - if (pieza==p_coma) { - lexico(); - if (((*ob).tloc.len2=constante())<0) error(4,40); // idem - if (pieza==p_coma) { - lexico(); - if (((*ob).tloc.len3=constante())<0) error(4,40); // reidem - } else (*ob).tloc.len3=-1; - } else { (*ob).tloc.len2=-1; (*ob).tloc.len3=-1; } - (*ob).tloc.totalen=(*ob).tloc.len1+1; - if ((*ob).tloc.len2>-1) (*ob).tloc.totalen*=(*ob).tloc.len2+1; - if ((*ob).tloc.len3>-1) (*ob).tloc.totalen*=(*ob).tloc.len3+1; - if (pieza!=p_corce) error(3,19); lexico(); // esperando ']' - - test_buffer(&mem,&imem_max,offstruct+len+(*ob).tloc.totalen); - if (pieza==p_asig) { - _imem=imem; imem=offstruct+len; - save_error(1); lexico(); tglo_init(0); - if (imem-(offstruct+len)>(*ob).tloc.totalen) error(4,48); // demasiados valores para la tabla - imem=_imem; - } len+=(*ob).tloc.totalen; - - } else { // Miembro variable - - (*ob).tipo=tvloc; (*ob).vloc.offset=len; - - test_buffer(&mem,&imem_max,offstruct+len); - if (pieza==p_asig) { - lexico(); mem[offstruct+len]=constante(); - } len+=1; - - } - } - - if (!free_sintax) if (pieza!=p_ptocoma && pieza!=p_coma) error(3,9); // esperando ';' - while (pieza==p_ptocoma || pieza==p_coma) lexico(); - - } else { error(0,39); do lexico(); while (pieza==p_ptocoma); } // esperando un elemento de la estructura - (*ob).bloque=bloque_lexico; - } return(len); -} - - -// - -int analiza_pointer_struct(int tipo, int offset, struct objeto * estructura) -{ - struct objeto * ob; - int items1,items2,items3; - - if (pieza!=p_id) error(1,23); // esperando un nombre - ob=o; if ((*ob).tipo!=tnone) { - if (parametros==-1 && (*ob).param==1 && (*ob).bloque==bloque_actual) { - if ((*ob).tipo==tipo) { // Se repite un pointer parámetro como private - save_error(0); lexico(); - items1=-1; items2=-1; items3=-1; - if (pieza==p_corab) { lexico(); - if ((items1=constante())<0) error(4,43); // estructura de longitud negativa - if (pieza==p_coma) { - lexico(); - if ((items2=constante())<0) error(4,43); // estructura de longitud negativa - if (pieza==p_coma) { - lexico(); - if ((items3=constante())<0) error(4,43); // estructura de longitud negativa - } - } if (pieza!=p_corce) error(3,19); lexico(); // esperando ']' - } - if (items1!=(*ob).psgl.items1 || items2!=(*ob).psgl.items2 || items3!=(*ob).psgl.items3) error(4,41); // la longitud no coincide con la declaración anterior - else if (pieza==p_asig) error(0,42); // no se puede inicializar un parámetro - else { - (*ob).param++; return(0); // No permite volver a redeclararlo - } - } else error(0,30); // el nombre no es nuevo - } else error(0,30); - } else lexico(); - if (parametros==-1) (*ob).bloque=bloque_actual; - (*ob).psgl.items1=-1; (*ob).psgl.items2=-1; (*ob).psgl.items3=-1; - if (pieza==p_corab) { lexico(); - if (((*ob).psgl.items1=constante())<0) error(4,43); // estructura de longitud negativa - if (pieza==p_coma) { - lexico(); - if (((*ob).psgl.items2=constante())<0) error(4,43); // estructura de longitud negativa - if (pieza==p_coma) { - lexico(); - if (((*ob).psgl.items3=constante())<0) error(4,43); // estructura de longitud negativa - } - } - if (pieza!=p_corce) error(3,19); lexico(); // esperando ']' - } (*ob).psgl.totalitems=0; - if ((*ob).psgl.items1>-1) (*ob).psgl.totalitems=(*ob).psgl.items1+1; - if ((*ob).psgl.items2>-1) (*ob).psgl.totalitems*=(*ob).psgl.items2+1; - if ((*ob).psgl.items3>-1) (*ob).psgl.totalitems*=(*ob).psgl.items3+1; - - (*ob).tipo=tipo; // tpsgl o tpslo - (*ob).psgl.offset=offset; // del pointer - (*ob).psgl.ostruct=estructura; // struct original - - // (*ob).psgl.len_item ð (*((*ob).psgl.ostruct)).len_item; - - return(1); -} - - // - // Inicialización de tablas (a mem[imem++]) - // - // := ( | [ [p_dup] p_abrir p_cerrar ] ) - // [ p_coma ] - // - - -void tglo_init(int tipo) { // Tipo: 0-Int o variado (struct), 1-Word, 2-Byte - if (tipo==3) { memset(frm,0,ifrm_max*sizeof(int)); tipo=0; } - imemptr=(byte*)&mem[imem]; - tglo_init2(tipo); - if (!free_sintax) if (pieza!=p_ptocoma) error(3,9); // esperando ';' -} - -void tloc_init(int tipo) { - int * ptr; - - if (tipo==3) { memset(frm,0,ifrm_max*sizeof(int)); tipo=0; } - - ptr=mem; mem=loc; loc=ptr; - swap(imem,iloc); swap(imem_max,iloc_max); - - imemptr=(byte*)&mem[imem]; - tglo_init2(tipo); - - ptr=mem; mem=loc; loc=ptr; - swap(imem,iloc); swap(imem_max,iloc_max); - - if (!free_sintax) if (pieza!=p_ptocoma) error(3,9); // esperando ';' -} - -// OJO!!! tglo_init no puede llamar a test_buffer !!! - -void tglo_init2(int tipo) { - int valor,dup,_imem,len,n; - byte *oimemptr; - - while (1) { - - // Mira si finaliza la inicialización de datos - - if (pieza==p_cerrar || pieza==p_ptocoma) { - if (*(imemptr-(int)mem+(int)frm)==1 || tipo==1) { - imemptr+=2; - imem=((int)imemptr-(int)mem+3)/4; - if (*(imemptr-(int)mem+(int)frm)!=1 && tipo!=1) imemptr=(byte*)&mem[imem]; - } else if (*(imemptr-(int)mem+(int)frm)==2 || tipo==2) { - imemptr++; - imem=((int)imemptr-(int)mem+3)/4; - if (*(imemptr-(int)mem+(int)frm)!=2 && tipo!=2) imemptr=(byte*)&mem[imem]; - } else { - imemptr+=4; - imem=((int)imemptr-(int)mem+3)/4; - } -// test_buffer(&mem,&imem_max,imem); - return; - } - - // Una coma sola, como "3,,4", avanza una posición (y define un 0) - - if (pieza==p_coma) { - if (*(imemptr-(int)mem+(int)frm)==1 || tipo==1) { - (*(word*)imemptr)=0; - imemptr+=2; - imem=((int)imemptr-(int)mem+3)/4; - if (*(imemptr-(int)mem+(int)frm)!=1 && tipo!=1) imemptr=(byte*)&mem[imem]; - } else if (*(imemptr-(int)mem+(int)frm)==2 || tipo==2) { - *imemptr++=0; - imem=((int)imemptr-(int)mem+3)/4; - if (*(imemptr-(int)mem+(int)frm)!=2 && tipo!=2) imemptr=(byte*)&mem[imem]; - } else { - imemptr+=4; - imem=((int)imemptr-(int)mem+3)/4; - } -// test_buffer(&mem,&imem_max,imem); - lexico(); continue; - } - - if (pieza==p_abrir) { // Dup x 1 - - dup=1; - - } else if (pieza==p_dup) { // Dup x 2 - - dup=2; lexico(); - if (pieza!=p_abrir) error(3,22); // esperando '(' - - } else if (pieza==p_lit || (pieza==p_id && (*o).tipo==tcons && (*o).cons.literal)) { - - valor=pieza_num; lexico(); - if (pieza==p_abrir || pieza==p_dup) error(2,52); // no se puede duplicar 0 o menos veces (se ha indicado un literal como número de veces) - - // Mete un literal en un dato de tipo string - - if ((((int)imemptr-(int)mem)%4)==0) { - imem=((int)imemptr-(int)mem+3)/4; - if (frm[imem]==0xdad00000) { - if (strlen((char*)&mem_ory[valor])>(mem[imem]&0xFFFFF)+1) error(2,49); // literal demasiado largo - _imem=imem; - imem+=1+((mem[imem]&0xFFFFF)+5)/4; -// test_buffer(&mem,&imem_max,imem); - imemptr=(byte*)&mem[imem]; - strcpy((char*)&mem[_imem+1],(char*)&mem_ory[valor]); - if (pieza!=p_coma) return; - lexico(); continue; - } - } - - // Mete un valor literal en otro tipo de dato (en lugar de un string) - - if (*(imemptr-(int)mem+(int)frm)==1 || tipo==1) { // Un string en words (el puntero short) - - imemptr=(byte*)(((int)imemptr+1)&-2); // Lo hace par - *((word*)imemptr)=valor; - imemptr+=2; - imem=((int)imemptr-(int)mem+3)/4; - if (*(imemptr-(int)mem+(int)frm)!=1 && tipo!=1) imemptr=(byte*)&mem[imem]; - if (pieza!=p_coma) return; - lexico(); continue; - - } else if (*(imemptr-(int)mem+(int)frm)==2 || tipo==2) { // Un string en bytes - - oimemptr=imemptr; - while (*(oimemptr-(int)mem+(int)frm)==2) oimemptr++; - if (tipo==0) if (strlen((char*)&mem_ory[valor])>(int)(oimemptr-imemptr)) error(2,48); // demasiados valores para la tabla - strcpy(imemptr,(char*)&mem_ory[valor]); - imemptr+=strlen(imemptr); - imem=((int)imemptr-(int)mem+3)/4; - if (*(imemptr-(int)mem+(int)frm)!=2 && tipo!=2) imemptr=(byte*)&mem[imem]; - if (pieza!=p_coma) return; - lexico(); continue; - - } else { // Un string en un int (el puntero long, como en DIV 1) - - imem=((int)imemptr-(int)mem+3)/4; - mem[imem++]=valor; -// test_buffer(&mem,&imem_max,imem); - imemptr=(byte*)&mem[imem]; - if (pieza!=p_coma) return; - lexico(); continue; - - } - - } else { - valor=constante(); - if (pieza!=p_abrir) { - if (pieza!=p_dup) { - - if ((((int)imemptr-(int)mem)%4)==0) { - imem=((int)imemptr-(int)mem+3)/4; - if (frm[imem]==0xdad00000) error(2,46); // se esperaba un literal - } - - // Mete un valor numérico en la memoria - - if (*(imemptr-(int)mem+(int)frm)==1 || tipo==1) { // En un word - - if (valor<0 || valor>65535) error(2,51); // valor word fuera de rango - imemptr=(byte*)(((int)imemptr+1)&-2); // Lo hace par - *((word*)imemptr)=valor; - imemptr+=2; - imem=((int)imemptr-(int)mem+3)/4; - if (*(imemptr-(int)mem+(int)frm)!=1 && tipo!=1) imemptr=(byte*)&mem[imem]; - if (pieza!=p_coma) return; - lexico(); continue; - - } else if (*(imemptr-(int)mem+(int)frm)==2 || tipo==2) { // En un byte - - if (valor<0 || valor>255) error(2,50); // valor byte fuera de rango - *imemptr++=valor; - imem=((int)imemptr-(int)mem+3)/4; - if (*(imemptr-(int)mem+(int)frm)!=2 && tipo!=2) imemptr=(byte*)&mem[imem]; - if (pieza!=p_coma) return; - lexico(); continue; - - } else { // En un int (lo normal en DIV 1) - - imem=((int)imemptr-(int)mem+3)/4; - mem[imem++]=valor; -// test_buffer(&mem,&imem_max,imem); - imemptr=(byte*)&mem[imem]; - if (pieza!=p_coma) return; - lexico(); continue; - - } - - } else { - dup=valor; lexico(); - if (pieza!=p_abrir) error(3,22); // esperando '(' - } - } else dup=valor; - } - - // Duplica una secuencia de valores - - if (dup<1) error(2,52); // no se puede duplicar 0 o menos veces - lexico(); - - // Analiza la secuencia como otra inicialización ... - - oimemptr=imemptr; - tglo_init2(tipo); - if (pieza!=p_cerrar) error(3,18); // esperando ')' - - // Y la duplica el número de veces indicado - - if (dup>1) { - len=imemptr-oimemptr; -// test_buffer(&mem,&imem_max,(((int)oimemptr-(int)mem)+len*dup+3)/4); - while (--dup) { - for (n=0;n