File:  [Atari MiNT] / MiNT / src / asm.y
Revision 1.1.1.3 (vendor branch): download - view: text, annotated - select for diffs
Tue Apr 24 17:57:02 2018 UTC (8 years, 1 month ago) by root
Branches: mint, MAIN
CVS tags: mint112, mint110, mint108, HEAD
MiNT 1.08



%{

#define YYSTYPE char *



#include "asmtrans.h"

%}



%token WORD

%token WHITESP

%token EOLN

%token STRING

%token DEFINECMD

%token INCLUDECMD

%token IFDEFCMD

%token IFNDEFCMD

%token ELSECMD

%token ENDIFCMD



/* Grammar follows */

%%

input:

        | input line

;



line:	EOLN		{ emit($1); }

		/* note that emit() will automatically free the memory,

		   and will also check the hidecnt variable */

	| label EOLN	{ emit($1); emit($2); }

	| opline EOLN	{ emit($1); emit($2); }

	| label opline EOLN	{ emit($1); emit($2);

			emit($3); }

	| INCLUDECMD WHITESP STRING EOLN { if (!hidecnt) do_include($3); free($3); }

	| INCLUDECMD WHITESP WORD EOLN { if (!hidecnt) do_include($3); free($3); }

	| DEFINECMD WHITESP WORD WHITESP STRING EOLN {

		if (!hidecnt) do_define($3, $5); free($3); free($5); }

	| DEFINECMD WHITESP WORD WHITESP operand EOLN {

		if (!hidecnt) do_define($3, $5); free($3); free($5); }

	| IFDEFCMD WHITESP WORD EOLN { do_ifdef($3); free($3); }

	| IFNDEFCMD WHITESP WORD EOLN { do_ifndef($3); free($3); }

	| ELSECMD EOLN { do_else(); }

	| ENDIFCMD EOLN { do_endif(); } 

;



opline:	WHITESP opcode		{ $$ = do_ops("", $2, "", ""); free($2); }

	| WHITESP opcode WHITESP ops

			{ $$ = do_ops("", $2, $3, $4);

			 free($2); free($3); free($4); }

	| WORD WHITESP opcode	{ $$ = do_ops($1, $3, "", ""); free($1); free($3); }

	| WORD WHITESP opcode WHITESP ops

			{ $$ = do_ops($1, $3, $4, $5);

			 free($1); free($3); free($4); free($5);}

;



ops: operand { $$ = $1; }

	| operand ',' ops { $$ = concat3($1, ",", $3);

				free($1); free($3); }

;



opcode: WORD	{ $$ = wordlookup($1); free($1); }

;



label: WORD ':' { $$ = concat($1, ":"); free($1); }



operand: basic	{$$ = $1; }

	| '#' basic {$$ = immediate($2); free($2); }

	| '(' basic ')' {$$ = indirect($2); free($2); }

	| '(' basic ')' '+' {$$ = postinc($2); free($2); }

	| '-' '(' basic ')' {$$ = predec($3); free($3); }

	| basic '(' basic ')' {$$ = indexed($1, $3); free($1); free($3); }

	| '(' basic ')' WORD {$$ = sizedop($2, $4); free($2); free($4); }

	| basic '(' basic ',' basic ')' {$$ = twoindex($1, $3, $5);

				free($1); free($3); free($5); }

	| basic '{' basic ':' basic '}' {$$ = bitfield($1, $3, $5);

			free($1); free($3); free($5); }

	| '(' '[' basic ',' basic ']' ',' basic ',' basic ')'

	   { $$=postindex($3,$5,$8,$10); 

	     free($3); free($5); free($8); free($10); }		

	| '(' '[' basic ',' basic ',' basic ']' ',' basic ')'

	   { $$=preindex($3,$5,$7,$10); 

	     free($3); free($5); free($7); free($10); }		

	| '(' '[' basic ']' ')'

	   { $$=postindex0($3); 

	     free($3); }

	| '(' '[' basic ']' ','  basic ')'

	   { $$=postindex1($3,$6); 

	     free($3); free($6); }		     		     

;



basic: basexpr { $$ = $1; }

	| basexpr op basic { $$ = concat3($1, $2, $3); free($1); free($2); free($3); }

	| '-' basic { $$ = concat("-", $2); free($2); }



basexpr: WORD {$$ = wordlookup($1); free($1); }

	| '$' WORD {$$ = hexop($2); free($2);}

;



op: 	'+' { $$ = strdup("+"); }

	| '-' { $$ = strdup("-"); }

	| '*' { $$ = strdup("*"); }

	| '/' { $$ = strdup("/"); }

;

%%

#include <setjmp.h>



jmp_buf start;



#ifdef NATIVEATARI

#define STACK 32*1024L

#ifdef LATTICE

long _STACK = STACK;

#endif

#ifdef __GNUC__

long _stksize = STACK;

#endif



static void

hit_return()

{

	printf("Hit return to continue\n");

	fflush(stdout);

	getchar();

}

#endif



void usage()

{

	fprintf(stderr, "Usage: asmtrans [-gas][-asm][-o outfile] infile\n");

	exit(2);

}



int errors = 0;



void

do_include(file)

	char *file;

{

	jmp_buf save;

	FILE *oldin, *f;



	f = fopen(file, "rt");

	if (!f) {

		perror(file);

		return;

	}

	bcopy(start, save, sizeof(jmp_buf));

	oldin = infile;

	infile = f;

	setjmp(start);

	yyparse();

	fclose(f);

	infile = oldin;

	bcopy(save, start, sizeof(jmp_buf));

	longjmp(start,1);

}



/* set up initial definitions based on syntax type */



void

do_initial_defs()

{

	if (syntax == GAS) {

		do_define("mmusr", "psr");

		do_define("fpiar", "fpi");

		do_define("XREF", ".globl");

		do_define("XDEF", ".globl");

		do_define("TEXT", ".text");

		do_define("DATA", ".data");

	/* gas doesn't have a .bss directive */

		do_define("BSS", ".data");

		do_define("END", "| END");

		do_define("dc.l", ".long");

		do_define("dc.w", ".word");

		do_define("dc.b", ".byte");

	} else if (syntax == ASM) {

		do_define("TEXT", "SECTION TEXT,CODE");

		do_define("DATA", "SECTION DATA,DATA");

		do_define("BSS", "SECTION BSS,BSS");

	}

}



int

main (argc, argv)

	int argc; char **argv;

{

	FILE *f;

#ifdef NATIVEATARI

	if (!argv[0] || !argv[0][0])	/* run from desktop? */

		atexit(hit_return);

#endif

	argv++;

	outfile = stdout;



	while (*argv) {

		if (!strcmp(*argv, "-o")) {

			argv++;

			if (*argv == 0) {

				fprintf(stderr, "missing argument to -o\n");

				usage();

			}

			f = fopen(*argv, "wt");

			if (!f)

				perror(*argv);

			else

				outfile = f;

			argv++;

		} else if (!strcmp(*argv, "-gas")) {

			argv++;

			syntax = GAS;

		} else if (!strcmp(*argv, "-asm")) {

			argv++;

			syntax = ASM;

		} else if (!strcmp(*argv, "-purec")) {

			argv++;

			syntax = PUREC;

		} else if (!strncmp(*argv, "-D", 2)) {

			char *word, *defn;

			word = *argv+2;

			defn = index(word,'=');

			if (defn)

				*defn++ = '\0';

			else

				defn = "1";

			if (*word) do_define(word,defn);

			argv++;

		} else if (!strcmp(*argv, "--")) {

			argv++;

			break;

		} else {

			if (**argv == '-') {

				fprintf(stderr, "unknown option: %s\n",

					*argv);

				usage();

			}

			break;

		}

	}



	do_initial_defs();



	if (*argv == 0) {

		setjmp(start);

		infile = stdin;

		yyparse();

	} else {

	    while(*argv) {

		if (!(f = fopen(*argv, "rt")))

			perror(*argv);

		else {

			infile = f;

			setjmp(start);

			yyparse();

			fclose(f);

		}

		argv++;

	    }

	}



	if (ifstkptr != 0) {

		fputs("%ifdef without matching %endif\n", stderr);

		errors++;

	}

	return errors;

}



void

yyerror (s)  /* Called by yyparse on error */

     char *s;

{

	errors++;

	printf("%s\n", s);

	longjmp(start, 1);

}



void dbgmsg(s) char *s;

{

	fprintf(stderr, "%s\n", s);

}


unix.superglobalmegacorp.com

This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.