KLNX.cpp_



/****************************************************************
		COMPILADOR DE LENGUAJE KAREL PARA LINUX

		Autor: Ing. CUAUHTEMOC RIVERA LOAIZA

		Rutinas de generacion del lenguaje ensamblador
		Karel elaboradas por el Ing. Rafael R. Ochoa
		rochoa@scfie.eie.umich.mx

		Universidad Michoacana de San Nicolas de Hidalgo

		Seccion de Graduados de la Facultad de Ingenieria
		Electrica

		Maestria en Sistemas Computacionales

		crivera@scfie.eie.umich.mx
******************************************************************

Proposito: 	Este programa permite la compilacion de programas
		hechos en el lenguaje Karel, dentro del ambiente
		de Linux. En caso de una compilacion sin errores,
		se produce a la salida un archivo con extension
		*.ok, el cual puede ser visualizado en la interfaz
		hecha en Tcl/Tk (se requiere contar con el inter-
		prete de este lenguaje).

******************************************************************

Uso del
Programa:	Se requiere de un compliador de C++. Para la com-
		pilacion del programa fuente se necesita hacer lo
		siguiente:
			g++ -o <karel> <karel.cpp>
		Por ejemplo, para correr el archivo 6.kar:
			/<path>/karel 6
		Al correr el programa se pide al usuario que de
		el nombre del archivo karel, pero sin la extension
		exito se obtiene un archivo en lenguaje ensamblador
		de Karel (nombre_archivo.ok), el cual se visualiza
		en el interprete.
		En caso de errores en el programa *.kar se produce
		un mensaje de error.

*****************************************************************/


#include <stdlib.h>
#include <string.h>
#include <stdio.h>
#include <iostream.h>
#include <fstream.h>

char *token(int, char *);
char *instr_primitivas (char *);
char *pruebas_karel (char *);
char *genera_etiqueta(void);
char gen_etiq(void);

class tabla_de_simbolos{
		char *instr;
		tabla_de_simbolos *sig;
	public:
		void nueva_instruccion(char *);
		int existe_instruccion(char *);
};

class ensamblador {
		int linea;
		char *comando;
		ensamblador *sig;
	public:
		void archivo_virtual(char *,int);
		friend void archivo_ensamblador (char *);
		friend void genera_nva_instr();
};

class entrada{
	public:
		char *linea;
		int num;
		entrada *sig;
		void inserta_nodo (int , char *);
		void textLoadFile (char *);
};

class instrucciones:public entrada{
		void instruccion ();
		void genera_nva_instr();
		void repite ();
		void fin_bloque();
		void mientras ();
		void si ();
		friend void genera_nva_instr();
		friend void programa();
};

class ambiente:public entrada{
		void karel_inicio();
		void forma_entorno();
		void inicio_de_ambiente();
		void instrucciones_de_ambiente ();
		void fin_de_ambiente();
		friend void archivo_ensamblador (char *);
};

class ejecucion:public entrada{
		void inicia_programa();
		void inicia_ejecucion();
		void fin_ejecucion();
		void fin_programa();
		friend void archivo_ensamblador (char *);
		friend void programa();
};

entrada *start, *nodo;
ensamblador *karel;
tabla_de_simbolos *proxima_nva_instr;
int etiqueta;

/***********************************************************
	Nombre de la funcion: textLoadFile

	Proposito: Apertura del archivo *.kar para
	Entrega: Nada
	Funciones externas: inserta_nodo
************************************************************/
void entrada::textLoadFile(char *fileName){
	char ch, car[1], linea[80];
	int numero_linea = 1;

	ifstream inicio(fileName);
	if(!inicio){
		cout<<"Error de lectura!";
		exit (0);
	}
	inicio.get(ch);
	while (ch != EOF){
		linea[0] = '\0';
		while (ch == ' ' || ch == '\t' )
			inicio.get(ch);
		while (ch != '\n' && ch != EOF){
			car[0] = ch;
			car[1] = '\0';
			strcat(linea, car);
			inicio.get(ch);
		}
		if (strlen(linea) > 0)
			inserta_nodo(numero_linea, linea);
		numero_linea++;
		inicio.get(ch);
	}
	inicio.close();
}

/***********************************************************
	Nombre de la funcion: INSERTA_NODO

	Proposito: Formar la lista lineal con un nodo
		   para cada renglon del programa inicial
	Entrega: Nada
	Funciones externas: Ninguna.
************************************************************/
void entrada::inserta_nodo (int num_linea, char linea[80]){
	entrada *act = NULL, *ant = NULL, *nodo_nuevo = NULL;

	if (!(nodo_nuevo = new entrada)){
		cout<<"\nError de asignacion";
		exit(1);
	}
	nodo_nuevo->linea = strdup(linea);
	nodo_nuevo->num   = num_linea;
	nodo_nuevo->sig   = NULL;
	if(!start)
		start = nodo_nuevo;
	else {
		act = start;
		while (act) {
			ant = act;
			act = act->sig;
		}
	nodo_nuevo->linea   = strdup(linea);
	nodo_nuevo->num     = num_linea;
	nodo_nuevo->sig = NULL;
	ant->sig = nodo_nuevo;
	}
}


////////////////////////////////////////////////////////////////
//		RUTINAS DE CREACION DE AMBIENTE		      //
////////////////////////////////////////////////////////////////
/***********************************************************
	Nombre de la funcion: FORMA_ENTORNO

		   etiqueta "jc kini", que le indica al
	Entrega: Nada
************************************************************/
void ambiente::forma_entorno() {
	ensamblador haz;

	inicio_de_ambiente();
	karel_inicio();
	instrucciones_de_ambiente();
	fin_de_ambiente();
	haz.archivo_virtual("jc kini", nodo->num);
}

/***********************************************************
	Nombre de la funcion: KAREL_INICIO

	Entrega: Nada
	Funciones externas: archivo_virtual, token
************************************************************/
void ambiente::karel_inicio(){
	ensamblador haz;

	if (strncmp(nodo->linea, "KAREL_ESTA_EN_CALLE", 19) != 0 ){
		exit(1);
	}
	haz.archivo_virtual("k", nodo->num);
	haz.archivo_virtual(token(2,nodo->linea), nodo->num); // calle
	haz.archivo_virtual(token(4,nodo->linea), nodo->num); // avenida
	haz.archivo_virtual(token(6,nodo->linea), nodo->num); // direccion
	haz.archivo_virtual(token(8,nodo->linea), nodo->num); // monedas
	nodo = nodo->sig;
}

/***********************************************************
	Nombre de la funcion: INSTRUCCIONES DE AMBIENTE

	Entrega: Nada
	Funciones externas: archivo_virtual, token
************************************************************/
void ambiente::instrucciones_de_ambiente() {
	ensamblador haz;

	while (strncmp(nodo->linea, "FIN_DE_AMBIENTE", 15) != 0 ) {
	  if (strncmp(nodo->linea, "PARED_JUNTO_A_CALLE", 19) == 0 ) {
		haz.archivo_virtual("pc", nodo->num);
		haz.archivo_virtual(token(2,nodo->linea), nodo->num);
		haz.archivo_virtual(token(4,nodo->linea), nodo->num);
		haz.archivo_virtual(token(6,nodo->linea), nodo->num);
	  }
	  if (strncmp(nodo->linea, "PARED_JUNTO_A_AVENIDA", 21) == 0 ){
		haz.archivo_virtual("pa", nodo->num);
		haz.archivo_virtual(token(2,nodo->linea), nodo->num);
		haz.archivo_virtual(token(4,nodo->linea), nodo->num);
		haz.archivo_virtual(token(6,nodo->linea), nodo->num);
	  }
	  if (strncmp(nodo->linea, "HAY", 3) == 0 ){
		haz.archivo_virtual("m", nodo->num);
		haz.archivo_virtual(token(2,nodo->linea), nodo->num);
		haz.archivo_virtual(token(4,nodo->linea), nodo->num);
		haz.archivo_virtual(token(6,nodo->linea), nodo->num);
	  }
	nodo = nodo->sig;
	}
	if (strncmp(nodo->linea, "FIN_DE_AMBIENTE", 15) != 0 ){
		cout<<"\nNo se encuentra el FIN_DE_AMBIENTE";
		exit(1);
	}
}

/***********************************************************
	Nombre de la funcion: INICIO_AMBIENTE

		   AMBIENTE
	Entrega: Nada
************************************************************/
void ambiente::inicio_de_ambiente(){
	if (strncmp(nodo->linea, "INICIO_DE_AMBIENTE", 18) != 0 ){
		cout<<"No se encuentra INICIO_DE_AMBIENTE";
		exit(1);
	}
	nodo = nodo->sig;
}

/***********************************************************
	Nombre de la funcion: FIN_AMBIENTE

		   AMBIENTE
	Entrega: Nada
	Funciones externas: Ninguna
************************************************************/
void ambiente::fin_de_ambiente(){
	if (strncmp(nodo->linea, "FIN_DE_AMBIENTE", 15) != 0 ){
		cout<<"No se encuentra FIN_DE_AMBIENTE";
		exit(1);
	}
	nodo = nodo->sig;
}

/***********************************************************
	Nombre de la funcion: TOKEN

	Funciones externas:Ninguna
************************************************************/
char *token(int localizacion, char *renglon){
	char simbolo[1], palabra[80],*cadena = NULL, c=' ',*cad;
	int posicion=0;

	cadena = strdup(renglon);
	while(localizacion>1){
		cadena= strchr(cadena,c);
		cadena = cadena++;
		localizacion--;
	}
	palabra[0] = '\0';
	cad=strchr(cadena,c);
	posicion=cad-cadena;
	for (int i=0;i<posicion;i++){
		if (cadena[i]!=';' && cadena[i]!=' '){
			simbolo[0]=cadena[i];
			simbolo[1]='\0';
			strcat(palabra,simbolo);}
	}
	return palabra;
}


/***********************************************************
	Nombre de la funcion: INSTR_PRIMITIVAS

		    instruccion primitiva de karel
	Funciones externas: token
************************************************************/
char *instr_primitivas(char *cadena){
   tabla_de_simbolos checa;

   if ((strlen(token(1,cadena)) == 19) &&
       (strncmp(token(1,cadena), "gira_a_la_izquierda", 19) == 0 )
      ) return "gi";
   if ((strlen(token(1,cadena)) == 7) &&
       (strncmp(token(1,cadena), "apagate",7) == 0 )
      ) return "ap";
   if ((strlen(token(1,cadena)) == 13) &&
       (strncmp(token(1,cadena), "coloca_moneda",13) == 0 )
      ) return "cm";
   if ((strlen(token(1,cadena)) == 6) &&
       (strncmp(token(1,cadena), "avanza", 6) == 0 )
      ) return "av";
   if ((strlen(token(1,cadena)) == 13) &&
       (strncmp(token(1,cadena), "recoge_moneda", 13) == 0 )
      ) return "rm";
   if (checa.existe_instruccion(token(1, cadena))) return token(1, cadena);
   return "\0";
}

/***********************************************************
	Nombre de la funcion: PRUEBAS_KAREL

		    prueba de karel
		   prueba en ensamblador Karel
	Funciones externas:Ninguna
************************************************************/
char *pruebas_karel(char *cadena){
   if (strncmp(cadena, "frente_despejado",        16) == 0 ) return "fd";
   if (strncmp(cadena, "frente_bloqueado",        16) == 0 ) return "fn";
   if (strncmp(cadena, "izquierda_despejada",     19) == 0 ) return "id";
   if (strncmp(cadena, "izquierda_bloqueada",     19) == 0 ) return "ib";
   if (strncmp(cadena, "derecha_despejada",       17) == 0 ) return "dd";
   if (strncmp(cadena, "derecha_bloqueada",       17) == 0 ) return "db";
   if (strncmp(cadena, "junto_a_moneda",          14) == 0 ) return "jm";
   if (strncmp(cadena, "no_junto_a_moneda",       17) == 0 ) return "njm";
   if (strncmp(cadena, "hacia_el_norte",          14) == 0 ) return "hn";
   if (strncmp(cadena, "no_hacia_el_norte",       17) == 0 ) return "nhn";
   if (strncmp(cadena, "hacia_el_sur",            12) == 0 ) return "hs";
   if (strncmp(cadena, "no_hacia_el_sur",         15) == 0 ) return "nhs";
   if (strncmp(cadena, "hacia_el_este",           13) == 0 ) return "he";
   if (strncmp(cadena, "no_hacia_el_este",        16) == 0 ) return "nhe";
   if (strncmp(cadena, "hacia_el_oeste",          14) == 0 ) return "ho";
   if (strncmp(cadena, "no_hacia_el_oeste",       17) == 0 ) return "nho";
   if (strncmp(cadena, "con_monedas_en_su_bolsa", 23) == 0 ) return "din";
   if (strncmp(cadena, "sin_monedas_en_su_bolsa", 23) == 0 ) return "smb";
   else { cout<<"\nInstruccion desconocida!";
	exit(1); }
   return "\0";
}

/***********************************************************
	Nombre de la funcion: ARCHIVO_VIRTUAL

	Entrega: Nada.
		   coloca todo el programa en ensamblador Karel
	Funciones externas:Ninguna
************************************************************/
void ensamblador::archivo_virtual(char *mnemonico,int num_linea){
	ensamblador *ant = NULL, *act = karel;

	while(act) {
		ant = act;
		act = act->sig;
	}
	if (!(act = new ensamblador)) {
		cout<<"\nError de asignacion";
		exit(1);
	}
	act->comando = strdup(mnemonico);
	act->linea = num_linea;
	act->sig = NULL;
	if(!karel)
		karel = act;
	else
		ant->sig = act;
}


////////////////////////////////////////////////////////////////
//		RUTINAS PARA LA EJECUCION DE KAREL	      //
////////////////////////////////////////////////////////////////
void programa(){

	ensamblador haz;
	instrucciones ejecuta;
	ejecucion corre;

	corre.inicia_programa();
	ejecuta.genera_nva_instr();
	corre.inicia_ejecucion();
	while (strncmp(nodo->linea, "FIN_DE_EJECUCION", 16) != 0)
		ejecuta.instruccion();
	corre.fin_ejecucion();
	corre.fin_programa();
	haz.archivo_virtual("ok", 1);
}

/***********************************************************
	Nombre de la funcion: INICIA_PROGRAMA

	Proposito: Verifica la existencia del token
		   "INICIO_DE_PROGRAMA"
	Entrega: Nada
	Funciones externas: Ninguna
************************************************************/

void ejecucion::inicia_programa(){
	if (strncmp(nodo->linea, "INICIO_DE_PROGRAMA", 18) != 0 ){
		cout<<"\nNo se encuentra INICIO_DE_PROGRAMA";
		exit(1);
	}
	nodo = nodo->sig;
}

/***********************************************************
	Nombre de la funcion: INICIA_EJECUCION

	Proposito: Verifica la existencia del token
		   "INICIO_DE_EJECUCION" y agrega
		   al programa en ensamblador la
		   etiqueta "kini", la cual indica
		   karel.
	Entrega: Nada
	Funciones externas: archivo_virtual
************************************************************/
void ejecucion::inicia_ejecucion(){
	ensamblador haz;

	if (strncmp(nodo->linea, "INICIO_DE_EJECUCION", 19) != 0 ){
		cout<<"\nNo se encuentra INICIO_DE_EJECUCION";
		exit(1);
	}
	haz.archivo_virtual("kini", nodo->num);
	nodo = nodo->sig;
}


/***************************************************************
	Nombre de la funcion: GENERA_NVA_INSTR

		   ensamblador Karel
	Entrega: Nada
	Funciones externas: nueva_instruccion,instruccion
			    archivo_virtual.
****************************************************************/
void instrucciones::genera_nva_instr(){
   instrucciones ejecuta;
   ensamblador haz;
   tabla_de_simbolos checa;

   while ( (nodo) && (strncmp(nodo->linea, "INICIO_DE_EJECUCION", 19) != 0) )
   {
      if (strncmp(nodo->linea, "DEFINE_NUEVA_INSTRUCCION", 24) == 0 )
      {
	 haz.archivo_virtual(token(2, nodo->linea), nodo->num);
	 checa.nueva_instruccion(token(2, nodo->linea));
	 nodo = nodo->sig;
	 ejecuta.instruccion();
      }
      haz.archivo_virtual("rs", nodo->num);
   }
   if ( !nodo ){
	cout<<"\nError en la linea"<<nodo->num<<" => "<<nodo->linea;
	exit(1);
   }
}

/***************************************************************
	Nombre de la funcion: INSTRUCCION

		   o condicionales.
	Entrega: Nada
	Funciones externas: si, mientras, repite,
			    archivo_virtual, existe_instruccion
****************************************************************/
void instrucciones::instruccion(){
   char *id = NULL, *brinco = NULL;
   ensamblador haz;
   tabla_de_simbolos checa;

   if ( (strncmp(nodo->linea, "INICIO_DE_EJECUCION",     19) == 0 ) ||
	(strncmp(nodo->linea, "FIN_DE_EJECUCION",        16) == 0 ) ||
	(strncmp(nodo->linea, "DEFINE_INSTRUCCION_NUEVA",24) == 0 ) ||
	(strncmp(nodo->linea, "FIN",                      3) == 0 )
      ) return;
   if (strncmp(nodo->linea, "INICIO", 6) == 0 ){
	fin_bloque();
	return;
   }
   if (strncmp(nodo->linea, "SI", 2) == 0 ){
	si();
	return;
   }
   if (strncmp(nodo->linea, "REPITE", 6) == 0 ){
	repite();
	return;
   }
   if (strncmp(nodo->linea, "MIENTRAS", 8) == 0 ){
	mientras();
	return;
   }
   if (strlen(id = strdup(instr_primitivas(nodo->linea))) == 0){
	cout<<"\nError en la linea"<<nodo->num<<" => "<<nodo->linea;
	exit(1);
   }

   if (checa.existe_instruccion(token(1, nodo->linea))){
	sprintf(brinco, "js %s", id);
	haz.archivo_virtual(brinco, nodo->num);
   }
   else
	haz.archivo_virtual(id, nodo->num);
   nodo = nodo->sig;

}

/***********************************************************
	Nombre de la funcion: MIENTRAS

		   MIENTRAS con ensamblador Karel.
	Entrega: Nada
	Funciones externas: pruebas_karel, instruccion,
			    archivo_virtual, genera_etiqueta
************************************************************/
void instrucciones::mientras(){
   char *id = NULL, *etiq_ciclo, *etiq_no_ok, brinco[30],etic;
   ensamblador haz;
   instrucciones ejecuta;

   etiq_ciclo[0] = '\0'; etiq_no_ok[0] = '\0';
   if ( strlen(id = strdup(pruebas_karel(token(2,nodo->linea)))) == 0 ){
	cout<<"\nError en la linea"<<nodo->num<<" => "<<nodo->linea;
	exit(1);
   }
   etiq_ciclo = genera_etiqueta();
//   etic=gen_etiq();
   haz.archivo_virtual(etiq_ciclo, nodo->num);
   haz.archivo_virtual(id, nodo->num);
   etiq_no_ok = genera_etiqueta();
   sprintf(brinco,"jc %s", etiq_no_ok);
   haz.archivo_virtual(brinco, nodo->num);
   nodo = nodo->sig;
   ejecuta.instruccion();
   sprintf(brinco, "jc %s", etiq_ciclo);
   haz.archivo_virtual(brinco, nodo->num);
   haz.archivo_virtual(etiq_no_ok, nodo->num);
}

/***********************************************************
	Nombre de la funcion: REPITE

		   REPITE con ensamblador Karel.
	Entrega: Nada
	Funciones externas: instruccion
************************************************************/
void instrucciones::repite(){
	instrucciones ejecuta;
	entrada *ciclo = NULL;
	int n;

	n = atoi( token(2, nodo->linea)  );
	nodo = nodo->sig;
	ciclo = nodo;
	while (n) { nodo = ciclo;
		ejecuta.instruccion();
		n--;
	}
}

/***********************************************************
	Nombre de la funcion: SI

		   y SINO con ensamblador Karel.
	Entrega: Nada
	Funciones externas: genera_etiqueta,instruccion,
			    archivo_virtual, pruebas_karel
************************************************************/
void instrucciones::si(){
   char *id = NULL, *etiq_0, *etiq_1, brinco_0[30], brinco_1[30];
   ensamblador haz;
   instrucciones ejecuta;

   if ( strlen(id = strdup(pruebas_karel(token(2,nodo->linea)))) == 0 ){
	cout<<"\nError en la linea"<<nodo->num<<" => "<<nodo->linea;
	exit(1);
   }
   etiq_0 = genera_etiqueta();
   etiq_1 = genera_etiqueta();
   sprintf(brinco_0,"jc %s", etiq_0);
   sprintf(brinco_1,"jc %s", etiq_1);
   haz.archivo_virtual(id, nodo->num);
   haz.archivo_virtual(brinco_0, nodo->num);
   nodo = nodo->sig;
   ejecuta.instruccion();
   haz.archivo_virtual(brinco_1, nodo->num);
   haz.archivo_virtual(etiq_0, nodo->num);
   if (strncmp(nodo->linea,"SINO",4) == 0){
	nodo = nodo->sig;
	ejecuta.instruccion();
   }
   haz.archivo_virtual(etiq_1, nodo->num);
}

/***********************************************************
	Nombre de la funcion: GENERA_ETIQUETA

		   en ensamblador Karel
	Funciones externas: Ninguna
************************************************************/
char *genera_etiqueta(void){
	char etiq[10];

	sprintf(etiq, "etiq_%d", etiqueta);
	etiqueta++;
	return strdup(etiq);
}
char gen_etiq(void){
	char etiq[10];

	sprintf(etiq, "etiq_%d", etiqueta);
	etiqueta++;
	return *etiq;
}

/***********************************************************
	Nombre de la funcion: FIN_BLOQUE

	Entrega: Nada
	Funciones externas: instruccion
************************************************************/
void instrucciones::fin_bloque(){
	nodo = nodo->sig;
	entrada ir;
	instrucciones ejecuta;

	while ((strncmp(nodo->linea,"FIN", 3) != 0) && (nodo))
		ejecuta.instruccion();
	if (strncmp(nodo->linea, "FIN", 3) != 0 ){
		cout<<"\nError en la linea"<<nodo->num<<" => "<<nodo->linea;
		exit(1);
	}
	nodo = nodo->sig;
}

/***********************************************************
	Nombre de la funcion: FIN_EJECUCION

	Proposito: Verifica la existencia del token
		   "FIN_DE_EJECUCION"
	Entrega: Nada
	Funciones externas: Ninguna
************************************************************/
void ejecucion::fin_ejecucion(){
	if (strncmp(nodo->linea, "FIN_DE_EJECUCION", 16) != 0 ){
		cout<<"\nNo se encuentra FIN_DE_EJECUCION";
		exit(1);
	}
	nodo = nodo->sig;
}

/***********************************************************
	Nombre de la funcion: FIN_PROGRAMA

	Proposito: Verifica la existencia del token
		   "FIN_DE_PROGRAMA"
	Entrega: Nada
	Funciones externas: Ninguna
************************************************************/
void ejecucion::fin_programa(){
	if (strncmp(nodo->linea, "FIN_DE_PROGRAMA", 15) != 0 ){
		cout<<"\nNo se encuentra FIN_DE_PROGRAMA";
		exit(1);
	}
	nodo = nodo->sig;
}


////////////////////////////////////////////////////////////////
//		RUTINAS PARA LA CREACION DE UNA TABLA DE      //
//		SIMBOLOS EN DONDE PONER LAS NUEVAS	      //
//		INSTRUCCIONES		      		      //
////////////////////////////////////////////////////////////////
/***********************************************************
	Nombre de la funcion: NUEVA_INSTRUCCION

	Proposito: Insertar una nueva instruccion en la
		   tabla de simbolos
	Entrega: Nada.
	Funciones externas: Ninguna
************************************************************/
void tabla_de_simbolos::nueva_instruccion(char *instruccion){
	tabla_de_simbolos *act = NULL;

	if (!(act = new tabla_de_simbolos)){
		cout<<"Error de asignacion!";
		exit(1);
	}
	act->instr = strdup(instruccion);
	act->sig = proxima_nva_instr;
	proxima_nva_instr = act;
}

/***********************************************************
	Nombre de la funcion: EXISTE_INSTRUCCION

		simbolos
	Proposito: Realizar la escritura del archivo
	Entrega: 1 si la palabra existe, 0 en caso contrario
	Funciones externas: Ninguna
************************************************************/
int tabla_de_simbolos::existe_instruccion(char *cadena){
	tabla_de_simbolos *act = proxima_nva_instr;

	while (act){
		if ((strncmp(act->instr,cadena,strlen(cadena))== 0) &&
			(strlen(act->instr) == strlen(cadena)))
		    return 1;
		act = act->sig;
	}
	return 0;
}

/***********************************************************
	Nombre de la funcion: ARCHIVO_ENSAMBLADOR

	Proposito: Realizar la escritura del archivo
		   *.ok, el cual esta en lenguaje ensamblador
		   tipo Karel
	Entrega: Nada.
************************************************************/
void archivo_ensamblador(char *archivo_terminado) {
	nodo = start;
	char *num_linea, *mnemonico;
	int i;
	ambiente crea;
	crea.forma_entorno();

	//programa();
	ofstream salida(archivo_terminado);
	if (!salida){
		cout<<"Error de escritura en "<<archivo_terminado<<"!\n";
		return;
	}
		while(karel){
		sprintf(num_linea,"%d",karel->linea);
		mnemonico = strdup(karel->comando);
		i = 0;
		while (num_linea[i]) {
			salida.put(num_linea[i]);
			i++;
		}
		salida<<" ";
		i = 0;
		while (mnemonico[i]) {
			salida.put(mnemonico[i]);
			i++;
		}
		salida<<"\n";
		karel = karel->sig;
	}
	salida.close();
	cout<<"\nExito";
	delete mnemonico;
	delete karel;
	delete nodo;
	delete start;
}


/***************************************************************
////////////////////////////////////////////////////////////////
//		P R O G R A M A   P R I N C I P A L 	      //
////////////////////////////////////////////////////////////////
***************************************************************/
void main(){
	char *temp, fileName[20], archivo_ok[20],*cadena,*p;
	entrada ir;
	start = NULL;
	karel = NULL;
	etiqueta = 0;
	proxima_nva_instr = NULL;

	cout<<"\nkar ";
	cin>>temp;
	//cout<<"\n aparte"; gets(cadena);
	//p=strtok(cadena," ");

	strcpy(fileName,temp);

	sprintf(archivo_ok, "%s.ok",strtok(temp,"."));
	ir.textLoadFile(fileName);
	archivo_ensamblador(archivo_ok);
	exit (1);
}