Add a syntax to declare functions in a top table

Use the new syntax in the mips, pdp, powerpc tables to declare
functions before calling them.  These declarations prevent compiler
warnings about implicitly declaring functions.  They also provide
prototypes of the function parameters.

Also fix a warning in the powerpc table: use `bsearch(...) != NULL` to
avoid converting the pointer from bsearch() to an int.

The syntax for topgen is a block `{...}` among the parameters in the
top table.  It looks like the syntax of LLgen, but topgen doesn't
allow nested blocks, so declarations like `struct whatever {...};`
don't work.  The token OPEN_BRACKET that begins a declaration_block
doesn't conflict with the LETTER that begins a parameter_line or the
'%' that begins a separator.

Because a block writes a #line command to gen.h, a parameter line now
also writes a #line command to gen.h, so it doesn't get a wrong line
number from a previous block.
This commit is contained in:
George Koehler 2019-10-24 14:08:52 -04:00
parent 777d0abb00
commit 51e34acab1
4 changed files with 53 additions and 6 deletions

View file

@ -4,6 +4,10 @@
MAXOP 5;
LABEL_STARTER '.';
{
int plus(const char *, const char *, const char *);
}
%%;
X, Y, Z { TRUE };

View file

@ -6,6 +6,13 @@ MAXOP 2;
LABEL_STARTER 'I';
OPC_TERMINATOR ' ';
{
int no_side_effects(char *);
int is_register(char *);
int is_scratchreg(char *);
int carry_dead(char *);
}
%%;
/* useful addressing modes: */

View file

@ -4,6 +4,13 @@
MAXOP 5;
LABEL_STARTER '.';
{
int not_using_sp(const char *);
int positive(const char *);
int lift(const char *);
int plus(const char *, const char *, const char *);
}
%%;
L1, L2, L3, L4, L5 { not_using_sp(VAL) };
@ -160,7 +167,7 @@ static int liftcmp(const void *a, const void *b) {
int lift(const char *s) {
return bsearch(&s, liftables,
sizeof(liftables) / sizeof(liftables[0]),
sizeof(liftables[0]), liftcmp);
sizeof(liftables[0]), liftcmp) != NULL;
}

View file

@ -41,14 +41,14 @@ extern void error(char *s, char* s1);
optim_description
{ struct symtab *p; } :
SPACE* parameter_line*
SPACE* parameters
{ p = findident("MAXOP",LOOKING,&deftable);
if (p == 0) maxoperand = 2; /* default */
else maxoperand = p->s_num;
}
separator SPACE* mode_definitions
separator SPACE* patterns
separator
separator SPACE* patterns
separator
{ register int c;
fprintf(genc, linedir, lineno, inpfile);
while ((c = getc(input)) != EOF) {
@ -57,17 +57,25 @@ optim_description
}
;
parameters :
[ parameter_line | declaration_block ]*
;
parameter_line
{ struct symtab *p;} :
{ struct symtab *p;
int lin;
} :
identifier
{ p = findident(idbuf,ENTERING,&deftable);}
SPACE
{ lin = lineno;}
value
{ p->s_num = atoi(buf);}
/* This action in fact only needed for MAXOP */
LINE_TERMINATOR
SPACE*
{ fprintf(genh,"#define %s %s\n",p->s_name,buf);}
{ fprintf(genh, linedir, lin, inpfile);
fprintf(genh,"#define %s %s\n",p->s_name,buf);}
;
value
@ -89,6 +97,27 @@ value
{ *p1 = '\0';}
;
declaration_block :
OPEN_BRACKET
{ fprintf(genh, linedir, lineno, inpfile);}
[
[ LINE_TERMINATOR
| OPERAND_SEPARATOR
| PATTERN_SEPARATOR
| INSTRUCTION_SEPARATOR
| SPACE
| LETTER
| DIGIT
| OTHER
| '%'
]
{ putc(dot.t_attrib, genh);}
]*
CLOSE_BRACKET
SPACE*
{ putc('\n', genh);}
;
mode_definitions
{ int lin; } :
{ fputs("tok_chk(varno) {\n\tint r;\n", genc);