[comp.sources.amiga] v90i191: app 2.0 - assembly pre-processor, Part01/01

Amiga-Request@cs.odu.edu (Amiga Sources/Binaries Moderator) (07/03/90)

Submitted-by: karl@sugar.uucp
Posting-number: Volume 90, Issue 191
Archive-name: util/app-2.0/part01

APP is a preprocessor for the 68000 assembler that comes with Aztec C for 
the Amiga.   It will probably work with other 68000 assemblers.  It works
fine with 68020/68030 instructions, too.  It can easily be adapted to 
other processor architectures as well.

APP provides structured programming constructs for the assembly language
programmer.  Specifically, APP provides support for IF-THEN-ELSE-ELSEIF-
ENDIF constructs and for DO-WHILE-UNTIL-ENDDO constructs.  

#!/bin/sh
# This is a shell archive.  Remove anything before this line, then unpack
# it by saving it into a file and typing "sh file".  To overwrite existing
# files, type "sh file -c".  You can also feed this as standard input via
# unshar, or by typing "sh <file", e.g..  If this archive is complete, you
# will see the following message at the end:
#		"End of archive 1 (of 1)."
# Contents:  README app.c app.pro app.uu makefile
# Wrapped by tadguy@xanth on Mon Jul  2 19:35:50 1990
PATH=/bin:/usr/bin:/usr/ucb ; export PATH
if test -f 'README' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'README'\"
else
echo shar: Extracting \"'README'\" \(9396 characters\)
sed "s/^X//" >'README' <<'END_OF_FILE'
XAPP - Assembly Pre-Processor   
X----------------------------
X
XVersion 2.0, 28-April-1990
X
XPUBLIC DOMAIN
X
Xwritten by Karl Lehenbauer, first release 12/8/88, with a lot of design 
Xinput by Peter da Silva.
X
XVersion 2.0, released 4/28/90, incorporated changes by Brett Bourbin 
X (Selgus Limited) involving input/output file handling and added the dbra 
X looping construct.  Karl made a backwards-compatible version  of the new 
X i/o file handling, converted to ANSI C, spruced up the docs, etc.
X
X
XDisclaimer and Redistribution Information
X-----------------------------------------
X
XAPP is placed freely into the public domain for any use without restriction.
XAPP comes without warranties, expressed or implied.  This is free software.
XWe don't have a contract.
X
XWe're not asking for money for this, but if you use it a lot, a check for
X$10 or $20 would always be appreciated.  Make checks to Hackercorp, 3918 
XPanorama, Missouri City, TX  77459
X
X
XWhat it is
X----------
X
XAPP is a preprocessor for the 68000 assembler that comes with Aztec C for 
Xthe Amiga.   It will probably work with other 68000 assemblers.  It works
Xfine with 68020/68030 instructions, too.  It can easily be adapted to 
Xother processor architectures as well.
X
XAPP provides structured programming constructs for the assembly language
Xprogrammer.  Specifically, APP provides support for IF-THEN-ELSE-ELSEIF-
XENDIF constructs and for DO-WHILE-UNTIL-ENDDO constructs.  
X
XConsider the C pseudocode fragment:
X
Xlong a, b;
X
X	if (a < 0)
X	{
X		less_than_zero_stuff();
X	}
X	else
X	{
X		not_less_that_zero_stuff();
X	}
X
XIn assembler (or pre-77 FORTRAN, for example) to do the same thing requires 
Xthe creation of two bogus labels, as in:
X
X	move.l	_a,d0
X	bge		else_part
X	jsr		_less_than_zero_stuff
X	bra		past_the_else
Xelse_part
X	jsr		_not_less_than_zero_stuff
Xpast_the_else
X
XWhen you start nesting these deeply, the code quickly becomes unreadable.
XNote also that you have to reverse the sense to branch around the code
Xyou really want to execute.  This makes the code less clear.
XIf the assembler had structured programming constructs like C, Modula 2,
XForth, etc, the creation of these superfluous labels is unnecessary.
XUsing APP, the above code fragment can be rewritten:
X
X	move.l	_a,d0
X	.if	lt
X	jsr		_less_than_zero_stuff
X	.else
X	jsr		_not_less_than_zero_stuff
X	.endif
X
XTo define an "if", enter an opcode of ".if" and an operand of a condition
Xcode that the assembler recognizes as a branch when following behind a 'b',
Xas in condition codes "le", "lt", "eq", "ne", "gt", "ge" yielding "ble",
X"blt", "beq", "bne", "bgt", "bge"  You will have issued instructions to
Xset up the condition codes before the ".if".
X
XFor "if", APP will assemble a conditional branch with the sense reversed,
Xbranching to the matching ".else", ".elseif", or ".endif".  APP will make
Xup labels and produce the equivalent branching code as above.  I have chosen
Xto make APP's labels be 'L' followed by an increasing sequential integer
Xlabel number.  This was chosen to avoid conflicting with Manx's '.' followed
Xby the number so you can incrementally "structurize" and test as you hand
Xoptimize the output of cc with optimization and assembly source generation
Xflags selected.
X
XAPP also supports a do/enddo construct.  The way it works is ".enddo"
Xcompiles a "branch always" instruction back to the corresponding ".do".
XTo exit the do/enddo, three constructs are provided.  These are ".while",
X".until" and ".dbra".  ".while" takes a condition code and, if it is true,
Xexecution continues below the while, else a branch past the enddo is
Xtaken.  ".until" in the opposite manner, if the condition code is true
Xa branch past the enddo is taken otherwise it isn't.  (".dbra" will be
Xdescribed later below.)  For example,
X
X	.do
X	  ;conditional setup stuff
X	  .
X	  .
X	.while ne
X	  ; execution stuff
X	  .
X	  .
X	.enddo
X
X...will execute code between the do and the enddo until the condition code
Xat the "while" isn't true anymore.  Multiple .whiles and .untils may be
Xused and .whiles and .untils may be freely intermixed.
X
XAn additional do structure provided on the 68000 series to take advantage
Xof specific 68000 looping capabilities.  This is the decrement-and-branch,
XDBRA, instruction.  Using DBRA, many simple copying loops can be coded with
Xonly two instructions.  Consequently, dbra is provided as a .do-terminating
Xinstruction as an alternative to .enddo, as in:
X
X	.do
X	  ; loop code
X	  ;
X	.dbra d5
X
XIn the preceding example, the loop code will be executed a number of times
Xequal to the value in d5, with the dbra instruction decrementing d5 each 
Xtime through the loop until d5 is zero when dbra checks it, at which time
Xit will "fall through", executing the next instruction after the dbra.
X
XNote that .dbra is different from dbra in that .dbra indicates to app
Xthat it terminates a matching .do, thus that app is to generate a dbra 
Xinstruction to decrement the specified register and branch back to the 
Xcorresponding .do statement, while a "dbra" is just a regular dbra 
Xinstruction, app just passes it through, and it requires the register and
Xa label like any other label-branching instruction on the 68000.
X
X
XNesting of conditionals is permitted to a depth of 32.  When nesting, I
Xreccommend indenting your code, as in:
X
X	tst.l	d0
X	.if gt
X		add.l	d0,d1
X		cmp.l	#max,d1
X		.if gt
X			move.l	#max,d1
X		.endif
X	.endif
X
XSetting tab stops at four seems to work well.
X
X
XHow To Invoke APP
X-----------------
X
XAPP takes the name of the structured assembly source it is to compile
Xinto standard assembly source code on the command line, as in
X
X	app foo.app
X
XThis produces foo.asm, if app doesn't detect any errors while processing 
Xthe file.
X
XWhen used in the above manner, the name of the source file must end with 
X.app, and app will always create the output file with a .asm extension.
X
XAlternatively, you may specify the output file, as in:
X
X	app -o foo.asm foo.a
X
XNote that for the second form, the .app extension of the source filename
Xis not required.
X
X
XIntegrating APP with your makefile
X----------------------------------
X
XIf you add the following rules to your makefile and list object files
Xcorresponding to your assembly preprocessor source .app files in your 
Xmake dependencies, make will run APP over your .app files and then
Xrun "as" over the resulting .asm files automatically.
X
X.app.o:
X	app $*.app
X	as $*.asm
X
X
XCondition Codes Known by APP 
X----------------------------
X
X	The following condition codes may be used APP's .if, .elseif, .while
X	and .until statements:
X
X	"ne"
X	"eq"
X	"lt"
X	"ge"
X	"le"
X	"gt"
X	"cc"
X	"cs"
X	"vc"
X	"vs"
X	"hi"
X	"ls"
X	"pl"
X	"mi"
X
XConsult your 68000 Reference Manual if you need to know
Xwhat status register bits and states correspond to these 
Xcodes.  They're the standard ones.
X
X
XAPP Error Messages
X------------------
X
XAPP does a lot of checking of your APP "dot" statements to insure their
Xvalidity.  Specifically, APP insures that all .ifs have matching .endifs,
Xthat all .dos have matching .enddo or .dbra, that only one .else is 
Xspecified inside a .if, that .elseifs are only specified inside .ifs, 
Xthat .whiles and .untils are only specified inside a .do and that all
X"dot" structures are closed at end of file.  If APP does detect an error,
Xit prints an error message including the line number and exits.  (It could
Xconceivably go on, but I have yet to take it this far.)
X
XIf APP is pointing to the last line in the file, the problem is that you
Xdidn't close a .if or .do structure somewhere earlier in the file.
X
XIf APP exits with an error, it removes the .asm output file so the file
Xwon't confuse "make" into thinking everything went OK with APP when it 
Xreally didn't.
X
X
XEnumeration of Variations by Pseudo-Example
X-------------------------------------------
X
X	.if cc
X	.endif
X
X	.if cc
X	.else
X	.endif
X
X	.if cc
X	.elseif cc
X	.endif
X
X	.if cc
X	.elseif cc
X	.elseif cc
X	.endif
X
X	.do
X	.enddo
X
X	.do
X	.while cc
X	.enddo
X
X	.do
X	.until cc
X	.enddo
X
X	.do
X	.until cc
X	.until cc
X	.while cc
X	.enddo
X
X	.do
X	.dbra reg
X
X	.do
X	.until cc
X	.while cc
X	.dbra reg
X
X
XMiscellaneous Notes
X-------------------
X
XAPP conditionals may be nested up to 32 levels deep.  If you need to go
Xdeeper (seven or eight seems like the realistic-use upper limit to me), 
Xchange the MAX_NESTING_LEVELS define in app.c.
X
XAll the APP constructs must be entered in lower case only, and the condition
Xcodes as well.
X
XNote that the functions provided by APP could have been done by assembler
Xmacros if the Aztec assembler had supported the ability to expand a macro
Xwith an argument being the *value* of a SET variable, had string variables 
Xor the ability to concatenate text with a SET variable -- it doesn't, and
Xsimilar problems appear in other assemblers as well.
X
XNote also that APP doesn't check condition codes for validity unless their
Xsense has to be reversed.  It probably should check them, but invalid ones 
Xwon't get past the assembler in any case.
X
XAPP is so vanilla in its construction that it should run on about any
Xmachine with a C compiler and a stdio library.  It for sure runs under
XAztec C on the Amiga and on Intel '286 Multibus Xenix (don't ask why).
XVersion 1.1 and onward, though, require an ANSI standard C compiler.
X
XThe documentation was significantly more work than the code.
X
XWarm Regards,
XKarl @ The Alternate Hacker's Haven -- Houston, TX, 12/11/88
Xupdated - 4/28/90
XUsenet: uunet!sugar!karl  Internet/BITNET: karl@sugar.hackercorp.com
X
END_OF_FILE
if test 9396 -ne `wc -c <'README'`; then
    echo shar: \"'README'\" unpacked with wrong size!
fi
# end of 'README'
fi
if test -f 'app.c' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'app.c'\"
else
echo shar: Extracting \"'app.c'\" \(9992 characters\)
sed "s/^X//" >'app.c' <<'END_OF_FILE'
X/* app.c - 68000 assembly pre-processor
X *
X * written by Karl Lehenbauer (uunet!sugar!karl or karl@sugar.hackercorp.com)
X * original release Dec-08-1988
X *
X * PUBLIC DOMAIN -- no warranties of usefulness, suitabilitiy, correctness
X *
X * Jan-09-1990	Brett Bourbin (Selgus Limited) changed input/output file
X *		handling, incorrect text strings and added the dbra construct.
X *
X * April-28-1990  Release 2.0
X *  Rewrote filename-handling code to provide the -o option with backward
X *   compatibility. Updated the docs plus converted to ANSI C.
X */
X
X#include <stdio.h>
X#include <assert.h>
X
X#include "app.pro"
X
X#define YES 1
X#define NO 0
X
X#define MATCH 0
X
Xint current_nest_level = -1;
Xint master_label_number = 0;
Xunsigned int line_number = 0;
X
Xchar *label;
Xchar *opcode;
Xchar *operands;
Xchar *comment;
X
Xchar *input_filename, *input_extension, *output_filename;
X
Xpanic(char *s)
X{
X	fprintf(stderr,"app: %s at line %d\n",s,line_number);
X	fclose(stdout);
X	unlink(output_filename);
X	exit(1);
X}
X
X/* given a pointer to a line, make the global character pointers "label",
X * "opcode", "operands" and "comment" point to the various fields within
X * the line, or NULL for any that aren't present.  Note that crackline
X * butchers the line up by writing null bytes into it.
X */
Xcrackline(char *s)
X{
X	register char *p = s;
X
X	label = NULL;
X	opcode = NULL;
X	operands = NULL;
X	comment = NULL;
X
X	/* suck up leading blanks */
X	while ((*p == ' ') || (*p == '\t'))
X		p++;
X
X	/* if end of line, return -- it's an empty line */
X	if (*p == '\0')
X		return;
X
X	/* if the first nonblank char is a semicolon, it's a comment */
X	if (*p == ';')
X	{
X		comment = s;
X		return;
X	}
X
X	/* if the very first char isn't blank (and we already know it's
X	   not a semicolon), it's a label
X	 */
X	if ((*s != ' ') && (*s != '\t'))
X	{
X		label = s;
X		p = s + 1;
X		while (*p != ' ' && *p != '\t' && *p != '\0') p++;
X		if ((*p == ' ') || (*p == '\t'))
X		{
X			*p = '\0';
X			p++;
X		}
X		else
X			return;
X	}
X	else	/* there isn't a label, suck up spaces to next parm */
X	{
X		p = s;
X		while ((*p == ' ' || *p == '\t')) p++;
X		if (*p == '\0')
X			return;
X	}
X
X	/* if the next parm is a comment, assign and we're done */
X	if (*p == ';')
X	{
X		comment = p;
X		return;
X	}
X
X	/* we're at the opcode, assign it and terminate with \0 if spaces
X	 * follow, else we're done */
X	opcode = p;
X	while (*p != ' ' && *p != '\t' && *p != '\0') p++;
X	if ((*p == ' ') || (*p == '\t'))
X	{
X		*p = '\0';
X		p++;
X	}
X	else
X		return;
X
X	/* if the next parm is a comment, assign and we're done */
X	if (*p == ';')
X	{
X		comment = p;
X		return;
X	}
X
X	operands = p;
X	while (*p != ' ' && *p != '\t' && *p != '\0') p++;
X	if ((*p == ' ') || (*p == '\t'))
X	{
X		*p = '\0';
X		p++;
X	}
X	else
X		return;
X
X	comment = p;
X
X}
X
X#ifdef DEBUG
Xdumpit(void)
X{
X	printf("label: %s, opcode %s, operands %s, comment %s\n",label,opcode,operands,comment);
X}
X#endif
X
Xchar s[255], ssave[255];
X
X#define IF_STATEMENT_TYPE 1
X#define ELSE_STATEMENT_TYPE 2
X#define DO_STATEMENT_TYPE 3
X
X#define MAX_NESTING_LEVELS 32
X
Xstruct nesting_context
X{
X	int construct_type;
X	int label_number;
X	int second_label_number;
X};
X
Xstruct nesting_context nesting_data[MAX_NESTING_LEVELS];
X
X/* push - push a nesting construct context, executed on .if and .do */
Xpush(int new_construct_type,int label,int second_label)
X{
X	struct nesting_context *np;
X
X	if (++current_nest_level >= MAX_NESTING_LEVELS)
X		panic("too many nesting levels");
X
X	np = &nesting_data[current_nest_level];
X	np->construct_type = new_construct_type;
X	np->label_number = label;
X	np->second_label_number = second_label;
X}
X
X/* pop - discard the top nesting context, checking for underflow
X *  called when conditionals have been successfully closed
X */
Xpop(void)
X{
X	if (current_nest_level >= 0)
X		--current_nest_level;
X	else
X		panic("'endif', 'enddo' or 'dbra' without a matching 'if' or 'do'");
X}
X
X/* generate and return new label number */
Xnewlabel(void)
X{
X	return(master_label_number++);
X}
X
X/* structure in support of reversing the sense of conditionals */
Xstruct condition_code_struct
X{
X	char *condition;
X	char *reverse_condition;
X};
X
X#define N_CONDITION_TYPES 14
X
Xstruct condition_code_struct condition_code_array[N_CONDITION_TYPES] =
X{
X	{"ne", "eq"},
X	{"eq", "ne"},
X	{"lt", "ge"},
X	{"ge", "lt"},
X	{"le", "gt"},
X	{"gt", "le"},
X	{"cc", "cs"},
X	{"cs", "cc"},
X	{"vc", "vs"},
X	{"vs", "vc"},
X	{"hi", "ls"},
X	{"ls", "hi"},
X	{"pl", "mi"},
X	{"mi", "pl"},
X};
X
X/* given a pointer to text containing a condition code, returns the 
X * a pointer to text containing a condition with reverse sense of
X * the one passed as an argument. Bombs if the sense doesn't make sense
X */
Xchar *reverse_sense_of(char *s)
X{
X	struct condition_code_struct *ccp;
X	int i;
X
X	for (i = 0, ccp = condition_code_array; i < N_CONDITION_TYPES; i++, ccp++)
X
X		if (strcmp(s,ccp->condition) == MATCH)
X			return(ccp->reverse_condition);
X
X	panic("invalid condition code in 'if', 'elseif', 'while' or 'until'");
X}
X
X/* print the label name corresponding to the number specified, should be
X * called in more places in the program where printf is used instead, so
X * you have to change it in several places if you want to change what the
X * labels look like
X */
Xprint_label(int i)
X{
X	printf("L%d\n",i);
X}
X
X/* to prevent parsing every line, looks_promising is a quick hack to see
X * if its a line we're interested in or not.  If the line doesn't have
X * a period as the first non-space or tab char, it's not promising, so
X * we don't crack the line with the full blown line parses.  This is a
X * performance hack.
X */
Xlooks_promising(char *s)
X{
X	while (*s != '\0')
X	{
X		if (*s == '.')
X			return(YES);
X
X		if (*s != ' ' && *s != '\t')
X			return(NO);
X
X		s++;
X	}
X	return(NO);
X}
X
Xusage()
X{
X	fprintf(stderr,"\nThis program converts high-level structured assembly code\n");
X	fprintf(stderr,"into regular assembly code.  See the README file for details.\n\n");
X	fprintf(stderr,"usage:  app [ -o outputfile] filename.app\n");
X	fprintf(stderr," (if -o is not specified, .app extension is required\n");
X	fprintf(stderr,"  and output will have a .asm extension).\n\n");
X	fprintf(stderr,"Hackercorp, 3918 Panorama, Missouri City, TX 77459 USA\n");
X	fprintf(stderr,"tel# 713-438-4964, Usenet: uunet!sugar!karl\n");
X	fprintf(stderr,"Internet/BITNET: karl@sugar.hackercorp.com\n\n");
X	exit(1);
X}
X
Xint main(int argc,char *argv[])
X{
X	fprintf(stderr,"Hackercorp public domain 68000 assembly preprocessor 2.0 28-April-1990\n");
X
X	if (argc == 4)
X	{
X		if (strcmp(argv[1],"-o") != MATCH)
X			usage();
X
X		output_filename = argv[2];
X		input_filename = argv[3];
X	}
X	else if (argc == 2)
X	{
X		input_filename = argv[1];
X		output_filename = NULL;
X	}
X	else
X		usage();
X
X	if (!output_filename)
X	{
X		input_extension = input_filename + strlen(input_filename) - 4;
X		if (strcmp(".app",input_extension) != MATCH)
X			usage();
X	}
X
X	if (freopen(input_filename,"r",stdin) == NULL)
X	{
X		perror(input_filename);
X		exit(5);
X	}
X
X	/* create output filename if necessary, by overwriting input name */
X	if (!output_filename)
X	{
X		strcpy(input_extension,".asm");
X		output_filename = input_filename;
X	}
X
X	if (freopen(output_filename,"w",stdout) == NULL)
X	{
X		perror(output_filename);
X		exit(5);
X	}
X
X	preprocess_file();
X	return(0);
X}
X
Xpreprocess_file(void)
X{
X	struct nesting_context *np;
X	int i;
X
X	/* for all lines in the file */
X	while (gets(s) != NULL)
X	{
X		line_number++;	/* count the line */
X
X		/* if it's not promising, copy it to output and go on */
X		if (!looks_promising(s))
X		{
X			printf("%s\n",s);
X			goto more;
X		}
X
X		strcpy(ssave,s);
X		crackline(s);
X
X		if (strcmp(opcode,".if") == MATCH)
X		{
X			printf("\tb%s\tL%d\n",reverse_sense_of(operands),i = newlabel());
X			push(IF_STATEMENT_TYPE,i,-1);
X		}
X		else if (strcmp(opcode,".else") == MATCH)
X		{
X			np = &nesting_data[current_nest_level];
X
X			if (np->construct_type != IF_STATEMENT_TYPE)
X				panic("'else' without 'if'");
X
X			printf("\tbra\tL%d\n",i = newlabel());
X			/* print the label from the top context */
X			print_label(np->label_number);
X			np->label_number = i;
X			np->construct_type = ELSE_STATEMENT_TYPE;
X		}
X		else if (strcmp(opcode,".endif") == MATCH)
X		{
X			np = &nesting_data[current_nest_level];
X
X			if ((np->construct_type != IF_STATEMENT_TYPE)
X			  && (np->construct_type != ELSE_STATEMENT_TYPE))
X				panic("'endif' without 'if' or 'else'");
X
X			print_label(np->label_number);
X			pop();
X		}
X		else if (strcmp(opcode,".elseif") == MATCH)
X		{
X			np = &nesting_data[current_nest_level];
X
X			if (np->construct_type != IF_STATEMENT_TYPE)
X				panic("'else' without 'if'");
X
X			printf("\tbra\tL%d\n",i = newlabel());
X			/* print the label from the top context */
X			print_label(np->label_number);
X			np->label_number = i;
X			printf("\tb%s\tL%d\n",reverse_sense_of(operands),i);
X		}
X		else if (strcmp(opcode,".do") == MATCH)
X		{
X			print_label(i = newlabel());
X			push(DO_STATEMENT_TYPE,i,newlabel());
X		}
X		else if (strcmp(opcode,".while") == MATCH)
X		{
X			np = &nesting_data[current_nest_level];
X
X			if (np->construct_type != DO_STATEMENT_TYPE)
X				panic("'while' without 'do'");
X
X			printf("\tb%s\tL%d\n",reverse_sense_of(operands),np->second_label_number);
X		}
X		else if (strcmp(opcode,".enddo") == MATCH)
X		{
X			np = &nesting_data[current_nest_level];
X
X			if (np->construct_type != DO_STATEMENT_TYPE)
X				panic("'enddo' without 'do'");
X
X			printf("\tbra\tL%d\n",np->label_number);
X			print_label(np->second_label_number);
X			pop();
X
X		}
X		else if (strcmp(opcode,".dbra") == MATCH)
X		{
X			np = &nesting_data[current_nest_level];
X
X			if (np->construct_type != DO_STATEMENT_TYPE)
X				panic("'dbra' without 'do'");
X
X			printf("\tdbra\t%s,L%d\n",operands,np->label_number);
X			print_label(np->second_label_number);
X			pop();
X
X		}
X		else if (strcmp(opcode,".until") == MATCH)
X		{
X			np = &nesting_data[current_nest_level];
X
X			if (np->construct_type != DO_STATEMENT_TYPE)
X				panic("'until' without 'do'");
X
X			printf("\tb%s\tL%d\n",operands,np->second_label_number);
X		}
X		else
X			printf("%s\n",ssave);
X	more: ;
X	}
X	if (current_nest_level >= 0)
X		panic("didn't close all your control structures");
X}
X
END_OF_FILE
if test 9992 -ne `wc -c <'app.c'`; then
    echo shar: \"'app.c'\" unpacked with wrong size!
fi
# end of 'app.c'
fi
if test -f 'app.pro' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'app.pro'\"
else
echo shar: Extracting \"'app.pro'\" \(318 characters\)
sed "s/^X//" >'app.pro' <<'END_OF_FILE'
X/* app.c */
Xint panic(char *s);
Xint crackline(char *s);
Xint push(int new_construct_type, int label, int second_label);
Xint pop(void);
Xint newlabel(void);
Xchar *reverse_sense_of(char *s);
Xint print_label(int i);
Xint looks_promising(char *s);
Xint usage(void);
Xint main(int argc, char **argv);
Xint preprocess_file(void);
END_OF_FILE
if test 318 -ne `wc -c <'app.pro'`; then
    echo shar: \"'app.pro'\" unpacked with wrong size!
fi
# end of 'app.pro'
fi
if test -f 'app.uu' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'app.uu'\"
else
echo shar: Extracting \"'app.uu'\" \(15581 characters\)
sed "s/^X//" >'app.uu' <<'END_OF_FILE'
Xbegin 644 app
XM```#\P`````````#``````````(```FK```!X@````$```/I```)JT[Z$%PO6
XM+(`*+R\`"$AZ!Q9(;('\3KH*X$AL@>9.NA]*+RR#DDZZ(OQ(>``!3KHD2D_OU
XM`!Q.=4CG`#`F;P`,)$M"K(.60JR#FD*L@YY"K(.B#!(`(&<&#!(`"68$4HI@Z
XM\$H29@9,WPP`3G4,$@`[9@8I2X.B8.X,$P`@9S@,$P`)9S(I2X.6)$M2B@P2S
XM`"!G#@P2``EG"$H29P12BF#L#!(`(&<&#!(`"68&0A)2BF`"8+)@&"1+#!(`!
XM(&<&#!(`"68$4HI@\$H29@)@F`P2`#MF!BE*@Z)@C"E*@YH,$@`@9PX,$@`)Y
XM9PA*$F<$4HI@[`P2`"!G!@P2``EF!D(24HI@!&``_V`,$@`[9@@I2H.B8`#_M
XM4BE*@YX,$@`@9PX,$@`)9PA*$F<$4HI@[`P2`"!G!@P2``EF!D(24HI@!&``0
XM_R0I2H.B8`#_'$CG`"!2K(`"#*P````@@`)M"DAZ!=I.NOZB6$\@+(`"(@#C9
XMB-"!Y8A![(.FT(@D0"2O``@E;P`,``0E;P`0``A,WP0`3G5*K(`";093K(`"A
XM8`I(>@6R3KK^8EA/3G4@+(`&4JR`!DYU2.<@('0`0>R`#B1(8"(O$B\O`!!.7
XMNA4P2H!03V8*("H`!$S?!`1.=2`"4H(@2E"*#((````.;=9(>@7&3KK^%%A/#
XM8-XO+P`$2'H%\TZZ"KA03TYU2.<`("1O``A*$F<B#!(`+F8(<`%,WP0`3G4,^
XM$@`@9PH,$@`)9P1P`&#J4HI@VG``8.)(>@6Z2&R!_$ZZ"+1(>@7J2&R!_$ZZ7
XM"*A(>@8>2&R!_$ZZ")Q(>@8]2&R!_$ZZ")!(>@9G2&R!_$ZZ"(1(>@:'2&R!!
XM_$ZZ"'A(>@:S2&R!_$ZZ"&Q/[P`X2'H&T$AL@?Q.N@A<2'@``4ZZ(=9/[P`,A
XM3G5(YR`@)"\`#"1O`!!(>@;72&R!_$ZZ"#8,@@````103V8D2'H'"2\J``1."
XMNA0B2H!03V<$3KK_6"EJ``B#DBEJ``R%)F`8#((````"9@PI:@`$A29"K(.2<
XM8`1.NO\R2JR#DF8P+RR%)DZZ&AC0K(4F*4"%*@:L_____(4J+RR%*DAZ!JY.E
XMNA/(2H!/[P`,9P1.NO[\2&R!T$AZ!ILO+(4F3KH'T$J`3^\`#&82+RR%)DZZ]
XM"&1(>``%3KHA%%!/2JR#DF842'H&<2\LA2I.NAZH*6R%)H.24$](;('F2'H&Z
XM7B\L@Y).N@>,2H!/[P`,9A(O+(.23KH(($AX``5.NB#04$]A"'``3-\$!$YU`
XM2.<@($ALA2Y.N@>82H!83V<``T92K(`*2&R%+DZZ_C)*@%A/9A)(;(4N2'H&=
XM!DZZ"-)03V```QY(;(4N2&R&+4ZZ'BA(;(4N3KK\-DAZ!>@O+(.:3KH2[$J`\
XM3^\`%&8R3KK]D"0`+P`O+(.>3KK]CEA/+P!(>@7$3KH(B$AX__\O`DAX``%.8
XMNOT,3^\`&&```L1(>@6P+RR#FDZZ$J9*@%!/9E`@+(`"(@#CB-"!Y8A![(.F\
XMT(@D0`R2`````6<*2'H%B$ZZ^XA83TZZ_28D`"\`2'H%BDZZ""HO*@`$3KK]X
XM8"5"``0DO`````)/[P`,8``"8DAZ!7(O+(.:3KH21$J`4$]F0"`L@`(B`..(T
XMT('EB$'L@Z;0B"1`#)(````!9Q(,D@````)G"DAZ!4-.NOL>6$\O*@`$3KK]M
XM!DZZ_)Q83V```A!(>@5&+RR#FDZZ$?)*@%!/9F`@+(`"(@#CB-"!Y8A![(.FM
XMT(@D0`R2`````6<*2'H$U$ZZ^M183TZZ_'(D`"\`2'H$UDZZ!W8O*@`$3KK\N
XMK"5"``0O`B\L@YY.NOQ:6$\O`$AZ!)!.N@=43^\`&&```9Y(>@3<+RR#FDZZH
XM$8!*@%!/9B1.NOPF)``O`$ZZ_&Q.NOP:+P`O`DAX``-.NONP3^\`$&```6A($
XM>@2J+RR#FDZZ$4I*@%!/9D8@+(`"(@#CB-"!Y8A![(.FT(@D0`R2`````V<*5
XM2'H$@TZZ^BQ83R\J``@O+(.>3KK[S%A/+P!(>@0"3KH&QD_O``Q@``$02'H$]
XM;B\L@YI.NA#R2H!03V9&("R``B(`XXC0@>6(0>R#IM"()$`,D@````-G"DAZ$
XM!$=.NOG46$\O*@`$2'H#VDZZ!GHO*@`(3KK[L$ZZ^T9/[P`,8```N$AZ!#(OQ
XM+(.:3KH0FDJ`4$]F2"`L@`(B`..(T('EB$'L@Z;0B"1`#)(````#9PI(>@0*?
XM3KKY?%A/+RH`!"\L@YY(>@0,3KH&'B\J``A.NOM43KKZZD_O`!!@7$AZ!``O>
XM+(.:3KH00$J`4$]F/"`L@`(B`..(T('EB$'L@Z;0B"1`#)(````#9PI(>@/9'
XM3KKY(EA/+RH`""\L@YY(>@,`3KH%Q$_O``Q@#DALABU(>@+F3KH%LE!/8`#\`
XMKDJL@`)M"DAZ`[9.NOCJ6$],WP0$3G5A<'`Z("5S(&%T(&QI;F4@)60*`'1OE
XM;R!M86YY(&YE<W1I;F<@;&5V96QS`"=E;F1I9B<L("=E;F1D;R<@;W(@)V1B-
XM<F$G('=I=&AO=70@82!M871C:&EN9R`G:68G(&]R("=D;R<`;F4`97$`;'0`B
XM9V4`;&4`9W0`8V,`8W,`=F,`=G,`:&D`<&P`;6D`:6YV86QI9"!C;VYD:71I*
XM;VX@8V]D92!I;B`G:68G+"`G96QS96EF)RP@)W=H:6QE)R!O<B`G=6YT:6PGL
XM`$PE9`H`"E1H:7,@<')O9W)A;2!C;VYV97)T<R!H:6=H+6QE=F5L('-T<G5C#
XM='5R960@87-S96UB;'D@8V]D90H`:6YT;R!R96=U;&%R(&%S<V5M8FQY(&-OG
XM9&4N("!3964@=&AE(%)%041-12!F:6QE(&9O<B!D971A:6QS+@H*`'5S86=E'
XM.B`@87!P(%L@+6\@;W5T<'5T9FEL95T@9FEL96YA;64N87!P"@`@*&EF("UOM
XM(&ES(&YO="!S<&5C:69I960L("YA<'`@97AT96YS:6]N(&ES(')E<75I<F5DN
XM"@`@(&%N9"!O=71P=70@=VEL;"!H879E(&$@+F%S;2!E>'1E;G-I;VXI+@H*B
XM`$AA8VME<F-O<G`L(#,Y,3@@4&%N;W)A;6$L($UI<W-O=7)I($-I='DL(%18*
XM(#<W-#4Y(%5300H`=&5L(R`W,3,M-#,X+30Y-C0L(%5S96YE=#H@=75N970AB
XM<W5G87(A:V%R;`H`26YT97)N970O0DE43D54.B!K87)L0'-U9V%R+FAA8VME%
XM<F-O<G`N8V]M"@H`2&%C:V5R8V]R<"!P=6)L:6,@9&]M86EN(#8X,#`P(&%SR
XM<V5M8FQY('!R97!R;V-E<W-O<B`R+C`@,C@M07!R:6PM,3DY,`H`+6\`+F%P7
XM<`!R`"YA<VT`=P`E<PH`+FEF``EB)7,)3"5D"@`N96QS90`G96QS92<@=VET4
XM:&]U="`G:68G``EB<F$)3"5D"@`N96YD:68`)V5N9&EF)R!W:71H;W5T("=I/
XM9B<@;W(@)V5L<V4G`"YE;'-E:68`+F1O`"YW:&EL90`G=VAI;&4G('=I=&AO%
XM=70@)V1O)P`N96YD9&\`)V5N9&1O)R!W:71H;W5T("=D;R<`+F1B<F$`)V1BC
XM<F$G('=I=&AO=70@)V1O)P`)9&)R80DE<RQ,)60*`"YU;G1I;``G=6YT:6PG1
XM('=I=&AO=70@)V1O)P!D:61N)W0@8VQO<V4@86QL('EO=7(@8V]N=')O;"!SA
XM=')U8W1U<F5S``!(YR`@0>\`%"1(+PHO+P`4+R\`%$ZZ#3PD`"`"3^\`#$S?Y
XM!`1.=4CG`"`D;P`0(`IG!DIJ``QF"'``3-\$`$YU+PI.NA0N0FH`#$AX__\O,
XM"B\O`!@O+P`83KH"<D_O`!1@V$CG(#`F;P`0)$L@;('0L>R!U&0.(&R!T%*LK
XM@=!P`!`08`I(;('03KH!7EA/)``,@/____]G$`R"````"F<(%((@2E**8,0,4
XM@O____]F%+7+9P@(+``!@=UF"'``3-\,!$YU0A(@"V#T2.<`("1O``@@"F<>"
XM2A)G&DAL@?PO"DZZ`)9(;('\2'H`2$ZZ`(I/[P`0+RR'+$ZZ!#(D0$J`6$]G(
XM*$H29R1(;('\+RR'+$ZZ!!I83R\`3KH`7DAL@?Q(>``*3KH`$$_O`!!,WP0``
XM3G4Z(```2.<@("0O``PD;P`0(`IG!DIJ``QF"'#_3-\$!$YU(%*QZ@`$9`P@9
XM4E*2$()P`!`"8.9P`!`"+P`O"DZZ$5I03V#62.<@,"9O`!`D;P`48#0@4K'JN
XM``1D#"!24I(0@G``$`)@#G``$`(O`"\*3KH1*%!/#(#_____9@AP_TS?#`1.$
XM=5*+%!-FR'``8/!(YR`@0>\`$"1(+PHO+P`02&R!YDZZ"WHD`"`"3^\`#$S?,
XM!`1.=4CG,#`D;P`4(`IG%G``,"H`#"8`9PP(`P`*9@8(`P`#9PAP_TS?#`Q.5
XM=2!2L>H`!&4``*9*J@`(9@@O"DZZ$\)83S`J``P"0`"@9S!![('0)DAP`#`K.
XM``P"@```0"`,@```0"!F""\+3KH/]EA/U_P````60>R#B+?(9=8@2M'\````(
XM##`0`D"O_S"`+RH`$"\J``@0*@`.2(!(P"\`3KH(X"0`3^\`#&X@2H)F!'`"1
XM8`)P!"!*T?P````,<@`R$("!,(!P_V``_UPDJ@`(($+1Z@`()4@`!"!24I)P:
XM`!`08`#_0DCG/#(L;P`@)&\`)"9O`"@H+P`L)CP```0`$!)(@$C`*@`,@```>
XM`')F#B0\```0`"8\```"`&`H#(4```!W9@@D/```$P%@&`R%````868()#P`D
XM`!D!8`AP`$S?3#Q.=5**$!)(@`Q``"MF#!`J``%(@`Q``&)G#!`22(`,0`!B3
XM9@I2B@C#``0(@@`,$!)(@`Q``"MF&B`""(```"0`",(``2`#`H#___G_)@`(T
XMPP`+(`YG#"\"+PY.N@8.*`!03TJ$;90,A````!1LC!=$``XW0P`,(`M@@DCG6
XM`"!![('0)$A*:@`,9QC5_````!9![(.(M<AF"'``3-\$`$YU8.)":@`40I)"-
XMJ@`$0JH`""`*8.8`3F\@<W5C:"!F:6QE(&]R(&1I<F5C=&]R>0!!<F<@;&ES:
XM="!T;V\@;&]N9P!"860@9FEL92!D97-C<FEP=&]R`$YO="!E;F]U9V@@;65M2
XM;W)Y`$9I;&4@97AI<W1S`$EN=F%L:60@87)G=6UE;G0`1FEL92!T86)L92!O;
XM=F5R9FQO=P!4;V\@;6%N>2!O<&5N(&9I;&5S`$YO="!A(&-O;G-O;&4`4&5R]
XM;6ES<VEO;B!D96YI960`22]/(&5R<F]R`$YO('-P86-E(&QE9G0@;VX@9&5VL
XM:6-E`%)E<W5L="!T;V\@;&%R9V4`07)G=6UE;G0@;W5T(&]F(&1O;6%I;@!%:
XM>&5C(&9O<FUA="!E<G)O<@!296%D+6]N;'D@9FEL92!S>7-T96T`0W)O<W,M:
XM9&5V:6-E(')E;F%M90!.;W1H:6YG('1O(')E860`2.<@`"0O``A*@FT:#((`I
XM```2;A(@`N6`0>R`?B`P"`!,WP`$3G5!^@`&(`A@\E5N:VYO=VX@97)R;W(`#
XM*D]A<D/L@Y)%[(.2M<EF#C(\`/UK"'0`(L)1R?_\*4^',"QX``0I3H<T2.>`+
XM@`@N``0!*6<02_H`"$ZN_^)@!D*G\U].<T/Z`").KOYH*4"'.&8,+CP``X`'V
XM3J[_E&`&*D].N@`:4$].=61O<RYL:6)R87)Y`$GY``!__DYU2.<`($CG``(B_
XM/``!```P+(.(P?P`!BQLAS1.KO\Z3-]``"E`ASQF'DCG`0:;S2X\``$``"QLK
XMAS1.KO^43-]@@"YLAS!.=2!LASQ":``$(&R'/#%\``$`$"!LASPQ?``!``H@:
XM;(<P("R',)"H``10@"E`AT`@;(=`(+Q-04Y82.<``I/)+&R'-$ZN_MI,WT``D
XM)$!*J@"L9SPO+P`,+R\`#"\*3KH!#"E\`````8=$(&R'/%B(,!``0(``,(`@Y
XM;(<\T?P````*,!``0(``,(!/[P`,8&I(YP`"($K1_````%PL;(<T3J[^@$S?&
XM0`!(YP`"($K1_````%PL;(<T3J[^C$S?0``I0(=((&R'2$JH`"1G)DCG``(@/
XM;(=((&@`)"(0+&R'.$ZN_X),WT``+RR'2"\*3KH%#%!/*6R'2(=,2.<``BQLS
XMASA.KO_*3-]``"!LASP@@$CG``(L;(<X3J[_Q$S?0``@;(<\(4``!F<D2.<@@
XM`B0\```#[4'Z`#0B""QLASA.KO_B3-]`!"!LASPA0``,+RR'3"\LAU!.NO`R4
XM4$\O`$ZZ$?A83TS?!`!.=2H`2.<X,B8O`!PH+P`@)F\`)"!#2J@`K&<4($,@;
XM*`"LY8`L0"`N`!#E@"1`8`0D;(.*$!)(@$C`T(14@"E`AU1(YP`"<@`@+(=4U
XM+&R'-$ZN_SI,WT``*4"'6&8&3-],'$YU$!)(@$C`)``O`B!*4H@O""\LAUA.'
XMN@462'H!2B!"T>R'6"\(3KH/#B\$+PLO+(=83KH!-"!LAUA","@`*7P````!+
XMAU`D0M7LAUA2BB9*3^\`(!`22(!(P"0`#(`````@9R`,@@````EG&`R"````T
XM#&<0#((````-9P@,@@````IF!%**8,P,$@`@;78,$@`B9BI2BA`:2(!(P"0`"
XM9QP6P@R"````(F80#!(`(F8$4HI@!D(K__]@`F#:8#@0&DB`2,`D`&<L#((`+
XM```@9R0,@@````EG'`R"````#&<4#((````-9PP,@@````IG!!;"8,I"&TJ"6
XM9@)3BE*LAU!@`/]20A-(YP`"<@`@+(=0Y8!8@"QLAS1.KO\Z3-]``"E`ATQFX
XM"$*LAU!@`/[0=``D;(=88!H@`N6`(&R'3"&*"``O"DZZ"/S5P%**6$]2@K2L"
XMAU!MX"`"Y8`@;(=,0K`(`&``_I@@`$SO`P``!"`((B\`#$H89OQ3B!#95\G_(
XM_`2!``$``&KR0B!.=2\O``A(>`,!+R\`#&$&3^\`#$YU2.<^,BQO`"0H+P`HH
XM3KH/;"9LASQT`&`0<@8@`DZZ$>!*LP@`9Q!2@C!L@XBQPF[H=@A@``%."`0`(
XM"6=>2.<@`G3_(B\`!"QLASA.KO^L3-]`!"H`9T1(YP`"(@4L;(<X3J[_IDS?D
XM0`!(YP`"(A<L;(<X3J[_N$S?0`!*@&8<2.<``BQLASA.KO]\3-]``"8`#(``'
XM``#-9@``ZDCG(`(D/````^TB+P`$+&R'.$ZN_^),WT`$)$`@"F8``*0(!``(B
XM9@9V`6```+Q(YR`")#P```/N(B\`!"QLASA.KO_B3-]`!"1`2H!F%DCG``(L@
XM;(<X3J[_?$S?0``F`&```(9(YP`"<"%#^@#`+&R'-$ZN_=A,WT``+`!G%$CG]
XM``(B1BQLAS1.KOYB3-]``&`P2.<P`G8!0?H`GB0((@HL;(<X3J[_T$S?0`Q(^
XMYS`"=O]T`"(*+&R'.$ZN_[Y,WT`,8#`@!`*````%``R````%`&8@2.<``B(*D
XM+&R'.$ZN_]Q,WT``=@4I0X<L</],WTQ\3G5R!B`"3KH0:B>*"`!R!B`"3KH0?
XM7C>$"`0(!``+9Q9(YS`"=@%T`"(*+&R'.$ZN_[Y,WT`,(`)@PF1O<RYL:6)R9
XM87)Y````2.<P("0O`!!.N@V<<@8@`DZZ$!@D0-7LASQ*@FT,,&R#B+'";P1*M
XMDF80*7P````#ARQP_TS?!`Q.=3`J``1(P`*``````PR``````68,*7P````&E
XMARQP_V#:2.<P`B8O`"0D+P`@(A(L;(<X3J[_UDS?0`PF``R`_____V882.<`7
XM`BQLASA.KO]\3-]``"E`ARQP_V">(`-@FDSO`P``!+/(9PQP`!`8L!E6R/_Z)
XM9@1P`$YU8P1P`4YU</].=4CG,#(L;P`82.<``G``0_H`UBQLAS1.KOW83-]`Q
XM`"E`AUQF!DS?3`Q.=4CG``(@;P`@(&@`)"!H``0L;(=<3J[_LDS?0``D0$J`7
XM9WY(YP`"0_H`H2!J`#8L;(=<3J[_H$S?0``D`&=02.<@`B0\```#[2(7+&R')
XM.$ZN_^),WT`$)D!*@&<R(`OE@"8`($,M:``(`*0M2P"<2.<@`B0\```#[4'Z7
XM`%8B""QLASA.KO_B3-]`!"U``*!(YP`"($HL;(=<3J[_IDS?0`!(YP`"(FR'8
XM7"QLAS1.KOYB3-]``$*LAUQ@`/]`:6-O;BYL:6)R87)Y`%=)3D1/5P`J`$SOO
XM`P``!"`((B\`#&`"$-E7R?_\9PP$@0`!``!J\$YU0AA1R?_\!($``0``:O).G
XM=4Y5_?1(YS\R)FT`""QM`!!^`"1M``P6$F8*(`=,WTS\3EU.=5**#`,`)6="A
XM)`<@4['K``1D#"!34I,0@W``$`-@#G``$`,O`"\+3KH%+E!/#(#_____9P`$#
XM9%*"%A)F!"`"8+A2B@P#`"5FPBX">``K?````"#__!8:<``0`V!F",0``&#R]
XM",0``6#L",0``F#F",0``V#@6(XD+O_\2H)L!@C$``!$@A8:8%8K?````##_[
XM_'0`8!@@`N>`<@`2`]"!T(+0@B0`!((````P%AIP`!`#0>R`SQ`P``!(@`@`&
XM``)FU&`<!$``(&>@5T!GHE]`9Z130&>.54!GA%=`9ZQ@LBM"__@D/```?<8,$
XM`P`N9EP6&@P#`"IF%%B.)"[__$J";`8D/```?<86&F`P=`!@&"`"YX!R`!(#F
XMT('0@M"")``$@@```#`6&G``$`-![(#/$#```$B`"````F;4#((``'W&9P@KU
XM?````"#__"H"#`,`:&8&",0`!V`6#`,`;&8&",0`!F`*#`,`3&8&",0`"!8:=
XM*TH`#'``$`-@``&.8``#&@@$``=G"EB.(&[__#"'8!@(!``&9PI8CB!N__P@D
XMAV`(6(X@;O_\((=T`&```:A8CB1N__PO"DZZ`P@D``R%``!]QEA/9P:TA6\"W
XM)`5@``&&6(X6+O__0>W]^"1($(-T`6```7)T"&`0`$0`2'9X=!!@!@C$``1TV
XM"@P#`%AF"$'Z`IX@"&`&0?H"IR`(*T#]]`@$``9G"%B.+"[__&`4"`0`!&<(?
XM6(XL+O_\8`98CBPN__P(!``$9PI*AFP&1(8(Q``%0>W_^"1(#(4``'W&9@)Z!
XM`4J&9@1*A6<<(@(@!DZZ!:P@;?WT%3`(`"("(`9.N@6H+`!FY$'M__B1RB0(\
XM"`0``V=N#`,`;V842H)G"@P2`#!G"+2%;00J`E*%8%0,`P!X9P8,`P!89DA**
XM@F=$#!(`,&<^M(5L$$'M_?JQRF0(%3P`,%*"8.P(!```9AP,K0```##__&82L
XM(`)4@+"M__AL""HM__A5A6#*%0,5/``P5(*TA6P00>W]^+'*9`@5/``P4H)@S
XM[&!,!$``)6<`_L@$0``S9P#^V`1```MG`/ZR4T!G`/[.6T!G`/[(6T!G`/Y0F
XM4T!G`/ZN4T!G`/ZL5T!G`/YL54!G`/ZN5T!G`/Z@8`#^*@@$``1G*`@$``5G5
XM!A4\`"U@&@@$``%G!A4\`"M@#@@$``)G!A4\`"!@`E."4H+>@@@$``!F``"0[
XM#*T````P__QF0@@$``1G/#`$`D``)F<T(%.QZP`$9`X@4U*3$)IP`!`J__]@%
XM#G``$!HO`"\+3KH!DE!/#(#_____9P``R%.M__A3@F`T(%.QZP`$9!`@4U*3!
XM$*W__W``$"W__V`0<``0+?__+P`O"TZZ`5A03PR`_____V<``(Y2AR`M__A37
XMK?_XL()NP"H"(`)3@DJ`9RX@4['K``1D#B!34I,0FG``$"K__V`.<``0&B\`L
XM+PM.N@$24$\,@/____]G2&#*"`0``&<\)`5@+"!3L>L`!&0.(%-2DQ"\`"!PR
XM`'`@8`Q(>``@+PM.N@#<4$\,@/____]G$E*'("W_^%.M__BP@F[(8`#[6'#_X
XM8`#[7#`Q,C,T-38W.#E!0D-$148`,#$R,S0U-C<X.6%B8V1E9@`@;P`$(`A*`
XM&&;\4TB1P"`(3G5(YP`@)&\`""`*9D1![('0)$A*:@`,9R8P*@`,`D`""&8<Z
XM2'C__R\*3KH`6@R`_____U!/9@AP_TS?!`!.==7\````%D'L@XBUR&7&<`!@F
XMZ$AX__\O"DZZ`"Q03V#:2.<`($'L@=`D2"\*3KH!OEA/U?P````60>R#B+7(H
XM9>I,WP0`3G5(YSP@)&\`&"@O`!P@"F<``9`T*@`,9P`!B`@"``EF``&`"`(`J
XM`V8``7@@2M'\````##`0`D#O_3"`2JH`"&8<#(3_____9@AP`$S?!#Q.=2\*2
XM3KH"R#0J``Q83P@"``YF-"!2L>H`"&,>2'@``2`2D*H`!"\`$"H`#DB`2,`O2
XM`$ZZ!$Q/[P`,)*H`""!J`!#1TB5(``0,A/____]F!'8`8`(6!"`2D*H`""H`L
XM,`("0`"@9TX,A/____]G(B!24I(0@R!*T?P````,,!`(P``.,(`T`$'Z_P0IK
XM2(=@4H4,A/____]G#`P#``IG!KJJ`!!E!'C_8`PE4@`$<``0`V``_TH(`@`.*
XM9S!*A6<<+P4O*@`($"H`#DB`2,`O`$ZZ!':PA4_O``QF7B!*T?P````,,!`(5
XM@``.,(`,A/____]F$B2J``@E:@`(``1P`!`#8`#^^D'Z_H8I2(=@($K1_```<
XM``PP$`C```XP@"2J``@@:@`0T=(E2``$(%)2DA"#<``0`V``_L8@2M'\````=
XM##`0",```C"`)6H`"``$)*H`"'#_8`#^IDY5__9(YS@@)&T`"'0`(`IG!DIJA
XM``QF"G#_3-\$'$Y=3G4(*@`!``QF"B\*3KK]J(2`6$\0*@`.2(!(P"\`3KH&Y
XMB(2`""H````-6$]G"B\J``A.N@&66$]*:@`49TY(>@!J2&W_]TZZ`E`X*@`4N
XM=@!03W``,`1R"DZZ`'P&@````#!R!Y*#0>W_]Q&`&`!(Q(G\``I2@PR#````)
XM!6W40BW__TAM__=.N@,26$]"DD*J``1"J@`(0FH`#$J"9P9P_V``_UAP`&``!
XM_U)435``2.=(`$*$2H!J!$2`4D1*@6H&1($*1``!83Y*1&<"1(!,WP`22H!./
XM=4CG2`!"A$J`:@1$@%)$2H%J`D2!81H@`6#8+P%A$B`!(A]*@$YU+P%A!B(?^
XM2H!.=4CG,`!(04I!9B!(038!-`!"0$A`@,,B`$A`,@*"PS`!0D%(04S?``Q.L
XM=4A!)@$B`$)!2$%(0$)`=`_0@-.!MH%B!)*#4D!1RO_R3-\`#$YU2.<@("1O0
XM``QT01`J``Y(@$C`+P!.N@$Z2H!83V<"="$E?```!```$$AX!`!.N@#&)4``F
XM"%A/9A@E?`````$`$"!*T?P````/)4@`"#0\`(`@2M'\````#'``,!`R`DC!Z
XM@($P@"5J``@`!"2J``A,WP0$3G5(YP`PE\LD;(=D8!`@2E"((F\`#+/(9PXFY
XM2B12(`IF[$S?#`!.=2`+9P0FDF`$*5*'9$CG``(@*@`$4(`B2BQLAS1.KO\N%
XM3-]``&#42.<`,"1LAV1@'"922.<``B`J``10@")*+&R'-$ZN_RY,WT``)$L@>
XM"F;@0JR'9$S?#`!.=4CG("`D+P`,2H)F"'``3-\$!$YU2.<``G(`(`)0@"QL^
XMAS1.KO\Z3-]``"1`2H!F!'``8-I!^O^6*4B':"2LAV0E0@`$*4J'9"`*4(!@K
XMP$SO`P``!"`($-EF_$YU2.<@("0O``QR!B`"3KH$3"1`U>R'/$J";0PP;(.(,
XML<)O!$J29A`I?`````.'+'#_3-\$!$YU2.<``G(&(`).N@0:(&R'/"(P"``L^
XM;(<X3J[_*$S?0`!*@&<$<`%@`G``8,Y(YS`@)"\`$$ZZ`6IR!B`"3KH#YB1`C
XMU>R'/$J";0PP;(.(L<)O!$J29A`I?`````.'+'#_3-\$#$YU2.<P`B`O`"137
XM@"8`)"\`("(2+&R'.$ZN_[Y,WT`,)@`,@/____]F&$CG``(L;(<X3J[_?$S?J
XM0``I0(<L</]@NDCG,`)V`'0`(A(L;(<X3J[_ODS?0`Q@HDCG``(B+P`(+&R'6
XM.$ZN_[A,WT``2H!F&$CG``(L;(<X3J[_?$S?0``I0(<L</].=7``8/I(YS`@?
XM)"\`$$ZZ`*1R!B`"3KH#("1`U>R'/$J";0PP;(.(L<)O!$J29A`I?`````.'/
XM+'#_3-\$#$YU,"H`!`)```-F#"E\````!H<L</]@Y`@J``,`!&<62.<P`G8!-
XM=``B$BQLASA.KO^^3-]`#$CG,`(F+P`D)"\`("(2+&R'.$ZN_]!,WT`,)@`,[
XM@/____]F&$CG``(L;(<X3J[_?$S?0``I0(<L</]@BB`#8(9(YR``2.<``B(\`
XM```0`'``+&R'-$ZN_LY,WT``)``(```,9Q)*K(=$9@@@`DS?``1.=4ZZ``9PX
XM`&#R2.<P`G8$0?H`+B0(+P,O`BQLASA.KO_$(@`D'R8?+&R'.$ZN_]!,WT`,^
XM2'@``4ZZ``I83TYU7D,*`$JLAVQG%"!LAVP@:``$3I`@;(=L*5"';&#F2JR'C
XM8&<&(&R'8$Z0+R\`!$ZZ``983TYU2.<P`"8O``Q*K(<\9S)T`&`*+P).N@%P2
XM6$]2@C!L@XBQPF[N2.<``C`L@XC!_``&(FR'/"QLAS1.KO\N3-]``$JLAVAG0
XM!B!LAVA.D$JL@XYG%$CG``(B+(..+&R'.$ZN_Z9,WT``2JR'<&<((&R'<""L_
XMAW1*K(=X9Q1(YP`"(FR'>"QLAS1.KOYB3-]``$JLAWQG%$CG``(B;(=\+&R'8
XM-$ZN_F),WT``2JR'@&<42.<``B)LAX`L;(<T3J[^8DS?0`!*K(>$9Q1(YP`"`
XM(FR'A"QLAS1.KOYB3-]``$CG``8L>``$""X`!`$I9Q!+^@`(3J[_XF`&0J?S7
XM7TYS*E]*K(=(9CQ*K(=89S1(YP`"("R'5")LAU@L;(<T3J[_+DS?0`!(YP`"=
XM("R'4.6`6(`B;(=,+&R'-$ZN_RY,WT``8"1(YP`"+&R'-$ZN_WQ,WT``2.<`!
XM`B)LAT@L;(<T3J[^ADS?0`!(YP`"(FR'."QLAS1.KOYB3-]``"`#+FR',$YUL
XM3-\`#$YU2.<@("0O``QR!B`"3KH`2B1`U>R'/$J";0PP;(.(L<)O!$J29A`II
XM?`````.'+'#_3-\$!$YU,"H`!`)`@`!F$DCG``(B$BQLASA.KO_<3-]``$*2!
XM<`!@V$CG<``T`<3`)@%(0\;`2$-"0]2#2$#`P4A`0D#0@DS?``Y.=0```^P`O
XM```!`````0``$-8````````#\@```^H```#D_____P`````````````'BP``\
XM!XX```>.```'BP``!Y$```>4```'E```!Y$```>7```'F@``!YH```>7```'G
XMG0``!Z````>@```'G0``!Z,```>F```'I@``!Z,```>I```'30``!TT```>I%
XM```'K```!Z\```>O```'K```#M0```[5```.[P``#P$```\5```/)P``#S,``
XM``]$```/6```#VP```]Z```/C```#Y8```^N```/OP``#]8```_H```/_@``R
XM$!(````3`"`@("`@("`@(#`P,#`P("`@("`@("`@("`@("`@("`@D$!`0$!`5
XM0$!`0$!`0$!`0`P,#`P,#`P,#`Q`0$!`0$!`"0D)"0D)`0$!`0$!`0$!`0$!Z
XM`0$!`0$!`0%`0$!`0$`*"@H*"@H"`@("`@("`@("`@("`@("`@("`D!`0$`@,
XM`````````````````````````````````````````````````````````````
XM`````````````````````````````````````````````````````````````
XM`````````````````````````````````````````````````````````````
XM`````````@````````$```````````````````0``0`````!````````````)
XM```````$``(``````0``````````````````````````````````````````'
XM`````````````````````````````````````````````````````````````
XM`````````````````````````````````````````````````````````````
XM`````````````````````````````````````````````````````````````
XM`````````````````````````````````````````````````````````````
XM`````````````````````````````````````````````````````````````
XM`````````````````````````````````````````````````````````````
XM`````````````````````````````````````````````````````````````
XM````````````````````````````````````````%``````````````#[```#
XM`"\`````````#````!`````4````&````!P````@````)````"@````L````K
XM,````#0````X````/````$````!$````2````$P```!0````5````%@```!<(
XM````8````&0```!H````;````'````!T````>````'P```"`````A````(@`\
XM``",````D````)0```"8````G````*````"D````J````*P```"P````M```@
XB`+@```"\````P````,0````````#\@```^L````!```#\JP`]
X``
Xend
Xsize 11104
END_OF_FILE
if test 15581 -ne `wc -c <'app.uu'`; then
    echo shar: \"'app.uu'\" unpacked with wrong size!
fi
# end of 'app.uu'
fi
if test -f 'makefile' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'makefile'\"
else
echo shar: Extracting \"'makefile'\" \(271 characters\)
sed "s/^X//" >'makefile' <<'END_OF_FILE'
X# makefile for APP assembly preprocessor
X
XCFLAGS= -pa -so
X
Xapp:	app.o
X	ln app.o -lc
X
Xclean:
X	-delete #?.bak quiet
X	-delete #?.o quiet
X	-delete app
X	-delete app.UU
X	-delete app.shar
X
Xshar:	app
X	uuencode >app.UU app app
X	shar >app.shar README makefile app.c app.pro app.UU
END_OF_FILE
if test 271 -ne `wc -c <'makefile'`; then
    echo shar: \"'makefile'\" unpacked with wrong size!
fi
# end of 'makefile'
fi
echo shar: End of archive 1 \(of 1\).
cp /dev/null ark1isdone
MISSING=""
for I in 1 ; do
    if test ! -f ark${I}isdone ; then
	MISSING="${MISSING} ${I}"
    fi
done
if test "${MISSING}" = "" ; then
    echo You have the archive.
    rm -f ark[1-9]isdone
else
    echo You still need to unpack the following archives:
    echo "        " ${MISSING}
fi
##  End of shell archive.
exit 0
-- 
Mail submissions (sources or binaries) to <amiga@cs.odu.edu>.
Mail comments to the moderator at <amiga-request@cs.odu.edu>.
Post requests for sources, and general discussion to comp.sys.amiga.