Convert all the things to Unix format.

This commit is contained in:
David Given 2022-07-16 00:02:46 +02:00
parent 020c84db3d
commit 9519588f59
16 changed files with 4274 additions and 4274 deletions

View file

@ -1,4 +1,4 @@
--- ---
AlignAfterOpenBracket: AlwaysBreak AlignAfterOpenBracket: AlwaysBreak
AllowShortFunctionsOnASingleLine: false AllowShortFunctionsOnASingleLine: false
AllowShortLoopsOnASingleLine: false AllowShortLoopsOnASingleLine: false

View file

@ -1,135 +1,135 @@
!File: lint.h !File: lint.h
/*#define LINT 1 *//* if defined, 'lint' is produced */ /*#define LINT 1 *//* if defined, 'lint' is produced */
!File: pathlength.h !File: pathlength.h
#define PATHLENGTH 1024 /* max. length of path to file */ #define PATHLENGTH 1024 /* max. length of path to file */
!File: errout.h !File: errout.h
#define ERROUT STDERR /* file pointer for writing messages */ #define ERROUT STDERR /* file pointer for writing messages */
#define ERR_SHADOW 5 /* a syntax error overshadows error messages #define ERR_SHADOW 5 /* a syntax error overshadows error messages
until ERR_SHADOW symbols have been until ERR_SHADOW symbols have been
accepted without syntax error */ accepted without syntax error */
!File: idfsize.h !File: idfsize.h
#define IDFSIZE 64 /* maximum significant length of an identifier */ #define IDFSIZE 64 /* maximum significant length of an identifier */
!File: numsize.h !File: numsize.h
#define NUMSIZE 256 /* maximum length of a numeric constant */ #define NUMSIZE 256 /* maximum length of a numeric constant */
!File: nparams.h !File: nparams.h
#define NPARAMS 32 /* maximum number of parameters */ #define NPARAMS 32 /* maximum number of parameters */
#define STDC_NPARAMS 31 /* ANSI limit on number of parameters */ #define STDC_NPARAMS 31 /* ANSI limit on number of parameters */
!File: ifdepth.h !File: ifdepth.h
#define IFDEPTH 256 /* maximum number of nested if-constructions */ #define IFDEPTH 256 /* maximum number of nested if-constructions */
!File: density.h !File: density.h
#define DENSITY 3 /* see switch.[ch] for an explanation */ #define DENSITY 3 /* see switch.[ch] for an explanation */
!File: macbuf.h !File: macbuf.h
#define LAPBUF 128 /* initial size of macro replacement buffer */ #define LAPBUF 128 /* initial size of macro replacement buffer */
#define ARGBUF 128 /* initial size of macro parameter buffer(s) */ #define ARGBUF 128 /* initial size of macro parameter buffer(s) */
!File: strsize.h !File: strsize.h
#define ISTRSIZE 32 /* minimum number of bytes allocated for #define ISTRSIZE 32 /* minimum number of bytes allocated for
storing a string */ storing a string */
#define RSTRSIZE 16 /* step size in enlarging the memory for #define RSTRSIZE 16 /* step size in enlarging the memory for
the storage of a string */ the storage of a string */
!File: trgt_sizes.h !File: trgt_sizes.h
#define MAXSIZE 8 /* the maximum of the SZ_* constants */ #define MAXSIZE 8 /* the maximum of the SZ_* constants */
/* target machine sizes */ /* target machine sizes */
#define SZ_CHAR 1 #define SZ_CHAR 1
#define SZ_SHORT 2 #define SZ_SHORT 2
#define SZ_WORD 4 #define SZ_WORD 4
#define SZ_INT 4 #define SZ_INT 4
#define SZ_LONG 4 #define SZ_LONG 4
#define SZ_LNGLNG -1 #define SZ_LNGLNG -1
#define SZ_FLOAT 4 #define SZ_FLOAT 4
#define SZ_DOUBLE 8 #define SZ_DOUBLE 8
#define SZ_LNGDBL 8 /* for now */ #define SZ_LNGDBL 8 /* for now */
#define SZ_POINTER 4 #define SZ_POINTER 4
/* target machine alignment requirements */ /* target machine alignment requirements */
#define AL_CHAR 1 #define AL_CHAR 1
#define AL_SHORT SZ_SHORT #define AL_SHORT SZ_SHORT
#define AL_WORD SZ_WORD #define AL_WORD SZ_WORD
#define AL_INT SZ_WORD #define AL_INT SZ_WORD
#define AL_LONG SZ_WORD #define AL_LONG SZ_WORD
#define AL_LNGLNG SZ_WORD #define AL_LNGLNG SZ_WORD
#define AL_FLOAT SZ_WORD #define AL_FLOAT SZ_WORD
#define AL_DOUBLE SZ_WORD #define AL_DOUBLE SZ_WORD
#define AL_LNGDBL SZ_WORD #define AL_LNGDBL SZ_WORD
#define AL_POINTER SZ_WORD #define AL_POINTER SZ_WORD
#define AL_STRUCT 1 #define AL_STRUCT 1
#define AL_UNION 1 #define AL_UNION 1
!File: botch_free.h !File: botch_free.h
/*#define BOTCH_FREE 1* *//* when defined, botch freed memory, as a check */ /*#define BOTCH_FREE 1* *//* when defined, botch freed memory, as a check */
!File: dataflow.h !File: dataflow.h
#define DATAFLOW 1 /* produce some compile-time xref */ #define DATAFLOW 1 /* produce some compile-time xref */
!File: debug.h !File: debug.h
/*#define DEBUG 1 *//* perform various self-tests */ /*#define DEBUG 1 *//* perform various self-tests */
#define NDEBUG 1 /* disable assertions */ #define NDEBUG 1 /* disable assertions */
!File: use_tmp.h !File: use_tmp.h
#define PREPEND_SCOPES 1 /* collect exa, exp, ina and inp commands #define PREPEND_SCOPES 1 /* collect exa, exp, ina and inp commands
and if USE_TMP is defined let them and if USE_TMP is defined let them
precede the rest of the generated precede the rest of the generated
compact code */ compact code */
#define USE_TMP 1 /* use C_insertpart, C_endpart mechanism #define USE_TMP 1 /* use C_insertpart, C_endpart mechanism
to generate EM-code in the order needed to generate EM-code in the order needed
for the code-generators. If not defined, for the code-generators. If not defined,
the old-style peephole optimizer is the old-style peephole optimizer is
needed. */ needed. */
!File: parbufsize.h !File: parbufsize.h
#define PARBUFSIZE 1024 #define PARBUFSIZE 1024
!File: textsize.h !File: textsize.h
#define ITEXTSIZE 32 /* 1st piece of memory for repl. text */ #define ITEXTSIZE 32 /* 1st piece of memory for repl. text */
!File: inputtype.h !File: inputtype.h
#define INP_READ_IN_ONE 1 /* read input file in one */ #define INP_READ_IN_ONE 1 /* read input file in one */
!File: nobitfield.h !File: nobitfield.h
/*#define NOBITFIELD 1 *//* if NOT defined, implement bitfields */ /*#define NOBITFIELD 1 *//* if NOT defined, implement bitfields */
!File: static.h !File: static.h
#define GSTATIC /* for large global "static" arrays */ #define GSTATIC /* for large global "static" arrays */
!File: nocross.h !File: nocross.h
/*#define NOCROSS 1 *//* if NOT defined, cross compiler */ /*#define NOCROSS 1 *//* if NOT defined, cross compiler */
!File: regcount.h !File: regcount.h
/*#define REGCOUNT 1 *//* count occurrences for register messages */ /*#define REGCOUNT 1 *//* count occurrences for register messages */
!File: dbsymtab.h !File: dbsymtab.h
#define DBSYMTAB 1 /* ability to produce symbol table for debugger */ #define DBSYMTAB 1 /* ability to produce symbol table for debugger */

File diff suppressed because it is too large Load diff

View file

@ -1,354 +1,354 @@
/* /*
* (c) copyright 1987 by the Vrije Universiteit, Amsterdam, The Netherlands. * (c) copyright 1987 by the Vrije Universiteit, Amsterdam, The Netherlands.
* See the copyright notice in the ACK home directory, in the file "Copyright". * See the copyright notice in the ACK home directory, in the file "Copyright".
*/ */
/* $Id$ */ /* $Id$ */
/* EXPRESSION SYNTAX PARSER */ /* EXPRESSION SYNTAX PARSER */
{ {
#include <alloc.h> #include <alloc.h>
#include "parameters.h" #include "parameters.h"
#include <flt_arith.h> #include <flt_arith.h>
#include "arith.h" #include "arith.h"
#include "LLlex.h" #include "LLlex.h"
#include "type.h" #include "type.h"
#include "label.h" #include "label.h"
#include "expr.h" #include "expr.h"
#include "code.h" #include "code.h"
#include "error.h" #include "error.h"
#include "ch3.h" #include "ch3.h"
#include "ch3bin.h" #include "ch3bin.h"
#include "ch3mon.h" #include "ch3mon.h"
#include "proto.h" #include "proto.h"
#include "sizes.h" #include "sizes.h"
extern struct expr *intexpr(); extern struct expr *intexpr();
int InSizeof = 0; /* inside a sizeof- expression */ int InSizeof = 0; /* inside a sizeof- expression */
int ResultKnown = 0; /* result of the expression is already known */ int ResultKnown = 0; /* result of the expression is already known */
/* Since the grammar in the standard is not LL(n), it is modified so that /* Since the grammar in the standard is not LL(n), it is modified so that
* it accepts basically the same grammar. This means that there is no 1-1 * it accepts basically the same grammar. This means that there is no 1-1
* mapping from the grammar in the standard to the grammar given here. * mapping from the grammar in the standard to the grammar given here.
* Such is life. * Such is life.
*/ */
} }
/* 3.3.1 */ /* 3.3.1 */
primary(register struct expr **expp;) : primary(register struct expr **expp;) :
IDENTIFIER IDENTIFIER
{dot2expr(expp);} {dot2expr(expp);}
| |
constant(expp) constant(expp)
| |
string(expp) string(expp)
| |
'(' expression(expp) ')' '(' expression(expp) ')'
{ (*expp)->ex_flags |= EX_PARENS; } { (*expp)->ex_flags |= EX_PARENS; }
; ;
/* Character string literals that are adjacent tokens /* Character string literals that are adjacent tokens
* are concatenated into a single character string * are concatenated into a single character string
* literal. * literal.
*/ */
string(register struct expr **expp;) string(register struct expr **expp;)
{ register int i, len; { register int i, len;
register char *str; register char *str;
register int fund; register int fund;
} }
: :
STRING STRING
{ str = dot.tk_bts; { str = dot.tk_bts;
len = dot.tk_len; len = dot.tk_len;
fund = dot.tk_fund; fund = dot.tk_fund;
} }
[ [
STRING STRING
{ /* A pasted string keeps the type of the first { /* A pasted string keeps the type of the first
* string literal. * string literal.
* The pasting of normal strings and wide * The pasting of normal strings and wide
* character strings are stated as having an * character strings are stated as having an
* undefined behaviour. * undefined behaviour.
*/ */
if (dot.tk_fund != fund) if (dot.tk_fund != fund)
warning("illegal pasting of string literals"); warning("illegal pasting of string literals");
str = Realloc(str, (unsigned) (--len + dot.tk_len)); str = Realloc(str, (unsigned) (--len + dot.tk_len));
for (i = 0; i < dot.tk_len; i++) for (i = 0; i < dot.tk_len; i++)
str[len++] = dot.tk_bts[i]; str[len++] = dot.tk_bts[i];
} }
]* ]*
{ string2expr(expp, str, len); } { string2expr(expp, str, len); }
; ;
/* 3.3.2 */ /* 3.3.2 */
postfix_expression(register struct expr **expp;) postfix_expression(register struct expr **expp;)
{ int oper; { int oper;
struct expr *e1 = 0; struct expr *e1 = 0;
struct idf *idf; struct idf *idf;
} }
: :
primary(expp) primary(expp)
[ [
'[' expression(&e1) ']' '[' expression(&e1) ']'
{ ch3bin(expp, '[', e1); e1 = 0; } { ch3bin(expp, '[', e1); e1 = 0; }
| |
'(' parameter_list(&e1)? ')' '(' parameter_list(&e1)? ')'
{ ch3bin(expp, '(', e1); call_proto(expp); e1 = 0; } { ch3bin(expp, '(', e1); call_proto(expp); e1 = 0; }
| |
[ '.' | ARROW ] { oper = DOT; } [ '.' | ARROW ] { oper = DOT; }
identifier(&idf) { ch3sel(expp, oper, idf); } identifier(&idf) { ch3sel(expp, oper, idf); }
| |
[ [
PLUSPLUS { oper = POSTINCR; } PLUSPLUS { oper = POSTINCR; }
| |
MINMIN { oper = POSTDECR; } MINMIN { oper = POSTDECR; }
] ]
{ ch3incr(expp, oper); } { ch3incr(expp, oper); }
]* ]*
; ;
parameter_list(struct expr **expp;) parameter_list(struct expr **expp;)
{struct expr *e1 = 0;} {struct expr *e1 = 0;}
: :
assignment_expression(expp) assignment_expression(expp)
{any2opnd(expp, PARCOMMA);} {any2opnd(expp, PARCOMMA);}
[ %persistent [ %persistent
',' ','
assignment_expression(&e1) assignment_expression(&e1)
{any2opnd(&e1, PARCOMMA);} {any2opnd(&e1, PARCOMMA);}
{ch3bin(expp, PARCOMMA, e1);} {ch3bin(expp, PARCOMMA, e1);}
]* ]*
; ;
%first first_of_type_specifier, type_specifier; %first first_of_type_specifier, type_specifier;
/* 3.3.3 & 3.3.4 */ /* 3.3.3 & 3.3.4 */
unary(register struct expr **expp;) unary(register struct expr **expp;)
{struct type *tp; int oper;} {struct type *tp; int oper;}
: :
%if (first_of_type_specifier(AHEAD) && AHEAD != IDENTIFIER) %if (first_of_type_specifier(AHEAD) && AHEAD != IDENTIFIER)
cast(&tp) unary(expp) cast(&tp) unary(expp)
{ ch3cast(expp, CAST, tp); { ch3cast(expp, CAST, tp);
(*expp)->ex_flags |= EX_CAST; (*expp)->ex_flags |= EX_CAST;
if (int_size != pointer_size) if (int_size != pointer_size)
(*expp)->ex_flags &= ~EX_PTRDIFF; (*expp)->ex_flags &= ~EX_PTRDIFF;
} }
| |
postfix_expression(expp) postfix_expression(expp)
| |
unop(&oper) unary(expp) unop(&oper) unary(expp)
{ch3mon(oper, expp);} {ch3mon(oper, expp);}
| |
size_of(expp) size_of(expp)
; ;
/* When an identifier is used in a sizeof()-expression, we must stil not /* When an identifier is used in a sizeof()-expression, we must stil not
* mark it as used. * mark it as used.
* extern int i; .... sizeof(i) .... need not have a definition for i * extern int i; .... sizeof(i) .... need not have a definition for i
*/ */
size_of(register struct expr **expp;) size_of(register struct expr **expp;)
{struct type *tp;} {struct type *tp;}
: :
SIZEOF { InSizeof++; } /* handle (sizeof(sizeof(int))) too */ SIZEOF { InSizeof++; } /* handle (sizeof(sizeof(int))) too */
[%if (first_of_type_specifier(AHEAD) && AHEAD != IDENTIFIER) [%if (first_of_type_specifier(AHEAD) && AHEAD != IDENTIFIER)
cast(&tp) cast(&tp)
{ {
*expp = intexpr(size_of_type(tp, "type"), UNSIGNED); *expp = intexpr(size_of_type(tp, "type"), UNSIGNED);
(*expp)->ex_flags |= EX_SIZEOF; (*expp)->ex_flags |= EX_SIZEOF;
} }
| |
unary(expp) unary(expp)
{ch3mon(SIZEOF, expp);} {ch3mon(SIZEOF, expp);}
] ]
{ InSizeof--; } { InSizeof--; }
; ;
/* 3.3.5-3.3.17 */ /* 3.3.5-3.3.17 */
/* The set of operators in C is stratified in 15 levels, with level /* The set of operators in C is stratified in 15 levels, with level
N being treated in RM 7.N (although this is not the standard N being treated in RM 7.N (although this is not the standard
anymore). The standard describes this in phrase-structure-grammar, anymore). The standard describes this in phrase-structure-grammar,
which we are unable to parse. The description that follows comes which we are unable to parse. The description that follows comes
from the old C-compiler. from the old C-compiler.
In principle each operator is assigned a rank, ranging In principle each operator is assigned a rank, ranging
from 1 to 15. Such an expression can be parsed by a construct from 1 to 15. Such an expression can be parsed by a construct
like: like:
binary_expression(int maxrank;) binary_expression(int maxrank;)
{int oper;} {int oper;}
: :
binary_expression(maxrank - 1) binary_expression(maxrank - 1)
[%if (rank_of(DOT) <= maxrank) [%if (rank_of(DOT) <= maxrank)
binop(&oper) binop(&oper)
binary_expression(rank_of(oper)-1) binary_expression(rank_of(oper)-1)
]? ]?
; ;
except that some call of 'unary' is necessary, depending on the except that some call of 'unary' is necessary, depending on the
grammar. grammar.
This simple view is marred by three complications: This simple view is marred by three complications:
1. Level 15 (comma operator) is not allowed in many 1. Level 15 (comma operator) is not allowed in many
contexts and is different. contexts and is different.
2. Level 13 (conditional operator) is a ternary operator, 2. Level 13 (conditional operator) is a ternary operator,
which does not fit this scheme at all. which does not fit this scheme at all.
3. Level 14 (assignment operators) group right-to-left, as 3. Level 14 (assignment operators) group right-to-left, as
opposed to 2-12, which group left-to-right (or are opposed to 2-12, which group left-to-right (or are
immaterial). immaterial).
4. The operators in level 14 start with operators in levels 4. The operators in level 14 start with operators in levels
2-13 (RM 7.14: The two parts of a compound assignment 2-13 (RM 7.14: The two parts of a compound assignment
operator are separate tokens.) This causes LL1 problems. operator are separate tokens.) This causes LL1 problems.
This forces us to have four rules: This forces us to have four rules:
binary_expression for level 2-12 binary_expression for level 2-12
conditional_expression for level 13 conditional_expression for level 13
assignment_expression for level 14 and assignment_expression for level 14 and
expression for the most general expression expression for the most general expression
*/ */
binary_expression(int maxrank; struct expr **expp;) binary_expression(int maxrank; struct expr **expp;)
{int oper, OldResultKnown; struct expr *e1;} {int oper, OldResultKnown; struct expr *e1;}
: :
unary(expp) unary(expp)
[%while (rank_of(DOT) <= maxrank ) [%while (rank_of(DOT) <= maxrank )
/* '?', '=', and ',' are no binops /* '?', '=', and ',' are no binops
*/ */
binop(&oper) binop(&oper)
{ OldResultKnown = ResultKnown; { OldResultKnown = ResultKnown;
if (oper == OR || oper == AND) { if (oper == OR || oper == AND) {
if (is_cp_cst(*expp) || is_fp_cst(*expp)) { if (is_cp_cst(*expp) || is_fp_cst(*expp)) {
if (is_zero_cst(*expp)) { if (is_zero_cst(*expp)) {
if (oper == AND) ResultKnown++; if (oper == AND) ResultKnown++;
} else if (oper == OR) ResultKnown++; } else if (oper == OR) ResultKnown++;
} }
} }
} }
binary_expression(rank_of(oper)-1, &e1) binary_expression(rank_of(oper)-1, &e1)
{ {
ch3bin(expp, oper, e1); ch3bin(expp, oper, e1);
ResultKnown = OldResultKnown; ResultKnown = OldResultKnown;
} }
]* ]*
; ;
/* 3.3.15 */ /* 3.3.15 */
conditional_expression(struct expr **expp;) conditional_expression(struct expr **expp;)
{struct expr *e1 = 0, *e2 = 0; int OldResultKnown, ConstExpr=0;} {struct expr *e1 = 0, *e2 = 0; int OldResultKnown, ConstExpr=0;}
: :
/* allow all binary operators */ /* allow all binary operators */
binary_expression(rank_of('?') - 1, expp) binary_expression(rank_of('?') - 1, expp)
[ '?' [ '?'
{ OldResultKnown = ResultKnown; { OldResultKnown = ResultKnown;
if (is_cp_cst(*expp) || is_fp_cst(*expp)) { if (is_cp_cst(*expp) || is_fp_cst(*expp)) {
ConstExpr++; ConstExpr++;
if (is_zero_cst(*expp)) ResultKnown++; if (is_zero_cst(*expp)) ResultKnown++;
} }
} }
expression(&e1) expression(&e1)
':' ':'
{ if (ConstExpr) { { if (ConstExpr) {
if (OldResultKnown == ResultKnown) ResultKnown++; if (OldResultKnown == ResultKnown) ResultKnown++;
else ResultKnown = OldResultKnown; else ResultKnown = OldResultKnown;
} }
} }
conditional_expression(&e2) conditional_expression(&e2)
{ {
ResultKnown = OldResultKnown; ResultKnown = OldResultKnown;
ch3bin(&e1, ':', e2); ch3bin(&e1, ':', e2);
opnd2test(expp, '?'); opnd2test(expp, '?');
ch3bin(expp, '?', e1); ch3bin(expp, '?', e1);
} }
]? ]?
; ;
/* 3.3.16 */ /* 3.3.16 */
assignment_expression(struct expr **expp;) assignment_expression(struct expr **expp;)
{ int oper; { int oper;
struct expr *e1 = 0; struct expr *e1 = 0;
} }
: :
conditional_expression(expp) conditional_expression(expp)
[ [
asgnop(&oper) asgnop(&oper)
assignment_expression(&e1) assignment_expression(&e1)
{ch3asgn(expp, oper, e1);} {ch3asgn(expp, oper, e1);}
| |
empty /* LLgen artefact ??? */ empty /* LLgen artefact ??? */
] ]
; ;
/* 3.3.17 */ /* 3.3.17 */
expression(struct expr **expp;) expression(struct expr **expp;)
{struct expr *e1;} {struct expr *e1;}
: :
assignment_expression(expp) assignment_expression(expp)
[ ',' [ ','
assignment_expression(&e1) assignment_expression(&e1)
{ {
ch3bin(expp, ',', e1); ch3bin(expp, ',', e1);
} }
]* ]*
; ;
unop(int *oper;) : unop(int *oper;) :
['*' | '&' | '-' | '+' | '!' | '~' | PLUSPLUS | MINMIN] ['*' | '&' | '-' | '+' | '!' | '~' | PLUSPLUS | MINMIN]
{ if (DOT == '&') DOT = ADDRESSOF; { if (DOT == '&') DOT = ADDRESSOF;
*oper = DOT; *oper = DOT;
} }
; ;
multop: multop:
'*' | '/' | '%' '*' | '/' | '%'
; ;
addop: addop:
'+' | '-' '+' | '-'
; ;
shiftop: shiftop:
LEFT | RIGHT LEFT | RIGHT
; ;
relop: relop:
'<' | '>' | LESSEQ | GREATEREQ '<' | '>' | LESSEQ | GREATEREQ
; ;
eqop: eqop:
EQUAL | NOTEQUAL EQUAL | NOTEQUAL
; ;
arithop: arithop:
multop | addop | shiftop multop | addop | shiftop
| |
'&' | '^' | '|' '&' | '^' | '|'
; ;
binop(int *oper;) : binop(int *oper;) :
[ arithop | relop | eqop | AND | OR ] [ arithop | relop | eqop | AND | OR ]
{*oper = DOT;} {*oper = DOT;}
; ;
asgnop(register int *oper;): asgnop(register int *oper;):
[ '=' | PLUSAB | MINAB | TIMESAB | DIVAB | MODAB [ '=' | PLUSAB | MINAB | TIMESAB | DIVAB | MODAB
| LEFTAB | RIGHTAB | ANDAB | XORAB | ORAB ] | LEFTAB | RIGHTAB | ANDAB | XORAB | ORAB ]
{ *oper = DOT; } { *oper = DOT; }
; ;
constant(struct expr **expp;) : constant(struct expr **expp;) :
[ [
INTEGER INTEGER
| |
FLOATING FLOATING
] {dot2expr(expp);} ] {dot2expr(expp);}
; ;
/* 3.4 */ /* 3.4 */
constant_expression (struct expr **expp;) : constant_expression (struct expr **expp;) :
conditional_expression(expp) conditional_expression(expp)
{ chk_cst_expr(expp); } { chk_cst_expr(expp); }
; ;
identifier(struct idf **idfp;) : identifier(struct idf **idfp;) :
[ IDENTIFIER [ IDENTIFIER
| TYPE_IDENTIFIER | TYPE_IDENTIFIER
] ]
{ *idfp = dot.tk_idf; } { *idfp = dot.tk_idf; }
; ;

File diff suppressed because it is too large Load diff

View file

@ -1,227 +1,227 @@
/* /*
* (c) copyright 1987 by the Vrije Universiteit, Amsterdam, The Netherlands. * (c) copyright 1987 by the Vrije Universiteit, Amsterdam, The Netherlands.
* See the copyright notice in the ACK home directory, in the file "Copyright". * See the copyright notice in the ACK home directory, in the file "Copyright".
*/ */
/* $Id$ */ /* $Id$ */
/* PROGRAM PARSER */ /* PROGRAM PARSER */
/* The presence of typedef declarations renders it impossible to /* The presence of typedef declarations renders it impossible to
make a context-free grammar of C. Consequently we need make a context-free grammar of C. Consequently we need
context-sensitive parsing techniques, the simplest one being context-sensitive parsing techniques, the simplest one being
a subtle cooperation between the parser and the lexical scanner. a subtle cooperation between the parser and the lexical scanner.
The lexical scanner has to know whether to return IDENTIFIER The lexical scanner has to know whether to return IDENTIFIER
or TYPE_IDENTIFIER for a given tag, and it obtains this information or TYPE_IDENTIFIER for a given tag, and it obtains this information
from the definition list, as constructed by the parser. from the definition list, as constructed by the parser.
The present grammar is essentially LL(2), and is processed by The present grammar is essentially LL(2), and is processed by
a parser generator which accepts LL(1) with tie breaking rules a parser generator which accepts LL(1) with tie breaking rules
in C, of the form %if(cond) and %while(cond). To solve the LL(1) in C, of the form %if(cond) and %while(cond). To solve the LL(1)
ambiguities, the lexical scanner does a one symbol look-ahead. ambiguities, the lexical scanner does a one symbol look-ahead.
This symbol, however, cannot always be correctly assessed, since This symbol, however, cannot always be correctly assessed, since
the present symbol may cause a change in the definition list the present symbol may cause a change in the definition list
which causes the identification of the look-ahead symbol to be which causes the identification of the look-ahead symbol to be
invalidated. invalidated.
The lexical scanner relies on the parser (or its routines) to The lexical scanner relies on the parser (or its routines) to
detect this situation and then update the look-ahead symbol. detect this situation and then update the look-ahead symbol.
An alternative approach would be to reassess the look-ahead symbol An alternative approach would be to reassess the look-ahead symbol
in the lexical scanner when it is promoted to dot symbol. This in the lexical scanner when it is promoted to dot symbol. This
would be more beautiful but less correct, since then for a short would be more beautiful but less correct, since then for a short
while there would be a discrepancy between the look-ahead symbol while there would be a discrepancy between the look-ahead symbol
and the definition list; I think it would nevertheless work in and the definition list; I think it would nevertheless work in
correct programs. correct programs.
A third solution would be to enter the identifier as soon as it A third solution would be to enter the identifier as soon as it
is found; its storage class is then known, although its full type is found; its storage class is then known, although its full type
isn't. We would have to fill that in afterwards. isn't. We would have to fill that in afterwards.
At block exit the situation is even worse. Upon reading the At block exit the situation is even worse. Upon reading the
closing brace, the names declared inside the function are cleared closing brace, the names declared inside the function are cleared
from the name list. This action may expose a type identifier that from the name list. This action may expose a type identifier that
is the same as the identifier in the look-ahead symbol. This is the same as the identifier in the look-ahead symbol. This
situation certainly invalidates the third solution, and casts situation certainly invalidates the third solution, and casts
doubts upon the second. doubts upon the second.
*/ */
%lexical LLlex; %lexical LLlex;
%start C_program, program; %start C_program, program;
%start If_expr, control_if_expression; %start If_expr, control_if_expression;
{ {
#include "parameters.h" #include "parameters.h"
#include <flt_arith.h> #include <flt_arith.h>
#include "arith.h" #include "arith.h"
#include "LLlex.h" #include "LLlex.h"
#include "label.h" #include "label.h"
#include "type.h" #include "type.h"
#include "declar.h" #include "declar.h"
#include "decspecs.h" #include "decspecs.h"
#include "code.h" #include "code.h"
#include "expr.h" #include "expr.h"
#include "def.h" #include "def.h"
#include "idf.h" #include "idf.h"
#include "declarator.h" #include "declarator.h"
#include "stack.h" #include "stack.h"
#include "proto.h" #include "proto.h"
#include "error.h" #include "error.h"
#ifdef LINT #ifdef LINT
#include "l_lint.h" #include "l_lint.h"
#endif /* LINT */ #endif /* LINT */
} }
control_if_expression control_if_expression
{ {
struct expr *exprX; struct expr *exprX;
} }
: :
constant_expression(&exprX) constant_expression(&exprX)
{ {
} }
; ;
/* 3.7 */ /* 3.7 */
program: program:
[%persistent external_definition]* [%persistent external_definition]*
{ unstack_world(); } { unstack_world(); }
; ;
/* A C identifier definition is remarkable in that it formulates /* A C identifier definition is remarkable in that it formulates
the declaration in a way different from most other languages: the declaration in a way different from most other languages:
e.g., rather than defining x as a pointer-to-integer, it defines e.g., rather than defining x as a pointer-to-integer, it defines
*x as an integer and lets the compiler deduce that x is actually *x as an integer and lets the compiler deduce that x is actually
pointer-to-integer. This has profound consequences, both for the pointer-to-integer. This has profound consequences, both for the
structure of an identifier definition and for the compiler. structure of an identifier definition and for the compiler.
A definition starts with a decl_specifiers, which contains things A definition starts with a decl_specifiers, which contains things
like like
typedef int typedef int
which is implicitly repeated for every definition in the list, and which is implicitly repeated for every definition in the list, and
then for each identifier a declarator is given, of the form then for each identifier a declarator is given, of the form
*a() *a()
or so. The decl_specifiers is kept in a struct decspecs, to be or so. The decl_specifiers is kept in a struct decspecs, to be
used again and again, while the declarator is stored in a struct used again and again, while the declarator is stored in a struct
declarator, only to be passed to declare_idf together with the declarator, only to be passed to declare_idf together with the
struct decspecs. struct decspecs.
With the introduction of prototypes, extra problems for the scope With the introduction of prototypes, extra problems for the scope
administration were introduced as well. We can have, for example, administration were introduced as well. We can have, for example,
int x(double x); int x(double x);
and and
int x(double x) { ... use(x) ... } int x(double x) { ... use(x) ... }
In the first case, the parameter name can be forgotten, whereas in In the first case, the parameter name can be forgotten, whereas in
the second case, the parameter should have a block scope. The the second case, the parameter should have a block scope. The
problem lies in the fact that the parameter's type is known before problem lies in the fact that the parameter's type is known before
the type of the function, which causes the def structure to be on the type of the function, which causes the def structure to be on
the end of the list. Our solution is as follows: the end of the list. Our solution is as follows:
1- In case of a declaration, throw the parameter identifier away 1- In case of a declaration, throw the parameter identifier away
before the declaration of the outer x. before the declaration of the outer x.
2- In case of a definition, the function begin_proc() changes the 2- In case of a definition, the function begin_proc() changes the
def list for the identifier. This means that declare_idf() def list for the identifier. This means that declare_idf()
contains an extra test in case we already saw a declaration of contains an extra test in case we already saw a declaration of
such a function, because this function is called before such a function, because this function is called before
begin_proc(). begin_proc().
*/ */
external_definition external_definition
{ struct decspecs Ds; { struct decspecs Ds;
struct declarator Dc; struct declarator Dc;
} }
: :
{ Ds = null_decspecs; { Ds = null_decspecs;
Dc = null_declarator; Dc = null_declarator;
} }
[ %if (DOT != IDENTIFIER || AHEAD == IDENTIFIER) [ %if (DOT != IDENTIFIER || AHEAD == IDENTIFIER)
decl_specifiers(&Ds) decl_specifiers(&Ds)
| |
{do_decspecs(&Ds);} {do_decspecs(&Ds);}
] ]
[ [
declarator(&Dc) declarator(&Dc)
{ {
declare_idf(&Ds, &Dc, level); declare_idf(&Ds, &Dc, level);
#ifdef LINT #ifdef LINT
lint_ext_def(Dc.dc_idf, Ds.ds_sc); lint_ext_def(Dc.dc_idf, Ds.ds_sc);
#endif /* LINT */ #endif /* LINT */
} }
[ [
function(&Ds, &Dc) function(&Ds, &Dc)
| |
{ if (! Ds.ds_sc_given && ! Ds.ds_typequal && { if (! Ds.ds_sc_given && ! Ds.ds_typequal &&
Ds.ds_notypegiven) { Ds.ds_notypegiven) {
strict("declaration specifiers missing"); strict("declaration specifiers missing");
} }
} }
non_function(&Ds, &Dc) non_function(&Ds, &Dc)
] ]
| |
{ if (! Ds.ds_sc_given && ! Ds.ds_typequal && { if (! Ds.ds_sc_given && ! Ds.ds_typequal &&
Ds.ds_notypegiven) { Ds.ds_notypegiven) {
strict("declaration missing"); strict("declaration missing");
} }
} }
';' ';'
] ]
{remove_declarator(&Dc); flush_strings(); } {remove_declarator(&Dc); flush_strings(); }
; ;
non_function(register struct decspecs *ds; register struct declarator *dc;) non_function(register struct decspecs *ds; register struct declarator *dc;)
: :
{ reject_params(dc); { reject_params(dc);
} }
[ [
initializer(dc->dc_idf, ds->ds_sc) initializer(dc->dc_idf, ds->ds_sc)
| |
{ code_declaration(dc->dc_idf, (struct expr *) 0, level, ds->ds_sc); } { code_declaration(dc->dc_idf, (struct expr *) 0, level, ds->ds_sc); }
] ]
{ {
#ifdef LINT #ifdef LINT
lint_non_function_decl(ds, dc); lint_non_function_decl(ds, dc);
#endif /* LINT */ #endif /* LINT */
} }
[ [
',' ','
init_declarator(ds) init_declarator(ds)
]* ]*
';' ';'
; ;
/* 3.7.1 */ /* 3.7.1 */
function(struct decspecs *ds; struct declarator *dc;) function(struct decspecs *ds; struct declarator *dc;)
{ {
arith fbytes; arith fbytes;
register struct idf *idf = dc->dc_idf; register struct idf *idf = dc->dc_idf;
} }
: :
{ {
#ifdef LINT #ifdef LINT
lint_start_function(); lint_start_function();
#endif /* LINT */ #endif /* LINT */
idf_initialized(idf); idf_initialized(idf);
stack_level(); /* L_FORMAL1 declarations */ stack_level(); /* L_FORMAL1 declarations */
declare_params(dc); declare_params(dc);
begin_proc(ds, idf); /* sets global function info */ begin_proc(ds, idf); /* sets global function info */
stack_level(); /* L_FORMAL2 declarations */ stack_level(); /* L_FORMAL2 declarations */
declare_protos(dc); declare_protos(dc);
} }
declaration* declaration*
{ {
check_formals(idf, dc); /* check style-mixtures */ check_formals(idf, dc); /* check style-mixtures */
declare_formals(idf, &fbytes); declare_formals(idf, &fbytes);
#ifdef LINT #ifdef LINT
lint_formals(); lint_formals();
#endif /* LINT */ #endif /* LINT */
} }
compound_statement compound_statement
{ {
end_proc(fbytes); end_proc(fbytes);
#ifdef LINT #ifdef LINT
lint_implicit_return(); lint_implicit_return();
#endif /* LINT */ #endif /* LINT */
unstack_level(); /* L_FORMAL2 declarations */ unstack_level(); /* L_FORMAL2 declarations */
#ifdef LINT #ifdef LINT
lint_end_formals(); lint_end_formals();
#endif /* LINT */ #endif /* LINT */
unstack_level(); /* L_FORMAL1 declarations */ unstack_level(); /* L_FORMAL1 declarations */
#ifdef LINT #ifdef LINT
lint_end_function(); lint_end_function();
#endif /* LINT */ #endif /* LINT */
} }
; ;

File diff suppressed because it is too large Load diff

View file

@ -1,16 +1,16 @@
default: default:
if (tok <= 0) return "end of file"; if (tok <= 0) return "end of file";
if (tok < 040 || tok >= 0177) { if (tok < 040 || tok >= 0177) {
return "bad token"; return "bad token";
} }
/* fall through */ /* fall through */
case '\n': case '\n':
case '\f': case '\f':
case '\v': case '\v':
case '\r': case '\r':
case '\t': case '\t':
index = (index+2) & (SIZBUF-1); index = (index+2) & (SIZBUF-1);
buf[index] = tok; buf[index] = tok;
return &buf[index]; return &buf[index];
} }
} }

View file

@ -1,12 +1,12 @@
/* Generated by make.tokcase */ /* Generated by make.tokcase */
/* $Id$ */ /* $Id$ */
#include "Lpars.h" #include "Lpars.h"
char *symbol2str(int tok) char *symbol2str(int tok)
{ {
#define SIZBUF 8 #define SIZBUF 8
/* allow for a few invocations in f.i. an argument list */ /* allow for a few invocations in f.i. an argument list */
static char buf[SIZBUF]; static char buf[SIZBUF];
static int index; static int index;
switch (tok) { switch (tok) {

View file

@ -1,13 +1,13 @@
L_ACK_MODULES_ALLOC = { L_ACK_MODULES_ALLOC = {
$PWD/Malloc.c, $PWD/Malloc.c,
$PWD/Salloc.c, $PWD/Salloc.c,
$PWD/Srealloc.c, $PWD/Srealloc.c,
$PWD/Realloc.c, $PWD/Realloc.c,
$PWD/botch.c, $PWD/botch.c,
$PWD/clear.c, $PWD/clear.c,
$PWD/st_alloc.c, $PWD/st_alloc.c,
$PWD/std_alloc.c, $PWD/std_alloc.c,
$PWD/No_Mem.c, $PWD/No_Mem.c,
$PWD/alloc.h $PWD/alloc.h
}; };

View file

@ -1,80 +1,80 @@
.TH ALLOC 3 "$Revision$" .TH ALLOC 3 "$Revision$"
.ad .ad
.SH NAME .SH NAME
Malloc, Salloc, Realloc, Srealloc, st_alloc, st_free\ \-\ low level memory allocation routines Malloc, Salloc, Realloc, Srealloc, st_alloc, st_free\ \-\ low level memory allocation routines
.SH SYNOPSIS .SH SYNOPSIS
.B #include <alloc.h> .B #include <alloc.h>
.PP .PP
.B char *Malloc(unsigned int size) .B char *Malloc(unsigned int size)
.PP .PP
.B char *Salloc(char *str, unsigned int size) .B char *Salloc(char *str, unsigned int size)
.PP .PP
.B char *Realloc(char *buf, unsigned int size) .B char *Realloc(char *buf, unsigned int size)
.PP .PP
.B char *Srealloc(char *str, unsigned int size) .B char *Srealloc(char *str, unsigned int size)
.PP .PP
.B char *st_alloc(char **phead, unsigned int size, int count) .B char *st_alloc(char **phead, unsigned int size, int count)
.PP .PP
.B st_free(char *ptr, char **phead, unsigned int size) .B st_free(char *ptr, char **phead, unsigned int size)
.PP .PP
.B void clear(char *ptr, unsigned int size) .B void clear(char *ptr, unsigned int size)
.PP .PP
.void No_Mem() .void No_Mem()
.PP .PP
.SH DESCRIPTION .SH DESCRIPTION
This set of routines provides a checking memory allocation mechanism. This set of routines provides a checking memory allocation mechanism.
.PP .PP
\fIMalloc\fR returns a pointer to a block of at least \fIsize\fR \fIMalloc\fR returns a pointer to a block of at least \fIsize\fR
bytes, beginning on a boundary suitable for any data type. bytes, beginning on a boundary suitable for any data type.
.PP .PP
\fISalloc\fR returns a pointer to a block of at least \fIsize\fR \fISalloc\fR returns a pointer to a block of at least \fIsize\fR
bytes, initialized with the null-terminated string \fIstr\fR. bytes, initialized with the null-terminated string \fIstr\fR.
.PP .PP
\fIRealloc\fR changes the size of \fIRealloc\fR changes the size of
the block at \fIbuf\fR to \fIsize\fR bytes, and returns a pointer to the the block at \fIbuf\fR to \fIsize\fR bytes, and returns a pointer to the
(possibly moved) block. If \fIbuf\fP is a null pointer, \fIRealloc\fP (possibly moved) block. If \fIbuf\fP is a null pointer, \fIRealloc\fP
behaves as \fIMalloc\fP. behaves as \fIMalloc\fP.
.PP .PP
\fISrealloc\fR reallocates \fISrealloc\fR reallocates
the string at \fIstr\fR to \fIsize\fR bytes. the string at \fIstr\fR to \fIsize\fR bytes.
It actually does the same as \fIRealloc\fP, and exists only for It actually does the same as \fIRealloc\fP, and exists only for
backwards compatibility. backwards compatibility.
.PP .PP
All these routines use \fImalloc\fR and \fIrealloc\fR. All these routines use \fImalloc\fR and \fIrealloc\fR.
The routine \fIfree\fR can be used on pointers returned by these routines. The routine \fIfree\fR can be used on pointers returned by these routines.
.PP .PP
\fISt_alloc\fR and \fIst_free\fR provide a mechanism for maintaining free lists \fISt_alloc\fR and \fIst_free\fR provide a mechanism for maintaining free lists
of structures. of structures.
\fISt_alloc\fR takes three parameters: \fIphead\fR is a pointer to a field \fISt_alloc\fR takes three parameters: \fIphead\fR is a pointer to a field
containing the head of the free list, \fIsize\fR contains the size of the containing the head of the free list, \fIsize\fR contains the size of the
structures, and \fIcount\fR indicates how many new structures must be allocated structures, and \fIcount\fR indicates how many new structures must be allocated
in case the free list is exhausted. in case the free list is exhausted.
It returns a pointer to a zero-initialized structure. It returns a pointer to a zero-initialized structure.
\fISt_free\fR also takes three parameters: \fIptr\fR is a pointer to \fISt_free\fR also takes three parameters: \fIptr\fR is a pointer to
the structure to be freed, \fIphead\fR is again a pointer to a field the structure to be freed, \fIphead\fR is again a pointer to a field
containing the head of the free list, and \fIsize\fR again contains the size containing the head of the free list, and \fIsize\fR again contains the size
of the structures. of the structures.
These last two routines are best used in a macro. These last two routines are best used in a macro.
.PP .PP
\fIclear\fR clears \fIsize\fR bytes, starting at \fIptr\fR. \fIclear\fR clears \fIsize\fR bytes, starting at \fIptr\fR.
.SH FILES .SH FILES
.nf .nf
~em/modules/h/alloc.h ~em/modules/h/alloc.h
~em/modules/lib/liballoc.a ~em/modules/lib/liballoc.a
.fi .fi
.SH "SEE ALSO" .SH "SEE ALSO"
malloc(3) malloc(3)
.SH DIAGNOSTICS .SH DIAGNOSTICS
\fIMalloc\fR, \fISalloc\fR, \fIRealloc\fP, \fISrealloc\fR, and \fIst_alloc\fR \fIMalloc\fR, \fISalloc\fR, \fIRealloc\fP, \fISrealloc\fR, and \fIst_alloc\fR
call a routine \fINo_Mem\fR if there is no memory available. This routine call a routine \fINo_Mem\fR if there is no memory available. This routine
is not supposed to return. A default one, that is not supposed to return. A default one, that
gives an error message and stops execution, is provided. gives an error message and stops execution, is provided.
.SH BUGS .SH BUGS
The The
.I st_alloc .I st_alloc
mechanism only works for structures that are large enough to contain one mechanism only works for structures that are large enough to contain one
pointer. pointer.
Also, Also,
.I st_free .I st_free
actually is a macro, and references its arguments more than once, so they actually is a macro, and references its arguments more than once, so they
better not have side-effects. better not have side-effects.

View file

@ -1,116 +1,116 @@
# #
.sect .text .sect .text
.sect .rom .sect .rom
.sect .data .sect .data
.sect .bss .sect .bss
.sect .text .sect .text
bdos: ! BDOS entry point bdos: ! BDOS entry point
out 0xff out 0xff
ora a ora a
ret ret
COLDSTART: ! system startup entry point --- this needs to be four bytes after FBASE. COLDSTART: ! system startup entry point --- this needs to be four bytes after FBASE.
jmp boot ! 0: Cold start routine jmp boot ! 0: Cold start routine
bios: bios:
jmp wboot ! 1: Warm boot - reload command processor jmp wboot ! 1: Warm boot - reload command processor
jmp const ! 2: Console status jmp const ! 2: Console status
jmp conin ! 3: Console input jmp conin ! 3: Console input
jmp conout ! 4: Console output jmp conout ! 4: Console output
jmp list ! 5: Printer output jmp list ! 5: Printer output
jmp punch ! 6: Paper tape punch output jmp punch ! 6: Paper tape punch output
jmp reader ! 7: Paper tape reader input jmp reader ! 7: Paper tape reader input
jmp home ! 8: Move disc head to track 0 jmp home ! 8: Move disc head to track 0
jmp seldsk ! 9: Select disc drive jmp seldsk ! 9: Select disc drive
jmp settrk !10: Set track number jmp settrk !10: Set track number
jmp setsec !11: Set sector number jmp setsec !11: Set sector number
jmp setdma !12: Set DMA address jmp setdma !12: Set DMA address
jmp read !13: Read a sector jmp read !13: Read a sector
jmp write !14: Write a sector jmp write !14: Write a sector
boot: boot:
xra a xra a
sta 3 ! iobyte sta 3 ! iobyte
sta 4 ! drive sta 4 ! drive
! falls through ! falls through
wboot: wboot:
mvi a, 0xc3 ! jmp mvi a, 0xc3 ! jmp
sta 0 sta 0
sta 5 sta 5
lxi h, bios lxi h, bios
shld 1 shld 1
lxi h, bdos lxi h, bdos
shld 6 shld 6
lda 4 ! get the current drive/user lda 4 ! get the current drive/user
mov c, a mov c, a
out 1 out 1
const: const:
out 2 out 2
ora a ora a
ret ret
conin: conin:
out 3 out 3
ora a ora a
ret ret
conout: conout:
out 4 out 4
ora a ora a
ret ret
list: list:
out 5 out 5
ora a ora a
ret ret
punch: punch:
out 6 out 6
ora a ora a
ret ret
reader: reader:
out 7 out 7
ora a ora a
ret ret
home: home:
out 8 out 8
ora a ora a
ret ret
seldsk: seldsk:
out 9 out 9
ora a ora a
ret ret
settrk: settrk:
out 10 out 10
ora a ora a
ret ret
setsec: setsec:
out 11 out 11
ora a ora a
ret ret
setdma: setdma:
out 12 out 12
ora a ora a
ret ret
read: read:
out 13 out 13
ora a ora a
ret ret
write: write:
out 14 out 14
ora a ora a
ret ret

File diff suppressed because it is too large Load diff

View file

@ -1,15 +1,15 @@
#ifndef SIM__HEADER #ifndef SIM__HEADER
#define SIM__HEADER #define SIM__HEADER
unsigned int cpu_read_byte(unsigned int address); unsigned int cpu_read_byte(unsigned int address);
unsigned int cpu_read_word(unsigned int address); unsigned int cpu_read_word(unsigned int address);
unsigned int cpu_read_long(unsigned int address); unsigned int cpu_read_long(unsigned int address);
void cpu_write_byte(unsigned int address, unsigned int value); void cpu_write_byte(unsigned int address, unsigned int value);
void cpu_write_word(unsigned int address, unsigned int value); void cpu_write_word(unsigned int address, unsigned int value);
void cpu_write_long(unsigned int address, unsigned int value); void cpu_write_long(unsigned int address, unsigned int value);
void cpu_pulse_reset(void); void cpu_pulse_reset(void);
void cpu_set_fc(unsigned int fc); void cpu_set_fc(unsigned int fc);
int cpu_irq_ack(int level); int cpu_irq_ack(int level);
void cpu_instr_callback(int pc); void cpu_instr_callback(int pc);
#endif /* SIM__HEADER */ #endif /* SIM__HEADER */

View file

@ -1,45 +1,45 @@
Following is a repost of the public domain 'make' that I posted Following is a repost of the public domain 'make' that I posted
to net.sources a couple of months ago. I have fixed a few bugs, and to net.sources a couple of months ago. I have fixed a few bugs, and
added some more features, and the resulting changes amounted to added some more features, and the resulting changes amounted to
about as much text as the whole program (hence the repost). about as much text as the whole program (hence the repost).
For those that missed the net.sources posting, this is a public domain For those that missed the net.sources posting, this is a public domain
re-implementation of the UNIX make program. There is no manual included; re-implementation of the UNIX make program. There is no manual included;
for documentation, refer to a UNIX manual, or the source. for documentation, refer to a UNIX manual, or the source.
Here is a list of the changes made: Here is a list of the changes made:
i) If '-' (ignore) or '@' (silent) where used at the start i) If '-' (ignore) or '@' (silent) where used at the start
of a command, their effect was not turned off for the following of a command, their effect was not turned off for the following
commands. commands.
ii) A special target (.SUFFIXES, .PRECIOUS) or a rule (.c.o, .a.o), ii) A special target (.SUFFIXES, .PRECIOUS) or a rule (.c.o, .a.o),
if first in the file would be taken as the default target. if first in the file would be taken as the default target.
This resulted in error messages like "Don't know how to This resulted in error messages like "Don't know how to
make .c", because things like .SUFFIXES were being made. make .c", because things like .SUFFIXES were being made.
This was further complicated by --- This was further complicated by ---
iii) Special target lines with no dependents (ie. .SUFFIXES:\n) iii) Special target lines with no dependents (ie. .SUFFIXES:\n)
were not clearing out the existing dependents like were not clearing out the existing dependents like
they should. they should.
iv) Default rules could not be redefined because of the error iv) Default rules could not be redefined because of the error
checking for commands being defined twice. Now you are checking for commands being defined twice. Now you are
allowed to define a target beinging with '.', having allowed to define a target beinging with '.', having
no dependents with commands. no dependents with commands.
v) The -q option didn't do the time comparison correctly, v) The -q option didn't do the time comparison correctly,
or clear the variable used to keep track of this. Thus or clear the variable used to keep track of this. Thus
it didn't work very well. it didn't work very well.
vi) The syntax ${..} for macro's supported by UNIX make was vi) The syntax ${..} for macro's supported by UNIX make was
not supported. not supported.
vii) There wuz a couple of spelling errors. vii) There wuz a couple of spelling errors.
viii) When make checked for implicit rules on targets without viii) When make checked for implicit rules on targets without
a suffix, there were problems. (Note: The ~ feature of a suffix, there were problems. (Note: The ~ feature of
UNIX make wasn't and still isn't supported) UNIX make wasn't and still isn't supported)
ix) The -n option did not print @ lines like it was supposed to. ix) The -n option did not print @ lines like it was supposed to.
x) :: added. (See UNIX manual) x) :: added. (See UNIX manual)
xi) $? added. (see UNIX manual) xi) $? added. (see UNIX manual)
Hacked further by Ceriel Jacobs to make it work better. Use this "make" to Hacked further by Ceriel Jacobs to make it work better. Use this "make" to
install ACK under Microsoft Xenix V3.2. Some of the makefiles are just too install ACK under Microsoft Xenix V3.2. Some of the makefiles are just too
big for the Xenix "make". Strange, they work on a PDP-11 ... big for the Xenix "make". Strange, they work on a PDP-11 ...
Made it almost ISO C90 and POSIX portable by Carl Eric Codere, and Made it almost ISO C90 and POSIX portable by Carl Eric Codere, and
also made it safer by using correct datatypes on some library calls. also made it safer by using correct datatypes on some library calls.

View file

@ -1,349 +1,349 @@
/* $Id$ */ /* $Id$ */
/* /*
* (c) copyright 1987 by the Vrije Universiteit, Amsterdam, The Netherlands. * (c) copyright 1987 by the Vrije Universiteit, Amsterdam, The Netherlands.
* See the copyright notice in the ACK home directory, in the file "Copyright". * See the copyright notice in the ACK home directory, in the file "Copyright".
*/ */
/* t o p g e n . g /* t o p g e n . g
* *
* Grammar of optimizer description, and some code generation * Grammar of optimizer description, and some code generation
*/ */
%token LETTER, DIGIT, OTHER, SPACE; %token LETTER, DIGIT, OTHER, SPACE;
%token LINE_TERMINATOR, OPERAND_SEPARATOR, INSTRUCTION_SEPARATOR, %token LINE_TERMINATOR, OPERAND_SEPARATOR, INSTRUCTION_SEPARATOR,
PATTERN_SEPARATOR, OPEN_BRACKET, CLOSE_BRACKET; PATTERN_SEPARATOR, OPEN_BRACKET, CLOSE_BRACKET;
%lexical LLlex; %lexical LLlex;
%start LLparse, optim_description; %start LLparse, optim_description;
{ {
#include <stdlib.h> #include <stdlib.h>
#include <stdio.h> #include <stdio.h>
#include <string.h> #include <string.h>
#include "token.h" #include "token.h"
#include "symtab.h" #include "symtab.h"
#include "misc.h" #include "misc.h"
#include "hash.h" #include "hash.h"
#include "pattern.h" #include "pattern.h"
char idbuf[BUFSIZ], buf[BUFSIZ]; char idbuf[BUFSIZ], buf[BUFSIZ];
int countid; /* # of variables */ int countid; /* # of variables */
int countpat; /* # of patterns */ int countpat; /* # of patterns */
static int patlen; /* Maximum number of instructions in pattern */ static int patlen; /* Maximum number of instructions in pattern */
static int maxoperand; /* Maximum number of operands of instruction */ static int maxoperand; /* Maximum number of operands of instruction */
extern FILE *input; /* file descriptor of inputfile */ extern FILE *input; /* file descriptor of inputfile */
extern int onlyspace(char* s); extern int onlyspace(char* s);
extern void error(char *s, char* s1); extern void error(char *s, char* s1);
} }
optim_description optim_description
{ struct symtab *p; } : { struct symtab *p; } :
SPACE* parameters 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) {
putc(c,genc); putc(c,genc);
} }
} }
; ;
parameters : parameters :
[ parameter_line | declaration_block ]* [ parameter_line | declaration_block ]*
; ;
parameter_line parameter_line
{ struct symtab *p; { struct symtab *p;
int lin; int lin;
} : } :
identifier identifier
{ p = findident(idbuf,ENTERING,&deftable);} { p = findident(idbuf,ENTERING,&deftable);}
SPACE SPACE
{ lin = lineno;} { 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, linedir, lin, inpfile); { fprintf(genh, linedir, lin, inpfile);
fprintf(genh,"#define %s %s\n",p->s_name,buf);} fprintf(genh,"#define %s %s\n",p->s_name,buf);}
; ;
value value
{ char *p1 = buf;} : { char *p1 = buf;} :
[ [
[ OPEN_BRACKET [ OPEN_BRACKET
| CLOSE_BRACKET | CLOSE_BRACKET
| OPERAND_SEPARATOR | OPERAND_SEPARATOR
| PATTERN_SEPARATOR | PATTERN_SEPARATOR
| INSTRUCTION_SEPARATOR | INSTRUCTION_SEPARATOR
| SPACE | SPACE
| LETTER | LETTER
| DIGIT | DIGIT
| OTHER | OTHER
| '%' | '%'
] ]
{ *p1++ = dot.t_attrib;} { *p1++ = dot.t_attrib;}
]* ]*
{ *p1 = '\0';} { *p1 = '\0';}
; ;
declaration_block : declaration_block :
OPEN_BRACKET OPEN_BRACKET
{ fprintf(genh, linedir, lineno, inpfile);} { fprintf(genh, linedir, lineno, inpfile);}
[ [
[ LINE_TERMINATOR [ LINE_TERMINATOR
| OPERAND_SEPARATOR | OPERAND_SEPARATOR
| PATTERN_SEPARATOR | PATTERN_SEPARATOR
| INSTRUCTION_SEPARATOR | INSTRUCTION_SEPARATOR
| SPACE | SPACE
| LETTER | LETTER
| DIGIT | DIGIT
| OTHER | OTHER
| '%' | '%'
] ]
{ putc(dot.t_attrib, genh);} { putc(dot.t_attrib, genh);}
]* ]*
CLOSE_BRACKET CLOSE_BRACKET
SPACE* SPACE*
{ putc('\n', genh);} { putc('\n', genh);}
; ;
mode_definitions mode_definitions
{ int lin; } : { int lin; } :
{ fputs("int tok_chk(int varno) {\n\tint r;\n", genc); { fputs("int tok_chk(int varno) {\n\tint r;\n", genc);
fputs("\tchar *VAL;\n\n",genc); fputs("\tchar *VAL;\n\n",genc);
fputs("\tVAL = var[varno].value;\n",genc); fputs("\tVAL = var[varno].value;\n",genc);
fputs("\tswitch(varno) {\n",genc); fputs("\tswitch(varno) {\n",genc);
} }
[ [
token_list token_list
constraint(&lin) constraint(&lin)
{ fprintf(genc,linedir,lin,inpfile); { fprintf(genc,linedir,lin,inpfile);
fprintf(genc,"\t\tr = (%s); break;\n",buf); fprintf(genc,"\t\tr = (%s); break;\n",buf);
} }
LINE_TERMINATOR LINE_TERMINATOR
SPACE* SPACE*
]* ]*
{ fputs("\tdefault :\n\t\tassert(0);\n",genc); { fputs("\tdefault :\n\t\tassert(0);\n",genc);
fputs("\t}\n\treturn r;\n}\n\n",genc); fputs("\t}\n\treturn r;\n}\n\n",genc);
} }
; ;
token_list : token_list :
new_identifier new_identifier
SPACE* SPACE*
[ [
OPERAND_SEPARATOR OPERAND_SEPARATOR
SPACE* SPACE*
new_identifier new_identifier
SPACE* SPACE*
]* ]*
; ;
new_identifier new_identifier
{ struct symtab *p;} : { struct symtab *p;} :
identifier identifier
{ p = findident(idbuf,ENTERING,&idtable); { p = findident(idbuf,ENTERING,&idtable);
p->s_num = ++countid; p->s_num = ++countid;
fprintf(genc,"\tcase %d:\n", countid); fprintf(genc,"\tcase %d:\n", countid);
} }
; ;
constraint (int *lin;) constraint (int *lin;)
{ char *p = buf; } : { char *p = buf; } :
OPEN_BRACKET OPEN_BRACKET
{ *lin = lineno;} { *lin = lineno;}
[ [
[ LINE_TERMINATOR [ LINE_TERMINATOR
| OPERAND_SEPARATOR | OPERAND_SEPARATOR
| PATTERN_SEPARATOR | PATTERN_SEPARATOR
| INSTRUCTION_SEPARATOR | INSTRUCTION_SEPARATOR
| LETTER | LETTER
| DIGIT | DIGIT
| SPACE | SPACE
| OTHER | OTHER
| '%' | '%'
] ]
{ *p++ = dot.t_attrib;} { *p++ = dot.t_attrib;}
]* ]*
{ *p = '\0'; { *p = '\0';
if (onlyspace(buf)) strcpy(buf,"TRUE"); if (onlyspace(buf)) strcpy(buf,"TRUE");
} }
CLOSE_BRACKET CLOSE_BRACKET
SPACE* SPACE*
; ;
patterns patterns
{ int lin; { int lin;
char *constr; char *constr;
int np, nr; int np, nr;
} : } :
[ [
{ countpat++; { countpat++;
constr = (char *) 0; constr = (char *) 0;
fprintf(genc,"struct instr_descr pat%d[] = {\n", fprintf(genc,"struct instr_descr pat%d[] = {\n",
countpat); countpat);
} }
instruction_list(&np) instruction_list(&np)
{ if (np > patlen) patlen = np; { if (np > patlen) patlen = np;
fputs("\n};\n\n",genc); fputs("\n};\n\n",genc);
} }
[ [
constraint(&lin) constraint(&lin)
{ /* Save the constraint, we need it later on */ { /* Save the constraint, we need it later on */
constr = malloc((unsigned)(strlen(buf)+1)); constr = malloc((unsigned)(strlen(buf)+1));
strcpy(constr,buf); strcpy(constr,buf);
} }
]? ]?
PATTERN_SEPARATOR PATTERN_SEPARATOR
{ fprintf(genc,"struct instr_descr rep%d[] = {\n", { fprintf(genc,"struct instr_descr rep%d[] = {\n",
countpat); countpat);
} }
replacement(&nr) replacement(&nr)
{ fputs("\n};\n\n",genc);} { fputs("\n};\n\n",genc);}
LINE_TERMINATOR LINE_TERMINATOR
SPACE* SPACE*
{ addpattern(constr,lin,np,nr);} { addpattern(constr,lin,np,nr);}
]* ]*
{ printhashtable(); { printhashtable();
printpatterns(); printpatterns();
fprintf(genh,"#define NRVARS %d\n",countid); fprintf(genh,"#define NRVARS %d\n",countid);
fprintf(genh,"#define NRPATTERNS %d\n",countpat); fprintf(genh,"#define NRPATTERNS %d\n",countpat);
fprintf(genh,"#define MIN_WINDOW_SIZE %d\n", fprintf(genh,"#define MIN_WINDOW_SIZE %d\n",
patlen+3); patlen+3);
fclose(genh); fclose(genh);
} }
; ;
instruction_list(int *n;) : instruction_list(int *n;) :
instruction(1) instruction(1)
{ *n = 1;} { *n = 1;}
[ [
INSTRUCTION_SEPARATOR INSTRUCTION_SEPARATOR
{ fputs(",\n",genc);} { fputs(",\n",genc);}
SPACE* SPACE*
instruction(0) instruction(0)
{ *n += 1;} { *n += 1;}
]* ]*
; ;
instruction(int opt;) instruction(int opt;)
{ int count = 0;} : { int count = 0;} :
opcode(opt) opcode(opt)
{ if (strcmp(buf,"ANY") != 0) { { if (strcmp(buf,"ANY") != 0) {
fprintf(genc,"\t{\"%s\", {",buf); fprintf(genc,"\t{\"%s\", {",buf);
} }
else fputs("\t{(char *) 0, {",genc); else fputs("\t{(char *) 0, {",genc);
count = 0; count = 0;
} }
[ [
operand(' ') operand(' ')
{ count = 1;} { count = 1;}
[ [
OPERAND_SEPARATOR OPERAND_SEPARATOR
{ count++;} { count++;}
SPACE* SPACE*
operand(',') operand(',')
]* ]*
{ if (count > maxoperand) { { if (count > maxoperand) {
error("Too many operands",""); error("Too many operands","");
} }
} }
]? ]?
{ while (count++ < maxoperand) { { while (count++ < maxoperand) {
fprintf(genc,"%c{\"\",-1,\"\"}",count == 1 ? ' ' : ','); fprintf(genc,"%c{\"\",-1,\"\"}",count == 1 ? ' ' : ',');
} }
putc('}',genc); putc('}',genc);
putc('}',genc); putc('}',genc);
} }
; ;
opcode(int opt;) opcode(int opt;)
{ char *p = buf;} : { char *p = buf;} :
[ [
[ LETTER [ LETTER
| DIGIT | DIGIT
| OTHER | OTHER
] ]
{ *p++ = dot.t_attrib;} { *p++ = dot.t_attrib;}
]+ ]+
SPACE+ SPACE+
{ *p = '\0'; { *p = '\0';
if (opt) addtohashtable(buf,countpat); if (opt) addtohashtable(buf,countpat);
} }
; ;
operand(int c;) operand(int c;)
{ register struct symtab *p = 0;} : { register struct symtab *p = 0;} :
{ fprintf(genc, "%c{\"", c);} { fprintf(genc, "%c{\"", c);}
[ [
identifier identifier
{ if (!p) { { if (!p) {
p = findident(idbuf,LOOKING,&idtable); p = findident(idbuf,LOOKING,&idtable);
if (p) fprintf(genc,"\",%d,\"",p->s_num); if (p) fprintf(genc,"\",%d,\"",p->s_num);
else fputs(idbuf,genc); else fputs(idbuf,genc);
} }
else fputs(idbuf,genc); else fputs(idbuf,genc);
} }
| DIGIT | DIGIT
{ putc(dot.t_attrib,genc);} { putc(dot.t_attrib,genc);}
| OTHER | OTHER
{ putc(dot.t_attrib,genc);} { putc(dot.t_attrib,genc);}
]+ ]+
{ if (p) fputs("\"}",genc); { if (p) fputs("\"}",genc);
else fputs("\",0,\"\"}",genc); else fputs("\",0,\"\"}",genc);
} }
SPACE* SPACE*
; ;
replacement (int *n;) replacement (int *n;)
{register int i;} : {register int i;} :
SPACE* SPACE*
{ *n = 0;} { *n = 0;}
[ [
instruction(0) instruction(0)
{ *n = 1;} { *n = 1;}
[ [
INSTRUCTION_SEPARATOR INSTRUCTION_SEPARATOR
{ fputs(",\n", genc);} { fputs(",\n", genc);}
SPACE* SPACE*
instruction(0) instruction(0)
{ *n += 1;} { *n += 1;}
]* ]*
| /* empty replacement, but there must be a | /* empty replacement, but there must be a
* structure initializer anyway * structure initializer anyway
*/ */
{ fputs("\t{\"\", {",genc); { fputs("\t{\"\", {",genc);
for (i = 0; i < maxoperand; i++) { for (i = 0; i < maxoperand; i++) {
fprintf(genc, "%c{\"\",-1,\"\"}",i?',':' '); fprintf(genc, "%c{\"\",-1,\"\"}",i?',':' ');
} }
fputs("}}",genc); fputs("}}",genc);
} }
] ]
; ;
identifier identifier
{ char *p = idbuf; } : { char *p = idbuf; } :
LETTER LETTER
{ *p++ = dot.t_attrib;} { *p++ = dot.t_attrib;}
[ %while (1) [ %while (1)
LETTER { *p++ = dot.t_attrib;} LETTER { *p++ = dot.t_attrib;}
| DIGIT { *p++ = dot.t_attrib;} | DIGIT { *p++ = dot.t_attrib;}
]* ]*
{ *p = '\0';} { *p = '\0';}
; ;
separator : separator :
'%' '%' SPACE* LINE_TERMINATOR '%' '%' SPACE* LINE_TERMINATOR
; ;