Line 38... |
Line 38... |
%{
|
%{
|
#include
|
#include
|
#include
|
#include
|
#include "asmdata.h"
|
#include "asmdata.h"
|
|
|
|
#define DEFAULT_OUTPUT_FNAME "z.out"
|
|
#define YYDEBUG 1
|
|
|
extern "C" int yylex(void);
|
extern "C" int yylex(void);
|
extern "C" int yyparse(void);
|
extern "C" int yyparse(void);
|
// extern "C" FILE *yyin;
|
// extern "C" FILE *yyin;
|
void yyerror(const char *);
|
void yyerror(const char *);
|
unsigned int global_parser_pc;
|
unsigned int global_parser_pc;
|
Line 73... |
Line 76... |
%type BAREOP SINGLOP DUALOP BRANCHOP LDHLOP
|
%type BAREOP SINGLOP DUALOP BRANCHOP LDHLOP
|
%type unlabeledline instruction wordlist fillist opb
|
%type unlabeledline instruction wordlist fillist opb
|
%type bareop singlop dualop loadop storop line
|
%type bareop singlop dualop loadop storop line
|
%type expr value multident
|
%type expr value multident
|
|
|
|
%left BOOLEANOR
|
|
%left BOOLEANAND
|
|
%left BITWISEOR BITWISEXOR
|
|
%left BITWISEAND
|
|
%left PLUS MINUS
|
|
%left TIMES '/'
|
|
|
%% /* The grammar follows */
|
%% /* The grammar follows */
|
|
|
input:
|
input:
|
%empty
|
%empty
|
| input line { if ($2) {objcode += $2; global_parser_pc += $2->nlines(); if ($2->isdefined()) delete $2; } }
|
| input line { if ($2) {objcode += $2; global_parser_pc += $2->nlines(); if ($2->isdefined()) delete $2; } }
|
Line 400... |
Line 410... |
;
|
;
|
%%
|
%%
|
|
|
#include
|
#include
|
#include
|
#include
|
|
#include
|
#include
|
#include
|
#include
|
#include
|
#include
|
#include
|
|
|
OBJFILE objcode;
|
OBJFILE objcode;
|
Line 411... |
Line 422... |
void yyerror(const char *str) {
|
void yyerror(const char *str) {
|
fprintf(stderr, "%s:%d: ERROR: %s\n", master_input_filename, yylineno, str);
|
fprintf(stderr, "%s:%d: ERROR: %s\n", master_input_filename, yylineno, str);
|
if (linecp) fprintf(stderr, "Offending line was: %s\n", linecp);
|
if (linecp) fprintf(stderr, "Offending line was: %s\n", linecp);
|
}
|
}
|
|
|
FILE *run_preprocessor(const char *path = NULL, const char *zname = NULL) {
|
FILE *run_preprocessor(pid_t &pid, const char *path = NULL, const char *zname = NULL) {
|
int pipefd[2];
|
int pipefd[2];
|
int pid;
|
|
|
|
if (pipe(pipefd)!=0) {
|
if (pipe(pipefd)!=0) {
|
fprintf(stderr, "PIPE FAILED!\n");
|
fprintf(stderr, "PIPE FAILED!\n");
|
perror("O/S Err:");
|
perror("O/S Err:");
|
exit(-2);
|
exit(-2);
|
Line 465... |
Line 475... |
|
|
close(pipefd[1]);
|
close(pipefd[1]);
|
return fdopen(pipefd[0], "r");
|
return fdopen(pipefd[0], "r");
|
}
|
}
|
|
|
|
void usage(void) {
|
|
printf("USAGE: zasm [-h] [-d] [-E] [-o ] [ ]* ...\n");
|
|
printf("\t-d\tTurns on debugging in the parser\n");
|
|
printf("\t-E\tProduces preprocessor output only\n");
|
|
printf("\t-h\tDisplays this message\n");
|
|
printf("\t-o \tWrites the output to . The\n"
|
|
"\t\tdefault output file is \"" DEFAULT_OUTPUT_FNAME "\".\n");
|
|
|
|
printf("\t-I \tSearch for include files.\n");
|
|
}
|
|
|
int main(int argc, char **argv) {
|
int main(int argc, char **argv) {
|
int skp = 0;
|
int skp = 0;
|
const char *zout_fname = NULL;
|
const char *zout_fname = NULL;
|
char *path_to_zasm = NULL;
|
char *path_to_zasm = NULL;
|
bool preprocess_only = false;
|
bool preprocess_only = false;
|
|
FILE *ppout;
|
|
pid_t zpp_pid;
|
|
int zpp_status;
|
|
|
master_input_filename = NULL;
|
master_input_filename = NULL;
|
|
|
// Find what directory zasm is in, so that we can find zpp when
|
// Find what directory zasm is in, so that we can find zpp when
|
// necessary.
|
// necessary.
|
path_to_zasm = NULL;
|
path_to_zasm = NULL;
|
Line 491... |
Line 516... |
free((void *)zout_fname);
|
free((void *)zout_fname);
|
zout_fname = strdup(argv[argn+skp+1]);
|
zout_fname = strdup(argv[argn+skp+1]);
|
skp++;
|
skp++;
|
} else if (argv[argn+skp][1] == 'E')
|
} else if (argv[argn+skp][1] == 'E')
|
preprocess_only = true;
|
preprocess_only = true;
|
|
else if (argv[argn+skp][1] == 'd')
|
|
yydebug = 1;
|
|
else if (argv[argn+skp][1] == 'h') {
|
|
usage();
|
|
exit(0);
|
|
}
|
|
|
skp++;
|
skp++;
|
} argv[argn] = argv[argn+skp];
|
} argv[argn] = argv[argn+skp];
|
} argc -= skp;
|
} argc -= skp;
|
|
|
|
if (zout_fname) {
|
|
for(int argn=0; argn
|
|
if (strcmp(zout_fname, argv[argn])==0) {
|
|
fprintf(stderr, "ERR: Cowardly refusing to overwrite \'%s\'\n", zout_fname);
|
|
exit(-2);
|
|
}
|
|
}
|
|
}
|
|
|
if (preprocess_only) {
|
if (preprocess_only) {
|
objcode.open("/dev/null");
|
objcode.open("/dev/null");
|
|
if (zout_fname)
|
|
ppout = fopen(zout_fname, "w");
|
|
else
|
|
ppout = stdout;
|
} else {
|
} else {
|
if (!zout_fname)
|
if (!zout_fname)
|
zout_fname = "z.out";
|
zout_fname = DEFAULT_OUTPUT_FNAME;
|
|
|
objcode.open(zout_fname);
|
objcode.open(zout_fname);
|
}
|
}
|
|
|
master_input_filename = NULL;
|
master_input_filename = NULL;
|
Line 518... |
Line 562... |
create_new_context();
|
create_new_context();
|
if (master_input_filename)
|
if (master_input_filename)
|
free(master_input_filename);
|
free(master_input_filename);
|
master_input_filename = strdup(argv[argn]);
|
master_input_filename = strdup(argv[argn]);
|
if (preprocess_only) {
|
if (preprocess_only) {
|
FILE *fp = run_preprocessor(path_to_zasm, master_input_filename);
|
FILE *fp = run_preprocessor(zpp_pid, path_to_zasm, master_input_filename);
|
int ch;
|
int ch;
|
while(EOF != (ch = fgetc(fp)))
|
while(EOF != (ch = fgetc(fp)))
|
fputc(ch, stdout);
|
fputc(ch, ppout);
|
|
waitpid(zpp_pid, &zpp_status, WNOHANG);
|
} else {
|
} else {
|
yyrestart(run_preprocessor(path_to_zasm, master_input_filename));
|
yyrestart(run_preprocessor(zpp_pid, path_to_zasm, master_input_filename));
|
yylineno = 1;
|
yylineno = 1;
|
yyparse();
|
yyparse();
|
|
waitpid(zpp_pid, &zpp_status, WNOHANG);
|
}
|
}
|
}
|
}
|
} else { // Run from Stdin
|
} else { // Run from Stdin
|
extern FILE *yyin;
|
extern FILE *yyin;
|
extern void yyrestart(FILE *);
|
extern void yyrestart(FILE *);
|
|
|
create_new_context();
|
create_new_context();
|
master_input_filename = strdup("(stdin)");
|
master_input_filename = strdup("(stdin)");
|
if (preprocess_only) {
|
if (preprocess_only) {
|
int ch;
|
int ch;
|
FILE *fp = run_preprocessor(path_to_zasm, master_input_filename);
|
FILE *fp = run_preprocessor(zpp_pid, path_to_zasm, master_input_filename);
|
while(EOF != (ch = fgetc(fp)))
|
while(EOF != (ch = fgetc(fp)))
|
fputc(ch, stdout);
|
fputc(ch, ppout);
|
|
waitpid(zpp_pid, &zpp_status, WNOHANG);
|
} else {
|
} else {
|
yyin = run_preprocessor(NULL);
|
yyin = run_preprocessor(zpp_pid, NULL);
|
yyrestart(yyin);
|
yyrestart(yyin);
|
yyparse();
|
yyparse();
|
|
waitpid(zpp_pid, &zpp_status, WNOHANG);
|
}
|
}
|
}
|
}
|
|
|
if (!objcode.reduce())
|
if (0 != WEXITSTATUS(zpp_status)) {
|
|
if (!preprocess_only) {
|
|
objcode.close();
|
|
unlink(zout_fname);
|
|
}
|
|
} if (!objcode.reduce())
|
fprintf(stderr, "Not all symbols defined!\n");
|
fprintf(stderr, "Not all symbols defined!\n");
|
}
|
}
|
|
|
|
|