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; MAXOP 5;
LABEL_STARTER '.'; LABEL_STARTER '.';
{
int plus(const char *, const char *, const char *);
}
%%; %%;
X, Y, Z { TRUE }; X, Y, Z { TRUE };

View file

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

View file

@ -4,6 +4,13 @@
MAXOP 5; MAXOP 5;
LABEL_STARTER '.'; 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) }; 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) { int lift(const char *s) {
return bsearch(&s, liftables, return bsearch(&s, liftables,
sizeof(liftables) / sizeof(liftables[0]), 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 optim_description
{ struct symtab *p; } : { struct symtab *p; } :
SPACE* parameter_line* SPACE* parameters
{ p = findident("MAXOP",LOOKING,&deftable); { p = findident("MAXOP",LOOKING,&deftable);
if (p == 0) maxoperand = 2; /* default */ if (p == 0) maxoperand = 2; /* default */
else maxoperand = p->s_num; else maxoperand = p->s_num;
} }
separator SPACE* mode_definitions separator SPACE* mode_definitions
separator SPACE* patterns separator SPACE* patterns
separator separator
{ register int c; { register int c;
fprintf(genc, linedir, lineno, inpfile); fprintf(genc, linedir, lineno, inpfile);
while ((c = getc(input)) != EOF) { while ((c = getc(input)) != EOF) {
@ -57,17 +57,25 @@ optim_description
} }
; ;
parameters :
[ parameter_line | declaration_block ]*
;
parameter_line parameter_line
{ struct symtab *p;} : { struct symtab *p;
int lin;
} :
identifier identifier
{ p = findident(idbuf,ENTERING,&deftable);} { p = findident(idbuf,ENTERING,&deftable);}
SPACE SPACE
{ lin = lineno;}
value value
{ p->s_num = atoi(buf);} { p->s_num = atoi(buf);}
/* This action in fact only needed for MAXOP */ /* This action in fact only needed for MAXOP */
LINE_TERMINATOR LINE_TERMINATOR
SPACE* 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 value
@ -89,6 +97,27 @@ value
{ *p1 = '\0';} { *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 mode_definitions
{ int lin; } : { int lin; } :
{ fputs("tok_chk(varno) {\n\tint r;\n", genc); { fputs("tok_chk(varno) {\n\tint r;\n", genc);