Another batch especially on C ANSI frontend
This commit is contained in:
parent
369ec26b03
commit
c0cd8650a6
@ -27,15 +27,15 @@
|
||||
#include "field.h"
|
||||
#include "mes.h"
|
||||
#include "assert.h"
|
||||
#include "ch3.h"
|
||||
#include "ch3bin.h"
|
||||
#include "code_c.h"
|
||||
#include "conversion.h"
|
||||
#include "cstoper.h"
|
||||
|
||||
extern char *symbol2str();
|
||||
extern char options[];
|
||||
extern arith flt_flt2arith();
|
||||
extern label code_string();
|
||||
|
||||
arithbalance(e1p, oper, e2p) /* 3.1.2.5 */
|
||||
register struct expr **e1p, **e2p;
|
||||
int oper;
|
||||
void arithbalance(struct expr **e1p, int oper, struct expr **e2p) /* 3.1.2.5 */
|
||||
{
|
||||
/* The expressions *e1p and *e2p are balanced to be operands
|
||||
of the arithmetic operator oper.
|
||||
@ -44,7 +44,7 @@ arithbalance(e1p, oper, e2p) /* 3.1.2.5 */
|
||||
have a floating type, in which case the flags shouldn't
|
||||
travel upward in the expression tree.
|
||||
*/
|
||||
register int t1, t2, u1, u2;
|
||||
int t1, t2, u1, u2;
|
||||
int shifting = (oper == LEFT || oper == RIGHT
|
||||
|| oper == LEFTAB || oper == RIGHTAB);
|
||||
int ptrdiff = 0;
|
||||
@ -53,7 +53,7 @@ arithbalance(e1p, oper, e2p) /* 3.1.2.5 */
|
||||
t2 = any2arith(e2p, oper);
|
||||
|
||||
if (int_size != pointer_size) {
|
||||
if (ptrdiff = ((*e1p)->ex_flags & EX_PTRDIFF)
|
||||
if ((ptrdiff = ((*e1p)->ex_flags & EX_PTRDIFF))
|
||||
|| ((*e2p)->ex_flags & EX_PTRDIFF)) {
|
||||
if (!((*e1p)->ex_flags & EX_PTRDIFF) && t1 == LONG)
|
||||
ptrdiff = 0;
|
||||
@ -82,10 +82,16 @@ arithbalance(e1p, oper, e2p) /* 3.1.2.5 */
|
||||
return;
|
||||
} else if (t2 == LNGDBL) {
|
||||
if (t1 != LNGDBL)
|
||||
{
|
||||
if (t1 == DOUBLE || t1 == FLOAT)
|
||||
{
|
||||
float2float(e1p, lngdbl_type);
|
||||
}
|
||||
else
|
||||
{
|
||||
int2float(e1p, lngdbl_type);
|
||||
}
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
@ -173,8 +179,7 @@ arithbalance(e1p, oper, e2p) /* 3.1.2.5 */
|
||||
}
|
||||
}
|
||||
|
||||
relbalance(e1p, oper, e2p)
|
||||
register struct expr **e1p, **e2p;
|
||||
void relbalance(struct expr **e1p, int oper, struct expr **e2p)
|
||||
{
|
||||
/* The expressions *e1p and *e2p are balanced to be operands
|
||||
of the relational operator oper, or the ':'.
|
||||
@ -183,7 +188,7 @@ relbalance(e1p, oper, e2p)
|
||||
allows assignments of a null-pointer to a function
|
||||
pointer.
|
||||
*/
|
||||
register struct expr *e1 = *e1p, *e2 = *e2p;
|
||||
struct expr *e1 = *e1p, *e2 = *e2p;
|
||||
struct expr *tmpexpr;
|
||||
|
||||
if (e1->ex_type->tp_fund == POINTER
|
||||
@ -206,15 +211,13 @@ relbalance(e1p, oper, e2p)
|
||||
arithbalance(e1p, oper, e2p);
|
||||
}
|
||||
|
||||
ch3pointer(expp, oper, tp)
|
||||
struct expr **expp;
|
||||
register struct type *tp;
|
||||
void ch3pointer(struct expr **expp, int oper, struct type *tp)
|
||||
{
|
||||
/* Checks whether *expp may be compared to tp using oper,
|
||||
as described in chapter 3.3.8 and 3.3.9.
|
||||
tp is known to be a pointer.
|
||||
*/
|
||||
register struct expr *exp = *expp;
|
||||
struct expr *exp = *expp;
|
||||
|
||||
if (exp->ex_type->tp_fund == POINTER) {
|
||||
if (exp->ex_type != tp)
|
||||
@ -239,10 +242,7 @@ ch3pointer(expp, oper, tp)
|
||||
}
|
||||
}
|
||||
|
||||
int
|
||||
any2arith(expp, oper)
|
||||
register struct expr **expp;
|
||||
register int oper;
|
||||
int any2arith(struct expr **expp, int oper)
|
||||
{
|
||||
/* Turns any expression into int_type, long_type,
|
||||
float_type, double_type or lngdbl_type.
|
||||
@ -297,8 +297,7 @@ any2arith(expp, oper)
|
||||
return (*expp)->ex_type->tp_fund;
|
||||
}
|
||||
|
||||
erroneous2int(expp)
|
||||
struct expr **expp;
|
||||
void erroneous2int(struct expr **expp)
|
||||
{
|
||||
/* the (erroneous) expression *expp is replaced by an
|
||||
int expression
|
||||
@ -312,16 +311,12 @@ erroneous2int(expp)
|
||||
*expp = exp;
|
||||
}
|
||||
|
||||
struct expr *
|
||||
arith2arith(tp, oper, expr)
|
||||
struct type *tp;
|
||||
int oper;
|
||||
register struct expr *expr;
|
||||
struct expr *arith2arith(struct type *tp, int oper, struct expr *expr)
|
||||
{
|
||||
/* arith2arith constructs a new expression containing a
|
||||
run-time conversion between some arithmetic types.
|
||||
*/
|
||||
register struct expr *new = new_expr();
|
||||
struct expr *new = new_expr();
|
||||
|
||||
new->ex_file = expr->ex_file;
|
||||
new->ex_line = expr->ex_line;
|
||||
@ -330,18 +325,15 @@ arith2arith(tp, oper, expr)
|
||||
return new_oper(tp, new, oper, expr);
|
||||
}
|
||||
|
||||
int
|
||||
int2int(expp, tp)
|
||||
struct expr **expp;
|
||||
register struct type *tp;
|
||||
int int2int(struct expr **expp, struct type *tp)
|
||||
{
|
||||
/* The expression *expp, which is of some integral type, is
|
||||
converted to the integral type tp.
|
||||
*/
|
||||
register struct expr *exp = *expp;
|
||||
struct expr *exp = *expp;
|
||||
|
||||
if (is_cp_cst(exp)) {
|
||||
register struct type *tp1 = exp->ex_type;
|
||||
struct type *tp1 = exp->ex_type;
|
||||
|
||||
exp->ex_type = tp;
|
||||
if (! tp1->tp_unsigned && tp->tp_unsigned) {
|
||||
@ -371,14 +363,12 @@ int2int(expp, tp)
|
||||
/* With compile-time constants, we don't set fp_used, since this is done
|
||||
* only when necessary in eval.c.
|
||||
*/
|
||||
int2float(expp, tp)
|
||||
register struct expr **expp;
|
||||
struct type *tp;
|
||||
void int2float(struct expr **expp, struct type *tp)
|
||||
{
|
||||
/* The expression *expp, which is of some integral type, is
|
||||
converted to the floating type tp.
|
||||
*/
|
||||
register struct expr *exp = *expp;
|
||||
struct expr *exp = *expp;
|
||||
int uns = exp->ex_type->tp_unsigned;
|
||||
|
||||
if (is_cp_cst(exp)) {
|
||||
@ -392,14 +382,12 @@ int2float(expp, tp)
|
||||
}
|
||||
}
|
||||
|
||||
float2int(expp, tp)
|
||||
struct expr **expp;
|
||||
struct type *tp;
|
||||
void float2int(struct expr **expp, struct type *tp)
|
||||
{
|
||||
/* The expression *expp, which is of some floating type, is
|
||||
converted to the integral type tp.
|
||||
*/
|
||||
register struct expr *ex = *expp;
|
||||
struct expr *ex = *expp;
|
||||
|
||||
if (is_fp_cst(ex)) {
|
||||
arith ar = flt_flt2arith(&ex->FL_ARITH, tp->tp_unsigned);
|
||||
@ -420,9 +408,7 @@ float2int(expp, tp)
|
||||
}
|
||||
}
|
||||
|
||||
float2float(expp, tp)
|
||||
register struct expr **expp;
|
||||
struct type *tp;
|
||||
void float2float(struct expr**expp, struct type *tp)
|
||||
{
|
||||
/* The expression *expp, which is of some floating type, is
|
||||
converted to the floating type tp.
|
||||
@ -438,8 +424,7 @@ float2float(expp, tp)
|
||||
}
|
||||
}
|
||||
|
||||
array2pointer(exp)
|
||||
register struct expr *exp;
|
||||
void array2pointer(struct expr *exp)
|
||||
{
|
||||
/* The expression, which must be an array, is converted
|
||||
to a pointer.
|
||||
@ -449,8 +434,7 @@ array2pointer(exp)
|
||||
, (arith)0, NO_PROTO);
|
||||
}
|
||||
|
||||
function2pointer(exp)
|
||||
register struct expr *exp;
|
||||
void function2pointer(struct expr *exp)
|
||||
{
|
||||
/* The expression, which must be a function, is converted
|
||||
to a pointer to the function.
|
||||
@ -459,8 +443,7 @@ function2pointer(exp)
|
||||
(arith)0, NO_PROTO);
|
||||
}
|
||||
|
||||
string2pointer(ex)
|
||||
register struct expr *ex;
|
||||
void string2pointer(struct expr *ex)
|
||||
{
|
||||
/* The expression, which must be a string constant, is converted
|
||||
to a pointer to the string-containing area.
|
||||
@ -474,11 +457,9 @@ string2pointer(ex)
|
||||
ex->VL_VALUE = (arith)0;
|
||||
}
|
||||
|
||||
opnd2integral(expp, oper)
|
||||
register struct expr **expp;
|
||||
int oper;
|
||||
void opnd2integral(struct expr **expp, int oper)
|
||||
{
|
||||
register int fund = (*expp)->ex_type->tp_fund;
|
||||
int fund = (*expp)->ex_type->tp_fund;
|
||||
|
||||
if (fund != INT && fund != LONG) {
|
||||
expr_error(*expp, "%s operand to %s",
|
||||
@ -488,9 +469,7 @@ opnd2integral(expp, oper)
|
||||
}
|
||||
}
|
||||
|
||||
opnd2logical(expp, oper)
|
||||
register struct expr **expp;
|
||||
int oper;
|
||||
void opnd2logical(struct expr **expp, int oper)
|
||||
{
|
||||
int fund = (*expp)->ex_type->tp_fund;
|
||||
|
||||
@ -526,8 +505,7 @@ opnd2logical(expp, oper)
|
||||
}
|
||||
}
|
||||
|
||||
opnd2test(expp, oper)
|
||||
register struct expr **expp;
|
||||
void opnd2test(struct expr **expp, int oper)
|
||||
{
|
||||
opnd2logical(expp, oper);
|
||||
if ((*expp)->ex_class == Oper) {
|
||||
@ -551,8 +529,7 @@ opnd2test(expp, oper)
|
||||
ch3bin(expp, NOTEQUAL, intexpr((arith)0, INT));
|
||||
}
|
||||
|
||||
any2opnd(expp, oper)
|
||||
register struct expr **expp;
|
||||
void any2opnd(struct expr **expp, int oper)
|
||||
{
|
||||
if (!*expp)
|
||||
return;
|
||||
@ -563,7 +540,9 @@ any2opnd(expp, oper)
|
||||
case CHAR:
|
||||
case SHORT:
|
||||
case ENUM:
|
||||
/* case FLOAT: /* not necessary anymore */
|
||||
#if 0
|
||||
case FLOAT: /* not necessary anymore */
|
||||
#endif
|
||||
any2arith(expp, oper);
|
||||
break;
|
||||
case ARRAY:
|
||||
@ -584,8 +563,7 @@ any2opnd(expp, oper)
|
||||
}
|
||||
}
|
||||
|
||||
any2parameter(expp)
|
||||
register struct expr **expp;
|
||||
void any2parameter(struct expr **expp)
|
||||
{
|
||||
/* To handle default argument promotions
|
||||
*/
|
||||
@ -598,14 +576,13 @@ any2parameter(expp)
|
||||
}
|
||||
|
||||
#ifndef NOBITFIELD
|
||||
field2arith(expp)
|
||||
register struct expr **expp;
|
||||
void field2arith(struct expr **expp)
|
||||
{
|
||||
/* The expression to extract the bitfield value from the
|
||||
memory word is put in the tree.
|
||||
*/
|
||||
register struct type *tp = (*expp)->ex_type->tp_up;
|
||||
register struct field *fd = (*expp)->ex_type->tp_field;
|
||||
struct type *tp = (*expp)->ex_type->tp_up;
|
||||
struct field *fd = (*expp)->ex_type->tp_field;
|
||||
|
||||
(*expp)->ex_type = word_type;
|
||||
|
||||
@ -630,8 +607,7 @@ field2arith(expp)
|
||||
/* switch_sign_fp() negates the given floating constant expression,
|
||||
* and frees the string representing the old value.
|
||||
*/
|
||||
switch_sign_fp(expr)
|
||||
register struct expr *expr;
|
||||
void switch_sign_fp(struct expr *expr)
|
||||
{
|
||||
flt_umin(&(expr->FL_ARITH));
|
||||
}
|
||||
|
||||
@ -30,3 +30,13 @@
|
||||
#define arith_size (sizeof(arith))
|
||||
#define arith_sign ((arith) 1 << (arith_size * 8 - 1))
|
||||
#define max_arith (~arith_sign)
|
||||
|
||||
struct expr;
|
||||
struct type;
|
||||
|
||||
void erroneous2int(struct expr **expp);
|
||||
int int2int(struct expr **expp, struct type *tp);
|
||||
void int2float(struct expr **expp, struct type *tp);
|
||||
void float2float(struct expr**expp, struct type *tp);
|
||||
void field2arith(struct expr **expp);
|
||||
void ch3pointer(struct expr **expp, int oper, struct type *tp);
|
||||
@ -18,9 +18,11 @@
|
||||
#include "label.h"
|
||||
#include "stack.h"
|
||||
#include "Lpars.h"
|
||||
extern arith NewLocal();
|
||||
#define LocalPtrVar() NewLocal(pointer_size, pointer_align, reg_pointer, REGISTER)
|
||||
#define LocalIntVar() NewLocal(int_size, int_align, reg_any, REGISTER)
|
||||
|
||||
static void copy_loop(arith sz, arith src, arith dst);
|
||||
|
||||
#endif /* STB */
|
||||
|
||||
/* Because EM does not support the loading and storing of
|
||||
@ -52,9 +54,7 @@ extern arith NewLocal();
|
||||
while we need a loop to store the stack block into a memory object.
|
||||
*/
|
||||
|
||||
suitable_sz(sz, al)
|
||||
arith sz;
|
||||
int al;
|
||||
static int suitable_sz(arith sz, int al)
|
||||
{
|
||||
return ((int)sz % (int)word_size == 0 && al % word_align == 0) ||
|
||||
(
|
||||
@ -64,9 +64,7 @@ suitable_sz(sz, al)
|
||||
);
|
||||
}
|
||||
|
||||
store_block(sz, al)
|
||||
arith sz;
|
||||
int al;
|
||||
void store_block(arith sz, int al)
|
||||
{
|
||||
if (suitable_sz(sz, al))
|
||||
C_sti(sz);
|
||||
@ -102,9 +100,7 @@ store_block(sz, al)
|
||||
}
|
||||
}
|
||||
|
||||
load_block(sz, al)
|
||||
arith sz;
|
||||
int al;
|
||||
void load_block(arith sz, int al)
|
||||
{
|
||||
|
||||
if (suitable_sz(sz, al))
|
||||
@ -138,9 +134,7 @@ load_block(sz, al)
|
||||
}
|
||||
}
|
||||
|
||||
copy_block(sz, al)
|
||||
arith sz;
|
||||
int al;
|
||||
void copy_block(arith sz, int al)
|
||||
{
|
||||
|
||||
if (suitable_sz(sz, al))
|
||||
@ -167,8 +161,7 @@ copy_block(sz, al)
|
||||
}
|
||||
|
||||
#ifndef STB
|
||||
copy_loop(sz, src, dst)
|
||||
arith sz, src, dst;
|
||||
static void copy_loop(arith sz, arith src, arith dst)
|
||||
{
|
||||
/* generate inline byte-copy loop */
|
||||
label l_cont = text_label(), l_stop = text_label();
|
||||
|
||||
8
lang/cem/cemcom.ansi/blocks.h
Normal file
8
lang/cem/cemcom.ansi/blocks.h
Normal file
@ -0,0 +1,8 @@
|
||||
#ifndef LANG_CEM_CEMCOM_ANSI_BLOCKS_H
|
||||
#define LANG_CEM_CEMCOM_ANSI_BLOCKS_H
|
||||
|
||||
void store_block(arith sz, int al);
|
||||
void load_block(arith sz, int al);
|
||||
void copy_block(arith sz, int al);
|
||||
|
||||
#endif
|
||||
@ -20,26 +20,32 @@
|
||||
#include "Lpars.h"
|
||||
#include "assert.h"
|
||||
#include "file_info.h"
|
||||
#include "ch3.h"
|
||||
#include "ch3bin.h"
|
||||
#include "decspecs.h"
|
||||
#include "conversion.h"
|
||||
#include <symbol2str.h>
|
||||
|
||||
extern char options[];
|
||||
extern char *symbol2str();
|
||||
extern struct type *qualifier_type();
|
||||
|
||||
static int check_pseudoproto(struct proto *pl, struct proto *opl, int diag);
|
||||
static int legal_mixture(struct type *tp, struct type *otp, int diag);
|
||||
static int equal_proto(struct proto *pl, struct proto *opl, int diag);
|
||||
static int is_arith_type(struct type *tp);
|
||||
|
||||
/* Most expression-handling routines have a pointer to a
|
||||
(struct type *) as first parameter. The object under the pointer
|
||||
gets updated in the process.
|
||||
*/
|
||||
|
||||
ch3sel(expp, oper, idf)
|
||||
struct expr **expp;
|
||||
struct idf *idf;
|
||||
void ch3sel(struct expr **expp, int oper, struct idf *idf)
|
||||
{
|
||||
/* The selector idf is applied to *expp; oper may be '.' or
|
||||
ARROW.
|
||||
*/
|
||||
register struct expr *exp;
|
||||
register struct type *tp;
|
||||
register struct sdef *sd;
|
||||
struct expr *exp;
|
||||
struct type *tp;
|
||||
struct sdef *sd;
|
||||
|
||||
any2opnd(expp, oper);
|
||||
exp = *expp;
|
||||
@ -162,8 +168,7 @@ ch3sel(expp, oper, idf)
|
||||
*expp = exp;
|
||||
}
|
||||
|
||||
ch3incr(expp, oper)
|
||||
struct expr **expp;
|
||||
void ch3incr(struct expr **expp, int oper)
|
||||
{
|
||||
/* The monadic prefix/postfix incr/decr operator oper is
|
||||
applied to *expp.
|
||||
@ -171,17 +176,15 @@ ch3incr(expp, oper)
|
||||
ch3asgn(expp, oper, intexpr((arith)1, INT));
|
||||
}
|
||||
|
||||
ch3cast(expp, oper, tp)
|
||||
register struct expr **expp;
|
||||
register struct type *tp;
|
||||
void ch3cast(struct expr **expp, int oper, struct type *tp)
|
||||
{
|
||||
/* The expression *expp is cast to type tp; the cast is
|
||||
caused by the operator oper. If the cast has
|
||||
to be passed on to run time, its left operand will be an
|
||||
expression of class Type.
|
||||
*/
|
||||
register struct type *oldtp;
|
||||
register struct expr *exp = *expp;
|
||||
struct type *oldtp;
|
||||
struct expr *exp = *expp;
|
||||
int qual_lev, ascompat = 0;
|
||||
|
||||
if (oper == RETURN && tp->tp_fund == VOID) {
|
||||
@ -410,9 +413,7 @@ ch3cast(expp, oper, tp)
|
||||
|
||||
/* Determine whether two types are equal.
|
||||
*/
|
||||
equal_type(tp, otp, qual_lev, diag)
|
||||
register struct type *tp, *otp;
|
||||
int qual_lev, diag;
|
||||
int equal_type(struct type *tp, struct type *otp, int qual_lev, int diag)
|
||||
{
|
||||
if (tp == otp)
|
||||
return 1;
|
||||
@ -473,8 +474,7 @@ equal_type(tp, otp, qual_lev, diag)
|
||||
}
|
||||
}
|
||||
|
||||
check_pseudoproto(pl, opl, diag)
|
||||
register struct proto *pl, *opl;
|
||||
static int check_pseudoproto(struct proto *pl, struct proto *opl, int diag)
|
||||
{
|
||||
int retval = 1;
|
||||
|
||||
@ -517,13 +517,11 @@ check_pseudoproto(pl, opl, diag)
|
||||
return retval;
|
||||
}
|
||||
|
||||
legal_mixture(tp, otp, diag)
|
||||
struct type *tp, *otp;
|
||||
int diag;
|
||||
static int legal_mixture(struct type *tp, struct type *otp, int diag)
|
||||
{
|
||||
struct proto *pl = tp->tp_proto, *opl = otp->tp_proto;
|
||||
int retval = 1;
|
||||
register struct proto *prot;
|
||||
struct proto *prot;
|
||||
int fund;
|
||||
|
||||
ASSERT( (pl != 0) ^ (opl != 0));
|
||||
@ -560,9 +558,7 @@ legal_mixture(tp, otp, diag)
|
||||
return retval;
|
||||
}
|
||||
|
||||
equal_proto(pl, opl, diag)
|
||||
register struct proto *pl, *opl;
|
||||
int diag;
|
||||
static int equal_proto(struct proto *pl, struct proto *opl, int diag)
|
||||
{
|
||||
if (pl == opl)
|
||||
return 1;
|
||||
@ -584,11 +580,9 @@ equal_proto(pl, opl, diag)
|
||||
}
|
||||
|
||||
/* check if a type has a consqualified member */
|
||||
recurqual(tp, qual)
|
||||
struct type *tp;
|
||||
int qual;
|
||||
int recurqual(struct type *tp, int qual)
|
||||
{
|
||||
register struct sdef *sdf;
|
||||
struct sdef *sdf;
|
||||
|
||||
ASSERT(tp);
|
||||
|
||||
@ -608,9 +602,7 @@ int qual;
|
||||
return 0;
|
||||
}
|
||||
|
||||
ch3asgn(expp, oper, expr)
|
||||
struct expr **expp;
|
||||
struct expr *expr;
|
||||
void ch3asgn(struct expr **expp, int oper, struct expr *expr)
|
||||
{
|
||||
/* The assignment operators.
|
||||
"f op= e" should be interpreted as
|
||||
@ -625,7 +617,7 @@ ch3asgn(expp, oper, expr)
|
||||
f (typeof (f op e))e
|
||||
EVAL should however take care of evaluating (typeof (f op e))f
|
||||
*/
|
||||
register struct expr *exp = *expp;
|
||||
struct expr *exp = *expp;
|
||||
int fund = exp->ex_type->tp_fund;
|
||||
struct type *tp;
|
||||
char *oper_string = symbol2str(oper);
|
||||
@ -685,9 +677,7 @@ ch3asgn(expp, oper, expr)
|
||||
|
||||
/* Some interesting (?) questions answered.
|
||||
*/
|
||||
int
|
||||
is_integral_type(tp)
|
||||
register struct type *tp;
|
||||
int is_integral_type(struct type *tp)
|
||||
{
|
||||
switch (tp->tp_fund) {
|
||||
case CHAR:
|
||||
@ -705,9 +695,7 @@ is_integral_type(tp)
|
||||
}
|
||||
}
|
||||
|
||||
int
|
||||
is_arith_type(tp)
|
||||
register struct type *tp;
|
||||
static int is_arith_type(struct type *tp)
|
||||
{
|
||||
switch (tp->tp_fund) {
|
||||
case CHAR:
|
||||
|
||||
17
lang/cem/cemcom.ansi/ch3.h
Normal file
17
lang/cem/cemcom.ansi/ch3.h
Normal file
@ -0,0 +1,17 @@
|
||||
/*
|
||||
* The Amsterdam Compiler Kit
|
||||
* See the copyright notice in the ACK home directory, in the file "Copyright".
|
||||
*/
|
||||
|
||||
#ifndef LANG_CEM_CEMCOM_ANSI_CH3_H
|
||||
#define LANG_CEM_CEMCOM_ANSI_CH3_H
|
||||
|
||||
void ch3cast(struct expr **expp, int oper, struct type *tp);
|
||||
void ch3sel(struct expr **expp, int oper, struct idf *idf);
|
||||
void ch3incr(struct expr **expp, int oper);
|
||||
int equal_type(struct type *tp, struct type *otp, int qual_lev, int diag);
|
||||
int recurqual(struct type *tp, int qual);
|
||||
void ch3asgn(struct expr **expp, int oper, struct expr *expr);
|
||||
int is_integral_type(struct type *tp);
|
||||
|
||||
#endif
|
||||
@ -18,9 +18,19 @@
|
||||
#include "expr.h"
|
||||
#include "Lpars.h"
|
||||
#include "sizes.h"
|
||||
#include "ch3.h"
|
||||
#include "ch3bin.h"
|
||||
#include "ch3mon.h"
|
||||
#include "cstoper.h"
|
||||
#include <symbol2str.h>
|
||||
|
||||
extern char options[];
|
||||
extern char *symbol2str();
|
||||
|
||||
static void pntminuspnt(struct expr **expp, int oper, struct expr *expr);
|
||||
static int arg_switched(int oper);
|
||||
static void mk_binop(struct expr **expp, int oper, struct expr *expr, int commutative);
|
||||
static void pointer_arithmetic(struct expr **expp1, int oper, struct expr **expp2);
|
||||
static void pointer_binary(struct expr **expp, int oper, struct expr *expr);
|
||||
|
||||
/* This chapter asks for the repeated application of code to handle
|
||||
an operation that may be executed at compile time or at run time,
|
||||
@ -35,9 +45,7 @@ extern char *symbol2str();
|
||||
#define commutative_binop(expp, oper, expr) mk_binop(expp, oper, expr, 1)
|
||||
#define non_commutative_relop(expp, oper, expr) mk_binop(expp, oper, expr, 1)
|
||||
|
||||
ch3bin(expp, oper, expr)
|
||||
register struct expr **expp;
|
||||
struct expr *expr;
|
||||
void ch3bin(struct expr **expp, int oper, struct expr *expr)
|
||||
{
|
||||
/* apply binary operator oper between *expp and expr.
|
||||
NB: don't swap operands if op is one of the op= operators!!!
|
||||
@ -295,8 +303,7 @@ ch3bin(expp, oper, expr)
|
||||
}
|
||||
}
|
||||
|
||||
pntminuspnt(expp, oper, expr)
|
||||
register struct expr **expp, *expr;
|
||||
static void pntminuspnt(struct expr **expp, int oper, struct expr *expr)
|
||||
{
|
||||
/* Subtracting two pointers is so complicated it merits a
|
||||
routine of its own.
|
||||
@ -327,8 +334,7 @@ pntminuspnt(expp, oper, expr)
|
||||
* when the arguments are switched. This is special for some relational
|
||||
* operators.
|
||||
*/
|
||||
int
|
||||
arg_switched(oper)
|
||||
static int arg_switched(int oper)
|
||||
{
|
||||
switch (oper) {
|
||||
case '<': return '>';
|
||||
@ -339,9 +345,7 @@ arg_switched(oper)
|
||||
}
|
||||
}
|
||||
|
||||
mk_binop(expp, oper, expr, commutative)
|
||||
struct expr **expp;
|
||||
register struct expr *expr;
|
||||
static void mk_binop(struct expr **expp, int oper, struct expr *expr, int commutative)
|
||||
{
|
||||
/* Constructs in *expp the operation indicated by the operands.
|
||||
"commutative" indicates whether "oper" is a commutative
|
||||
@ -365,8 +369,7 @@ mk_binop(expp, oper, expr, commutative)
|
||||
}
|
||||
}
|
||||
|
||||
pointer_arithmetic(expp1, oper, expp2)
|
||||
register struct expr **expp1, **expp2;
|
||||
static void pointer_arithmetic(struct expr **expp1, int oper, struct expr **expp2)
|
||||
{
|
||||
int typ;
|
||||
/* prepares the integral expression expp2 in order to
|
||||
@ -386,8 +389,7 @@ pointer_arithmetic(expp1, oper, expp2)
|
||||
);
|
||||
}
|
||||
|
||||
pointer_binary(expp, oper, expr)
|
||||
register struct expr **expp, *expr;
|
||||
static void pointer_binary(struct expr **expp, int oper, struct expr *expr)
|
||||
{
|
||||
/* constructs the pointer arithmetic expression out of
|
||||
a pointer expression, a binary operator and an integral
|
||||
|
||||
11
lang/cem/cemcom.ansi/ch3bin.h
Normal file
11
lang/cem/cemcom.ansi/ch3bin.h
Normal file
@ -0,0 +1,11 @@
|
||||
/*
|
||||
* The Amsterdam Compiler Kit
|
||||
* See the copyright notice in the ACK home directory, in the file "Copyright".
|
||||
*/
|
||||
|
||||
#ifndef LANG_CEM_CEMCOM_ANSI_CH3BIN_H
|
||||
#define LANG_CEM_CEMCOM_ANSI_CH3BIN_H
|
||||
|
||||
void ch3bin(struct expr **expp, int oper, struct expr *expr);
|
||||
|
||||
#endif
|
||||
@ -18,13 +18,15 @@
|
||||
#include "idf.h"
|
||||
#include "def.h"
|
||||
#include "sizes.h"
|
||||
#include "ch3.h"
|
||||
#include "ch3mon.h"
|
||||
#include <symbol2str.h>
|
||||
|
||||
extern char options[];
|
||||
extern arith full_mask[/*MAXSIZE + 1*/]; /* cstoper.c */
|
||||
char *symbol2str(int tok);
|
||||
|
||||
ch3mon(oper, expp)
|
||||
register struct expr **expp;
|
||||
|
||||
void ch3mon(int oper, struct expr **expp)
|
||||
{
|
||||
/* The monadic prefix operator oper is applied to *expp.
|
||||
*/
|
||||
|
||||
11
lang/cem/cemcom.ansi/ch3mon.h
Normal file
11
lang/cem/cemcom.ansi/ch3mon.h
Normal file
@ -0,0 +1,11 @@
|
||||
/*
|
||||
* The Amsterdam Compiler Kit
|
||||
* See the copyright notice in the ACK home directory, in the file "Copyright".
|
||||
*/
|
||||
|
||||
#ifndef LANG_CEM_CEMCOM_ANSI_CH3MON_H
|
||||
#define LANG_CEM_CEMCOM_ANSI_CH3MON_H
|
||||
|
||||
void ch3mon(int oper, struct expr **expp);
|
||||
|
||||
#endif
|
||||
@ -40,6 +40,12 @@
|
||||
#include "assert.h"
|
||||
#include "LLlex.h"
|
||||
#include "align.h"
|
||||
#include "blocks.h"
|
||||
#include "code_c.h"
|
||||
#include "conversion.h"
|
||||
|
||||
#include <symbol2str.h>
|
||||
|
||||
#ifdef LINT
|
||||
#include "l_lint.h"
|
||||
#endif /* LINT */
|
||||
@ -51,7 +57,6 @@ label lab_count = 1;
|
||||
label datlab_count = 1;
|
||||
|
||||
int fp_used;
|
||||
extern arith NewLocal(); /* util.c */
|
||||
|
||||
/* global function info */
|
||||
char *func_name;
|
||||
@ -66,12 +71,14 @@ static int pro_id;
|
||||
#endif /* USE_TMP */
|
||||
|
||||
extern char options[];
|
||||
extern char *symbol2str();
|
||||
extern char *source;
|
||||
|
||||
static void def_strings(struct string_cst *sc);
|
||||
static void prc_entry(char *name);
|
||||
static void prc_exit();
|
||||
|
||||
#ifndef LINT
|
||||
init_code(dst_file)
|
||||
char *dst_file;
|
||||
void init_code(char *dst_file)
|
||||
{
|
||||
/* init_code() initialises the output file on which the
|
||||
compact EM code is written
|
||||
@ -108,10 +115,7 @@ init_code(dst_file)
|
||||
|
||||
struct string_cst *str_list = 0;
|
||||
|
||||
label
|
||||
code_string(val, len)
|
||||
char *val;
|
||||
int len;
|
||||
label code_string(char *val, int len)
|
||||
{
|
||||
register struct string_cst *sc = new_string_cst();
|
||||
label dlb = data_label();
|
||||
@ -125,8 +129,7 @@ code_string(val, len)
|
||||
return dlb;
|
||||
}
|
||||
|
||||
def_strings(sc)
|
||||
register struct string_cst *sc;
|
||||
static void def_strings(struct string_cst *sc)
|
||||
{
|
||||
while (sc) {
|
||||
struct string_cst *sc1 = sc;
|
||||
@ -140,7 +143,8 @@ def_strings(sc)
|
||||
}
|
||||
|
||||
/* flush_strings() is called from program.g after each external definition */
|
||||
flush_strings() {
|
||||
void flush_strings()
|
||||
{
|
||||
if (str_list) {
|
||||
def_strings(str_list);
|
||||
str_list = 0;
|
||||
@ -148,7 +152,7 @@ flush_strings() {
|
||||
}
|
||||
|
||||
#ifndef LINT
|
||||
end_code()
|
||||
void end_code()
|
||||
{
|
||||
/* end_code() performs the actions to be taken when closing
|
||||
the output stream.
|
||||
@ -163,19 +167,19 @@ end_code()
|
||||
#endif /* LINT */
|
||||
|
||||
#ifdef PREPEND_SCOPES
|
||||
prepend_scopes()
|
||||
void prepend_scopes()
|
||||
{
|
||||
/* prepend_scopes() runs down the list of global idf's
|
||||
and generates those exa's, exp's, ina's and inp's
|
||||
that superior hindsight has provided.
|
||||
*/
|
||||
register struct stack_entry *se = local_level->sl_entry;
|
||||
struct stack_entry *se = local_level->sl_entry;
|
||||
|
||||
#ifdef USE_TMP
|
||||
C_beginpart(tmp_id);
|
||||
#endif /* USE_TMP */
|
||||
while (se != 0) {
|
||||
register struct def *df = se->se_idf->id_def;
|
||||
struct def *df = se->se_idf->id_def;
|
||||
|
||||
if (df && (df->df_initialized || df->df_used || df->df_alloc)) {
|
||||
code_scope(se->se_idf->id_text, df);
|
||||
@ -188,9 +192,7 @@ prepend_scopes()
|
||||
}
|
||||
#endif /* PREPEND_SCOPES */
|
||||
|
||||
code_scope(text, def)
|
||||
char *text;
|
||||
register struct def *def;
|
||||
void code_scope(char *text, struct def *def)
|
||||
{
|
||||
/* generates code for one name, text, of the storage class
|
||||
as given by def, if meaningful.
|
||||
@ -221,9 +223,8 @@ static int struct_return;
|
||||
static char *last_fn_given = (char *)0;
|
||||
static label file_name_label;
|
||||
|
||||
begin_proc(ds, idf) /* to be called when entering a procedure */
|
||||
struct decspecs *ds;
|
||||
struct idf *idf;
|
||||
/* to be called when entering a procedure */
|
||||
void begin_proc(struct decspecs *ds, struct idf *idf)
|
||||
{
|
||||
/* begin_proc() is called at the entrance of a new function
|
||||
and performs the necessary code generation:
|
||||
@ -233,8 +234,8 @@ begin_proc(ds, idf) /* to be called when entering a procedure */
|
||||
does not fit in the return area
|
||||
- a fil pseudo instruction
|
||||
*/
|
||||
register char *name = idf->id_text;
|
||||
register struct def *def = idf->id_def;
|
||||
char *name = idf->id_text;
|
||||
struct def *def = idf->id_def;
|
||||
|
||||
/* idf->id_def does not indicate the right def structure
|
||||
* when the function being defined has a parameter of the
|
||||
@ -320,8 +321,7 @@ begin_proc(ds, idf) /* to be called when entering a procedure */
|
||||
#endif
|
||||
}
|
||||
|
||||
end_proc(fbytes)
|
||||
arith fbytes;
|
||||
void end_proc(arith fbytes)
|
||||
{
|
||||
/* end_proc() deals with the code to be generated at the end of
|
||||
a function, as there is:
|
||||
@ -391,7 +391,7 @@ end_proc(fbytes)
|
||||
options['n'] = optionsn;
|
||||
}
|
||||
|
||||
do_return()
|
||||
void do_return()
|
||||
{
|
||||
/* do_return handles the case of a return without expression.
|
||||
This version branches to the return label, which is
|
||||
@ -404,8 +404,7 @@ do_return()
|
||||
C_bra(return2_label);
|
||||
}
|
||||
|
||||
do_return_expr(expr)
|
||||
struct expr *expr;
|
||||
void do_return_expr(struct expr *expr)
|
||||
{
|
||||
/* do_return_expr() generates the expression and the jump for
|
||||
a return statement with an expression.
|
||||
@ -420,11 +419,12 @@ do_return_expr(expr)
|
||||
return_expr_occurred = 1;
|
||||
}
|
||||
|
||||
code_declaration(idf, expr, lvl, sc)
|
||||
register struct idf *idf; /* idf to be declared */
|
||||
struct expr *expr; /* initialisation; NULL if absent */
|
||||
int lvl; /* declaration level */
|
||||
int sc; /* storage class, as in the declaration */
|
||||
/* struct idf *idf idf to be declared
|
||||
* struct expr *expr initialisation; NULL if absent
|
||||
* int lvl declaration level
|
||||
* int sc storage class, as in the declaration
|
||||
*/
|
||||
void code_declaration(struct idf *idf, struct expr *expr, int lvl, int sc)
|
||||
{
|
||||
/* code_declaration() does the actual declaration of the
|
||||
variable indicated by "idf" on declaration level "lvl".
|
||||
@ -445,8 +445,8 @@ code_declaration(idf, expr, lvl, sc)
|
||||
The sc is the actual storage class, as given in the
|
||||
declaration.
|
||||
*/
|
||||
register struct def *def = idf->id_def;
|
||||
register arith size = def->df_type->tp_size;
|
||||
struct def *def = idf->id_def;
|
||||
arith size = def->df_type->tp_size;
|
||||
int fund = def->df_type->tp_fund;
|
||||
int def_sc = def->df_sc;
|
||||
|
||||
@ -532,17 +532,15 @@ code_declaration(idf, expr, lvl, sc)
|
||||
}
|
||||
}
|
||||
|
||||
loc_init(expr, id)
|
||||
struct expr *expr;
|
||||
struct idf *id;
|
||||
void loc_init(struct expr *expr, struct idf *id)
|
||||
{
|
||||
/* loc_init() generates code for the assignment of
|
||||
expression expr to the local variable described by id.
|
||||
It frees the expression afterwards.
|
||||
*/
|
||||
register struct expr *e = expr;
|
||||
register struct def *df = id->id_def;
|
||||
register struct type *tp = df->df_type;
|
||||
struct expr *e = expr;
|
||||
struct def *df = id->id_def;
|
||||
struct type *tp = df->df_type;
|
||||
static arith tmpoffset = 0;
|
||||
static arith unknownsize = 0;
|
||||
|
||||
@ -610,12 +608,11 @@ loc_init(expr, id)
|
||||
}
|
||||
}
|
||||
|
||||
bss(idf)
|
||||
register struct idf *idf;
|
||||
void bss(struct idf *idf)
|
||||
{
|
||||
/* bss() allocates bss space for the global idf.
|
||||
*/
|
||||
register struct def *df = idf->id_def;
|
||||
struct def *df = idf->id_def;
|
||||
|
||||
#ifndef PREPEND_SCOPES
|
||||
code_scope(idf->id_text, df);
|
||||
@ -641,15 +638,13 @@ bss(idf)
|
||||
}
|
||||
}
|
||||
|
||||
formal_cvt(hasproto,df)
|
||||
int hasproto;
|
||||
register struct def *df;
|
||||
void formal_cvt(int hasproto, struct def *df)
|
||||
{
|
||||
/* formal_cvt() converts a formal parameter of type char or
|
||||
short from int to that type. It also converts a formal
|
||||
parameter of type float from a double to a float.
|
||||
*/
|
||||
register struct type *tp = df->df_type;
|
||||
struct type *tp = df->df_type;
|
||||
|
||||
if (tp->tp_size != int_size &&
|
||||
(tp->tp_fund == CHAR || tp->tp_fund == SHORT)
|
||||
@ -673,9 +668,7 @@ formal_cvt(hasproto,df)
|
||||
#ifdef LINT
|
||||
/*ARGSUSED*/
|
||||
#endif /* LINT */
|
||||
code_expr(expr, val, code, tlbl, flbl)
|
||||
struct expr *expr;
|
||||
label tlbl, flbl;
|
||||
void code_expr(struct expr *expr, int val, int code, label tlbl, label flbl)
|
||||
{
|
||||
/* code_expr() is the parser's interface to the expression code
|
||||
generator. If line number trace is wanted, it generates a
|
||||
@ -708,9 +701,9 @@ static struct stmt_block *stmt_stack; /* top of statement stack */
|
||||
which are the only ones that are stacked, only the top of
|
||||
the stack is interesting.
|
||||
*/
|
||||
code_break()
|
||||
void code_break()
|
||||
{
|
||||
register struct stmt_block *stmt_block = stmt_stack;
|
||||
struct stmt_block *stmt_block = stmt_stack;
|
||||
|
||||
#ifdef DBSYMTAB
|
||||
if (options['g']) db_line(dot.tk_file, dot.tk_line);
|
||||
@ -726,9 +719,9 @@ code_break()
|
||||
it generates a branch instruction to the continue label of the
|
||||
innermost statement in which continue has a meaning.
|
||||
*/
|
||||
code_continue()
|
||||
void code_continue()
|
||||
{
|
||||
register struct stmt_block *stmt_block = stmt_stack;
|
||||
struct stmt_block *stmt_block = stmt_stack;
|
||||
|
||||
while (stmt_block) {
|
||||
if (stmt_block->st_continue) {
|
||||
@ -743,10 +736,9 @@ code_continue()
|
||||
error("continue not inside for, while or do");
|
||||
}
|
||||
|
||||
stack_stmt(break_label, cont_label)
|
||||
label break_label, cont_label;
|
||||
void stack_stmt(label break_label, label cont_label)
|
||||
{
|
||||
register struct stmt_block *stmt_block = new_stmt_block();
|
||||
struct stmt_block *stmt_block = new_stmt_block();
|
||||
|
||||
stmt_block->next = stmt_stack;
|
||||
stmt_block->st_break = break_label;
|
||||
@ -754,7 +746,7 @@ stack_stmt(break_label, cont_label)
|
||||
stmt_stack = stmt_block;
|
||||
}
|
||||
|
||||
unstack_stmt()
|
||||
void unstack_stmt()
|
||||
{
|
||||
/* unstack_stmt() unstacks the data of a statement
|
||||
which may contain break or continue
|
||||
@ -766,8 +758,7 @@ unstack_stmt()
|
||||
|
||||
static label prc_name;
|
||||
|
||||
prc_entry(name)
|
||||
char *name;
|
||||
static void prc_entry(char *name)
|
||||
{
|
||||
if (options['p']) {
|
||||
C_df_dlb(prc_name = data_label());
|
||||
@ -778,7 +769,7 @@ prc_entry(name)
|
||||
}
|
||||
}
|
||||
|
||||
prc_exit()
|
||||
static void prc_exit()
|
||||
{
|
||||
if (options['p']) {
|
||||
C_lae_dlb(prc_name, (arith) 0);
|
||||
@ -788,9 +779,7 @@ prc_exit()
|
||||
}
|
||||
|
||||
#ifdef DBSYMTAB
|
||||
db_line(file, line)
|
||||
char *file;
|
||||
unsigned int line;
|
||||
void db_line(char *file, unsigned int line)
|
||||
{
|
||||
static unsigned oldline;
|
||||
static char *oldfile;
|
||||
|
||||
39
lang/cem/cemcom.ansi/code_c.h
Normal file
39
lang/cem/cemcom.ansi/code_c.h
Normal file
@ -0,0 +1,39 @@
|
||||
/*
|
||||
* The Amsterdam Compiler Kit
|
||||
* See the copyright notice in the ACK home directory, in the file "Copyright".
|
||||
*/
|
||||
#ifndef LANG_CEM_CEMCOM_ANSI_CODE_H
|
||||
#define LANG_CEM_CEMCOM_ANSI_CODE_H
|
||||
|
||||
struct decspecs;
|
||||
|
||||
void init_code(char *dst_file);
|
||||
label code_string(char *val, int len);
|
||||
void flush_strings();
|
||||
void code_scope(char *text, struct def *def);
|
||||
void begin_proc(struct decspecs *ds, struct idf *idf);
|
||||
void end_proc(arith fbytes);
|
||||
void do_return();
|
||||
void do_return_expr(struct expr *expr);
|
||||
void code_declaration(struct idf *idf, struct expr *expr, int lvl, int sc);
|
||||
void loc_init(struct expr *expr, struct idf *id);
|
||||
void bss(struct idf *idf);
|
||||
void code_expr(struct expr *expr, int val, int code, label tlbl, label flbl);
|
||||
void code_break();
|
||||
void code_continue();
|
||||
void stack_stmt(label break_label, label cont_label);
|
||||
void unstack_stmt();
|
||||
|
||||
#ifdef DBSYMTAB
|
||||
void db_line(char *file, unsigned int line);
|
||||
#endif
|
||||
|
||||
#ifdef PREPEND_SCOPES
|
||||
void prepend_scopes();
|
||||
#endif
|
||||
|
||||
#ifndef LINT
|
||||
void end_code();
|
||||
#endif
|
||||
|
||||
#endif
|
||||
@ -27,13 +27,12 @@
|
||||
C??
|
||||
*/
|
||||
|
||||
static int convtype();
|
||||
static int convtype(struct type *tp);
|
||||
|
||||
conversion(from_type, to_type)
|
||||
register struct type *from_type, *to_type;
|
||||
void conversion(struct type *from_type, struct type *to_type)
|
||||
{
|
||||
register arith from_size = from_type->tp_size;
|
||||
register arith to_size = to_type->tp_size;
|
||||
arith from_size = from_type->tp_size;
|
||||
arith to_size = to_type->tp_size;
|
||||
int from_cnvtype = convtype(from_type);
|
||||
int to_cnvtype = convtype(to_type);
|
||||
|
||||
@ -126,9 +125,7 @@ conversion(from_type, to_type)
|
||||
/* convtype() returns in which category a given type falls:
|
||||
signed, unsigned or floating
|
||||
*/
|
||||
static int
|
||||
convtype(tp)
|
||||
register struct type *tp;
|
||||
static int convtype(struct type *tp)
|
||||
{
|
||||
switch (tp->tp_fund) {
|
||||
case CHAR:
|
||||
|
||||
8
lang/cem/cemcom.ansi/conversion.h
Normal file
8
lang/cem/cemcom.ansi/conversion.h
Normal file
@ -0,0 +1,8 @@
|
||||
#ifndef LANG_CEM_CEMCOM_ANSI_CONVERSION_H
|
||||
#define LANG_CEM_CEMCOM_ANSI_CONVERSION_H
|
||||
|
||||
struct type;
|
||||
|
||||
void conversion(struct type *from_type, struct type *to_type);
|
||||
|
||||
#endif
|
||||
@ -15,6 +15,7 @@
|
||||
#include "sizes.h"
|
||||
#include "Lpars.h"
|
||||
#include "assert.h"
|
||||
#include "cstoper.h"
|
||||
|
||||
/* full_mask[1] == 0XFF, full_mask[2] == 0XFFFF, .. */
|
||||
arith full_mask[MAXSIZE + 1];
|
||||
@ -24,15 +25,14 @@ arith max_unsigned; /* maximum unsigned on target machine */
|
||||
#endif /* NOCROSS */
|
||||
extern int ResultKnown;
|
||||
|
||||
cstbin(expp, oper, expr)
|
||||
register struct expr **expp, *expr;
|
||||
void cstbin(struct expr **expp, int oper, struct expr *expr)
|
||||
{
|
||||
/* The operation oper is performed on the constant
|
||||
expressions *expp(ld) and expr(ct), and the result restored in
|
||||
*expp.
|
||||
*/
|
||||
register arith o1 = (*expp)->VL_VALUE;
|
||||
register arith o2 = expr->VL_VALUE;
|
||||
arith o1 = (*expp)->VL_VALUE;
|
||||
arith o2 = expr->VL_VALUE;
|
||||
int uns = (*expp)->ex_type->tp_unsigned;
|
||||
|
||||
ASSERT(is_ld_cst(*expp) && is_cp_cst(expr));
|
||||
@ -205,13 +205,12 @@ cstbin(expp, oper, expr)
|
||||
free_expression(expr);
|
||||
}
|
||||
|
||||
cut_size(expr)
|
||||
register struct expr *expr;
|
||||
void cut_size(struct expr *expr)
|
||||
{
|
||||
/* The constant value of the expression expr is made to
|
||||
conform to the size of the type of the expression.
|
||||
*/
|
||||
register arith o1 = expr->VL_VALUE;
|
||||
arith o1 = expr->VL_VALUE;
|
||||
int uns = expr->ex_type->tp_unsigned;
|
||||
int size = (int) expr->ex_type->tp_size;
|
||||
|
||||
@ -241,10 +240,10 @@ cut_size(expr)
|
||||
expr->VL_VALUE = o1;
|
||||
}
|
||||
|
||||
init_cst()
|
||||
void init_cst()
|
||||
{
|
||||
register int i = 0;
|
||||
register arith bt = (arith)0;
|
||||
int i = 0;
|
||||
arith bt = (arith)0;
|
||||
|
||||
while (!(bt < 0)) {
|
||||
bt = (bt << 8) + 0377, i++;
|
||||
|
||||
8
lang/cem/cemcom.ansi/cstoper.h
Normal file
8
lang/cem/cemcom.ansi/cstoper.h
Normal file
@ -0,0 +1,8 @@
|
||||
#ifndef LANG_CEM_CEMCOM_ANSI_CSTOPER_H
|
||||
#define LANG_CEM_CEMCOM_ANSI_CSTOPER_H
|
||||
|
||||
void cstbin(struct expr **expp, int oper, struct expr *expr);
|
||||
void cut_size(struct expr *expr);
|
||||
void init_cst();
|
||||
|
||||
#endif
|
||||
@ -28,6 +28,7 @@
|
||||
#include "expr.h"
|
||||
#include "sizes.h"
|
||||
#include "level.h"
|
||||
#include "code_c.h"
|
||||
#ifdef LINT
|
||||
#include "l_lint.h"
|
||||
#endif /* LINT */
|
||||
|
||||
@ -20,13 +20,12 @@ extern struct type *qualifier_type();
|
||||
|
||||
struct decspecs null_decspecs;
|
||||
|
||||
do_decspecs(ds)
|
||||
register struct decspecs *ds;
|
||||
void do_decspecs(struct decspecs *ds)
|
||||
{
|
||||
/* The provisional decspecs ds as obtained from the program
|
||||
is turned into a legal consistent decspecs.
|
||||
*/
|
||||
register struct type *tp = ds->ds_type;
|
||||
struct type *tp = ds->ds_type;
|
||||
|
||||
ASSERT(level != L_FORMAL1);
|
||||
|
||||
@ -67,7 +66,7 @@ do_decspecs(ds)
|
||||
tp = int_type;
|
||||
}
|
||||
if (ds->ds_size) {
|
||||
register int ds_isshort = (ds->ds_size == SHORT);
|
||||
int ds_isshort = (ds->ds_size == SHORT);
|
||||
|
||||
if (ds->ds_typedef) goto SIZE_ERROR; /* yes */
|
||||
if (tp == int_type) {
|
||||
@ -82,7 +81,7 @@ do_decspecs(ds)
|
||||
ds->ds_notypegiven = 0;
|
||||
}
|
||||
if (ds->ds_unsigned) {
|
||||
register int ds_isunsigned = (ds->ds_unsigned == UNSIGNED);
|
||||
int ds_isunsigned = (ds->ds_unsigned == UNSIGNED);
|
||||
|
||||
if (ds->ds_typedef) goto SIGN_ERROR; /* yes */
|
||||
/*
|
||||
@ -113,13 +112,10 @@ do_decspecs(ds)
|
||||
In case of a complex type the top of the type list will be
|
||||
replaced by a qualified version.
|
||||
*/
|
||||
struct type *
|
||||
qualifier_type(tp, typequal)
|
||||
register struct type *tp;
|
||||
int typequal;
|
||||
struct type *qualifier_type(struct type *tp, int typequal)
|
||||
{
|
||||
register struct type *dtp = tp;
|
||||
register int fund = tp->tp_fund;
|
||||
struct type *dtp = tp;
|
||||
int fund = tp->tp_fund;
|
||||
|
||||
while (dtp && dtp->tp_typequal != typequal)
|
||||
dtp = dtp->next;
|
||||
|
||||
@ -17,5 +17,8 @@ struct decspecs {
|
||||
int ds_typequal; /* type qualifiers - see type.str */
|
||||
};
|
||||
|
||||
extern struct type *qualifier_type();
|
||||
extern struct decspecs null_decspecs;
|
||||
|
||||
void do_decspecs(struct decspecs *ds);
|
||||
struct type *qualifier_type(struct type *tp, int typequal);
|
||||
|
||||
|
||||
@ -30,6 +30,8 @@
|
||||
#include "align.h"
|
||||
#include "mes.h"
|
||||
#include "atw.h"
|
||||
#include "blocks.h"
|
||||
#include "conversion.h"
|
||||
#include "specials.h"
|
||||
|
||||
#define CRASH() crash("EVAL: CRASH at line %u", __LINE__)
|
||||
|
||||
@ -24,8 +24,10 @@
|
||||
#include "sizes.h"
|
||||
#include "level.h"
|
||||
#include "use_tmp.h"
|
||||
#include "cstoper.h"
|
||||
|
||||
#include <symbol2str.h>
|
||||
|
||||
extern char *symbol2str();
|
||||
extern char options[];
|
||||
extern int InSizeof;
|
||||
|
||||
|
||||
@ -18,8 +18,9 @@
|
||||
#include "expr.h"
|
||||
#include "code.h"
|
||||
#include "sizes.h"
|
||||
|
||||
extern struct expr *intexpr();
|
||||
#include "ch3.h"
|
||||
#include "ch3bin.h"
|
||||
#include "ch3mon.h"
|
||||
int InSizeof = 0; /* inside a sizeof- expression */
|
||||
int ResultKnown = 0; /* result of the expression is already known */
|
||||
|
||||
@ -31,7 +32,7 @@ int ResultKnown = 0; /* result of the expression is already known */
|
||||
}
|
||||
|
||||
/* 3.3.1 */
|
||||
primary(register struct expr **expp;) :
|
||||
primary(struct expr **expp;) :
|
||||
IDENTIFIER
|
||||
{dot2expr(expp);}
|
||||
|
|
||||
@ -48,10 +49,10 @@ primary(register struct expr **expp;) :
|
||||
* are concatenated into a single character string
|
||||
* literal.
|
||||
*/
|
||||
string(register struct expr **expp;)
|
||||
{ register int i, len;
|
||||
register char *str;
|
||||
register int fund;
|
||||
string(struct expr **expp;)
|
||||
{ int i, len;
|
||||
char *str;
|
||||
int fund;
|
||||
}
|
||||
:
|
||||
STRING
|
||||
@ -78,7 +79,7 @@ string(register struct expr **expp;)
|
||||
;
|
||||
|
||||
/* 3.3.2 */
|
||||
postfix_expression(register struct expr **expp;)
|
||||
postfix_expression(struct expr **expp;)
|
||||
{ int oper;
|
||||
struct expr *e1 = 0;
|
||||
struct idf *idf;
|
||||
@ -120,7 +121,7 @@ parameter_list(struct expr **expp;)
|
||||
%first first_of_type_specifier, type_specifier;
|
||||
|
||||
/* 3.3.3 & 3.3.4 */
|
||||
unary(register struct expr **expp;)
|
||||
unary(struct expr **expp;)
|
||||
{struct type *tp; int oper;}
|
||||
:
|
||||
%if (first_of_type_specifier(AHEAD) && AHEAD != IDENTIFIER)
|
||||
@ -143,7 +144,7 @@ unary(register struct expr **expp;)
|
||||
* mark it as used.
|
||||
* extern int i; .... sizeof(i) .... need not have a definition for i
|
||||
*/
|
||||
size_of(register struct expr **expp;)
|
||||
size_of(struct expr **expp;)
|
||||
{struct type *tp;}
|
||||
:
|
||||
SIZEOF { InSizeof++; } /* handle (sizeof(sizeof(int))) too */
|
||||
@ -322,7 +323,7 @@ binop(int *oper;) :
|
||||
{*oper = DOT;}
|
||||
;
|
||||
|
||||
asgnop(register int *oper;):
|
||||
asgnop(int *oper;):
|
||||
[ '=' | PLUSAB | MINAB | TIMESAB | DIVAB | MODAB
|
||||
| LEFTAB | RIGHTAB | ANDAB | XORAB | ORAB ]
|
||||
{ *oper = DOT; }
|
||||
|
||||
@ -26,6 +26,7 @@
|
||||
#include "align.h"
|
||||
#include "Lpars.h"
|
||||
#include "field.h"
|
||||
#include "conversion.h"
|
||||
|
||||
arith NewLocal(); /* util.c */
|
||||
extern arith full_mask[]; /* cstoper.c */
|
||||
|
||||
@ -18,9 +18,11 @@
|
||||
#include "expr.h"
|
||||
#include "sizes.h"
|
||||
#include "Lpars.h"
|
||||
#include "cstoper.h"
|
||||
|
||||
#include <symbol2str.h>
|
||||
|
||||
extern int ResultKnown;
|
||||
extern char *symbol2str();
|
||||
|
||||
fltcstbin(expp, oper, expr)
|
||||
register struct expr **expp, *expr;
|
||||
|
||||
@ -31,6 +31,9 @@
|
||||
#include "sizes.h"
|
||||
#include "Lpars.h"
|
||||
#include "assert.h"
|
||||
#include "ch3.h"
|
||||
#include "code_c.h"
|
||||
#include "conversion.h"
|
||||
|
||||
extern char options[];
|
||||
extern arith NewLocal();
|
||||
|
||||
@ -34,6 +34,8 @@
|
||||
#include "def.h"
|
||||
#include "LLlex.h"
|
||||
#include "estack.h"
|
||||
#include "conversion.h"
|
||||
#include "cstopen.h"
|
||||
|
||||
#define con_nullbyte() C_con_ucon("0", (arith)1)
|
||||
#define aggregate_type(tp) ((tp)->tp_fund == ARRAY || (tp)->tp_fund == STRUCT)
|
||||
|
||||
@ -14,6 +14,8 @@
|
||||
* to terminate the compilation process.
|
||||
*/
|
||||
|
||||
#include "blocks.h"
|
||||
|
||||
#define store_block(sz, al)
|
||||
#define load_block(sz, al)
|
||||
|
||||
|
||||
@ -26,8 +26,9 @@
|
||||
#include "type.h"
|
||||
#include "level.h"
|
||||
#include "l_state.h"
|
||||
#include "conversion.h"
|
||||
#include <symbol2str.h>
|
||||
|
||||
extern char *symbol2str();
|
||||
extern struct type *func_type;
|
||||
|
||||
PRIVATE lint_enum_arith();
|
||||
|
||||
@ -29,9 +29,12 @@
|
||||
#include "align.h"
|
||||
#include "macro.h"
|
||||
#include "assert.h"
|
||||
#include "code_c.h"
|
||||
#include "cstoper.h"
|
||||
|
||||
#include <symbol2str.h>
|
||||
|
||||
extern struct tokenname tkidf[];
|
||||
extern char *symbol2str();
|
||||
extern char options[128];
|
||||
|
||||
#ifndef NOPP
|
||||
|
||||
@ -22,6 +22,7 @@
|
||||
#include "use_tmp.h"
|
||||
#include "dataflow.h"
|
||||
#include "dbsymtab.h"
|
||||
#include "conversion.h"
|
||||
|
||||
#ifndef NOPP
|
||||
extern char **inctable;
|
||||
|
||||
@ -59,6 +59,7 @@
|
||||
#include "code.h"
|
||||
#include "expr.h"
|
||||
#include "def.h"
|
||||
#include "code_c.h"
|
||||
#ifdef LINT
|
||||
#include "l_lint.h"
|
||||
#endif /* LINT */
|
||||
|
||||
@ -27,6 +27,7 @@
|
||||
#include "decspecs.h"
|
||||
#include "proto.h"
|
||||
#include "assert.h"
|
||||
#include "conversion.h"
|
||||
|
||||
extern char options[];
|
||||
|
||||
|
||||
@ -24,7 +24,7 @@
|
||||
#include "struct.h"
|
||||
#include "level.h"
|
||||
#include "mes.h"
|
||||
|
||||
#include "code_c.h"
|
||||
/* #include <em_reg.h> */
|
||||
|
||||
extern char options[];
|
||||
|
||||
@ -28,6 +28,7 @@
|
||||
#include "code.h"
|
||||
#include "stack.h"
|
||||
#include "def.h"
|
||||
#include "code_c.h"
|
||||
#ifdef DBSYMTAB
|
||||
#include <stb.h>
|
||||
#endif /* DBSYMTAB */
|
||||
|
||||
@ -26,6 +26,7 @@
|
||||
#include "expr.h"
|
||||
#include "type.h"
|
||||
#include "sizes.h"
|
||||
#include "code_c.h"
|
||||
|
||||
extern char options[];
|
||||
|
||||
|
||||
@ -5,9 +5,7 @@ cat <<'--EOT--'
|
||||
/* $Id$ */
|
||||
#include "Lpars.h"
|
||||
|
||||
char *
|
||||
symbol2str(tok)
|
||||
int tok;
|
||||
char *symbol2str(int tok)
|
||||
{
|
||||
#define SIZBUF 8
|
||||
/* allow for a few invocations in f.i. an argument list */
|
||||
|
||||
@ -1,34 +1,41 @@
|
||||
#!/bin/sh
|
||||
|
||||
cat <<'--EOT--'
|
||||
/* Generated by make.tokcase */
|
||||
/* $Id$ */
|
||||
#include "Lpars.h"
|
||||
|
||||
char *
|
||||
symbol2str(tok)
|
||||
int tok;
|
||||
char *symbol2str(int tok)
|
||||
{
|
||||
static char buf[2] = { '\0', '\0' };
|
||||
#define SIZBUF 8
|
||||
/* allow for a few invocations in f.i. an argument list */
|
||||
static char buf[SIZBUF];
|
||||
static int index;
|
||||
|
||||
if (040 <= tok && tok < 0177) {
|
||||
buf[0] = tok;
|
||||
buf[1] = '\0';
|
||||
return buf;
|
||||
}
|
||||
switch (tok) {
|
||||
--EOT--
|
||||
|
||||
sed '
|
||||
/{[A-Z]/!d
|
||||
s/.*{\(.*\),.*\(".*"\).*$/ case \1 :\
|
||||
return \2;/
|
||||
'
|
||||
|
||||
cat <<'--EOT--'
|
||||
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':
|
||||
buf[0] = tok;
|
||||
return buf;
|
||||
default:
|
||||
return "bad token";
|
||||
index = (index+2) & (SIZBUF-1);
|
||||
buf[index] = tok;
|
||||
return &buf[index];
|
||||
}
|
||||
}
|
||||
--EOT--
|
||||
|
||||
@ -1,16 +1,16 @@
|
||||
#!/bin/sh
|
||||
|
||||
cat <<'--EOT--'
|
||||
/* Generated by make.tokcase */
|
||||
/* $Id$ */
|
||||
#include "Lpars.h"
|
||||
|
||||
char *
|
||||
symbol2str(tok)
|
||||
int tok;
|
||||
char *symbol2str(int tok)
|
||||
{
|
||||
#define SIZBUF 8
|
||||
/* allow for a few invocations in f.i. an argument list */
|
||||
static char buf[SIZBUF] = { '\'', 0, '\'', 0, '\'', 0, '\'', 0};
|
||||
static int index = 1;
|
||||
static char buf[SIZBUF];
|
||||
static int index;
|
||||
|
||||
switch (tok) {
|
||||
--EOT--
|
||||
@ -27,9 +27,15 @@ cat <<'--EOT--'
|
||||
if (tok < 040 || tok >= 0177) {
|
||||
return "bad token";
|
||||
}
|
||||
index = (index+4) & (SIZBUF-1);
|
||||
/* fall through */
|
||||
case '\n':
|
||||
case '\f':
|
||||
case '\v':
|
||||
case '\r':
|
||||
case '\t':
|
||||
index = (index+2) & (SIZBUF-1);
|
||||
buf[index] = tok;
|
||||
return &buf[index-1];
|
||||
return &buf[index];
|
||||
}
|
||||
}
|
||||
--EOT--
|
||||
|
||||
@ -1,11 +1,11 @@
|
||||
#!/bin/sh
|
||||
|
||||
cat <<'--EOT--'
|
||||
/* Generated by make.tokcase */
|
||||
/* $Id$ */
|
||||
#include "Lpars.h"
|
||||
|
||||
char *
|
||||
symbol2str(tok)
|
||||
int tok;
|
||||
char *symbol2str(int tok)
|
||||
{
|
||||
#define SIZBUF 8
|
||||
/* allow for a few invocations in f.i. an argument list */
|
||||
|
||||
@ -1,11 +1,11 @@
|
||||
#!/bin/sh
|
||||
|
||||
cat <<'--EOT--'
|
||||
/* Generated by make.tokcase */
|
||||
/* $Id$ */
|
||||
#include "Lpars.h"
|
||||
|
||||
char *
|
||||
symbol2str(tok)
|
||||
int tok;
|
||||
char *symbol2str(int tok)
|
||||
{
|
||||
#define SIZBUF 8
|
||||
/* allow for a few invocations in f.i. an argument list */
|
||||
|
||||
@ -1,36 +1,41 @@
|
||||
#!/bin/sh
|
||||
|
||||
cat <<'--EOT--'
|
||||
/* Generated by make.tokcase */
|
||||
/* $Id$ */
|
||||
#include "Lpars.h"
|
||||
|
||||
char *
|
||||
symbol2str(tok)
|
||||
int tok;
|
||||
char *symbol2str(int tok)
|
||||
{
|
||||
static char buf[2] = { '\0', '\0' };
|
||||
#define SIZBUF 8
|
||||
/* allow for a few invocations in f.i. an argument list */
|
||||
static char buf[SIZBUF];
|
||||
static int index;
|
||||
|
||||
if (040 <= tok && tok < 0177) {
|
||||
buf[0] = tok;
|
||||
buf[1] = '\0';
|
||||
return buf;
|
||||
}
|
||||
switch (tok) {
|
||||
--EOT--
|
||||
|
||||
sed '
|
||||
/{[A-Z]/!d
|
||||
s/.*{\(.*\),.*\(".*"\).*$/ case \1 :\
|
||||
return \2;/
|
||||
'
|
||||
|
||||
cat <<'--EOT--'
|
||||
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':
|
||||
buf[0] = tok;
|
||||
return buf;
|
||||
default:
|
||||
return "bad token";
|
||||
index = (index+2) & (SIZBUF-1);
|
||||
buf[index] = tok;
|
||||
return &buf[index];
|
||||
}
|
||||
}
|
||||
--EOT--
|
||||
|
||||
@ -1,16 +1,16 @@
|
||||
#!/bin/sh
|
||||
|
||||
cat <<'--EOT--'
|
||||
/* Generated by make.tokcase */
|
||||
/* $Id$ */
|
||||
#include "Lpars.h"
|
||||
|
||||
char *
|
||||
symbol2str(tok)
|
||||
int tok;
|
||||
char *symbol2str(int tok)
|
||||
{
|
||||
#define SIZBUF 8
|
||||
/* allow for a few invocations in f.i. an argument list */
|
||||
static char buf[SIZBUF] = { '\'', 0, '\'', 0, '\'', 0, '\'', 0};
|
||||
static int index = 1;
|
||||
static char buf[SIZBUF];
|
||||
static int index;
|
||||
|
||||
switch (tok) {
|
||||
--EOT--
|
||||
@ -24,13 +24,18 @@ s/.*{\(.*\),.*\(".*"\).*$/ case \1 :\
|
||||
cat <<'--EOT--'
|
||||
default:
|
||||
if (tok <= 0) return "end of file";
|
||||
if (tok == '\n') return "<newline>";
|
||||
if (tok < 040 || tok >= 0177) {
|
||||
return "bad token";
|
||||
}
|
||||
index = (index+4) & (SIZBUF-1);
|
||||
/* fall through */
|
||||
case '\n':
|
||||
case '\f':
|
||||
case '\v':
|
||||
case '\r':
|
||||
case '\t':
|
||||
index = (index+2) & (SIZBUF-1);
|
||||
buf[index] = tok;
|
||||
return &buf[index-1];
|
||||
return &buf[index];
|
||||
}
|
||||
}
|
||||
--EOT--
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user