Limpieza y comentarizacion

This commit is contained in:
Víctor Román Archidona 2002-10-06 20:42:51 +00:00
parent 73cdc41e91
commit becba8500f
2 changed files with 328 additions and 361 deletions

View file

@ -1,7 +1,7 @@
/* /*
* eDiv Compiler * eDiv Compiler
* Copyleft (C) 2000-2002 Sion Entertainment * Copyright (C) 2000-2002 Sion Entertainment
* http://www.sion-e.com * http://www.sionhq.com
* *
* This program is free software; you can redistribute it and/or modify * 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 * it under the terms of the GNU General Public License as published by
@ -21,10 +21,6 @@
#include <string.h> #include <string.h>
#include <stdlib.h> #include <stdlib.h>
//#include <sys/stat.h>
//#ifdef __linux__
//# include <limits.h>
//#endif
#include <zlib.h> #include <zlib.h>
@ -42,7 +38,7 @@
#include "varindex.h" #include "varindex.h"
#include "language.h" #include "language.h"
void analiza_ltlex(void); // en ltlex.c void analiza_ltlex(void); /* en ltlex.c */
void prepara_compilacion() void prepara_compilacion()
@ -63,18 +59,18 @@ void prepara_compilacion()
inicializa_lower(); inicializa_lower();
// Inicializamos la tabla de objetos /* Inicializamos la tabla de objetos */
memset(obj,0,sizeof(obj[0])*max_obj); memset(obj,0,sizeof(obj[0])*max_obj);
iobj=obj; iobj=obj;
num_obj=0; num_obj=0;
// Inicializamos la tabla de símbolos /* Inicializamos la tabla de símbolos */
memset(lex_simb,0,sizeof(lex_simb)); memset(lex_simb,0,sizeof(lex_simb));
ilex_simb=lex_simb; ilex_simb=lex_simb;
num_nodos=0; num_nodos=0;
// Inicializamos los caracteres básicos en lex_case /* Inicializamos los caracteres básicos en lex_case */
for (n=0;n<256;n++) for (n=0;n<256;n++)
if (lower[n]) { if (lower[n]) {
if (n>='0' && n<='9') if (n>='0' && n<='9')
@ -86,33 +82,33 @@ void prepara_compilacion()
lex_case[n]=(struct lex_ele *)l_err; lex_case[n]=(struct lex_ele *)l_err;
// Inicializamos el vector de nombres /* Inicializamos el vector de nombres */
vnom=(byte *) e_malloc(max_obj*long_med_id+1024); vnom=(byte *) e_malloc(max_obj*long_med_id+1024);
ivnom.b=vnom; ivnom.b=vnom;
// Leemos los símbolos y palabras reservadas de ltlex.def /* Leemos los símbolos y palabras reservadas de ltlex.def */
analiza_ltlex(); analiza_ltlex();
// Terminamos de inicializar lex_case /* Terminamos de inicializar lex_case */
lex_case[' ']=(struct lex_ele *)l_spc; lex_case[' ']=(struct lex_ele *)l_spc;
lex_case[tab]=(struct lex_ele *)l_spc; lex_case[tab]=(struct lex_ele *)l_spc;
lex_case[cr]=(struct lex_ele *)l_cr; lex_case[cr]=(struct lex_ele *)l_cr;
lex_case[lf]=(struct lex_ele *)l_cr; lex_case[lf]=(struct lex_ele *)l_cr;
lex_case[0]=(struct lex_ele *)l_eof; lex_case[0]=(struct lex_ele *)l_eof;
// Buffer para el bytecode /* Buffer para el bytecode */
imem_max=default_buffer; imem=0; imem_max=default_buffer; imem=0;
mem_ory=mem=(int*)e_malloc(imem_max*sizeof(int)); mem_ory=mem=(int*)e_malloc(imem_max*sizeof(int));
memset(mem,0,imem_max*sizeof(int)); memset(mem,0,imem_max*sizeof(int));
// Buffer para variables locales y privadas /* Buffer para variables locales y privadas */
iloc_max=default_buffer/2; iloc=0; iloc_len=0; iloc_max=default_buffer/2; iloc=0; iloc_len=0;
loc=(int*)e_malloc(iloc_max*sizeof(int)); loc=(int*)e_malloc(iloc_max*sizeof(int));
memset(loc,0,iloc_max*sizeof(int)); memset(loc,0,iloc_max*sizeof(int));
// No se lo que es /* ¿Que es esto? */
ifrm_max=default_buffer/2; ifrm_max=default_buffer/2;
frm=(int*)e_malloc(ifrm_max*sizeof(int)); frm=(int*)e_malloc(ifrm_max*sizeof(int));
memset(frm,0,ifrm_max*sizeof(int)); memset(frm,0,ifrm_max*sizeof(int));
@ -132,7 +128,7 @@ void compila()
unsigned long m; unsigned long m;
byte * q, * p; byte * q, * p;
int start_lin, start_dbg; int start_lin, start_dbg;
byte* varptr; // variables indexadas byte* varptr; /* variables indexadas */
FILE* fvar; FILE* fvar;
ultima_linea=prog; ultima_linea=prog;
@ -142,7 +138,7 @@ void compila()
printf(translate(27)); printf(translate(27));
itxt=inicio_textos=imem; itxt=inicio_textos=imem;
psintactico(); // Para obtener "longitud_textos" psintactico(); /* Para obtener "longitud_textos" */
imem+=longitud_textos; imem+=longitud_textos;
#ifdef _DEBUG #ifdef _DEBUG
printf("dbg: longitud_textos: %d\n",longitud_textos); printf("dbg: longitud_textos: %d\n",longitud_textos);
@ -154,7 +150,7 @@ void compila()
num_obj_predefinidos=num_obj; num_obj_predefinidos=num_obj;
ultima_linea=source; //fwrite(&cero,1,1,lprg); ultima_linea=source;
acceso_remoto=0; parametros=0; linea=1; acceso_remoto=0; parametros=0; linea=1;
sintactico(); sintactico();
@ -164,14 +160,14 @@ void compila()
if (i->usado) { if (i->usado) {
linea=i->linea; linea=i->linea;
ierror=i->ierror; ierror=i->ierror;
error(0,34,i->name); // nombre desconocido error(0,34,i->name); /* nombre desconocido */
} }
i++; i++;
} }
if(n_errors>0) return; if(n_errors>0) return;
// Borra todo y comienza de nuevo :P /* Borra todo y comienza de nuevo :P */
printf(translate(28)); printf(translate(28));
@ -183,8 +179,8 @@ void compila()
prepara_compilacion(); prepara_compilacion();
source=prog; source=prog;
inicializa_index(); // ahora toca construir el indice de variables inicializa_index(); /* ahora toca construir el indice de variables */
dll_func2(); // recarga sólo las dlls necesarias dll_func2(); /* recarga sólo las dlls necesarias */
if(debug) { if(debug) {
if((linf=tmpfile())==NULL) { if((linf=tmpfile())==NULL) {
@ -201,8 +197,10 @@ void compila()
sintactico(); 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: * 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;n<numdlls;n++) for(n=0;n<numdlls;n++)
if(dlls[n].usado || dlls[n].prioridad>=P_SIEMPRE) { if(dlls[n].usado || dlls[n].prioridad>=P_SIEMPRE) {
dlls[n].mem_nombre=imem; dlls[n].mem_nombre=imem;
@ -212,7 +210,7 @@ void compila()
test_buffer(&mem,&imem_max,imem); test_buffer(&mem,&imem_max,imem);
} }
// Si estamos compilando en modo debug, añadimos tambien la debug.dll /* Si estamos compilando en modo debug, añadimos tambien la debug.dll */
if(debug) { if(debug) {
dlls[numdlls].mem_nombre=imem; dlls[numdlls].mem_nombre=imem;
memcpy(&mem[imem],"debug",6); memcpy(&mem[imem],"debug",6);
@ -220,11 +218,13 @@ void compila()
test_buffer(&mem,&imem_max,imem); test_buffer(&mem,&imem_max,imem);
} }
// Ahora estamos en la posición donde comienza la rutina, por lo que tenemos /*
// que guardar la posición actual en el offset que guardamos en salto_import * Ahora estamos en la posición donde comienza la rutina, por lo que tenemos
* que guardar la posición actual en el offset que guardamos en salto_import
*/
mem[salto_import]=imem; mem[salto_import]=imem;
// Escribimos la rutina de carga de DLLs /* Escribimos la rutina de carga de DLLs */
for(n=0;n<numdlls;n++) for(n=0;n<numdlls;n++)
if(dlls[n].usado || dlls[n].prioridad>=P_SIEMPRE) if(dlls[n].usado || dlls[n].prioridad>=P_SIEMPRE)
g2(limp,dlls[n].mem_nombre); g2(limp,dlls[n].mem_nombre);
@ -234,41 +234,47 @@ void compila()
g2(ljmp,salto_import+1); g2(ljmp,salto_import+1);
// Ya está !! :) /* Ya está !! :) */
// Preparamos la cabecera del bytecode /* Preparamos la cabecera del bytecode */
mem[2]=imem; mem[2]=imem;
mem[3]=max_process; // Antes long_header, ahora no se utiliza mem[3]=max_process; /* Antes long_header, ahora no se utiliza */
mem[4]=0; // Antes mem[1]-mem[3] (long datos globales), ahora no se utiliza mem[4]=0; /* Antes mem[1]-mem[3] (long datos globales), ahora no se utiliza */
mem[5]=iloc_len-iloc; mem[5]=iloc_len-iloc;
mem[6]=iloc; mem[6]=iloc;
mem[7]=0; // Antes imem+iloc (inicio textos), ahora no se utiliza mem[7]=0; /* Antes imem+iloc (inicio textos), ahora no se utiliza */
mem[8]=imem+iloc; // Número de elementos ocupados en mem[] mem[8]=imem+iloc; /* Número de elementos ocupados en mem[] */
// mem[0] se usa para almacenar flags para el ejecutable. En el caso de DIV 2, /*
// éstas eran: * mem[0] se usa para almacenar flags para el ejecutable. En el caso de DIV 2,
// +1 = El programa es un setup de sonido (setup_program) * éstas eran:
// +128 = El programa invoca al trazador nada más ejecutarse (compilado con F12) * +1 = El programa es un setup de sonido (setup_program)
// +512 = Se ignoran los errores de ejecución (ignore_errors) * +128 = El programa invoca al trazador nada más ejecutarse (compilado con F12)
// +1024= Modo DEMO (mensaje en el centro de la pantalla parpadeando diciendo * +512 = Se ignoran los errores de ejecución (ignore_errors)
// "VERSIÓN DE DEMOSTRACIÓN") * +1024= Modo DEMO (mensaje en el centro de la pantalla parpadeando diciendo
* "VERSIÓN DE DEMOSTRACIÓN")
*/
// nosotros usaremos las siguientes: /*
// +16 = El exe lleva incluidas las DLL's * nosotros usaremos las siguientes:
// A ver como lo hacemos en Linux.. 1) con temporales o 2) hurgando en el codigo * +16 = El exe lleva incluidas las DLL's
// de dlopen y demas y haciendonos una pekeña lib (esto es mas aconsejable) * A ver como lo hacemos en Linux.. 1) con temporales o 2) hurgando en el codigo
// +32 = El exe lleva incluido el PAK * de dlopen y demas y haciendonos una pekeña lib (esto es mas aconsejable)
// +64 = Compilado en modo debug * +32 = El exe lleva incluido el PAK
// +128 = Igual que en DIV2, el programa invoca al trazador nada más ejecutarse (se * +64 = Compilado en modo debug
// ha usado la orden "trazar programa" en el IDE) * +128 = Igual que en DIV2, el programa invoca al trazador nada más ejecutarse (se
// +512 = ignore_errors, igual que en DIV2 * ha usado la orden "trazar programa" en el IDE)
* +512 = ignore_errors, igual que en DIV2
*/
mem[0]=0; mem[0]=0;
if (debug) mem[0]+=64; if (debug) mem[0]+=64;
if (ignore_errors) mem[0]+=512; if (ignore_errors) mem[0]+=512;
// Generamos los listados /*
// (debe hacerse ahora porque en el listado de objetos guardamos los valores de mem[1..8]) * Generamos los listados (debe hacerse ahora porque en el listado de objetos guardamos
* los valores de mem[1..8])
*/
if(listados) { if(listados) {
printf(translate(30)); printf(translate(30));
if(listados & 1) listado_ensamblador(); if(listados & 1) listado_ensamblador();
@ -279,23 +285,23 @@ void compila()
printf(translate(31)); printf(translate(31));
// descomprime la edivrun.lib y guarda una copia con el nombre temp.dj! /* descomprime la edivrun.lib y guarda una copia con el nombre temp.dj! */
_encriptar(0,edivrun_lib,la_clave); _encriptar(0,edivrun_lib,la_clave);
_comprimir(0,"temp.dj!"); _comprimir(0,"temp.dj!");
// si el archivo de salida ya existe, lo borra /* si el archivo de salida ya existe, lo borra */
if((f = fopen(outfilename, "rb"))!=NULL) { if((f = fopen(outfilename, "rb"))!=NULL) {
fclose(f); fclose(f);
remove(outfilename); remove(outfilename);
} }
// renombra temp.dj! al nombre del exe /* renombra temp.dj! al nombre del exe */
rename("temp.dj!",outfilename); rename("temp.dj!",outfilename);
// ordenamos varindex /* ordenamos varindex */
ordena_varindex(); ordena_varindex();
// escribimos en un temporal todo el indice de variables /* escribimos en un temporal todo el indice de variables */
fvar=tmpfile(); fvar=tmpfile();
for(n=0;n<num_indexed_vars;n++) { for(n=0;n<num_indexed_vars;n++) {
fputc(varindex[n].hash,fvar); fputc(varindex[n].hash,fvar);
@ -304,12 +310,12 @@ void compila()
fputc(varindex[n].tipo,fvar); fputc(varindex[n].tipo,fvar);
} }
// liberamos varindex /* liberamos varindex */
for(n=0;n<num_indexed_vars;n++) for(n=0;n<num_indexed_vars;n++)
free(varindex[n].nombre); free(varindex[n].nombre);
free(varindex); free(varindex);
// lo pasamos todo del temporal a la memoria /* lo pasamos todo del temporal a la memoria */
l=ftell(fvar); l=ftell(fvar);
fseek(fvar,0,SEEK_SET); fseek(fvar,0,SEEK_SET);
varptr=(byte*)e_malloc(l); varptr=(byte*)e_malloc(l);
@ -328,26 +334,25 @@ void compila()
m=(imem+iloc)*4+1024; m=(imem+iloc)*4+1024;
q=(byte*)e_malloc(m); q=(byte*)e_malloc(m);
if (p!=NULL && q!=NULL) { if (p!=NULL && q!=NULL) {
fwrite(mem,4,9,f); // mem[0..8] fwrite(mem,4,9,f); /* mem[0..8] */
memcpy(p,&mem[9],(imem-9)*4); memcpy(p,&mem[9],(imem-9)*4);
memcpy(p+(imem-9)*4,loc,iloc*4); memcpy(p+(imem-9)*4,loc,iloc*4);
n=(imem-9+iloc)*4; n=(imem-9+iloc)*4;
if (!compress(q,&m,p,n)) { if (!compress(q,&m,p,n)) {
fwrite(&n,1,4,f); // mem[0]..mem[8],longitud_datos_descomp,longitud_datos_comp,datos comp... fwrite(&n,1,4,f); /* mem[0]..mem[8],longitud_datos_descomp,longitud_datos_comp,datos comp... */
fwrite(&m,1,sizeof(unsigned long),f); fwrite(&m,1,sizeof(unsigned long),f);
fwrite(q,1,m,f); fwrite(q,1,m,f);
free(q); free(p); free(q); free(p);
//get_varptr(&varptr,&nvars); // indice de variables
m=l*2; m=l*2;
q=(byte*)e_malloc(m); q=(byte*)e_malloc(m);
if(!compress(q,&m,varptr,l)) { // nºvariables,longitud_datos_descomp,longitud_datos_comp,datos_comp... if(!compress(q,&m,varptr,l)) { /* nºvariables,longitud_datos_descomp,longitud_datos_comp,datos_comp... */
fwrite(&num_indexed_vars,1,4,f); fwrite(&num_indexed_vars,1,4,f);
fwrite(&l,1,4,f); fwrite(&l,1,4,f);
fwrite(&m,1,sizeof(unsigned long),f); fwrite(&m,1,sizeof(unsigned long),f);
fwrite(q,1,m,f); fwrite(q,1,m,f);
free(q); free(q);
free(varptr); free(varptr);
if(debug) { // formato de ejecutable de debug if(debug) { /* formato de ejecutable de debug */
printf(translate(32)); printf(translate(32));
start_lin=ftell(f); start_lin=ftell(f);
escribe_lin(f); escribe_lin(f);
@ -356,7 +361,7 @@ void compila()
fwrite(&start_lin,1,4,f); fwrite(&start_lin,1,4,f);
fwrite(&start_dbg,1,4,f); fwrite(&start_dbg,1,4,f);
} }
fwrite(&stub_size,1,4,f); // Ultimos 4 bytes siempre son el tamaño del stub fwrite(&stub_size,1,4,f); /* Ultimos 4 bytes siempre son el tamaño del stub */
fclose(f); fclose(f);
} else { } else {
free(q); free(q);
@ -385,18 +390,18 @@ void compila()
} }
#ifndef _WIN32 #ifndef _WIN32
chmod(outfilename,493); // -rwxr-xr-x chmod(outfilename,493); /* -rwxr-xr-x */
#endif #endif
printf(translate(34)); printf(translate(34));
} }
//----------------------------------------------------------------------------- /*
// Comprueba los límites de un buffer de generación de código * void test_buffer(int **bufer, int *maximo, int n);
//----------------------------------------------------------------------------- * Comprueba los límites de un buffer de generación de código
*/
void test_buffer(int * * buffer,int * maximo,int n) void test_buffer(int **buffer,int *maximo,int n)
{ {
int max; int max;
@ -418,11 +423,11 @@ void test_buffer(int * * buffer,int * maximo,int n)
} }
//----------------------------------------------------------------------------- /*
// Analisis de un bloque de sentencias * void sentencia(void)
//----------------------------------------------------------------------------- * Analiza un bloque de sentencias
*/
void sentencia() { void sentencia(void) {
int im1,im2,im3,im4; int im1,im2,im3,im4;
int dir,from,to,step; int dir,from,to,step;
@ -434,7 +439,7 @@ void sentencia() {
inicio_sentencia(); inicio_sentencia();
lexico(); if (pieza==p_abrir) { lexico(); if (pieza==p_abrir) {
lexico(); if (pieza!=p_cerrar) { lexico(); if (pieza!=p_cerrar) {
expresion(); if (pieza!=p_cerrar) error(3,18); // esperando ')' expresion(); if (pieza!=p_cerrar) error(3,18); /* esperando ')' */
g1(lrtf); g1(lrtf);
} else { } else {
g1(lret); g1(lret);
@ -442,17 +447,17 @@ void sentencia() {
} else { } else {
g1(lret); g1(lret);
} }
if (!free_sintax) if (pieza!=p_ptocoma) error(3,9); // esperando ';' if (!free_sintax) if (pieza!=p_ptocoma) error(3,9); /* esperando ';' */
while (pieza==p_ptocoma || pieza==p_coma) lexico(); while (pieza==p_ptocoma || pieza==p_coma) lexico();
final_sentencia(); grabar_sentencia(); break; final_sentencia(); grabar_sentencia(); break;
case p_if: case p_if:
telseif[itelseif++]=0; telseif[itelseif++]=0;
inicio_sentencia(); inicio_sentencia();
lexico(); lexico();
if (!free_sintax) if (pieza!=p_abrir) error(3,22); // esperando '(' if (!free_sintax) if (pieza!=p_abrir) error(3,22); /* esperando '(' */
if (pieza==p_abrir) lexico(); if (pieza==p_abrir) lexico();
condicion(); condicion();
if (!free_sintax) if (pieza!=p_cerrar) error(3,18); // esperando ')' if (!free_sintax) if (pieza!=p_cerrar) error(3,18); /* esperando ')' */
if (pieza==p_cerrar) lexico(); if (pieza==p_cerrar) lexico();
g2(ljpf,0); im1=imem-1; g2(ljpf,0); im1=imem-1;
final_sentencia(); grabar_sentencia(); final_sentencia(); grabar_sentencia();
@ -465,28 +470,28 @@ void sentencia() {
final_sentencia(); grabar_sentencia(); final_sentencia(); grabar_sentencia();
sentencia(); sentencia();
}else if (pieza==p_elseif) { }else if (pieza==p_elseif) {
if (itelseif==0) error(0,73); // elseif fuera de bloque if if (itelseif==0) error(0,73); /* elseif fuera de bloque if */
inicio_sentencia(); inicio_sentencia();
g2(ljmp,0); telseif[itelseif++]=imem-1; g2(ljmp,0); telseif[itelseif++]=imem-1;
mem[im1]=imem; mem[im1]=imem;
lexico(); lexico();
if (!free_sintax) if (pieza!=p_abrir) error(3,22); // esperando '(' if (!free_sintax) if (pieza!=p_abrir) error(3,22); /* esperando '(' */
if (pieza==p_abrir) lexico(); if (pieza==p_abrir) lexico();
condicion(); condicion();
if (!free_sintax) if (pieza!=p_cerrar) error(3,18); // esperando ')' if (!free_sintax) if (pieza!=p_cerrar) error(3,18); /* esperando ')' */
if (pieza==p_cerrar) lexico(); if (pieza==p_cerrar) lexico();
g2(ljpf,0); im1=imem-1; g2(ljpf,0); im1=imem-1;
final_sentencia(); grabar_sentencia(); final_sentencia(); grabar_sentencia();
goto if1; goto if1;
} }
mem[im1]=imem; if (pieza!=p_end) error(0,57); lexico(); // esperando END mem[im1]=imem; if (pieza!=p_end) error(0,57); lexico(); /* esperando END */
while (telseif[--itelseif]!=0) mem[telseif[itelseif]]=imem; while (telseif[--itelseif]!=0) mem[telseif[itelseif]]=imem;
break; break;
case p_loop: case p_loop:
tbreak[itbreak++]=0; tcont[itcont++]=0; tbreak[itbreak++]=0; tcont[itcont++]=0;
lexico(); lexico();
im1=imem; sentencia(); im1=imem; sentencia();
if (pieza!=p_end) error(0,57); // esperando END if (pieza!=p_end) error(0,57); /* esperando END */
inicio_sentencia(); lexico(); inicio_sentencia(); lexico();
g2(ljmp,im1); g2(ljmp,im1);
while (tbreak[--itbreak]!=0) mem[tbreak[itbreak]]=imem; while (tbreak[--itbreak]!=0) mem[tbreak[itbreak]]=imem;
@ -497,15 +502,15 @@ void sentencia() {
inicio_sentencia(); inicio_sentencia();
tbreak[itbreak++]=0; tcont[itcont++]=0; im1=imem; tbreak[itbreak++]=0; tcont[itcont++]=0; im1=imem;
lexico(); lexico();
if (!free_sintax) if (pieza!=p_abrir) error(3,22); // esperando '(' if (!free_sintax) if (pieza!=p_abrir) error(3,22); /* esperando '(' */
if (pieza==p_abrir) lexico(); if (pieza==p_abrir) lexico();
condicion(); condicion();
if (!free_sintax) if (pieza!=p_cerrar) error(3,18); // esperando ')' if (!free_sintax) if (pieza!=p_cerrar) error(3,18); /* esperando ')' */
if (pieza==p_cerrar) lexico(); if (pieza==p_cerrar) lexico();
g2(ljpf,0); im2=imem-1; g2(ljpf,0); im2=imem-1;
final_sentencia(); grabar_sentencia(); final_sentencia(); grabar_sentencia();
sentencia(); sentencia();
if (pieza!=p_end) error(0,57); inicio_sentencia(); // esperando END if (pieza!=p_end) error(0,57); inicio_sentencia(); /* esperando END */
lexico(); lexico();
g2(ljmp,im1); mem[im2]=imem; g2(ljmp,im1); mem[im2]=imem;
while (tbreak[--itbreak]!=0) mem[tbreak[itbreak]]=imem; while (tbreak[--itbreak]!=0) mem[tbreak[itbreak]]=imem;
@ -516,13 +521,13 @@ void sentencia() {
tbreak[itbreak++]=0; tcont[itcont++]=0; tbreak[itbreak++]=0; tcont[itcont++]=0;
lexico(); lexico();
im1=imem; sentencia(); im1=imem; sentencia();
if (pieza!=p_until) error(0,58); // esperando UNTIL if (pieza!=p_until) error(0,58); /* esperando UNTIL */
inicio_sentencia(); inicio_sentencia();
lexico(); lexico();
if (!free_sintax) if (pieza!=p_abrir) error(3,22); // esperando '(' if (!free_sintax) if (pieza!=p_abrir) error(3,22); /* esperando '(' */
if (pieza==p_abrir) lexico(); if (pieza==p_abrir) lexico();
condicion(); condicion();
if (!free_sintax) if (pieza!=p_cerrar) error(3,18); // esperando ')' if (!free_sintax) if (pieza!=p_cerrar) error(3,18); /* esperando ')' */
if (pieza==p_cerrar) lexico(); if (pieza==p_cerrar) lexico();
g2(ljpf,im1); g2(ljpf,im1);
while (tbreak[--itbreak]!=0) mem[tbreak[itbreak]]=imem; while (tbreak[--itbreak]!=0) mem[tbreak[itbreak]]=imem;
@ -533,35 +538,35 @@ void sentencia() {
inicio_sentencia(); inicio_sentencia();
tbreak[itbreak++]=0; tcont[itcont++]=0; tbreak[itbreak++]=0; tcont[itcont++]=0;
lexico(); lexico();
if (pieza!=p_id) error(0,59); // esperando una variable if (pieza!=p_id) error(0,59); /* esperando una variable */
if ((*o).tipo==tvglo) { if ((*o).tipo==tvglo) {
dir=(*o).vglo.offset; g2(lcar,dir); dir=(*o).vglo.offset; g2(lcar,dir);
} else if ((*o).tipo==tvloc && (!(*o).bloque || (*o).bloque==bloque_actual)) { } else if ((*o).tipo==tvloc && (!(*o).bloque || (*o).bloque==bloque_actual)) {
dir=-(*o).vloc.offset; dir=-(*o).vloc.offset;
g2(lcar,-dir); g1(laid); g2(lcar,-dir); g1(laid);
} else error(0,59); // esperando una variable } else error(0,59); /* esperando una variable */
lexico(); lexico();
if (pieza!=p_asig) error(3,7); lexico(); // esperando '=' if (pieza!=p_asig) error(3,7); lexico(); /* esperando '=' */
from=constante(); from=constante();
if (pieza!=p_to) error(1,60); lexico(); // esperando TO if (pieza!=p_to) error(1,60); lexico(); /* esperando TO */
to=constante(); to=constante();
if (from==to) error(4,61); // sentencia FROM incorrecta if (from==to) error(4,61); /* sentencia FROM incorrecta */
if (pieza==p_step) { if (pieza==p_step) {
lexico(); lexico();
step=constante(); step=constante();
if (from<to && step<=0) error(4,62); // el valor step no es válido if (from<to && step<=0) error(4,62); /* el valor step no es válido */
if (from>to && step>=0) error(4,62); if (from>to && step>=0) error(4,62);
} else { } else {
if (from<to) step=1; else step=-1; if (from<to) step=1; else step=-1;
} }
g2(lcar,from); // Asignación del from g2(lcar,from); /* Asignación del from */
g1(lasi); g1(lasp); g1(lasi); g1(lasp);
im1=imem; // Inicio del bucle im1=imem; /* Inicio del bucle */
if (dir>=0) { // Comparación de la condición de permanencia if (dir>=0) { /* Comparación de la condición de permanencia */
g2(lcar,dir); g2(lcar,dir);
} else { } else {
g2(lcar,-dir); g1(laid); g2(lcar,-dir); g1(laid);
@ -571,16 +576,16 @@ void sentencia() {
g2(ljpf,0); im2=imem-1; g2(ljpf,0); im2=imem-1;
final_sentencia(); grabar_sentencia(); final_sentencia(); grabar_sentencia();
if (!free_sintax) if (pieza!=p_ptocoma) error(3,9); // esperando ';' if (!free_sintax) if (pieza!=p_ptocoma) error(3,9); /* esperando ';' */
while (pieza==p_ptocoma || pieza==p_coma) lexico(); while (pieza==p_ptocoma || pieza==p_coma) lexico();
sentencia(); sentencia();
if (pieza!=p_end) error(0,57); inicio_sentencia(); // esperando END if (pieza!=p_end) error(0,57); inicio_sentencia(); /* esperando END */
lexico(); lexico();
im3=imem; // Posición del continue im3=imem; /* Posición del continue */
if (dir>=0) { // Incremento y vuelta al inicio del bucle if (dir>=0) { /* Incremento y vuelta al inicio del bucle */
g2(lcar,dir); g2(lcar,dir);
} else { } else {
g2(lcar,-dir); g1(laid); g2(lcar,-dir); g1(laid);
@ -599,12 +604,12 @@ void sentencia() {
inicio_sentencia(); inicio_sentencia();
tbreak[itbreak++]=0; tcont[itcont++]=0; tbreak[itbreak++]=0; tcont[itcont++]=0;
lexico(); lexico();
if (pieza!=p_abrir) error(3,22); lexico(); // esperando '(' if (pieza!=p_abrir) error(3,22); lexico(); /* esperando '(' */
if (pieza!=p_ptocoma) { if (pieza!=p_ptocoma) {
expresion(); g1(lasp); expresion(); g1(lasp);
while (pieza==p_coma) { lexico(); expresion(); g1(lasp); } while (pieza==p_coma) { lexico(); expresion(); g1(lasp); }
} im1=imem; } im1=imem;
if (pieza!=p_ptocoma) error(3,9); lexico(); // esperando ';' if (pieza!=p_ptocoma) error(3,9); lexico(); /* esperando ';' */
if (pieza==p_ptocoma) { if (pieza==p_ptocoma) {
g2(lcar,1); g2(lcar,1);
} else expresion(); } else expresion();
@ -612,16 +617,16 @@ void sentencia() {
while (pieza==p_coma) { lexico(); expresion(); while (pieza==p_coma) { lexico(); expresion();
g2(ljpf,im2); im2=imem-1; } g2(ljpf,im2); im2=imem-1; }
g2(ljmp,0); im3=imem-1; g2(ljmp,0); im3=imem-1;
if (pieza!=p_ptocoma) error(3,9); lexico(); // esperando ';' if (pieza!=p_ptocoma) error(3,9); lexico(); /* esperando ';' */
if (pieza!=p_cerrar) { if (pieza!=p_cerrar) {
expresion(); g1(lasp); expresion(); g1(lasp);
while (pieza==p_coma) { lexico(); expresion(); g1(lasp); } while (pieza==p_coma) { lexico(); expresion(); g1(lasp); }
} }
g2(ljmp,im1); g2(ljmp,im1);
if (pieza!=p_cerrar) error(3,18); lexico(); // esperando ')' if (pieza!=p_cerrar) error(3,18); lexico(); /* esperando ')' */
final_sentencia(); grabar_sentencia(); final_sentencia(); grabar_sentencia();
mem[im3++]=imem; sentencia(); mem[im3++]=imem; sentencia();
if (pieza!=p_end) error(0,57); // esperando END if (pieza!=p_end) error(0,57); /* esperando END */
inicio_sentencia(); lexico(); inicio_sentencia(); lexico();
g2(ljmp,im3); g2(ljmp,im3);
do { im1=mem[im2]; mem[im2]=imem; im2=im1; } while(im2); do { im1=mem[im2]; mem[im2]=imem; im2=im1; } while(im2);
@ -632,10 +637,10 @@ void sentencia() {
case p_switch: case p_switch:
inicio_sentencia(); inicio_sentencia();
lexico(); lexico();
if (!free_sintax) if (pieza!=p_abrir) error(3,22); // esperando '(' if (!free_sintax) if (pieza!=p_abrir) error(3,22); /* esperando '(' */
if (pieza==p_abrir) lexico(); if (pieza==p_abrir) lexico();
condicion(); condicion();
if (!free_sintax) if (pieza!=p_cerrar) error(3,18); // esperando ')' if (!free_sintax) if (pieza!=p_cerrar) error(3,18); /* esperando ')' */
if (pieza==p_cerrar) lexico(); if (pieza==p_cerrar) lexico();
while (pieza==p_ptocoma) { while (pieza==p_ptocoma) {
lexico(); lexico();
@ -667,13 +672,13 @@ void sentencia() {
} else if (pieza==p_default) { } else if (pieza==p_default) {
lexico(); lexico();
if (im1) mem[im1]=imem; im1=0; if (im1) mem[im1]=imem; im1=0;
} else error(0,63); // esperando case, default o end } else error(0,63); /* esperando case, default o end */
if (!free_sintax) if (pieza!=p_ptocoma) error(3,64); // esperando ':' if (!free_sintax) if (pieza!=p_ptocoma) error(3,64); /* esperando ':' */
while (pieza==p_ptocoma || pieza==p_coma) lexico(); while (pieza==p_ptocoma || pieza==p_coma) lexico();
g1(lasp); g1(lasp);
final_sentencia(); grabar_sentencia(); final_sentencia(); grabar_sentencia();
sentencia(); sentencia();
if (pieza!=p_end) error(0,57); // esperando END if (pieza!=p_end) error(0,57); /* esperando END */
inicio_sentencia(); inicio_sentencia();
g2(ljmp,im2); im2=imem-1; g2(ljmp,im2); im2=imem-1;
pasa_ptocoma(); pasa_ptocoma();
@ -687,7 +692,7 @@ void sentencia() {
inicio_sentencia(); inicio_sentencia();
lexico(); if (pieza==p_abrir) { lexico(); if (pieza==p_abrir) {
lexico(); if (pieza!=p_cerrar) { lexico(); if (pieza!=p_cerrar) {
expresion(); if (pieza!=p_cerrar) error(3,18); // esperando ')' expresion(); if (pieza!=p_cerrar) error(3,18); /* esperando ')' */
g1(lfrf); g1(lfrf);
} else { } else {
g1(lfrm); g1(lfrm);
@ -695,27 +700,27 @@ void sentencia() {
} else { } else {
g1(lfrm); g1(lfrm);
} }
if (!free_sintax) if (pieza!=p_ptocoma) error(3,9); // esperando ';' if (!free_sintax) if (pieza!=p_ptocoma) error(3,9); /* esperando ';' */
while (pieza==p_ptocoma || pieza==p_coma) lexico(); while (pieza==p_ptocoma || pieza==p_coma) lexico();
final_sentencia(); grabar_sentencia(); break; final_sentencia(); grabar_sentencia(); break;
case p_debug: case p_debug:
inicio_sentencia(); inicio_sentencia();
g1(ldbg); lexico(); g1(ldbg); lexico();
if (!free_sintax) if (pieza!=p_ptocoma) error(3,9); // esperando ';' if (!free_sintax) if (pieza!=p_ptocoma) error(3,9); /* esperando ';' */
while (pieza==p_ptocoma || pieza==p_coma) lexico(); while (pieza==p_ptocoma || pieza==p_coma) lexico();
final_sentencia(); grabar_sentencia(); final_sentencia(); grabar_sentencia();
break; break;
case p_break: case p_break:
inicio_sentencia(); inicio_sentencia();
if (itbreak==0) error(0,65); lexico(); // break fuera de un bucle if (itbreak==0) error(0,65); lexico(); /* break fuera de un bucle */
if (!free_sintax) if (pieza!=p_ptocoma) error(3,9); // esperando ';' if (!free_sintax) if (pieza!=p_ptocoma) error(3,9); /* esperando ';' */
while (pieza==p_ptocoma || pieza==p_coma) lexico(); while (pieza==p_ptocoma || pieza==p_coma) lexico();
g2(ljmp,0); tbreak[itbreak++]=imem-1; g2(ljmp,0); tbreak[itbreak++]=imem-1;
final_sentencia(); grabar_sentencia(); break; final_sentencia(); grabar_sentencia(); break;
case p_continue: case p_continue:
inicio_sentencia(); inicio_sentencia();
if (itcont==0) error(0,66); lexico(); // continue fuera de un bucle if (itcont==0) error(0,66); lexico(); /* continue fuera de un bucle */
if (!free_sintax) if (pieza!=p_ptocoma) error(3,9); // esperando ';' if (!free_sintax) if (pieza!=p_ptocoma) error(3,9); /* esperando ';' */
while (pieza==p_ptocoma || pieza==p_coma) lexico(); while (pieza==p_ptocoma || pieza==p_coma) lexico();
g2(ljmp,0); tcont[itcont++]=imem-1; g2(ljmp,0); tcont[itcont++]=imem-1;
final_sentencia(); grabar_sentencia(); break; final_sentencia(); grabar_sentencia(); break;
@ -724,7 +729,7 @@ void sentencia() {
lexico(); g2(lclo,0); im1=imem-1; lexico(); g2(lclo,0); im1=imem-1;
final_sentencia(); grabar_sentencia(); final_sentencia(); grabar_sentencia();
sentencia(); sentencia();
if (pieza!=p_end) error(0,57); lexico(); // esperando END if (pieza!=p_end) error(0,57); lexico(); /* esperando END */
mem[im1]=imem; break; mem[im1]=imem; break;
case p_ptocoma: case p_ptocoma:
lexico(); break; lexico(); break;
@ -738,7 +743,6 @@ void sentencia() {
error_25=25; error_25=25;
switch((*_exp).tipo) { switch((*_exp).tipo) {
case ecall: break; case ecall: break;
//case efunc: break;
case efext: break; case efext: break;
case eoper: case eoper:
switch((*_exp).token) { switch((*_exp).token) {
@ -758,11 +762,11 @@ void sentencia() {
case p_or_asigchar: case p_xor_asigchar: case p_shr_asigchar: case p_shl_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; case p_strcpy: case p_strcat: case p_strsub: break;
default: error(4,68); break; // expresion sin sentido default: error(4,68); break; /* expresion sin sentido */
} break; } break;
default: error(4,68); // expresion sin sentido default: error(4,68); /* expresion sin sentido */
} }
if (!free_sintax) if (pieza!=p_ptocoma) error(3,9); // esperando ';' if (!free_sintax) if (pieza!=p_ptocoma) error(3,9); /* esperando ';' */
while (pieza==p_ptocoma || pieza==p_coma) lexico(); while (pieza==p_ptocoma || pieza==p_coma) lexico();
g1(lasp); g1(lasp);
final_sentencia(); grabar_sentencia(); final_sentencia(); grabar_sentencia();
@ -772,29 +776,9 @@ void sentencia() {
} }
//----------------------------------------------------------------------------- /*
// Funciones de generación de código * 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) { void g1(int op) {
if (optimizar) gen(0,op,0); else mem[imem++]=op; if (optimizar) gen(0,op,0); else mem[imem++]=op;
@ -804,11 +788,19 @@ void g2(int op, int pa) {
if (optimizar) gen(1,op,pa); else { mem[imem++]=op; mem[imem++]=pa; } if (optimizar) gen(1,op,pa); else { mem[imem++]=op; mem[imem++]=pa; }
} }
/*
* Optimización peephole de código intermedio EML
*/
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);
int optimizado; int optimizado;
void gen(int param, int op, int pa) { void gen(int param, int op, int pa)
// int n; {
optimizado=0; optimizado=0;
switch(op) { switch(op) {
@ -960,7 +952,7 @@ void gen(int param, int op, int pa) {
} else if (code[15].op==lcar){ } else if (code[15].op==lcar){
if (mem[imem-1]==1) remove_code(1); if (mem[imem-1]==1) remove_code(1);
else if (mem[imem-1]!=0) { else if (mem[imem-1]!=0) {
code[15].op=mem[imem-2]=lcardiv; // Un cardiv nunca será "cardiv 0" code[15].op=mem[imem-2]=lcardiv; /* Un cardiv nunca será "cardiv 0" */
optimizado=1; optimizado=1;
} }
} break; } break;
@ -1014,10 +1006,9 @@ void add_code(int dir, int param, int op) {
} }
//----------------------------------------------------------------------------- /*
// Con el primer token leido guarda el inicio de una sentencia * Con el primer token leido guarda el inicio de una sentencia
//----------------------------------------------------------------------------- */
void inicio_sentencia(void) void inicio_sentencia(void)
{ {
byte * p=ierror-1; byte * p=ierror-1;
@ -1029,10 +1020,9 @@ void inicio_sentencia(void)
} }
} }
//----------------------------------------------------------------------------- /*
// Con el primer token que no es de la sentecia guarda el fin de una sentencia * Con el primer token que no es de la sentecia guarda el fin de una sentencia
//----------------------------------------------------------------------------- */
void final_sentencia(void) void final_sentencia(void)
{ {
byte * p=old_ierror_end-1; byte * p=old_ierror_end-1;
@ -1044,9 +1034,9 @@ void final_sentencia(void)
} }
} }
//----------------------------------------------------------------------------- /*
// Guarda un registro (inicio,final,linea1,...) en el temporal (linf) * Guarda un registro (inicio,final,linea1,...) en el temporal (linf)
//----------------------------------------------------------------------------- */
void grabar_sentencia(void) void grabar_sentencia(void)
{ {
@ -1060,9 +1050,9 @@ void grabar_sentencia(void)
} }
} }
//----------------------------------------------------------------------------- /*
// Agrega información de depurado al ejecutable * Agrega información de depurado al ejecutable
//----------------------------------------------------------------------------- */
void escribe_lin(FILE* f) void escribe_lin(FILE* f)
{ {
@ -1070,21 +1060,7 @@ void escribe_lin(FILE* f)
int l; int l;
byte* progcomp; byte* progcomp;
/*#ifdef WIN32 /* comprimimos el codigo fuente */
// 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);*/
// comprimimos el codigo fuente
while(prog[b]!=0) b++; while(prog[b]!=0) b++;
progcomp=e_malloc(b*2); progcomp=e_malloc(b*2);
l=b*2; l=b*2;
@ -1093,22 +1069,22 @@ void escribe_lin(FILE* f)
fclose(f); fclose(f);
errormem(); errormem();
} }
// escribe el tamaño del codigo descomprimido /* escribe el tamaño del codigo descomprimido */
fwrite(&b,1,4,f); fwrite(&b,1,4,f);
// escribe el tamaño del codigo comprimido /* escribe el tamaño del codigo comprimido */
fwrite(&l,1,4,f); fwrite(&l,1,4,f);
// escribe el codigo comprimido /* escribe el codigo comprimido */
fwrite(progcomp,1,l,f); fwrite(progcomp,1,l,f);
free(progcomp); free(progcomp);
// Escribe el tamaño del LIN /* Escribe el tamaño del LIN */
b=ftell(linf); b=ftell(linf);
#ifdef _DEBUG #ifdef _DEBUG
printf("dbg: TAMANO LIN: %d\n",b); printf("dbg: TAMANO LIN: %d\n",b);
#endif #endif
fwrite(&b,1,4,f); fwrite(&b,1,4,f);
// Escribe la información LIN (offset de cada sentencia en el prg y en el bytecode) /* Escribe la información LIN (offset de cada sentencia en el prg y en el bytecode) */
fseek(linf,0,SEEK_SET); fseek(linf,0,SEEK_SET);
while((b=fgetc(linf))!=EOF) while((b=fgetc(linf))!=EOF)
fputc(b,f); fputc(b,f);
@ -1117,13 +1093,14 @@ void escribe_lin(FILE* f)
} }
// Escribe información sobre los objetos /*
* Escribe información sobre los objetos
*/
void escribe_dbg(FILE* f) void escribe_dbg(FILE* f)
{ {
int n; int n;
// Datos comunes de cada objeto /* Datos comunes de cada objeto */
struct { struct {
int tipo; int tipo;
int nombre; int nombre;
@ -1132,7 +1109,7 @@ void escribe_dbg(FILE* f)
int v0,v1,v2,v3,v4,v5; int v0,v1,v2,v3,v4,v5;
} ob; } ob;
// Cabecera de sección DBG /* Cabecera de sección DBG */
fwrite(&num_obj,4,1,f); fwrite(&num_obj,4,1,f);
fwrite(&num_obj_predefinidos,4,1,f); fwrite(&num_obj_predefinidos,4,1,f);
n=(int)&obj[0]; n=(int)&obj[0];
@ -1140,10 +1117,10 @@ void escribe_dbg(FILE* f)
n=sizeof(struct objeto); n=sizeof(struct objeto);
fwrite(&n,4,1,f); fwrite(&n,4,1,f);
// Escribe los datos de cada objeto /* Escribe los datos de cada objeto */
for (n=0;n<num_obj;n++) { for (n=0;n<num_obj;n++) {
ob.tipo=(int)obj[n].tipo; ob.tipo=(int)obj[n].tipo;
ob.nombre=(int)obj[n].name-(int)vnom; // offset que apunta al nombre en vnom ob.nombre=(int)obj[n].name-(int)vnom; /* offset que apunta al nombre en vnom */
ob.bloque=(int)obj[n].bloque; ob.bloque=(int)obj[n].bloque;
ob.miembro=(int)obj[n].member; ob.miembro=(int)obj[n].member;
ob.v0=(int)obj[n].sglo.offset; ob.v0=(int)obj[n].sglo.offset;
@ -1153,14 +1130,15 @@ void escribe_dbg(FILE* f)
ob.v4=(int)obj[n].sglo.items2; ob.v4=(int)obj[n].sglo.items2;
ob.v5=(int)obj[n].sglo.items3; ob.v5=(int)obj[n].sglo.items3;
if (obj[n].tipo==tpsgl || obj[n].tipo==tpslo) ob.v1=(ob.v1-(int)&obj[0])/sizeof(struct objeto); if (obj[n].tipo==tpsgl || obj[n].tipo==tpslo) ob.v1=(ob.v1-(int)&obj[0])/sizeof(struct objeto);
// OJO ! que no se pueden añadir objetos aquí (ver uso de &obj[0] y sizeof(struct objeto))
/* OJO ! que no se pueden añadir objetos aquí (ver uso de &obj[0] y sizeof(struct objeto)) */
fwrite(&ob,sizeof(ob),1,f); fwrite(&ob,sizeof(ob),1,f);
} }
// Escribe el tamaño del vector de nombres /* Escribe el tamaño del vector de nombres */
n=(int)ivnom.b-(int)vnom; n=(int)ivnom.b-(int)vnom;
fwrite(&n,4,1,f); fwrite(&n,4,1,f);
// Escribe el vector de nombres /* Escribe el vector de nombres */
fwrite(vnom,1,n,f); fwrite(vnom,1,n,f);
} }

View file

@ -1,7 +1,7 @@
/* /*
* eDiv Compiler * eDiv Compiler
* Copyleft (C) 2000-2002 Sion Entertainment * Copyright (C) 2000-2002 Sion Entertainment
* http://www.sion-e.com * http://www.sionhq.com
* *
* This program is free software; you can redistribute it and/or modify * 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 * it under the terms of the GNU General Public License as published by
@ -23,6 +23,7 @@
#include "main.h" #include "main.h"
/* "Truco" para que MSVC no de problemas 'raros' */
#ifdef _WINBASE_ #ifdef _WINBASE_
# undef lstrcpy # undef lstrcpy
# undef lstrcat # undef lstrcat
@ -41,24 +42,26 @@ int itxt, ifrm_max;
byte * imemptr; byte * imemptr;
int iloc_len; // final de las variables locales incluyendo las privadas int iloc_len; /* final de las variables locales incluyendo las privadas */
// mem[] vector de memoria destino /*
// imem puntero para la generación de datos y código * mem[] vector de memoria destino
// imem_max fin de la memoria destino (indice máximo de mem[]) * imem puntero para la generación de datos y código
// iloc inicio en mem[] de las variables locales (inicializadas) * imem_max fin de la memoria destino (indice máximo de mem[])
// iloc_len longitud de las variables locales * iloc inicio en mem[] de las variables locales (inicializadas)
* iloc_len longitud de las variables locales
*/
//- - - - - - - Inserción en la tabla de expresiones, acceso a variables /*
* Inserción en la tabla de expresiones, acceso a variables:
//vglo &vglo ptr *
//tglo[_exp] &tglo <_exp> add rng ptr * vglo &vglo ptr
* tglo[_exp] &tglo <_exp> add rng ptr
//vloc &vloc aid ptr * vloc &vloc aid ptr
//tloc[_exp] &tloc <_exp> add rng aid ptr * tloc[_exp] &tloc <_exp> add rng aid ptr
* proc.vloc &proc ptr &vloc add ptr
//proc.vloc &proc ptr &vloc add ptr * proc.tloc[_exp] &proc ptr &tloc <_exp> add rng add ptr
//proc.tloc[_exp] &proc ptr &tloc <_exp> add rng add ptr */
FILE * fin, * fout; FILE * fin, * fout;
@ -80,75 +83,71 @@ int optimizar;
int case_sensitive; int case_sensitive;
//----------------------------------------------------------------------------- /*
// MNEMÓNICOS BYTECODE EML * MNEMÓNICOS BYTECODE EML
//----------------------------------------------------------------------------- */
#define lnop 0 /* * No operación */
//Mnemónico-Códg.-Operandos (Generación de código EML, "*" = "aún no usado") #define lcar 1 /* valor Carga una constante en pila */
#define lasi 2 /* Saca valor, offset y mete el valor en [offset] */
#define lnop 0 // * No operación #define lori 3 /* Or lógico */
#define lcar 1 // valor Carga una constante en pila #define lxor 4 /* Xor, or exclusivo */
#define lasi 2 // Saca valor, offset y mete el valor en [offset] #define land 5 /* And lógico, operador sobre condiciones */
#define lori 3 // Or lógico #define ligu 6 /* Igual, operador logico de comparación */
#define lxor 4 // Xor, or exclusivo #define ldis 7 /* Distinto, true si los 2 valores son diferentes */
#define land 5 // And lógico, operador sobre condiciones #define lmay 8 /* Mayor, comparación con signo */
#define ligu 6 // Igual, operador logico de comparación #define lmen 9 /* Menor, idem */
#define ldis 7 // Distinto, true si los 2 valores son diferentes #define lmei 10 /* Menor o igual */
#define lmay 8 // Mayor, comparación con signo #define lmai 11 /* Mayor o igual */
#define lmen 9 // Menor, idem #define ladd 12 /* Suma dos constantes */
#define lmei 10 // Menor o igual #define lsub 13 /* Resta, operación binaria */
#define lmai 11 // Mayor o igual #define lmul 14 /* Multiplicación */
#define ladd 12 // Suma dos constantes #define ldiv 15 /* División de enteros */
#define lsub 13 // Resta, operación binaria #define lmod 16 /* Módulo, resto de la división */
#define lmul 14 // Multiplicación #define lneg 17 /* Negación, cambia de signo una constante */
#define ldiv 15 // División de enteros #define lptr 18 /* Pointer, saca offset y mete [offset] */
#define lmod 16 // Módulo, resto de la división #define lnot 19 /* Negación binaria, bit a bit */
#define lneg 17 // Negación, cambia de signo una constante #define laid 20 /* Suma id a la constante de la pila */
#define lptr 18 // Pointer, saca offset y mete [offset] #define lcid 21 /* Carga id en la pila */
#define lnot 19 // Negación binaria, bit a bit #define lrng 22 /* rango Realiza una comparación de rango */
#define laid 20 // Suma id a la constante de la pila #define ljmp 23 /* offset Salta a una dirección de mem[] */
#define lcid 21 // Carga id en la pila #define ljpf 24 /* offset Salta si un valor es falso a una dirección */
#define lrng 22 // rango Realiza una comparación de rango #define lfun 25 /* código Llamada a un proceso interno, ej. signal() */
#define ljmp 23 // offset Salta a una dirección de mem[] #define lcal 26 /* offset Crea un nuevo proceso en el programa */
#define ljpf 24 // offset Salta si un valor es falso a una dirección #define lret 27 /* Auto-eliminación del proceso */
#define lfun 25 // código Llamada a un proceso interno, ej. signal() #define lasp 28 /* Desecha un valor apilado */
#define lcal 26 // offset Crea un nuevo proceso en el programa #define lfrm 29 /* Detiene por este frame la ejecución del proceso */
#define lret 27 // Auto-eliminación del proceso #define lcbp 30 /* num_par Inicializa el puntero a los parámetros locales */
#define lasp 28 // Desecha un valor apilado #define lcpa 31 /* Saca offset, lee parámetro [offset] y bp++ */
#define lfrm 29 // Detiene por este frame la ejecución del proceso #define ltyp 32 /* bloque Define el tipo de proceso actual (colisiones) */
#define lcbp 30 // num_par Inicializa el puntero a los parámetros locales #define lpri 33 /* offset Salta a la dirección, y carga var. privadas */
#define lcpa 31 // Saca offset, lee parámetro [offset] y bp++ #define lcse 34 /* offset Si switch <> expresión, salta al offset */
#define ltyp 32 // bloque Define el tipo de proceso actual (colisiones) #define lcsr 35 /* offset Si switch no esta en el rango, salta al offset */
#define lpri 33 // offset Salta a la dirección, y carga var. privadas #define lshr 36 /* Rotacion a la derecha (modo C, >>) */
#define lcse 34 // offset Si switch <> expresión, salta al offset #define lshl 37 /* Rotacion a la izquierda (modo C, <<) */
#define lcsr 35 // offset Si switch no esta en el rango, salta al offset #define lipt 38 /* Incremento y pointer */
#define lshr 36 // Rotacion a la derecha (modo C, >>) #define lpti 39 /* Pointer e incremento */
#define lshl 37 // Rotacion a la izquierda (modo C, <<) #define ldpt 40 /* Decremento y pointer */
#define lipt 38 // Incremento y pointer #define lptd 41 /* Pointer y decremento */
#define lpti 39 // Pointer e incremento #define lada 42 /* Add-asignación */
#define ldpt 40 // Decremento y pointer #define lsua 43 /* Sub-asignación */
#define lptd 41 // Pointer y decremento #define lmua 44 /* Mul-asignación */
#define lada 42 // Add-asignación #define ldia 45 /* Div-asignación */
#define lsua 43 // Sub-asignación #define lmoa 46 /* Mod-asignación */
#define lmua 44 // Mul-asignación #define lana 47 /* And-asignación */
#define ldia 45 // Div-asignación #define lora 48 /* Or-asignación */
#define lmoa 46 // Mod-asignación #define lxoa 49 /* Xor-asignación */
#define lana 47 // And-asignación #define lsra 50 /* Shr-asignación */
#define lora 48 // Or-asignación #define lsla 51 /* Shl-asignación */
#define lxoa 49 // Xor-asignación #define lpar 52 /* num_par_pri Define el número de parámetros privados */
#define lsra 50 // Shr-asignación #define lrtf 53 /* Auto-eliminación del proceso, devuelve un valor */
#define lsla 51 // Shl-asignación #define lclo 54 /* offset Crea un clon del proceso actual */
#define lpar 52 // num_par_pri Define el número de parámetros privados #define lfrf 55 /* Pseudo-Frame (frame a un porcentaje) */
#define lrtf 53 // Auto-eliminación del proceso, devuelve un valor #define limp 56 /* offset text Importa una DLL externa */
#define lclo 54 // offset Crea un clon del proceso actual #define lext 57 /* código Llama a una función externa */
#define lfrf 55 // Pseudo-Frame (frame a un porcentaje, frame(100)==frame) #define lchk 58 /* Comprueba la validez de un identificador */
#define limp 56 // offset text Importa una DLL externa #define ldbg 59 /* Invoca al debugger */
#define lext 57 // código Llama a una función externa
#define lchk 58 // Comprueba la validez de un identificador
#define ldbg 59 // Invoca al debugger
// Instrucciones añadidas para la optimización (DIV 2.0)
/* Instrucciones añadidas para la optimización (DIV 2.0) */
#define lcar2 60 #define lcar2 60
#define lcar3 61 #define lcar3 61
#define lcar4 62 #define lcar4 62
@ -168,68 +167,63 @@ int case_sensitive;
#define lcarsub 76 #define lcarsub 76
#define lcardiv 77 #define lcardiv 77
// Instrucciones añadidas para el manejo de caracteres /* Instrucciones añadidas para el manejo de caracteres */
#define lptrchr 78 /* Pointer, saca (index, offset) y mete [offset+byte index] */
#define lasichr 79 /* Saca (valor, index, offset) y mete el valor en [offset+byte index] */
#define liptchr 80 /* Incremento y pointer */
#define lptichr 81 /* Pointer e incremento */
#define ldptchr 82 /* Decremento y pointer */
#define lptdchr 83 /* Pointer y decremento */
#define ladachr 84 /* Add-asignación */
#define lsuachr 85 /* Sub-asignación */
#define lmuachr 86 /* Mul-asignación */
#define ldiachr 87 /* Div-asignación */
#define lmoachr 88 /* Mod-asignación */
#define lanachr 89 /* And-asignación */
#define lorachr 90 /* Or-asignación */
#define lxoachr 91 /* Xor-asignación */
#define lsrachr 92 /* Shr-asignación */
#define lslachr 93 /* Shl-asignación */
#define lcpachr 94 /* Saca offset, lee parámetro [offset] y bp++ */
#define lptrchr 78 // Pointer, saca (index, offset) y mete [offset+byte index] /* Instrucciones añadidas para el manejo de cadenas */
#define lasichr 79 // Saca (valor, index, offset) y mete el valor en [offset+byte index] #define lstrcpy 95 /* Saca si, di, y hace strcpy(mem[di],[si]) (deja di en pila) */
#define liptchr 80 // Incremento y pointer #define lstrfix 96 /* Amplia una cadena antes de meter un char en ella */
#define lptichr 81 // Pointer e incremento #define lstrcat 97 /* Concatena dos cadenas (opera como strcpy) */
#define ldptchr 82 // Decremento y pointer #define lstradd 98 /* Suma dos strings "en el aire" y deja en pila el puntero al aire */
#define lptdchr 83 // Pointer y decremento #define lstrdec 99 /* Añade o quita caracteres a una cadena */
#define ladachr 84 // Add-asignación #define lstrsub 100 /* Quita caracteres a una cadena (-=) */
#define lsuachr 85 // Sub-asignación #define lstrlen 101 /* Sustituye una cadena por su longitud */
#define lmuachr 86 // Mul-asignación #define lstrigu 102 /* Comparacion de igualdad de dos cadenas */
#define ldiachr 87 // Div-asignación #define lstrdis 103 /* Cadenas distintas */
#define lmoachr 88 // Mod-asignación #define lstrmay 104 /* Cadena mayor */
#define lanachr 89 // And-asignación #define lstrmen 105 /* Cadena menor */
#define lorachr 90 // Or-asignación #define lstrmei 106 /* Cadena mayor o igual */
#define lxoachr 91 // Xor-asignación #define lstrmai 107 /* Cadena menor o igual */
#define lsrachr 92 // Shr-asignación #define lcpastr 108 /* Carga un parámetro en una cadena */
#define lslachr 93 // Shl-asignación
#define lcpachr 94 // Saca offset, lee parámetro [offset] y bp++
// Instrucciones añadidas para el manejo de cadenas /* Instrucciones añadidas para el manejo de Words */
#define lptrwor 109 /* Pointer, saca (index, offset) y mete [offset+byte index] */
#define lasiwor 110 /* Saca (valor, index, offset) y mete el valor en [offset+byte index] */
#define liptwor 111 /* Incremento y pointer */
#define lptiwor 112 /* Pointer e incremento */
#define ldptwor 113 /* Decremento y pointer */
#define lptdwor 114 /* Pointer y decremento */
#define ladawor 115 /* Add-asignación */
#define lsuawor 116 /* Sub-asignación */
#define lmuawor 117 /* Mul-asignación */
#define ldiawor 118 /* Div-asignación */
#define lmoawor 119 /* Mod-asignación */
#define lanawor 120 /* And-asignación */
#define lorawor 121 /* Or-asignación */
#define lxoawor 122 /* Xor-asignación */
#define lsrawor 123 /* Shr-asignación */
#define lslawor 124 /* Shl-asignación */
#define lcpawor 125 /* Saca offset, lee parámetro [offset] y bp++ */
#define lstrcpy 95 // Saca si, di, y hace strcpy(mem[di],[si]) (deja di en pila) /* Miscelánea */
#define lstrfix 96 // Amplia una cadena antes de meter un char en ella #define lnul 126 /* Comprueba que un puntero no sea NULL */
#define lstrcat 97 // Concatena dos cadenas (opera como strcpy)
#define lstradd 98 // Suma dos strings "en el aire" y deja en pila el puntero al aire
#define lstrdec 99 // Añade o quita caracteres a una cadena
#define lstrsub 100 // Quita caracteres a una cadena (-=)
#define lstrlen 101 // Sustituye una cadena por su longitud
#define lstrigu 102 // Comparacion de igualdad de dos cadenas
#define lstrdis 103 // Cadenas distintas
#define lstrmay 104 // Cadena mayor
#define lstrmen 105 // Cadena menor
#define lstrmei 106 // Cadena mayor o igual
#define lstrmai 107 // Cadena menor o igual
#define lcpastr 108 // Carga un parámetro en una cadena
// Instrucciones añadidas para el manejo de Words
#define lptrwor 109 // Pointer, saca (index, offset) y mete [offset+byte index]
#define lasiwor 110 // Saca (valor, index, offset) y mete el valor en [offset+byte index]
#define liptwor 111 // Incremento y pointer
#define lptiwor 112 // Pointer e incremento
#define ldptwor 113 // Decremento y pointer
#define lptdwor 114 // Pointer y decremento
#define ladawor 115 // Add-asignación
#define lsuawor 116 // Sub-asignación
#define lmuawor 117 // Mul-asignación
#define ldiawor 118 // Div-asignación
#define lmoawor 119 // Mod-asignación
#define lanawor 120 // And-asignación
#define lorawor 121 // Or-asignación
#define lxoawor 122 // Xor-asignación
#define lsrawor 123 // Shr-asignación
#define lslawor 124 // Shl-asignación
#define lcpawor 125 // Saca offset, lee parámetro [offset] y bp++
// Miscelánea
#define lnul 126 // Comprueba que un puntero no sea NULL
//-----------------------------------------------------------------------------
struct { // Peephole, "mirilla" para el optimizador struct { // Peephole, "mirilla" para el optimizador
int dir; // Dirección int dir; // Dirección
@ -237,29 +231,25 @@ struct { // Peephole, "mirilla" para el optimizador
int op; // Opcode int op; // Opcode
} code[16]; // En code[15] debe quedar siempre la última instrucción generada } code[16]; // En code[15] debe quedar siempre la última instrucción generada
//----------------------------------------------------------------------------- /* Informacion para temporal de debug (posicion en mem y fuente de cada sentencia) */
FILE * linf; /* En este temporal guardamos la info y luego lo agregamos al exe */
// Informacion para temporal de debug (posicion en mem y fuente de cada sentencia) int inicio,final; /* Direcciones inicial y final de mem[] de la sentencia */
int linea1,columna1; /* Posicion en la que comienza la sentencia en el fuente */
int linea2,columna2; /* Posicion en la que acaba la sentencia en el fuente */
FILE * linf; // En este temporal guardamos la info y luego lo agregamos al exe void inicio_sentencia(void); /* Fija inicio, linea1, columna1 */
void final_sentencia(void); /* Fija final, linea2, columna2 */
int inicio,final; // Direcciones inicial y final de mem[] de la sentencia void grabar_sentencia(void); /* Guarda las seis variables en el fichero */
int linea1,columna1; // Posicion en la que comienza la sentencia en el fuente
int linea2,columna2; // Posicion en la que acaba la sentencia en el fuente
void inicio_sentencia(void); // Fija inicio, linea1, columna1
void final_sentencia(void); // Fija final, linea2, columna2
void grabar_sentencia(void); // Guarda las seis variables en el fichero
void escribe_lin(FILE* f); void escribe_lin(FILE* f);
void escribe_dbg(FILE* f); void escribe_dbg(FILE* f);
//-----------------------------------------------------------------------------
int salto_import; // offset donde guardaremos el offset del ljmp que salta int salto_import; /* offset donde guardaremos el offset del ljmp que salta
// a la rutina de carga de DLLs * a la rutina de carga de DLLs.
*/
//-----------------------------------------------------------------------------
#define max_break 512 #define max_break 512
int tbreak[max_break]; int tbreak[max_break];
@ -274,10 +264,9 @@ int telseif[max_elseif];
int itelseif; int itelseif;
//----------------------------------------------------------------------------- /*
// PROTOTIPOS * PROTOTIPOS
//----------------------------------------------------------------------------- */
void prepara_compilacion(); void prepara_compilacion();
void compila(); void compila();
void test_buffer(int * * ,int * ,int); void test_buffer(int * * ,int * ,int);
@ -286,4 +275,4 @@ void sentencia();
void g1(int op); void g1(int op);
void g2(int op, int pa); void g2(int op, int pa);
#endif // __COMPILER_H #endif /* __COMPILER_H */