#include <stdio.h>
#include <stdlib.h>
#include <ctype.h>

struct symbol
{
	struct symbol *next;
	int id;
	char s[256];
};

struct symbol *sym_tab = NULL;

struct symbol *read_sym( int len, int id )
{
	struct symbol *sym;
	int i;

	if( sym = malloc( sizeof( struct symbol ) ) )
	{
		sym->next = NULL;
		sym->id = id;
		for( i = 0; i < len; i++ )
			sym->s[i] = getchar();
		sym->s[len] = '\0';
	}
	return sym;
}

void store_sym( struct symbol *sym )
{
	struct symbol *s = (struct symbol *)&sym_tab;

	while( s->next ) s = s->next;
	s->next = sym;
}

char *get_sym( int id )
{
	struct symbol *sym;

	for( sym = sym_tab; sym; sym = sym->next )
		if( sym->id == id )
			return sym->s;
	return NULL;
}

void delete_sym_tab( void )
{
	struct symbol *sym, *next;

	for( sym = sym_tab; sym; sym = next )
	{
		next = sym->next;
		free( sym );
	}
}

int getword( void )
{
	int hi;
	
	hi = 0x100 * getchar();
	return hi + getchar();
}

int getlong( void )
{
	int hi;

	hi = 0x10000 * getword();
	return hi + getword();
}

int expand( void )
{
	int count = 0, c, id;
	char *s;
	float f;

	c = getchar();
	count++;
	switch( c )
	{
	case '"':
		putchar( c );
		for(;;)
		{
			c = getchar();
			count++;
			putchar( c );
			if( c == '"' )
			{
				char c1;
				
				c1 = getchar();
				if( c1 == '"' )
				{
					count++;
					putchar( c1 );
				}
				else
				{
					ungetc( c1, stdin );
					break;
				}
			}
		}
		break;
	case 0x00:
		putchar( '\n' );
		break;
	case 0x08:
		getchar();
		count++;
		getchar();
		count++;
		getchar();
		count++;
		break;
	case 0xAF:
		printf( "REM" );
		do
		{
			c = getchar();
			count++;
			if( c ) putchar( c );
		} while( c );
		putchar( '\n' );
		break;
	case 0xC0:
		printf( "ELSE IF" );
		break;
	case 0xf1:
		printf( "AND" );
		break;
	case 0x80:
		printf( "ABS" );
		break;
	case 0x81:
		printf( "ASC" );
		break;
	case 0x82:
		printf( "ATN" );
		break;
	case 0xc4:
		printf( "AREA" );
		break;
	case 0x83:
		printf( "CALL" );
		break;
	case 0x84:
		printf( "CDBL" );
		break;
	case 0x85:
		printf( "CHR$" );
		break;
	case 0x86:
		printf( "CINT" );
		break;
	case 0x87:
		printf( "CLOSE" );
		break;
	case 0x88:
		printf( "COMMON" );
		break;
	case 0x89:
		printf( "COS" );
		break;
	case 0x8a:
		printf( "CVD" );
		break;
	case 0x8b:
		printf( "CVI" );
		break;
	case 0x8c:
		printf( "CVS" );
		break;
	case 0xc1:
		printf( "CLNG" );
		break;
	case 0xc2:
		printf( "CVL" );
		break;
	case 0x8d:
		printf( "DATA" );
		break;
	case 0xf4:
		printf( "EQV" );
		break;
	case 0x8e:
		printf( "ELSE" );
		break;
	case 0x8f:
		printf( "EOF" );
		break;
	case 0x90:
		printf( "EXP" );
		break;
	case 0x91:
		printf( "FIELD" );
		break;
	case 0x92:
		printf( "FIX" );
		break;
	case 0x93:
		printf( "FN" );
		break;
	case 0x94:
		printf( "FOR" );
		break;
	case 0x95:
		printf( "GET" );
		break;
	case 0x96:
		printf( "GOSUB" );
		break;
	case 0x97:
		printf( "GOTO" );
		break;
	case 0xf5:
		printf( "IMP" );
		break;
	case 0x98:
		printf( "IF" );
		break;
	case 0x99:
		printf( "INKEY$" );
		break;
	case 0x9a:
		printf( "INPUT" );
		break;
	case 0x9b:
		printf( "INT" );
		break;
	case 0x9c:
		printf( "LEFT$" );
		break;
	case 0x9d:
		printf( "LEN" );
		break;
	case 0x9e:
		printf( "LET" );
		break;
	case 0x9f:
		printf( "LINE" );
		break;
	case 0xa1:
		printf( "LOC" );
		break;
	case 0xa2:
		printf( "LOF" );
		break;
	case 0xa3:
		printf( "LOG" );
		break;
	case 0xa4:
		printf( "LSET" );
		break;
	case 0xf6:
		printf( "MOD" );
		break;
	case 0xa5:
		printf( "MID$" );
		break;
	case 0xa6:
		printf( "MKD$" );
		break;
	case 0xa7:
		printf( "MKI$" );
		break;
	case 0xa8:
		printf( "MKS$" );
		break;
	case 0xc3:
		printf( "MKL$" );
		break;
	case 0xa9:
		printf( "NEXT" );
		break;
	case 0xe7:
		printf( "NOT" );
		break;
	case 0xf2:
		printf( "OR" );
		break;
	case 0xaa:
		printf( "ON" );
		break;
	case 0xab:
		printf( "OPEN" );
		break;
	case 0xac:
		printf( "PRINT" );
		break;
	case 0xad:
		printf( "PUT" );
		break;
	case 0xae:
		printf( "READ" );
		break;
	case 0xb0:
		printf( "RETURN" );
		break;
	case 0xb1:
		printf( "RIGHT$" );
		break;
	case 0xb2:
		printf( "RND" );
		break;
	case 0xb3:
		printf( "RSET" );
		break;
	case 0xb4:
		printf( "SGN" );
		break;
	case 0xb5:
		printf( "SIN" );
		break;
	case 0xb6:
		printf( "SPACE$" );
		break;
	case 0xb7:
		printf( "SQR" );
		break;
	case 0xb8:
		printf( "STR$" );
		break;
	case 0xb9:
		printf( "STRING$" );
		break;
	case 0xe3:
		printf( "STATIC" );
		break;
	case 0xba:
		printf( "TAN" );
		break;
	case 0xe6:
		printf( "THEN" );
		break;
	case 0xe5:
		printf( "TO" );
		break;
	case 0xe4:
		printf( "USING" );
		break;
	case 0xbc:
		printf( "VAL" );
		break;
	case 0xbd:
		printf( "WEND" );
		break;
	case 0xbe:
		printf( "WHILE" );
		break;
	case 0xbf:
		printf( "WRITE" );
		break;
	case 0xf3:
		printf( "XOR" );
		break;
	case 0xF8:
		c = getchar();
		count++;
		switch( c )
		{
		case 0xd8:
			printf( "AREAFILL" );
			break;
		case 0xb5:
			printf( "BEEP" );
			break;
		case 0x81:
			printf( "CHAIN" );
			break;
		case 0x82:
			printf( "CLEAR" );
			break;
		case 0x83:
			printf( "CLS" );
			break;
		case 0x84:
			printf( "CONT" );
			break;
		case 0x85:
			printf( "CSNG" );
			break;
		case 0xb6:
			printf( "CIRCLE" );
			break;
		case 0xc6:
			printf( "CSRLIN" );
			break;
		case 0xd9:
			printf( "COLOR" );
			break;
		case 0xdd:
			printf( "CHDIR" );
			break;
		case 0x86:
			printf( "DATE$" );
			break;
		case 0x87:
			printf( "DEFINT" );
			break;
		case 0x88:
			printf( "DEFSNG" );
			break;
		case 0x89:
			printf( "DEFDBL" );
			break;
		case 0x8a:
			printf( "DEFSTR" );
			break;
		case 0x8b:
			printf( "DEF" );
			break;
		case 0x8c:
			printf( "DELETE" );
			break;
		case 0x8d:
			printf( "DIM" );
			break;
		case 0xd4:
			printf( "DECLARE" );
			break;
		case 0xd6:
			printf( "DEFLNG" );
			break;
		case 0x8e:
			printf( "EDIT" );
			break;
		case 0x8f:
			printf( "END" );
			break;
		case 0x90:
			printf( "ERASE" );
			break;
		case 0x91:
			printf( "ERL" );
			break;
		case 0x92:
			printf( "ERROR" );
			break;
		case 0x93:
			printf( "ERR" );
			break;
		case 0xbf:
			printf( "EXIT" );
			break;
		case 0x94:
			printf( "FILES" );
			break;
		case 0x95:
			printf( "FRE" );
			break;
		case 0xd5:
			printf( "FUNCTION" );
			break;
		case 0x96:
			printf( "HEX$" );
			break;
		case 0x97:
			printf( "INSTR" );
			break;
		case 0x98:
			printf( "KILL" );
			break;
		case 0x99:
			printf( "LIST" );
			break;
		case 0x9a:
			printf( "LLIST" );
			break;
		case 0x9b:
			printf( "LOAD" );
			break;
		case 0x9c:
			printf( "LPOS" );
			break;
		case 0x9d:
			printf( "LPRINT" );
			break;
		case 0xc5:
			printf( "LOCATE" );
			break;
		case 0xc7:
			printf( "LBOUND" );
			break;
		case 0xcc:
			printf( "LIBRARY" );
			break;
		case 0x9e:
			printf( "MERGE" );
			break;
		case 0xb8:
			printf( "MOUSE" );
			break;
		case 0xc2:
			printf( "MENU" );
			break;
		case 0x9f:
			printf( "NAME" );
			break;
		case 0xa0:
			printf( "NEW" );
			break;
		case 0xa1:
			printf( "OCT$" );
			break;
		case 0xa2:
			printf( "OPTION" );
			break;
		case 0xa3:
			printf( "PEEK" );
			break;
		case 0xa4:
			printf( "POKE" );
			break;
		case 0xa5:
			printf( "POS" );
			break;
		case 0xb9:
			printf( "POINT" );
			break;
		case 0xba:
			printf( "PRESET" );
			break;
		case 0xbb:
			printf( "PSET" );
			break;
		case 0xd2:
			printf( "PAINT" );
			break;
		case 0xda:
			printf( "PATTERN" );
			break;
		case 0xdb:
			printf( "PALETTE" );
			break;
		case 0xa6:
			printf( "RANDOMIZE" );
			break;
		case 0xa8:
			printf( "RESTORE" );
			break;
		case 0xa9:
			printf( "RESUME" );
			break;
		case 0xaa:
			printf( "RUN" );
			break;
		case 0xbc:
			printf( "RESET" );
			break;
		case 0xab:
			printf( "SAVE" );
			break;
		case 0xad:
			printf( "STOP" );
			break;
		case 0xae:
			printf( "SWAP" );
			break;
		case 0xaf:
			printf( "SYSTEM" );
			break;
		case 0xbe:
			printf( "SUB" );
			break;
		case 0xc0:
			printf( "SOUND" );
			break;
		case 0xc9:
			printf( "SHARED" );
			break;
		case 0xcb:
			printf( "SCROLL" );
			break;
		case 0xd3:
			printf( "SCREEN" );
			break;
		case 0xd7:
			printf( "SADD" );
			break;
		case 0xdc:
			printf( "SLEEP" );
			break;
		case 0xde:
			printf( "STRIG" );
			break;
		case 0xdf:
			printf( "STICK" );
			break;
		case 0xb0:
			printf( "TIME" );
			break;
		case 0xb1:
			printf( "TRON" );
			break;
		case 0xb2:
			printf( "TROFF" );
			break;
		case 0xbd:
			printf( "TIMER" );
			break;
		case 0xc8:
			printf( "UBOUND" );
			break;
		case 0xca:
			printf( "UCASE$" );
			break;
		case 0xb3:
			printf( "VARPTR" );
			break;
		case 0xb4:
			printf( "WIDTH" );
			break;
		case 0xc3:
			printf( "WINDOW" );
			break;
		}
		break;
	case 0xF9:
		c = getchar();
		count++;
		switch( c )
		{
		case 0xfa:
			printf( "SPC" );
			break;
		case 0xff:
			printf( "ALL" );
			break;
		case 0xfe:
			printf( "APPEND" );
			break;
		case 0xfd:
			printf( "AS" );
			break;
		case 0xfc:
			printf( "BASE" );
			break;
		case 0xf5:
			printf( "BREAK" );
			break;
		case 0xfb:
			printf( "OUTPUT" );
			break;
		case 0xf4:
			printf( "OFF" );
			break;
		case 0xf9:
			printf( "STEP" );
			break;
		case 0xf8:
			printf( "TAB" );
			break;
		case 0xf6:
			printf( "WAIT" );
			break;
		case 0xf7:
			printf( "USR" );
			break;
		}
		break;
	case 0xFA:
		c = getchar();
		count++;
		switch( c )
		{
		case 0x97:
			printf( "COLLISION" );
			break;
		case 0x87:
			printf( "OBJECT.SHAPE" );
			break;
		case 0x88:
			printf( "OBJECT.PRIORITY" );
			break;
		case 0x89:
			printf( "OBJECT.X" );
			break;
		case 0x8a:
			printf( "OBJECT.Y" );
			break;
		case 0x8b:
			printf( "OBJECT.VX" );
			break;
		case 0x8c:
			printf( "OBJECT.VY" );
			break;
		case 0x8d:
			printf( "OBJECT.AX" );
			break;
		case 0x8e:
			printf( "OBJECT.AY" );
			break;
		case 0x8f:
			printf( "OBJECT.CLIP" );
			break;
		case 0x90:
			printf( "OBJECT.PLANES" );
			break;
		case 0x91:
			printf( "OBJECT.HIT" );
			break;
		case 0x92:
			printf( "OBJECT.ON" );
			break;
		case 0x93:
			printf( "OBJECT.OFF" );
			break;
		case 0x94:
			printf( "OBJECT.START" );
			break;
		case 0x95:
			printf( "OBJECT.STOP" );
			break;
		case 0x96:
			printf( "OBJECT.CLOSE" );
			break;
		case 0x81:
			printf( "POKEW" );
			break;
		case 0x82:
			printf( "POKEL" );
			break;
		case 0x83:
			printf( "PEEKW" );
			break;
		case 0x84:
			printf( "PEEKL" );
			break;
		case 0x85:
			printf( "SAY" );
			break;
		case 0x86:
			printf( "TRANSLATE$" );
			break;
		case 0x80:
			printf( "WAVE" );
			break;
		}
		break;
	case 0xFB:
		c = getchar();
		count++;
		switch( c )
		{
		case 0xFF:
			printf( "PTAB" );
			break;
		default:
			printf( "<fb><%02x>", c );
			break;
		}
		break;
	case 0x01:	/* variable */
	case 0x02:	/* define label */
		id = getword();
		count += 2;
		if( s = get_sym( id ) )
			printf( "%s", s );
		else
			printf( "<%04x>", id );
		break;
	case 0x03:	/* use label */
		c = getchar();
		count++;
		if( !c )
		{
			id = getword();
			count += 2;
			if( s = get_sym( id ) )
				printf( "%s", s );
			else
				printf( "<%04x>", id );
		}
		break;
	case 0xE9:
		putchar( '>' );
		break;
	case 0xF0:
		putchar( '^' );
		break;
	case 0xEB:
		putchar( '<' );
		break;
	case 0xEA:
		putchar( '=' );
		break;
	case 0xED:
		putchar( '-' );
		break;
	case 0xEE:
		putchar( '*' );
		break;
	case 0xEF:
		putchar( '/' );
		break;
	case 0xEC:
		putchar( '+' );
		break;
	case 0x0F:
		printf( "%d", getchar() );
		count++;
		break;
	case 0x11:
		putchar( '0' );
		break;
	case 0x12:
		putchar( '1' );
		break;
	case 0x13:
		putchar( '2' );
		break;
	case 0x14:
		putchar( '3' );
		break;
	case 0x15:
		putchar( '4' );
		break;
	case 0x16:
		putchar( '5' );
		break;
	case 0x17:
		putchar( '6' );
		break;
	case 0x18:
		putchar( '7' );
		break;
	case 0x19:
		putchar( '8' );
		break;
	case 0x1A:
		putchar( '9' );
		break;
	case 0x0C:
		printf( "&H%x", getword() );
		count += 2;
		break;
	case 0x1C:
		printf( "%d", getword() );
		count += 2;
		break;
	case 0x1D:
		*((long *)&f) = getlong();
		printf( "%g", f );
		count += 4;
		break;
	case 0x1E:
		printf( "%ld", getlong() );
		count += 4;
		break;
	default:
		if( isprint( c ) )
			putchar( c );
		else
			printf( "<%02x>", c );
		break;
	}
	return count;
}

void main( int argc, char *argv[] )
{
	int chars = 0, count, indent, nsym = 0;
	struct symbol *sym;

	/* pass 1 - read symbol table */
	getchar(); /* skip F5 */
	while( count = getword() )	/* skip code area */
	{
		chars += count;
		count -= 2;
		while( count-- ) getchar();
	}
	getchar(); /* skip null byte */
	if( !( chars & 1 ) ) getchar();
	while( ( count = getchar() ) != EOF )
	{
		if( sym = read_sym( count, nsym++ ) )
			store_sym( sym );
	}
#ifdef DUMP_SYM_TAB
	printf( "--- %d symbols ---\n", nsym );
	for( sym = sym_tab; sym; sym = sym->next )
		printf( "%d : %s\n", sym->id, sym->s );
	printf( "------------------\n" );
#endif

	rewind( stdin );

	/* pass 2 - read code */
	getchar();
	while( count = getword() ) 
	{
		count -= 2;
		indent = getchar();
		count--;
		while( indent-- )
			putchar( ' ' );
		while( count )
			count -= expand();
	}
	delete_sym_tab();
}
