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
AllowShortFunctionsOnASingleLine: false
AllowShortLoopsOnASingleLine: false

View file

@ -1,135 +1,135 @@
!File: lint.h
/*#define LINT 1 *//* if defined, 'lint' is produced */
!File: pathlength.h
#define PATHLENGTH 1024 /* max. length of path to file */
!File: errout.h
#define ERROUT STDERR /* file pointer for writing messages */
#define ERR_SHADOW 5 /* a syntax error overshadows error messages
until ERR_SHADOW symbols have been
accepted without syntax error */
!File: idfsize.h
#define IDFSIZE 64 /* maximum significant length of an identifier */
!File: numsize.h
#define NUMSIZE 256 /* maximum length of a numeric constant */
!File: nparams.h
#define NPARAMS 32 /* maximum number of parameters */
#define STDC_NPARAMS 31 /* ANSI limit on number of parameters */
!File: ifdepth.h
#define IFDEPTH 256 /* maximum number of nested if-constructions */
!File: density.h
#define DENSITY 3 /* see switch.[ch] for an explanation */
!File: macbuf.h
#define LAPBUF 128 /* initial size of macro replacement buffer */
#define ARGBUF 128 /* initial size of macro parameter buffer(s) */
!File: strsize.h
#define ISTRSIZE 32 /* minimum number of bytes allocated for
storing a string */
#define RSTRSIZE 16 /* step size in enlarging the memory for
the storage of a string */
!File: trgt_sizes.h
#define MAXSIZE 8 /* the maximum of the SZ_* constants */
/* target machine sizes */
#define SZ_CHAR 1
#define SZ_SHORT 2
#define SZ_WORD 4
#define SZ_INT 4
#define SZ_LONG 4
#define SZ_LNGLNG -1
#define SZ_FLOAT 4
#define SZ_DOUBLE 8
#define SZ_LNGDBL 8 /* for now */
#define SZ_POINTER 4
/* target machine alignment requirements */
#define AL_CHAR 1
#define AL_SHORT SZ_SHORT
#define AL_WORD SZ_WORD
#define AL_INT SZ_WORD
#define AL_LONG SZ_WORD
#define AL_LNGLNG SZ_WORD
#define AL_FLOAT SZ_WORD
#define AL_DOUBLE SZ_WORD
#define AL_LNGDBL SZ_WORD
#define AL_POINTER SZ_WORD
#define AL_STRUCT 1
#define AL_UNION 1
!File: botch_free.h
/*#define BOTCH_FREE 1* *//* when defined, botch freed memory, as a check */
!File: dataflow.h
#define DATAFLOW 1 /* produce some compile-time xref */
!File: debug.h
/*#define DEBUG 1 *//* perform various self-tests */
#define NDEBUG 1 /* disable assertions */
!File: use_tmp.h
#define PREPEND_SCOPES 1 /* collect exa, exp, ina and inp commands
and if USE_TMP is defined let them
precede the rest of the generated
compact code */
#define USE_TMP 1 /* use C_insertpart, C_endpart mechanism
to generate EM-code in the order needed
for the code-generators. If not defined,
the old-style peephole optimizer is
needed. */
!File: parbufsize.h
#define PARBUFSIZE 1024
!File: textsize.h
#define ITEXTSIZE 32 /* 1st piece of memory for repl. text */
!File: inputtype.h
#define INP_READ_IN_ONE 1 /* read input file in one */
!File: nobitfield.h
/*#define NOBITFIELD 1 *//* if NOT defined, implement bitfields */
!File: static.h
#define GSTATIC /* for large global "static" arrays */
!File: nocross.h
/*#define NOCROSS 1 *//* if NOT defined, cross compiler */
!File: regcount.h
/*#define REGCOUNT 1 *//* count occurrences for register messages */
!File: dbsymtab.h
#define DBSYMTAB 1 /* ability to produce symbol table for debugger */
!File: lint.h
/*#define LINT 1 *//* if defined, 'lint' is produced */
!File: pathlength.h
#define PATHLENGTH 1024 /* max. length of path to file */
!File: errout.h
#define ERROUT STDERR /* file pointer for writing messages */
#define ERR_SHADOW 5 /* a syntax error overshadows error messages
until ERR_SHADOW symbols have been
accepted without syntax error */
!File: idfsize.h
#define IDFSIZE 64 /* maximum significant length of an identifier */
!File: numsize.h
#define NUMSIZE 256 /* maximum length of a numeric constant */
!File: nparams.h
#define NPARAMS 32 /* maximum number of parameters */
#define STDC_NPARAMS 31 /* ANSI limit on number of parameters */
!File: ifdepth.h
#define IFDEPTH 256 /* maximum number of nested if-constructions */
!File: density.h
#define DENSITY 3 /* see switch.[ch] for an explanation */
!File: macbuf.h
#define LAPBUF 128 /* initial size of macro replacement buffer */
#define ARGBUF 128 /* initial size of macro parameter buffer(s) */
!File: strsize.h
#define ISTRSIZE 32 /* minimum number of bytes allocated for
storing a string */
#define RSTRSIZE 16 /* step size in enlarging the memory for
the storage of a string */
!File: trgt_sizes.h
#define MAXSIZE 8 /* the maximum of the SZ_* constants */
/* target machine sizes */
#define SZ_CHAR 1
#define SZ_SHORT 2
#define SZ_WORD 4
#define SZ_INT 4
#define SZ_LONG 4
#define SZ_LNGLNG -1
#define SZ_FLOAT 4
#define SZ_DOUBLE 8
#define SZ_LNGDBL 8 /* for now */
#define SZ_POINTER 4
/* target machine alignment requirements */
#define AL_CHAR 1
#define AL_SHORT SZ_SHORT
#define AL_WORD SZ_WORD
#define AL_INT SZ_WORD
#define AL_LONG SZ_WORD
#define AL_LNGLNG SZ_WORD
#define AL_FLOAT SZ_WORD
#define AL_DOUBLE SZ_WORD
#define AL_LNGDBL SZ_WORD
#define AL_POINTER SZ_WORD
#define AL_STRUCT 1
#define AL_UNION 1
!File: botch_free.h
/*#define BOTCH_FREE 1* *//* when defined, botch freed memory, as a check */
!File: dataflow.h
#define DATAFLOW 1 /* produce some compile-time xref */
!File: debug.h
/*#define DEBUG 1 *//* perform various self-tests */
#define NDEBUG 1 /* disable assertions */
!File: use_tmp.h
#define PREPEND_SCOPES 1 /* collect exa, exp, ina and inp commands
and if USE_TMP is defined let them
precede the rest of the generated
compact code */
#define USE_TMP 1 /* use C_insertpart, C_endpart mechanism
to generate EM-code in the order needed
for the code-generators. If not defined,
the old-style peephole optimizer is
needed. */
!File: parbufsize.h
#define PARBUFSIZE 1024
!File: textsize.h
#define ITEXTSIZE 32 /* 1st piece of memory for repl. text */
!File: inputtype.h
#define INP_READ_IN_ONE 1 /* read input file in one */
!File: nobitfield.h
/*#define NOBITFIELD 1 *//* if NOT defined, implement bitfields */
!File: static.h
#define GSTATIC /* for large global "static" arrays */
!File: nocross.h
/*#define NOCROSS 1 *//* if NOT defined, cross compiler */
!File: regcount.h
/*#define REGCOUNT 1 *//* count occurrences for register messages */
!File: dbsymtab.h
#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.
* See the copyright notice in the ACK home directory, in the file "Copyright".
*/
/* $Id$ */
/* EXPRESSION SYNTAX PARSER */
{
#include <alloc.h>
#include "parameters.h"
#include <flt_arith.h>
#include "arith.h"
#include "LLlex.h"
#include "type.h"
#include "label.h"
#include "expr.h"
#include "code.h"
#include "error.h"
#include "ch3.h"
#include "ch3bin.h"
#include "ch3mon.h"
#include "proto.h"
#include "sizes.h"
extern struct expr *intexpr();
int InSizeof = 0; /* inside a sizeof- expression */
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
* 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.
* Such is life.
*/
}
/* 3.3.1 */
primary(register struct expr **expp;) :
IDENTIFIER
{dot2expr(expp);}
|
constant(expp)
|
string(expp)
|
'(' expression(expp) ')'
{ (*expp)->ex_flags |= EX_PARENS; }
;
/* Character string literals that are adjacent tokens
* are concatenated into a single character string
* literal.
*/
string(register struct expr **expp;)
{ register int i, len;
register char *str;
register int fund;
}
:
STRING
{ str = dot.tk_bts;
len = dot.tk_len;
fund = dot.tk_fund;
}
[
STRING
{ /* A pasted string keeps the type of the first
* string literal.
* The pasting of normal strings and wide
* character strings are stated as having an
* undefined behaviour.
*/
if (dot.tk_fund != fund)
warning("illegal pasting of string literals");
str = Realloc(str, (unsigned) (--len + dot.tk_len));
for (i = 0; i < dot.tk_len; i++)
str[len++] = dot.tk_bts[i];
}
]*
{ string2expr(expp, str, len); }
;
/* 3.3.2 */
postfix_expression(register struct expr **expp;)
{ int oper;
struct expr *e1 = 0;
struct idf *idf;
}
:
primary(expp)
[
'[' expression(&e1) ']'
{ ch3bin(expp, '[', e1); e1 = 0; }
|
'(' parameter_list(&e1)? ')'
{ ch3bin(expp, '(', e1); call_proto(expp); e1 = 0; }
|
[ '.' | ARROW ] { oper = DOT; }
identifier(&idf) { ch3sel(expp, oper, idf); }
|
[
PLUSPLUS { oper = POSTINCR; }
|
MINMIN { oper = POSTDECR; }
]
{ ch3incr(expp, oper); }
]*
;
parameter_list(struct expr **expp;)
{struct expr *e1 = 0;}
:
assignment_expression(expp)
{any2opnd(expp, PARCOMMA);}
[ %persistent
','
assignment_expression(&e1)
{any2opnd(&e1, PARCOMMA);}
{ch3bin(expp, PARCOMMA, e1);}
]*
;
%first first_of_type_specifier, type_specifier;
/* 3.3.3 & 3.3.4 */
unary(register struct expr **expp;)
{struct type *tp; int oper;}
:
%if (first_of_type_specifier(AHEAD) && AHEAD != IDENTIFIER)
cast(&tp) unary(expp)
{ ch3cast(expp, CAST, tp);
(*expp)->ex_flags |= EX_CAST;
if (int_size != pointer_size)
(*expp)->ex_flags &= ~EX_PTRDIFF;
}
|
postfix_expression(expp)
|
unop(&oper) unary(expp)
{ch3mon(oper, expp);}
|
size_of(expp)
;
/* When an identifier is used in a sizeof()-expression, we must stil not
* mark it as used.
* extern int i; .... sizeof(i) .... need not have a definition for i
*/
size_of(register struct expr **expp;)
{struct type *tp;}
:
SIZEOF { InSizeof++; } /* handle (sizeof(sizeof(int))) too */
[%if (first_of_type_specifier(AHEAD) && AHEAD != IDENTIFIER)
cast(&tp)
{
*expp = intexpr(size_of_type(tp, "type"), UNSIGNED);
(*expp)->ex_flags |= EX_SIZEOF;
}
|
unary(expp)
{ch3mon(SIZEOF, expp);}
]
{ InSizeof--; }
;
/* 3.3.5-3.3.17 */
/* 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
anymore). The standard describes this in phrase-structure-grammar,
which we are unable to parse. The description that follows comes
from the old C-compiler.
In principle each operator is assigned a rank, ranging
from 1 to 15. Such an expression can be parsed by a construct
like:
binary_expression(int maxrank;)
{int oper;}
:
binary_expression(maxrank - 1)
[%if (rank_of(DOT) <= maxrank)
binop(&oper)
binary_expression(rank_of(oper)-1)
]?
;
except that some call of 'unary' is necessary, depending on the
grammar.
This simple view is marred by three complications:
1. Level 15 (comma operator) is not allowed in many
contexts and is different.
2. Level 13 (conditional operator) is a ternary operator,
which does not fit this scheme at all.
3. Level 14 (assignment operators) group right-to-left, as
opposed to 2-12, which group left-to-right (or are
immaterial).
4. The operators in level 14 start with operators in levels
2-13 (RM 7.14: The two parts of a compound assignment
operator are separate tokens.) This causes LL1 problems.
This forces us to have four rules:
binary_expression for level 2-12
conditional_expression for level 13
assignment_expression for level 14 and
expression for the most general expression
*/
binary_expression(int maxrank; struct expr **expp;)
{int oper, OldResultKnown; struct expr *e1;}
:
unary(expp)
[%while (rank_of(DOT) <= maxrank )
/* '?', '=', and ',' are no binops
*/
binop(&oper)
{ OldResultKnown = ResultKnown;
if (oper == OR || oper == AND) {
if (is_cp_cst(*expp) || is_fp_cst(*expp)) {
if (is_zero_cst(*expp)) {
if (oper == AND) ResultKnown++;
} else if (oper == OR) ResultKnown++;
}
}
}
binary_expression(rank_of(oper)-1, &e1)
{
ch3bin(expp, oper, e1);
ResultKnown = OldResultKnown;
}
]*
;
/* 3.3.15 */
conditional_expression(struct expr **expp;)
{struct expr *e1 = 0, *e2 = 0; int OldResultKnown, ConstExpr=0;}
:
/* allow all binary operators */
binary_expression(rank_of('?') - 1, expp)
[ '?'
{ OldResultKnown = ResultKnown;
if (is_cp_cst(*expp) || is_fp_cst(*expp)) {
ConstExpr++;
if (is_zero_cst(*expp)) ResultKnown++;
}
}
expression(&e1)
':'
{ if (ConstExpr) {
if (OldResultKnown == ResultKnown) ResultKnown++;
else ResultKnown = OldResultKnown;
}
}
conditional_expression(&e2)
{
ResultKnown = OldResultKnown;
ch3bin(&e1, ':', e2);
opnd2test(expp, '?');
ch3bin(expp, '?', e1);
}
]?
;
/* 3.3.16 */
assignment_expression(struct expr **expp;)
{ int oper;
struct expr *e1 = 0;
}
:
conditional_expression(expp)
[
asgnop(&oper)
assignment_expression(&e1)
{ch3asgn(expp, oper, e1);}
|
empty /* LLgen artefact ??? */
]
;
/* 3.3.17 */
expression(struct expr **expp;)
{struct expr *e1;}
:
assignment_expression(expp)
[ ','
assignment_expression(&e1)
{
ch3bin(expp, ',', e1);
}
]*
;
unop(int *oper;) :
['*' | '&' | '-' | '+' | '!' | '~' | PLUSPLUS | MINMIN]
{ if (DOT == '&') DOT = ADDRESSOF;
*oper = DOT;
}
;
multop:
'*' | '/' | '%'
;
addop:
'+' | '-'
;
shiftop:
LEFT | RIGHT
;
relop:
'<' | '>' | LESSEQ | GREATEREQ
;
eqop:
EQUAL | NOTEQUAL
;
arithop:
multop | addop | shiftop
|
'&' | '^' | '|'
;
binop(int *oper;) :
[ arithop | relop | eqop | AND | OR ]
{*oper = DOT;}
;
asgnop(register int *oper;):
[ '=' | PLUSAB | MINAB | TIMESAB | DIVAB | MODAB
| LEFTAB | RIGHTAB | ANDAB | XORAB | ORAB ]
{ *oper = DOT; }
;
constant(struct expr **expp;) :
[
INTEGER
|
FLOATING
] {dot2expr(expp);}
;
/* 3.4 */
constant_expression (struct expr **expp;) :
conditional_expression(expp)
{ chk_cst_expr(expp); }
;
identifier(struct idf **idfp;) :
[ IDENTIFIER
| TYPE_IDENTIFIER
]
{ *idfp = dot.tk_idf; }
;
/*
* (c) copyright 1987 by the Vrije Universiteit, Amsterdam, The Netherlands.
* See the copyright notice in the ACK home directory, in the file "Copyright".
*/
/* $Id$ */
/* EXPRESSION SYNTAX PARSER */
{
#include <alloc.h>
#include "parameters.h"
#include <flt_arith.h>
#include "arith.h"
#include "LLlex.h"
#include "type.h"
#include "label.h"
#include "expr.h"
#include "code.h"
#include "error.h"
#include "ch3.h"
#include "ch3bin.h"
#include "ch3mon.h"
#include "proto.h"
#include "sizes.h"
extern struct expr *intexpr();
int InSizeof = 0; /* inside a sizeof- expression */
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
* 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.
* Such is life.
*/
}
/* 3.3.1 */
primary(register struct expr **expp;) :
IDENTIFIER
{dot2expr(expp);}
|
constant(expp)
|
string(expp)
|
'(' expression(expp) ')'
{ (*expp)->ex_flags |= EX_PARENS; }
;
/* Character string literals that are adjacent tokens
* are concatenated into a single character string
* literal.
*/
string(register struct expr **expp;)
{ register int i, len;
register char *str;
register int fund;
}
:
STRING
{ str = dot.tk_bts;
len = dot.tk_len;
fund = dot.tk_fund;
}
[
STRING
{ /* A pasted string keeps the type of the first
* string literal.
* The pasting of normal strings and wide
* character strings are stated as having an
* undefined behaviour.
*/
if (dot.tk_fund != fund)
warning("illegal pasting of string literals");
str = Realloc(str, (unsigned) (--len + dot.tk_len));
for (i = 0; i < dot.tk_len; i++)
str[len++] = dot.tk_bts[i];
}
]*
{ string2expr(expp, str, len); }
;
/* 3.3.2 */
postfix_expression(register struct expr **expp;)
{ int oper;
struct expr *e1 = 0;
struct idf *idf;
}
:
primary(expp)
[
'[' expression(&e1) ']'
{ ch3bin(expp, '[', e1); e1 = 0; }
|
'(' parameter_list(&e1)? ')'
{ ch3bin(expp, '(', e1); call_proto(expp); e1 = 0; }
|
[ '.' | ARROW ] { oper = DOT; }
identifier(&idf) { ch3sel(expp, oper, idf); }
|
[
PLUSPLUS { oper = POSTINCR; }
|
MINMIN { oper = POSTDECR; }
]
{ ch3incr(expp, oper); }
]*
;
parameter_list(struct expr **expp;)
{struct expr *e1 = 0;}
:
assignment_expression(expp)
{any2opnd(expp, PARCOMMA);}
[ %persistent
','
assignment_expression(&e1)
{any2opnd(&e1, PARCOMMA);}
{ch3bin(expp, PARCOMMA, e1);}
]*
;
%first first_of_type_specifier, type_specifier;
/* 3.3.3 & 3.3.4 */
unary(register struct expr **expp;)
{struct type *tp; int oper;}
:
%if (first_of_type_specifier(AHEAD) && AHEAD != IDENTIFIER)
cast(&tp) unary(expp)
{ ch3cast(expp, CAST, tp);
(*expp)->ex_flags |= EX_CAST;
if (int_size != pointer_size)
(*expp)->ex_flags &= ~EX_PTRDIFF;
}
|
postfix_expression(expp)
|
unop(&oper) unary(expp)
{ch3mon(oper, expp);}
|
size_of(expp)
;
/* When an identifier is used in a sizeof()-expression, we must stil not
* mark it as used.
* extern int i; .... sizeof(i) .... need not have a definition for i
*/
size_of(register struct expr **expp;)
{struct type *tp;}
:
SIZEOF { InSizeof++; } /* handle (sizeof(sizeof(int))) too */
[%if (first_of_type_specifier(AHEAD) && AHEAD != IDENTIFIER)
cast(&tp)
{
*expp = intexpr(size_of_type(tp, "type"), UNSIGNED);
(*expp)->ex_flags |= EX_SIZEOF;
}
|
unary(expp)
{ch3mon(SIZEOF, expp);}
]
{ InSizeof--; }
;
/* 3.3.5-3.3.17 */
/* 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
anymore). The standard describes this in phrase-structure-grammar,
which we are unable to parse. The description that follows comes
from the old C-compiler.
In principle each operator is assigned a rank, ranging
from 1 to 15. Such an expression can be parsed by a construct
like:
binary_expression(int maxrank;)
{int oper;}
:
binary_expression(maxrank - 1)
[%if (rank_of(DOT) <= maxrank)
binop(&oper)
binary_expression(rank_of(oper)-1)
]?
;
except that some call of 'unary' is necessary, depending on the
grammar.
This simple view is marred by three complications:
1. Level 15 (comma operator) is not allowed in many
contexts and is different.
2. Level 13 (conditional operator) is a ternary operator,
which does not fit this scheme at all.
3. Level 14 (assignment operators) group right-to-left, as
opposed to 2-12, which group left-to-right (or are
immaterial).
4. The operators in level 14 start with operators in levels
2-13 (RM 7.14: The two parts of a compound assignment
operator are separate tokens.) This causes LL1 problems.
This forces us to have four rules:
binary_expression for level 2-12
conditional_expression for level 13
assignment_expression for level 14 and
expression for the most general expression
*/
binary_expression(int maxrank; struct expr **expp;)
{int oper, OldResultKnown; struct expr *e1;}
:
unary(expp)
[%while (rank_of(DOT) <= maxrank )
/* '?', '=', and ',' are no binops
*/
binop(&oper)
{ OldResultKnown = ResultKnown;
if (oper == OR || oper == AND) {
if (is_cp_cst(*expp) || is_fp_cst(*expp)) {
if (is_zero_cst(*expp)) {
if (oper == AND) ResultKnown++;
} else if (oper == OR) ResultKnown++;
}
}
}
binary_expression(rank_of(oper)-1, &e1)
{
ch3bin(expp, oper, e1);
ResultKnown = OldResultKnown;
}
]*
;
/* 3.3.15 */
conditional_expression(struct expr **expp;)
{struct expr *e1 = 0, *e2 = 0; int OldResultKnown, ConstExpr=0;}
:
/* allow all binary operators */
binary_expression(rank_of('?') - 1, expp)
[ '?'
{ OldResultKnown = ResultKnown;
if (is_cp_cst(*expp) || is_fp_cst(*expp)) {
ConstExpr++;
if (is_zero_cst(*expp)) ResultKnown++;
}
}
expression(&e1)
':'
{ if (ConstExpr) {
if (OldResultKnown == ResultKnown) ResultKnown++;
else ResultKnown = OldResultKnown;
}
}
conditional_expression(&e2)
{
ResultKnown = OldResultKnown;
ch3bin(&e1, ':', e2);
opnd2test(expp, '?');
ch3bin(expp, '?', e1);
}
]?
;
/* 3.3.16 */
assignment_expression(struct expr **expp;)
{ int oper;
struct expr *e1 = 0;
}
:
conditional_expression(expp)
[
asgnop(&oper)
assignment_expression(&e1)
{ch3asgn(expp, oper, e1);}
|
empty /* LLgen artefact ??? */
]
;
/* 3.3.17 */
expression(struct expr **expp;)
{struct expr *e1;}
:
assignment_expression(expp)
[ ','
assignment_expression(&e1)
{
ch3bin(expp, ',', e1);
}
]*
;
unop(int *oper;) :
['*' | '&' | '-' | '+' | '!' | '~' | PLUSPLUS | MINMIN]
{ if (DOT == '&') DOT = ADDRESSOF;
*oper = DOT;
}
;
multop:
'*' | '/' | '%'
;
addop:
'+' | '-'
;
shiftop:
LEFT | RIGHT
;
relop:
'<' | '>' | LESSEQ | GREATEREQ
;
eqop:
EQUAL | NOTEQUAL
;
arithop:
multop | addop | shiftop
|
'&' | '^' | '|'
;
binop(int *oper;) :
[ arithop | relop | eqop | AND | OR ]
{*oper = DOT;}
;
asgnop(register int *oper;):
[ '=' | PLUSAB | MINAB | TIMESAB | DIVAB | MODAB
| LEFTAB | RIGHTAB | ANDAB | XORAB | ORAB ]
{ *oper = DOT; }
;
constant(struct expr **expp;) :
[
INTEGER
|
FLOATING
] {dot2expr(expp);}
;
/* 3.4 */
constant_expression (struct expr **expp;) :
conditional_expression(expp)
{ chk_cst_expr(expp); }
;
identifier(struct idf **idfp;) :
[ IDENTIFIER
| TYPE_IDENTIFIER
]
{ *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.
* See the copyright notice in the ACK home directory, in the file "Copyright".
*/
/* $Id$ */
/* PROGRAM PARSER */
/* The presence of typedef declarations renders it impossible to
make a context-free grammar of C. Consequently we need
context-sensitive parsing techniques, the simplest one being
a subtle cooperation between the parser and the lexical scanner.
The lexical scanner has to know whether to return IDENTIFIER
or TYPE_IDENTIFIER for a given tag, and it obtains this information
from the definition list, as constructed by the parser.
The present grammar is essentially LL(2), and is processed by
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)
ambiguities, the lexical scanner does a one symbol look-ahead.
This symbol, however, cannot always be correctly assessed, since
the present symbol may cause a change in the definition list
which causes the identification of the look-ahead symbol to be
invalidated.
The lexical scanner relies on the parser (or its routines) to
detect this situation and then update 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
would be more beautiful but less correct, since then for a short
while there would be a discrepancy between the look-ahead symbol
and the definition list; I think it would nevertheless work in
correct programs.
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
isn't. We would have to fill that in afterwards.
At block exit the situation is even worse. Upon reading the
closing brace, the names declared inside the function are cleared
from the name list. This action may expose a type identifier that
is the same as the identifier in the look-ahead symbol. This
situation certainly invalidates the third solution, and casts
doubts upon the second.
*/
%lexical LLlex;
%start C_program, program;
%start If_expr, control_if_expression;
{
#include "parameters.h"
#include <flt_arith.h>
#include "arith.h"
#include "LLlex.h"
#include "label.h"
#include "type.h"
#include "declar.h"
#include "decspecs.h"
#include "code.h"
#include "expr.h"
#include "def.h"
#include "idf.h"
#include "declarator.h"
#include "stack.h"
#include "proto.h"
#include "error.h"
#ifdef LINT
#include "l_lint.h"
#endif /* LINT */
}
control_if_expression
{
struct expr *exprX;
}
:
constant_expression(&exprX)
{
}
;
/* 3.7 */
program:
[%persistent external_definition]*
{ unstack_world(); }
;
/* A C identifier definition is remarkable in that it formulates
the declaration in a way different from most other languages:
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
pointer-to-integer. This has profound consequences, both for the
structure of an identifier definition and for the compiler.
A definition starts with a decl_specifiers, which contains things
like
typedef int
which is implicitly repeated for every definition in the list, and
then for each identifier a declarator is given, of the form
*a()
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
declarator, only to be passed to declare_idf together with the
struct decspecs.
With the introduction of prototypes, extra problems for the scope
administration were introduced as well. We can have, for example,
int x(double x);
and
int x(double x) { ... use(x) ... }
In the first case, the parameter name can be forgotten, whereas in
the second case, the parameter should have a block scope. The
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 end of the list. Our solution is as follows:
1- In case of a declaration, throw the parameter identifier away
before the declaration of the outer x.
2- In case of a definition, the function begin_proc() changes the
def list for the identifier. This means that declare_idf()
contains an extra test in case we already saw a declaration of
such a function, because this function is called before
begin_proc().
*/
external_definition
{ struct decspecs Ds;
struct declarator Dc;
}
:
{ Ds = null_decspecs;
Dc = null_declarator;
}
[ %if (DOT != IDENTIFIER || AHEAD == IDENTIFIER)
decl_specifiers(&Ds)
|
{do_decspecs(&Ds);}
]
[
declarator(&Dc)
{
declare_idf(&Ds, &Dc, level);
#ifdef LINT
lint_ext_def(Dc.dc_idf, Ds.ds_sc);
#endif /* LINT */
}
[
function(&Ds, &Dc)
|
{ if (! Ds.ds_sc_given && ! Ds.ds_typequal &&
Ds.ds_notypegiven) {
strict("declaration specifiers missing");
}
}
non_function(&Ds, &Dc)
]
|
{ if (! Ds.ds_sc_given && ! Ds.ds_typequal &&
Ds.ds_notypegiven) {
strict("declaration missing");
}
}
';'
]
{remove_declarator(&Dc); flush_strings(); }
;
non_function(register struct decspecs *ds; register struct declarator *dc;)
:
{ reject_params(dc);
}
[
initializer(dc->dc_idf, ds->ds_sc)
|
{ code_declaration(dc->dc_idf, (struct expr *) 0, level, ds->ds_sc); }
]
{
#ifdef LINT
lint_non_function_decl(ds, dc);
#endif /* LINT */
}
[
','
init_declarator(ds)
]*
';'
;
/* 3.7.1 */
function(struct decspecs *ds; struct declarator *dc;)
{
arith fbytes;
register struct idf *idf = dc->dc_idf;
}
:
{
#ifdef LINT
lint_start_function();
#endif /* LINT */
idf_initialized(idf);
stack_level(); /* L_FORMAL1 declarations */
declare_params(dc);
begin_proc(ds, idf); /* sets global function info */
stack_level(); /* L_FORMAL2 declarations */
declare_protos(dc);
}
declaration*
{
check_formals(idf, dc); /* check style-mixtures */
declare_formals(idf, &fbytes);
#ifdef LINT
lint_formals();
#endif /* LINT */
}
compound_statement
{
end_proc(fbytes);
#ifdef LINT
lint_implicit_return();
#endif /* LINT */
unstack_level(); /* L_FORMAL2 declarations */
#ifdef LINT
lint_end_formals();
#endif /* LINT */
unstack_level(); /* L_FORMAL1 declarations */
#ifdef LINT
lint_end_function();
#endif /* LINT */
}
;
/*
* (c) copyright 1987 by the Vrije Universiteit, Amsterdam, The Netherlands.
* See the copyright notice in the ACK home directory, in the file "Copyright".
*/
/* $Id$ */
/* PROGRAM PARSER */
/* The presence of typedef declarations renders it impossible to
make a context-free grammar of C. Consequently we need
context-sensitive parsing techniques, the simplest one being
a subtle cooperation between the parser and the lexical scanner.
The lexical scanner has to know whether to return IDENTIFIER
or TYPE_IDENTIFIER for a given tag, and it obtains this information
from the definition list, as constructed by the parser.
The present grammar is essentially LL(2), and is processed by
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)
ambiguities, the lexical scanner does a one symbol look-ahead.
This symbol, however, cannot always be correctly assessed, since
the present symbol may cause a change in the definition list
which causes the identification of the look-ahead symbol to be
invalidated.
The lexical scanner relies on the parser (or its routines) to
detect this situation and then update 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
would be more beautiful but less correct, since then for a short
while there would be a discrepancy between the look-ahead symbol
and the definition list; I think it would nevertheless work in
correct programs.
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
isn't. We would have to fill that in afterwards.
At block exit the situation is even worse. Upon reading the
closing brace, the names declared inside the function are cleared
from the name list. This action may expose a type identifier that
is the same as the identifier in the look-ahead symbol. This
situation certainly invalidates the third solution, and casts
doubts upon the second.
*/
%lexical LLlex;
%start C_program, program;
%start If_expr, control_if_expression;
{
#include "parameters.h"
#include <flt_arith.h>
#include "arith.h"
#include "LLlex.h"
#include "label.h"
#include "type.h"
#include "declar.h"
#include "decspecs.h"
#include "code.h"
#include "expr.h"
#include "def.h"
#include "idf.h"
#include "declarator.h"
#include "stack.h"
#include "proto.h"
#include "error.h"
#ifdef LINT
#include "l_lint.h"
#endif /* LINT */
}
control_if_expression
{
struct expr *exprX;
}
:
constant_expression(&exprX)
{
}
;
/* 3.7 */
program:
[%persistent external_definition]*
{ unstack_world(); }
;
/* A C identifier definition is remarkable in that it formulates
the declaration in a way different from most other languages:
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
pointer-to-integer. This has profound consequences, both for the
structure of an identifier definition and for the compiler.
A definition starts with a decl_specifiers, which contains things
like
typedef int
which is implicitly repeated for every definition in the list, and
then for each identifier a declarator is given, of the form
*a()
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
declarator, only to be passed to declare_idf together with the
struct decspecs.
With the introduction of prototypes, extra problems for the scope
administration were introduced as well. We can have, for example,
int x(double x);
and
int x(double x) { ... use(x) ... }
In the first case, the parameter name can be forgotten, whereas in
the second case, the parameter should have a block scope. The
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 end of the list. Our solution is as follows:
1- In case of a declaration, throw the parameter identifier away
before the declaration of the outer x.
2- In case of a definition, the function begin_proc() changes the
def list for the identifier. This means that declare_idf()
contains an extra test in case we already saw a declaration of
such a function, because this function is called before
begin_proc().
*/
external_definition
{ struct decspecs Ds;
struct declarator Dc;
}
:
{ Ds = null_decspecs;
Dc = null_declarator;
}
[ %if (DOT != IDENTIFIER || AHEAD == IDENTIFIER)
decl_specifiers(&Ds)
|
{do_decspecs(&Ds);}
]
[
declarator(&Dc)
{
declare_idf(&Ds, &Dc, level);
#ifdef LINT
lint_ext_def(Dc.dc_idf, Ds.ds_sc);
#endif /* LINT */
}
[
function(&Ds, &Dc)
|
{ if (! Ds.ds_sc_given && ! Ds.ds_typequal &&
Ds.ds_notypegiven) {
strict("declaration specifiers missing");
}
}
non_function(&Ds, &Dc)
]
|
{ if (! Ds.ds_sc_given && ! Ds.ds_typequal &&
Ds.ds_notypegiven) {
strict("declaration missing");
}
}
';'
]
{remove_declarator(&Dc); flush_strings(); }
;
non_function(register struct decspecs *ds; register struct declarator *dc;)
:
{ reject_params(dc);
}
[
initializer(dc->dc_idf, ds->ds_sc)
|
{ code_declaration(dc->dc_idf, (struct expr *) 0, level, ds->ds_sc); }
]
{
#ifdef LINT
lint_non_function_decl(ds, dc);
#endif /* LINT */
}
[
','
init_declarator(ds)
]*
';'
;
/* 3.7.1 */
function(struct decspecs *ds; struct declarator *dc;)
{
arith fbytes;
register struct idf *idf = dc->dc_idf;
}
:
{
#ifdef LINT
lint_start_function();
#endif /* LINT */
idf_initialized(idf);
stack_level(); /* L_FORMAL1 declarations */
declare_params(dc);
begin_proc(ds, idf); /* sets global function info */
stack_level(); /* L_FORMAL2 declarations */
declare_protos(dc);
}
declaration*
{
check_formals(idf, dc); /* check style-mixtures */
declare_formals(idf, &fbytes);
#ifdef LINT
lint_formals();
#endif /* LINT */
}
compound_statement
{
end_proc(fbytes);
#ifdef LINT
lint_implicit_return();
#endif /* LINT */
unstack_level(); /* L_FORMAL2 declarations */
#ifdef LINT
lint_end_formals();
#endif /* LINT */
unstack_level(); /* L_FORMAL1 declarations */
#ifdef LINT
lint_end_function();
#endif /* LINT */
}
;

File diff suppressed because it is too large Load diff

View file

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

View file

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

View file

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

View file

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

View file

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

File diff suppressed because it is too large Load diff

View file

@ -1,15 +1,15 @@
#ifndef SIM__HEADER
#define SIM__HEADER
unsigned int cpu_read_byte(unsigned int address);
unsigned int cpu_read_word(unsigned int address);
unsigned int cpu_read_long(unsigned int address);
void cpu_write_byte(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_pulse_reset(void);
void cpu_set_fc(unsigned int fc);
int cpu_irq_ack(int level);
void cpu_instr_callback(int pc);
#endif /* SIM__HEADER */
#ifndef SIM__HEADER
#define SIM__HEADER
unsigned int cpu_read_byte(unsigned int address);
unsigned int cpu_read_word(unsigned int address);
unsigned int cpu_read_long(unsigned int address);
void cpu_write_byte(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_pulse_reset(void);
void cpu_set_fc(unsigned int fc);
int cpu_irq_ack(int level);
void cpu_instr_callback(int pc);
#endif /* SIM__HEADER */

View file

@ -1,45 +1,45 @@
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
added some more features, and the resulting changes amounted to
about as much text as the whole program (hence the repost).
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;
for documentation, refer to a UNIX manual, or the source.
Here is a list of the changes made:
i) If '-' (ignore) or '@' (silent) where used at the start
of a command, their effect was not turned off for the following
commands.
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.
This resulted in error messages like "Don't know how to
make .c", because things like .SUFFIXES were being made.
This was further complicated by ---
iii) Special target lines with no dependents (ie. .SUFFIXES:\n)
were not clearing out the existing dependents like
they should.
iv) Default rules could not be redefined because of the error
checking for commands being defined twice. Now you are
allowed to define a target beinging with '.', having
no dependents with commands.
v) The -q option didn't do the time comparison correctly,
or clear the variable used to keep track of this. Thus
it didn't work very well.
vi) The syntax ${..} for macro's supported by UNIX make was
not supported.
vii) There wuz a couple of spelling errors.
viii) When make checked for implicit rules on targets without
a suffix, there were problems. (Note: The ~ feature of
UNIX make wasn't and still isn't supported)
ix) The -n option did not print @ lines like it was supposed to.
x) :: added. (See UNIX manual)
xi) $? added. (see UNIX manual)
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
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
also made it safer by using correct datatypes on some library calls.
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
added some more features, and the resulting changes amounted to
about as much text as the whole program (hence the repost).
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;
for documentation, refer to a UNIX manual, or the source.
Here is a list of the changes made:
i) If '-' (ignore) or '@' (silent) where used at the start
of a command, their effect was not turned off for the following
commands.
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.
This resulted in error messages like "Don't know how to
make .c", because things like .SUFFIXES were being made.
This was further complicated by ---
iii) Special target lines with no dependents (ie. .SUFFIXES:\n)
were not clearing out the existing dependents like
they should.
iv) Default rules could not be redefined because of the error
checking for commands being defined twice. Now you are
allowed to define a target beinging with '.', having
no dependents with commands.
v) The -q option didn't do the time comparison correctly,
or clear the variable used to keep track of this. Thus
it didn't work very well.
vi) The syntax ${..} for macro's supported by UNIX make was
not supported.
vii) There wuz a couple of spelling errors.
viii) When make checked for implicit rules on targets without
a suffix, there were problems. (Note: The ~ feature of
UNIX make wasn't and still isn't supported)
ix) The -n option did not print @ lines like it was supposed to.
x) :: added. (See UNIX manual)
xi) $? added. (see UNIX manual)
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
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
also made it safer by using correct datatypes on some library calls.

View file

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