Added grind support

This commit is contained in:
ceriel 1991-11-08 15:12:28 +00:00
parent 97a7fcbca3
commit 3015fc2542
15 changed files with 239 additions and 48 deletions

View file

@ -98,3 +98,4 @@ type.c
type.str
util.str
util.c
stab.c

View file

@ -143,4 +143,8 @@
!File: regcount.h
#undef REGCOUNT 1 /* count occurrences for register messages */
!File: dbsymtab.h
#define DBSYMTAB 1 /* ability to produce symbol table for debugger
*/

View file

@ -144,3 +144,8 @@
#undef REGCOUNT 1 /* count occurrences for register messages */
!File: dbsymtab.h
#undef DBSYMTAB 1 /* ability to produce symbol table for debugger
*/

View file

@ -29,6 +29,8 @@ the same as \fB\-D\fIname\fR=1.
insert \fIdirname\fR in the list of include directories.
.IP \fB\-M\fP\fIn\fP
set maximum identifier length to \fIn\fP.
.IP \fB\-g\fP
produce a DBX-style symbol table.
.IP \fB\-n\fR
do not generate EM register messages.
The user-declared variables are not stored into registers on the target

View file

@ -3,9 +3,10 @@
* See the copyright notice in the ACK home directory, in the file "Copyright".
*/
/* $Header$ */
/* C O D E - G E N E R A T I N G R O U T I N E S */
/* C O D E - G E N E R A T I N G R O U T I N E S */
#include "lint.h"
#include "dbsymtab.h"
#ifndef LINT
#include <em.h>
#else
@ -34,7 +35,10 @@
#include "atw.h"
#include "assert.h"
#include "noRoption.h"
#include "file_info.h"
#include "LLlex.h"
#ifdef DBSYMTAB
#include <stb.h>
#endif /* DBSYMTAB */
label lab_count = 1;
label datlab_count = 1;
@ -68,6 +72,24 @@ init_code(dst_file)
fatal("cannot write to %s\n", dst_file);
C_magic();
C_ms_emx(word_size, pointer_size);
#ifdef DBSYMTAB
if (options['g']) {
extern char *source;
C_ms_std(source, N_SO, 0);
stb_typedef(int_type, "int");
stb_typedef(char_type, "char");
stb_typedef(long_type, "long");
stb_typedef(short_type, "short");
stb_typedef(uchar_type, "unsigned char");
stb_typedef(ushort_type, "unsigned short");
stb_typedef(ulong_type, "unsigned long");
stb_typedef(uint_type, "unsigned int");
stb_typedef(float_type, "float");
stb_typedef(double_type, "double");
stb_typedef(void_type, "void");
}
#endif /* DBSYMTAB */
#ifdef USE_TMP
#ifdef PREPEND_SCOPES
C_insertpart(tmp_id = C_getid());
@ -140,7 +162,7 @@ prepend_scopes()
while (se != 0) {
register struct idf *id = se->se_idf;
register struct def *df = id->id_def;
if (df && (df->df_initialized || df->df_used || df->df_alloc))
code_scope(id->id_text, df);
se = se->next;
@ -159,7 +181,7 @@ code_scope(text, def)
as given by def, if meaningful.
*/
int fund = def->df_type->tp_fund;
switch (def->df_sc) {
case EXTERN:
case GLOBAL:
@ -257,6 +279,14 @@ begin_proc(ds, idf) /* to be called when entering a procedure */
C_fil_dlb(file_name_label, (arith)0);
C_lin((arith)LineNumber);
}
#ifdef DBSYMTAB
if (options['g']) {
stb_string(def, FUNCTION, name);
if (! strcmp(name, "main")) {
C_ms_stb_cst(name, N_MAIN, 0, (arith) 0);
}
}
#endif
}
end_proc(fbytes)
@ -339,6 +369,9 @@ do_return()
probably smarter than generating a direct return.
Return sequences may be expensive.
*/
#ifdef DBSYMTAB
if (options['g']) db_line(dot.tk_file, dot.tk_line);
#endif /* DBSYMTAB */
C_bra(return2_label);
}
@ -373,7 +406,7 @@ code_declaration(idf, expr, lvl, sc)
Since the expression may be modified in the process,
code_declaration() frees it after use, as the caller can
no longer do so.
If there is a storage class indication (EXTERN/STATIC),
code_declaration() will generate an exa or ina.
The sc is the actual storage class, as given in the
@ -386,9 +419,15 @@ code_declaration(idf, expr, lvl, sc)
register struct def *def = idf->id_def;
register arith size = def->df_type->tp_size;
int def_sc = def->df_sc;
if (def_sc == TYPEDEF) /* no code for typedefs */
if (def_sc == TYPEDEF) { /* no code for typedefs */
#ifdef DBSYMTAB
if (options['g']) {
stb_typedef(def->df_type, idf->id_text);
}
#endif /* DBSYMTAB */
return;
}
if (sc == EXTERN && expr && !is_anon_idf(idf))
error("%s is extern; cannot initialize", idf->id_text);
if (lvl == L_GLOBAL) { /* global variable */
@ -418,6 +457,11 @@ code_declaration(idf, expr, lvl, sc)
/* they are handled on the spot and get an
integer label in EM.
*/
#ifdef DBSYMTAB
if (options['g'] && ! expr) {
stb_string(def, sc, idf->id_text);
}
#endif /* DBSYMTAB */
C_df_dlb((label)def->df_address);
if (expr) { /* there is an initialisation */
}
@ -436,6 +480,11 @@ code_declaration(idf, expr, lvl, sc)
break;
case AUTO:
case REGISTER:
#ifdef DBSYMTAB
if (options['g']) {
stb_string(def, sc, idf->id_text);
}
#endif /* DBSYMTAB */
if (expr)
loc_init(expr, idf);
break;
@ -456,7 +505,7 @@ loc_init(expr, id)
*/
register struct expr *e = expr;
register struct type *tp = id->id_def->df_type;
ASSERT(id->id_def->df_sc != STATIC);
switch (tp->tp_fund) {
case ARRAY:
@ -507,17 +556,22 @@ bss(idf)
/* bss() allocates bss space for the global idf.
*/
arith size = idf->id_def->df_type->tp_size;
#ifndef PREPEND_SCOPES
code_scope(idf->id_text, idf->id_def);
#endif PREPEND_SCOPES
#ifdef DBSYMTAB
if (options['g']) {
stb_string(idf->id_def, idf->id_def->df_sc, idf->id_text);
}
#endif /* DBSYMTAB */
/* Since bss() is only called if df_alloc is non-zero, and
since df_alloc is only non-zero if size >= 0, we have:
*/
/* but we already gave a warning at the declaration of the
array. Besides, the message given here does not apply to
voids
if (options['R'] && size == 0)
warning("actual array of size 0");
*/
@ -558,6 +612,9 @@ code_expr(expr, val, code, tlbl, flbl)
#ifndef LINT
if (! options['L']) /* profiling */
C_lin((arith)(expr->ex_line));
#ifdef DBSYMTAB
if (options['g']) db_line(expr->ex_file, (unsigned int)expr->ex_line);
#endif
EVAL(expr, val, code, tlbl, flbl);
#else LINT
lint_expr(expr, code ? USED : IGNORED);
@ -583,6 +640,9 @@ code_break()
{
register struct stmt_block *stmt_block = stmt_stack;
#ifdef DBSYMTAB
if (options['g']) db_line(dot.tk_file, dot.tk_line);
#endif /* DBSYMTAB */
if (stmt_block)
C_bra(stmt_block->st_break);
else
@ -600,6 +660,9 @@ code_continue()
while (stmt_block) {
if (stmt_block->st_continue) {
#ifdef DBSYMTAB
if (options['g']) db_line(dot.tk_file, dot.tk_line);
#endif /* DBSYMTAB */
C_bra(stmt_block->st_continue);
return;
}
@ -651,3 +714,19 @@ prc_exit()
C_asp(pointer_size);
}
}
#ifdef DBSYMTAB
db_line(file, line)
char *file;
unsigned int line;
{
static unsigned oldline;
static char *oldfile;
if (file != oldfile || line != oldline) {
C_ms_std((char *) 0, N_SLINE, (int) line);
oldline = line;
oldfile = file;
}
}
#endif /* DBSYMTAB */

View file

@ -7,6 +7,7 @@
{
#include "lint.h"
#include "dbsymtab.h"
#include <alloc.h>
#include "nobitfield.h"
#include "debug.h"
@ -54,7 +55,7 @@ declaration
This means that something like:
unsigned extern int short xx;
is perfectly good C.
On top of that, multiple occurrences of storage_class_specifiers,
unsigned_specifiers and size_specifiers are errors, but a second
type_specifier should end the decl_specifiers and be treated as
@ -65,7 +66,7 @@ declaration
occurrence of the type_specifier in the grammar (we have no choice),
collecting all data in a `struct decspecs' and turning that data
structure into what we want.
The existence of declarations like
short typedef yepp;
makes all hope of writing a specific grammar for typedefs illusory.
@ -223,8 +224,19 @@ initializer(struct idf *idf; int sc;)
#ifdef LINT
change_state(idf, SET);
#endif LINT
#ifdef DBSYMTAB
if (options['g'] && level >= L_LOCAL && expr) {
db_line(expr->ex_file, (unsigned) expr->ex_line)
;
}
#endif /* DBSYMTAB */
code_declaration(idf, expr, level, sc);
}
#ifdef DBSYMTAB
if (options['g'] && globalflag) {
stb_string(idf->id_def, sc, idf->id_text);
}
#endif /* DBSYMTAB */
init_idf(idf);
}
;
@ -295,7 +307,7 @@ formal(struct formal **fmp;)
identifier(&idf)
{
register struct formal *new = new_formal();
new->fm_idf = idf;
new->next = *fmp;
*fmp = new;
@ -318,6 +330,13 @@ enum_specifier(register struct type **tpp;)
[
{declare_struct(ENUM, idf, tpp);}
enumerator_pack(*tpp, &l)
{
#ifdef DBSYMTAB
if (options['g']) {
stb_tag(idf->id_enum, idf->id_text);
}
#endif /*DBSYMTAB */
}
|
{apply_struct(ENUM, idf, tpp);}
empty
@ -383,6 +402,11 @@ struct_or_union_specifier(register struct type **tpp;)
struct_declaration_pack(*tpp)
{
(idf->id_struct->tg_busy)--;
#ifdef DBSYMTAB
if (options['g']) {
stb_tag(idf->id_struct, idf->id_text);
}
#endif /*DBSYMTAB */
}
|
{apply_struct(fund, idf, tpp);}

View file

@ -15,16 +15,22 @@
#include "nopp.h"
#ifndef NOPP
#include "ifdepth.h"
#include "botch_free.h"
#include "nparams.h"
#include "parbufsize.h"
#include "textsize.h"
#include "idfsize.h"
#include "ifdepth.h"
#include "botch_free.h"
#include "nparams.h"
#include "parbufsize.h"
#include "textsize.h"
#include "idfsize.h"
#include "assert.h"
#include <alloc.h>
#include "class.h"
#include "macro.h"
#include "dbsymtab.h"
#ifdef DBSYMTAB
#include <stb.h>
int IncludeLevel = 0;
extern char options[];
#endif
IMPORT char **inctable; /* list of include directories */
IMPORT char *getwdir();
@ -269,6 +275,12 @@ do_include()
FileName = result;
LineNumber = 0;
nestlow = nestlevel;
#ifdef DBSYMTAB
IncludeLevel++;
if (options['g']) {
C_ms_std(FileName, N_BINCL, 0);
}
#endif /* DBSYMTAB */
}
}
}
@ -294,7 +306,7 @@ do_define()
return;
}
/* there is a formal parameter list if the identifier is
followed immediately by a '('.
followed immediately by a '('.
*/
LoadChar(ch);
if (ch == '(') {
@ -500,7 +512,7 @@ macro_def(id, text, nformals, length, flags)
else
id->id_macro = newdef = new_macro();
newdef->mc_text = text; /* replacement text */
newdef->mc_nps = nformals; /* nr of formals */
newdef->mc_nps = nformals; /* nr of formals */
newdef->mc_length = length; /* length of repl. text */
newdef->mc_flag = flags; /* special flags */
newdef->mc_count = 0;
@ -634,7 +646,7 @@ PRIVATE
macroeq(s, t)
register char *s, *t;
{
/* skip leading spaces */
while (BLANK(*s)) s++;
while (BLANK(*t)) t++;

View file

@ -100,12 +100,12 @@ hash_stat()
{
if (options['h']) {
register int i;
print("Hash table tally:\n");
for (i = 0; i < HASHSIZE; i++) {
register struct idf *notch = idf_hashtable[i];
int cnt = 0;
while (notch) {
cnt++;
notch = notch->next;
@ -113,7 +113,7 @@ hash_stat()
print("%d %d\n", i, cnt);
}
print("End hash table tally\n");
}
}
}
#endif DEBUG
@ -122,7 +122,7 @@ str2idf(tg)
char tg[];
{
/* str2idf() returns an entry in the symbol table for the
identifier tg. If necessary, an entry is created.
identifier tg. If necessary, an entry is created.
It is used where the text of the identifier is available
but its hash value is not; otherwise idf_hashed() is to
be used.
@ -187,7 +187,7 @@ declare_idf(ds, dc, lvl)
register struct type *type;
struct stack_level *stl = stack_level_of(lvl);
char formal_array = 0;
/* determine the present type */
if (ds->ds_type == 0) {
/* at the L_FORMAL1 level there is no type specified yet
@ -276,7 +276,7 @@ declare_idf(ds, dc, lvl)
check_hiding(idf, lvl, sc); /* of some idf by this idf */
#endif LINT
if (def &&
if (def &&
( def->df_level == lvl ||
( lvl != L_GLOBAL && def->df_level > lvl )
)
@ -382,7 +382,7 @@ actual_declaration(sc, tp)
/* An actual_declaration needs space, right here and now.
*/
register int fund = tp->tp_fund;
if (sc == ENUM || sc == TYPEDEF) /* virtual declarations */
return 0;
if (fund == FUNCTION || fund == ARRAY)
@ -569,7 +569,7 @@ declare_params(dc)
/* Declares the formal parameters if they exist.
*/
register struct formal *fm = dc->dc_formal;
while (fm) {
declare_parameter(fm->fm_idf);
fm = fm->next;
@ -584,7 +584,7 @@ init_idf(idf)
/* The topmost definition of idf is set to initialized.
*/
register struct def *def = idf->id_def; /* the topmost */
if (def->df_initialized)
error("multiple initialization of %s", idf->id_text);
if (def->df_sc == TYPEDEF) {
@ -630,7 +630,7 @@ declare_formals(fp)
#endif DEBUG
while (se) {
register struct def *def = se->se_idf->id_def;
def->df_address = f_offset;
/* the alignment convention for parameters is: align on
word boundaries, i.e. take care that the following
@ -638,11 +638,16 @@ declare_formals(fp)
*/
f_offset = align(f_offset + def->df_type->tp_size, (int) word_size);
formal_cvt(def); /* cvt int to char or short, if necessary */
se = se->next;
def->df_level = L_FORMAL2; /* CJ */
RegisterAccount(def->df_address, def->df_type->tp_size,
regtype(def->df_type),
def->df_sc);
#ifdef DBSYMTAB
if (options['g']) {
stb_string(def, FORMAL, se->se_idf->id_text);
}
#endif /* DBSYMTAB */
se = se->next;
}
*fp = f_offset;
}
@ -721,7 +726,7 @@ init_hmask()
described in Knuth, vol 2.
*/
register int h, rnd = HASH_X;
for (h = 0; h < IDFSIZE; h++) {
hmask[h] = rnd;
rnd = (HASH_A * rnd + HASH_C) & HASHMASK;

View file

@ -14,7 +14,13 @@ extern int nestlevel;
#include "nopp.h"
#include <inp_pkg.body>
#include "dbsymtab.h"
#ifndef NOPP
#ifdef DBSYMTAB
#include <stb.h>
extern int IncludeLevel;
extern char options[];
#endif
char *
getwdir(fn)
register char *fn;
@ -64,6 +70,12 @@ AtEoIF()
if (NoUnstack) lexerror("unexpected EOF");
#ifndef NOPP
nestlevel = nestlow;
#ifdef DBSYMTAB
if (options['g'] && IncludeLevel > 0) {
C_ms_std(FileName, N_EINCL, 0);
}
IncludeLevel--;
#endif
#endif
return 0;
}

View file

@ -265,6 +265,10 @@ compile(argc, argv)
init();
LineNumber = 0;
nestlow = -1;
#ifndef LINT
init_code(destination && strcmp(destination, "-") != 0 ?
destination : 0);
#endif
#ifndef NOPP
WorkingDir = getwdir(source);
#endif NOPP
@ -279,8 +283,6 @@ compile(argc, argv)
#endif DEBUG
{
#ifndef LINT
init_code(destination && strcmp(destination, "-") != 0 ?
destination : 0);
/* compile the source text */
C_program();
#ifdef PREPEND_SCOPES

View file

@ -4,12 +4,13 @@ C while running preprocessor, copy comment
d perform a small dataflow analysis
D see identifier following as a macro
E run preprocessor only
g produce symbol table for debugger
i suppress /usr/include include files in dependency list
I expand include table with directory name following
L don't generate linenumbers and filename indications
m generate file.o: file1.h format dependency lines
M set identifier length
n don't generate register messages
L don't generate linenumbers and filename indications
p trace
P in running the preprocessor do not output '# line' lines
R restricted C

View file

@ -3,7 +3,7 @@
* See the copyright notice in the ACK home directory, in the file "Copyright".
*/
/* $Header$ */
/* U S E R O P T I O N - H A N D L I N G */
/* U S E R O P T I O N - H A N D L I N G */
#include "lint.h"
#include "botch_free.h"
@ -21,6 +21,7 @@
#include "use_tmp.h"
#include "dataflow.h"
#include "noRoption.h"
#include "dbsymtab.h"
#ifndef NOPP
extern char **inctable;
@ -91,7 +92,7 @@ next_option: /* to allow combined one-char options */
#ifndef LINT
#ifndef NOPP
case 'A' : /* Amake dependency generation */
case 'A' : /* Amake dependency generation */
do_dependencies = 1;
if (*text) {
dep_file = text;
@ -103,7 +104,13 @@ next_option: /* to allow combined one-char options */
break;
#endif NOPP
#endif LINT
#ifdef DBSYMTAB
case 'g': /* symbol table for debugger */
options['g'] = 1;
options['n'] = 1;
break;
#endif /* DBSYMTAB */
case 'R': /* strict version */
#ifndef NOROPTION
options[opt] = 1;
@ -176,15 +183,15 @@ deleted, is now a debug-flag
if (*text) {
int i;
register char *new = text;
if (++inc_total > inc_max) {
inctable = (char **)
Realloc(inctable,(inc_max+=10)*sizeof(char *));
}
for (i = inc_pos++; i < inc_total; i++) {
char *tmp = inctable[i];
inctable[i] = new;
new = tmp;
}
@ -235,7 +242,7 @@ deleted, is now a debug-flag
#endif USE_TMP
break;
}
case 'U' : { /* -Uname : undefine predefined */
#ifndef NOPP
register struct idf *idef;
@ -353,7 +360,7 @@ txt2int(tp)
*tp; the resulting value is yielded.
*/
register int val = 0, ch;
while (ch = **tp, ch >= '0' && ch <= '9') {
val = val * 10 + ch - '0';
(*tp)++;

View file

@ -61,7 +61,9 @@ SRC_C = \
$(SRC_DIR)/switch.c \
$(SRC_DIR)/tokenname.c \
$(SRC_DIR)/type.c \
$(SRC_DIR)/util.c
$(SRC_DIR)/util.c \
$(SRC_DIR)/stab.c
GEN_C = tokenfile.c program.c declar.c expression.c statement.c ival.c \
symbol2str.c char.c Lpars.c next.c
CFILES= $(SRC_C) $(GEN_C)
@ -96,7 +98,7 @@ GEN_H = botch_free.h dataflow.h debug.h density.h errout.h \
regcount.h \
code.h declar.h decspecs.h def.h expr.h field.h estack.h util.h \
idf.h macro.h stmt.h struct.h switch.h type.h l_brace.h l_state.h \
l_outdef.h stack.h lapbuf.h noRoption.h nofloat.h
l_outdef.h stack.h lapbuf.h noRoption.h nofloat.h dbsymtab.h
HFILES= $(GEN_H) $(SRC_H)

View file

@ -16,6 +16,7 @@
#include "debug.h"
#include "botch_free.h"
#include "dbsymtab.h"
#include "arith.h"
#include "LLlex.h"
@ -26,8 +27,12 @@
#include "code.h"
#include "stack.h"
#include "def.h"
#ifdef DBSYMTAB
#include <stb.h>
#endif /* DBSYMTAB */
extern int level;
extern char options[];
}
/* Each statement construction is stacked in order to trace a ???
@ -451,7 +456,14 @@ jump
}
;
compound_statement:
compound_statement
{
#ifdef DBSYMTAB
static int brc_level = 1;
int decl_seen = brc_level == 1;
#endif /* DBSYMTAB */
}
:
'{'
{
stack_level();
@ -460,13 +472,32 @@ compound_statement:
(DOT == IDENTIFIER && AHEAD == IDENTIFIER))
/* >>> conflict on TYPE_IDENTIFIER, IDENTIFIER */
declaration
{
#ifdef DBSYMTAB
decl_seen++;
#endif /* DBSYMTAB */
}
]*
{
#ifdef DBSYMTAB
++brc_level;
if (options['g'] && decl_seen) {
C_ms_std((char *) 0, N_LBRAC, brc_level);
}
#endif /* DBSYMTAB */
}
[%persistent
statement
]*
'}'
{
unstack_level();
#ifdef DBSYMTAB
if (options['g'] && decl_seen) {
C_ms_std((char *) 0, N_RBRAC, brc_level);
}
brc_level--;
#endif /* DBSYMTAB */
}
;

View file

@ -7,6 +7,7 @@
#include "nofloat.h"
#include "nobitfield.h"
#include "dbsymtab.h"
struct type {
struct type *next; /* used only with ARRAY */
@ -22,6 +23,9 @@ struct type {
struct type *tp_pointer;/* to POINTER */
struct type *tp_array; /* to ARRAY */
struct type *tp_function;/* to FUNCTION */
#ifdef DBSYMTAB
int tp_dbindex;
#endif
};
extern struct type