From: ceriel Date: Mon, 7 Apr 1986 17:40:38 +0000 (+0000) Subject: newer version X-Git-Tag: release-5-5~5317 X-Git-Url: https://git.ndcode.org/public/gitweb.cgi?a=commitdiff_plain;h=f2b68c82618387413b93ee5bf4816baf08734adb;p=ack.git newer version --- diff --git a/lang/m2/comp/Makefile b/lang/m2/comp/Makefile index bbd5a93d3..c24ff052c 100644 --- a/lang/m2/comp/Makefile +++ b/lang/m2/comp/Makefile @@ -17,7 +17,8 @@ LFLAGS = $(PROFILE) LOBJ = tokenfile.o program.o declar.o expression.o statement.o COBJ = LLlex.o LLmessage.o char.o error.o main.o \ symbol2str.o tokenname.o idf.o input.o type.o def.o \ - scope.o misc.o enter.o defmodule.o typequiv.o node.o + scope.o misc.o enter.o defmodule.o typequiv.o node.o \ + cstoper.o OBJ = $(COBJ) $(LOBJ) Lpars.o GENFILES= tokenfile.c \ program.c declar.c expression.c statement.c \ @@ -80,15 +81,16 @@ idf.o: idf.h input.o: f_info.h input.h type.o: LLlex.h Lpars.h def.h def_sizes.h idf.h node.h type.h def.o: LLlex.h Lpars.h debug.h def.h idf.h main.h node.h scope.h type.h -scope.o: LLlex.h debug.h def.h idf.h scope.h type.h +scope.o: LLlex.h debug.h def.h idf.h main.h scope.h type.h misc.o: LLlex.h f_info.h idf.h misc.h enter.o: LLlex.h def.h idf.h node.h scope.h type.h defmodule.o: LLlex.h def.h f_info.h idf.h input.h scope.h typequiv.o: Lpars.h def.h type.h -node.o: LLlex.h def.h node.h type.h +node.o: LLlex.h debug.h def.h main.h node.h type.h +cstoper.o: Lpars.h def_sizes.h idf.h node.h type.h tokenfile.o: Lpars.h program.o: LLlex.h Lpars.h debug.h def.h idf.h main.h node.h scope.h type.h declar.o: LLlex.h Lpars.h def.h idf.h misc.h node.h scope.h type.h -expression.o: LLlex.h Lpars.h def.h idf.h node.h scope.h -statement.o: Lpars.h +expression.o: LLlex.h Lpars.h debug.h def.h idf.h main.h node.h scope.h +statement.o: LLlex.h Lpars.h node.h Lpars.o: Lpars.h diff --git a/lang/m2/comp/const.h b/lang/m2/comp/const.h new file mode 100644 index 000000000..02f7e28f6 --- /dev/null +++ b/lang/m2/comp/const.h @@ -0,0 +1,12 @@ +/* C O N S T A N T S F O R E X P R E S S I O N H A N D L I N G */ + +/* $Header$ */ + +extern long + mach_long_sign; /* sign bit of the machine long */ +extern int + mach_long_size; /* size of long on this machine == sizeof(long) */ +extern arith + max_int, /* maximum integer on target machine */ + max_unsigned, /* maximum unsigned on target machine */ + max_longint; /* maximum longint on target machine */ diff --git a/lang/m2/comp/cstoper.c b/lang/m2/comp/cstoper.c new file mode 100644 index 000000000..03e0cf256 --- /dev/null +++ b/lang/m2/comp/cstoper.c @@ -0,0 +1,238 @@ +/* C O N S T A N T E X P R E S S I O N H A N D L I N G */ + +static char *RcsId = "$Header$"; + +#include +#include +#include +#include "def_sizes.h" +#include "idf.h" +#include "type.h" +#include "LLlex.h" +#include "node.h" +#include "Lpars.h" + +long mach_long_sign; /* sign bit of the machine long */ +int mach_long_size; /* size of long on this machine == sizeof(long) */ +long full_mask[MAXSIZE];/* full_mask[1] == 0XFF, full_mask[2] == 0XFFFF, .. */ +arith max_int; /* maximum integer on target machine */ +arith max_unsigned; /* maximum unsigned on target machine */ +arith max_longint; /* maximum longint on target machine */ + +#if 0 + +cstbin(expp, oper, expr) + struct expr **expp, *expr; +{ + /* The operation oper is performed on the constant + expressions *expp(ld) and expr(ct), and the result restored in + *expp. + */ + 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)); + switch (oper) { + case '*': + o1 *= o2; + break; + case '/': + if (o2 == 0) { + expr_error(expr, "division by 0"); + break; + } + if (uns) { + /* this is more of a problem than you might + think on C compilers which do not have + unsigned long. + */ + if (o2 & mach_long_sign) {/* o2 > max_long */ + o1 = ! (o1 >= 0 || o1 < o2); + /* this is the unsigned test + o1 < o2 for o2 > max_long + */ + } + else { /* o2 <= max_long */ + long half, bit, hdiv, hrem, rem; + + half = (o1 >> 1) & ~mach_long_sign; + bit = o1 & 01; + /* now o1 == 2 * half + bit + and half <= max_long + and bit <= max_long + */ + hdiv = half / o2; + hrem = half % o2; + rem = 2 * hrem + bit; + o1 = 2 * hdiv + (rem < 0 || rem >= o2); + /* that is the unsigned compare + rem >= o2 for o2 <= max_long + */ + } + } + else + o1 /= o2; + break; + case '%': + if (o2 == 0) { + expr_error(expr, "modulo by 0"); + break; + } + if (uns) { + if (o2 & mach_long_sign) {/* o2 > max_long */ + o1 = (o1 >= 0 || o1 < o2) ? o1 : o1 - o2; + /* this is the unsigned test + o1 < o2 for o2 > max_long + */ + } + else { /* o2 <= max_long */ + long half, bit, hrem, rem; + + half = (o1 >> 1) & ~mach_long_sign; + bit = o1 & 01; + /* now o1 == 2 * half + bit + and half <= max_long + and bit <= max_long + */ + hrem = half % o2; + rem = 2 * hrem + bit; + o1 = (rem < 0 || rem >= o2) ? rem - o2 : rem; + } + } + else + o1 %= o2; + break; + case '+': + o1 += o2; + break; + case '-': + o1 -= o2; + break; + case LEFT: + o1 <<= o2; + break; + case RIGHT: + if (o2 == 0) + break; + if (uns) { + o1 >>= 1; + o1 & = ~mach_long_sign; + o1 >>= (o2-1); + } + else + o1 >>= o2; + break; + case '<': + if (uns) { + o1 = (o1 & mach_long_sign ? + (o2 & mach_long_sign ? o1 < o2 : 0) : + (o2 & mach_long_sign ? 1 : o1 < o2) + ); + } + else + o1 = o1 < o2; + break; + case '>': + if (uns) { + o1 = (o1 & mach_long_sign ? + (o2 & mach_long_sign ? o1 > o2 : 1) : + (o2 & mach_long_sign ? 0 : o1 > o2) + ); + } + else + o1 = o1 > o2; + break; + case LESSEQ: + if (uns) { + o1 = (o1 & mach_long_sign ? + (o2 & mach_long_sign ? o1 <= o2 : 0) : + (o2 & mach_long_sign ? 1 : o1 <= o2) + ); + } + else + o1 = o1 <= o2; + break; + case GREATEREQ: + if (uns) { + o1 = (o1 & mach_long_sign ? + (o2 & mach_long_sign ? o1 >= o2 : 1) : + (o2 & mach_long_sign ? 0 : o1 >= o2) + ); + } + else + o1 = o1 >= o2; + break; + case EQUAL: + o1 = o1 == o2; + break; + case NOTEQUAL: + o1 = o1 != o2; + break; + case '&': + o1 &= o2; + break; + case '|': + o1 |= o2; + break; + case '^': + o1 ^= o2; + break; + } + (*expp)->VL_VALUE = o1; + cut_size(*expp); + (*expp)->ex_flags |= expr->ex_flags; + (*expp)->ex_flags &= ~EX_PARENS; +} + +cut_size(expr) + struct expr *expr; +{ + /* The constant value of the expression expr is made to + conform to the size of the type of the expression. + */ + arith o1 = expr->VL_VALUE; + int uns = expr->ex_type->tp_unsigned; + int size = (int) expr->ex_type->tp_size; + + ASSERT(expr->ex_class == Value); + if (uns) { + if (o1 & ~full_mask[size]) + expr_warning(expr, + "overflow in unsigned constant expression"); + o1 &= full_mask[size]; + } + else { + int nbits = (int) (mach_long_size - size) * 8; + long remainder = o1 & ~full_mask[size]; + + if (remainder != 0 && remainder != ~full_mask[size]) + expr_warning(expr, "overflow in constant expression"); + o1 <<= nbits; /* ??? */ + o1 >>= nbits; + } + expr->VL_VALUE = o1; +} + +# endif + +init_cst() +{ + int i = 0; + arith bt = (arith)0; + + while (!(bt < 0)) { + bt = (bt << 8) + 0377, i++; + if (i == MAXSIZE) + fatal("array full_mask too small for this machine"); + full_mask[i] = bt; + } + mach_long_size = i; + mach_long_sign = 1 << (mach_long_size * 8 - 1); + if (sizeof(long) < mach_long_size) + fatal("sizeof (long) insufficient on this machine"); + + max_int = full_mask[int_size] & ~(1 << (int_size * 8 - 1)); + max_longint = full_mask[lint_size] & ~(1 << (lint_size * 8 - 1)); + max_unsigned = full_mask[int_size]; +} diff --git a/lang/m2/comp/def.c b/lang/m2/comp/def.c index 8a5e2999a..549167caa 100644 --- a/lang/m2/comp/def.c +++ b/lang/m2/comp/def.c @@ -34,7 +34,7 @@ define(id, scope, kind) register struct def *df; register struct scope *sc; - DO_DEBUG(debug(4,"Defining identifier %s in scope %d", id->id_text, scope->sc_scope)); + DO_DEBUG(5, debug("Defining identifier \"%s\" in scope %d", id->id_text, scope->sc_scope)); df = lookup(id, scope->sc_scope); if ( /* Already in this scope */ df @@ -94,7 +94,7 @@ lookup(id, scope) df1 = 0; df = id->id_def; - DO_DEBUG(debug(4,"Looking for identifier %s in scope %d", id->id_text, scope)); + DO_DEBUG(5, debug("Looking for identifier \"%s\" in scope %d", id->id_text, scope)); while (df) { if (df->df_scope == scope) { if (df->df_kind == D_IMPORT) { diff --git a/lang/m2/comp/enter.c b/lang/m2/comp/enter.c index 85df442ff..df39a13a5 100644 --- a/lang/m2/comp/enter.c +++ b/lang/m2/comp/enter.c @@ -5,6 +5,7 @@ static char *RcsId = "$Header$"; #include #include #include +#include #include "idf.h" #include "def.h" #include "type.h" @@ -17,6 +18,10 @@ Enter(name, kind, type, pnam) char *name; struct type *type; { + /* Enter a definition for "name" with kind "kind" and type + "type" in the Current Scope. If it is a standard name, also + put its number in the definition structure. + */ struct idf *id; struct def *df; @@ -35,6 +40,13 @@ EnterIdList(idlist, kind, flags, type, scope) struct type *type; struct scope *scope; { + /* Put a list of identifiers in the symbol table. + They all have kind "kind", and type "type", and are put + in scope "scope". "flags" initializes the "df_flags" field + of the definition structure. + Also assign numbers to enumeration literals, and link + them together. + */ register struct def *df; struct def *first = 0, *last = 0; int assval = 0; @@ -45,15 +57,16 @@ EnterIdList(idlist, kind, flags, type, scope) df->df_flags = flags; if (kind == D_ENUM) { if (!first) first = df; - df->df_value.df_enum.en_val = assval++; - if (last) last->df_value.df_enum.en_next = df; + df->enm_val = assval++; + if (last) last->enm_next = df; last = df; } idlist = idlist->next; } if (last) { - /* Also meaning : enumeration */ - last->df_value.df_enum.en_next = 0; + /* Also meaning : kind == D_ENUM */ + assert(kind == D_ENUM); + last->enm_next = 0; type->enm_enums = first; type->enm_ncst = assval; } diff --git a/lang/m2/comp/error.c b/lang/m2/comp/error.c index 8998e166b..e72269c42 100644 --- a/lang/m2/comp/error.c +++ b/lang/m2/comp/error.c @@ -46,10 +46,10 @@ extern char *symbol2str(); #ifdef DEBUG /*VARARGS2*/ -debug(level, fmt, args) +debug(fmt, args) char *fmt; { - if (level <= options['D']) _error(VDEBUG, NULLNODE, fmt, &args); + _error(VDEBUG, NULLNODE, fmt, &args); } #endif DEBUG diff --git a/lang/m2/comp/expression.g b/lang/m2/comp/expression.g index e35b7e330..7a841bc3f 100644 --- a/lang/m2/comp/expression.g +++ b/lang/m2/comp/expression.g @@ -6,19 +6,30 @@ static char *RcsId = "$Header$"; #include #include #include +#include "main.h" #include "LLlex.h" #include "idf.h" #include "def.h" #include "scope.h" #include "node.h" +#include "const.h" +#include "type.h" +#include "debug.h" } -number(struct node **p;): +number(struct node **p;) +{ + struct type *tp; +} : [ - INTEGER + INTEGER { tp = dot.TOK_INT <= max_int ? + intorcard_type : card_type; + } | - REAL -] { *p = MkNode(Value, NULLNODE, NULLNODE, dot); } + REAL { tp = real_type; } +] { *p = MkNode(Value, NULLNODE, NULLNODE, &dot); + (*p)->nd_type = tp; + } ; qualident(int types; struct def **pdf; char *str; struct node **p;) @@ -27,15 +38,16 @@ qualident(int types; struct def **pdf; char *str; struct node **p;) int module; register struct def *df; struct def *lookfor(); + register struct node **pnd; + struct node *nd; } : IDENT { if (types) { df = lookfor(dot.TOK_IDF, CurrentScope, 1); *pdf = df; if (df->df_kind == D_ERROR) types = 0; } - if (p) { - *p = MkNode(Value, NULLNODE, NULLNODE,&dot); - } + nd = MkNode(Value, NULLNODE, NULLNODE, &dot); + pnd = &nd; } [ { if (types &&!(scope = has_selectors(df))) { @@ -44,12 +56,11 @@ qualident(int types; struct def **pdf; char *str; struct node **p;) } } /* selector */ - '.' { if (p) *p = MkNode(Link, *p, NULLNODE, &dot); } + '.' { *pnd = MkNode(Link,*pnd,NULLNODE,&dot); + pnd = &(*pnd)->nd_right; + } IDENT - { if (p) { - p = &((*p)->nd_right); - *p = MkNode(Value, NULLNODE, NULLNODE,&dot); - } + { *pnd = MkNode(Value,NULLNODE,NULLNODE,&dot); if (types) { module = (df->df_kind == D_MODULE); df = lookup(dot.TOK_IDF, scope); @@ -70,6 +81,8 @@ qualident(int types; struct def **pdf; char *str; struct node **p;) error("identifier \"%s\" is not a %s", df->df_idf->id_text, str); } + if (!p) FreeNode(nd); + else *p = nd; } ; @@ -98,22 +111,24 @@ ConstExpression(struct node **pnd;): * Changed rule in new Modula-2. * Check that the expression is a constant expression and evaluate! */ + { DO_DEBUG(3, + ( debug("Constant expression:"), + PrNode(*pnd))); + } ; expression(struct node **pnd;) { - struct node *nd; } : - SimpleExpression(&nd) + SimpleExpression(pnd) [ /* relation */ [ '=' | '#' | UNEQUAL | '<' | LESSEQUAL | '>' | GREATEREQUAL | IN ] - { nd = MkNode(Oper, nd, NULLNODE, &dot); } - SimpleExpression(&(nd->nd_right)) + { *pnd = MkNode(Oper, *pnd, NULLNODE, &dot); } + SimpleExpression(&((*pnd)->nd_right)) ]? - { *pnd = nd; } ; /* Inline in expression @@ -124,15 +139,19 @@ relation: SimpleExpression(struct node **pnd;) { - register struct node *nd; } : - [ '+' | '-' ]? - term(pnd) { nd = *pnd; } + [ + [ '+' | '-' ] + { *pnd = MkNode(Uoper, NULLNODE, NULLNODE, &dot); + pnd = &((*pnd)->nd_right); + } + ]? + term(pnd) [ /* AddOperator */ [ '+' | '-' | OR ] - { *pnd = nd = MkNode(Oper, nd, NULLNODE, &dot); } - term(&(nd->nd_right)) + { *pnd = MkNode(Oper, *pnd, NULLNODE, &dot); } + term(&((*pnd)->nd_right)) ]* ; @@ -144,14 +163,13 @@ AddOperator: term(struct node **pnd;) { - register struct node *nd; }: - factor(pnd) { nd = *pnd; } + factor(pnd) [ /* MulOperator */ [ '*' | '/' | DIV | MOD | AND | '&' ] - { *pnd = nd = MkNode(Oper, nd, NULLNODE, &dot); } - factor(&(nd->nd_right)) + { *pnd = MkNode(Oper, *pnd, NULLNODE, &dot); } + factor(&((*pnd)->nd_right)) ]* ; @@ -164,23 +182,29 @@ MulOperator: factor(struct node **p;) { struct def *df; + struct node *nd; } : qualident(0, &df, (char *) 0, p) [ designator_tail(p)? [ - { *p = MkNode(Call, p, NULLNODE, &dot); } + { *p = MkNode(Call, *p, NULLNODE, &dot); } ActualParameters(&((*p)->nd_right)) ]? - | { *p = MkNode(Call, p, NULLNODE, &dot); } - bare_set(&((*p)->nd_right)) + | + bare_set(&nd) + { nd->nd_left = *p; + *p = nd; + } ] | bare_set(p) | %default number(p) | - STRING { *p = MkNode(Value, NULLNODE, NULLNODE, &dot); } + STRING { *p = MkNode(Value, NULLNODE, NULLNODE, &dot); + (*p)->nd_type = string_type; + } | '(' expression(p) ')' | @@ -190,20 +214,17 @@ factor(struct node **p;) bare_set(struct node **pnd;) { - struct node **nd; + register struct node *nd; } : '{' { dot.tk_symb = SET; - *pnd = MkNode(Link, NULLNODE, NULLNODE, &dot); - nd = &((*pnd)->nd_left); + *pnd = nd = MkNode(Link, NULLNODE, NULLNODE, &dot); + nd->nd_type = bitset_type; } [ element(nd) - [ - ',' { *nd = MkNode(Link, *nd, NULLNODE, &dot); - nd = &((*nd)->nd_right); - } - element(nd) + [ { nd = nd->nd_right; } + ',' element(nd) ]* ]? '}' @@ -213,12 +234,19 @@ ActualParameters(struct node **pnd;): '(' ExpList(pnd)? ')' ; -element(struct node **pnd;): - expression(pnd) +element(struct node *nd;) +{ + struct node *nd1; +} : + expression(&nd1) [ - UPTO { *pnd = MkNode(Link, *pnd, NULLNODE, &dot);} - expression(&((*pnd)->nd_right)) + UPTO + { nd1 = MkNode(Link, nd1, NULLNODE, &dot);} + expression(&(nd1->nd_right)) ]? + { nd->nd_right = MkNode(Link, nd1, NULLNODE, &dot); + nd->nd_right->nd_symb = ','; + } ; designator(struct node **pnd;) diff --git a/lang/m2/comp/main.c b/lang/m2/comp/main.c index caa9c4ee4..ea8af67a8 100644 --- a/lang/m2/comp/main.c +++ b/lang/m2/comp/main.c @@ -47,7 +47,7 @@ main(argc, argv) #ifdef DEBUG print("Mod2 compiler -- Debug version\n"); #endif DEBUG - DO_DEBUG(debug(1,"Debugging level: %d", options['D'])); + DO_DEBUG(1, debug("Debugging level: %d", options['D'])); return !Compile(Nargv[1]); } @@ -56,7 +56,7 @@ Compile(src) { extern struct tokenname tkidf[]; - DO_DEBUG(debug(1,"Filename : %s", src)); + DO_DEBUG(1, debug("Filename : %s", src)); if (! InsertFile(src, (char **) 0, &src)) { fprint(STDERR,"%s: cannot open %s\n", ProgName, src); return 0; @@ -65,15 +65,13 @@ Compile(src) FileName = src; init_DEFPATH(); init_idf(); + init_cst(); reserve(tkidf); init_scope(); init_types(); add_standards(); #ifdef DEBUG - if (options['L']) - LexScan(); - else if (options['T']) - TimeScan(); + if (options['L']) LexScan(); else { #endif DEBUG (void) open_scope(CLOSEDSCOPE, 0); @@ -92,7 +90,7 @@ LexScan() { register int symb; - while ((symb = LLlex()) != EOI) { + while ((symb = LLlex()) > 0) { print(">>> %s ", symbol2str(symb)); switch(symb) { @@ -113,14 +111,10 @@ LexScan() break; default: - putchar('\n'); + print("\n"); } } } - -TimeScan() { - while (LLlex() != -1) /* nothing */; -} #endif Option(str) @@ -165,11 +159,7 @@ add_standards() D_TYPE, construct_type(PROCEDURE, NULLTYPE), 0); - tp = construct_type(SUBRANGE, int_type); - tp->sub_lb = 0; - tp->sub_ub = wrd_size * 8 - 1; - df = Enter("BITSET", D_TYPE, construct_type(SET, tp), 0); - df->df_type->tp_size = wrd_size; + df = Enter("BITSET", D_TYPE, bitset_type, 0); df = Enter("FALSE", D_ENUM, bool_type, 0); df->df_value.df_enum.en_val = 0; df->df_value.df_enum.en_next = Enter("TRUE", D_ENUM, bool_type, 0); diff --git a/lang/m2/comp/node.c b/lang/m2/comp/node.c index dcd5a9eed..b50e30d01 100644 --- a/lang/m2/comp/node.c +++ b/lang/m2/comp/node.c @@ -5,10 +5,13 @@ static char *RcsId = "$Header$"; #include #include #include +#include +#include "main.h" #include "def.h" #include "type.h" #include "LLlex.h" #include "node.h" +#include "debug.h" struct node *h_node; /* header of free list */ @@ -26,6 +29,7 @@ MkNode(class, left, right, token) nd->nd_token = *token; nd->nd_class = class; nd->nd_type = NULLTYPE; + DO_DEBUG(4,(debug("Create node:"), PrNode(nd))); return nd; } @@ -39,3 +43,28 @@ FreeNode(nd) if (nd->nd_right) FreeNode(nd->nd_right); free_node(nd); } + +#ifdef DEBUG + +extern char *symbol2str(); + +static +printnode(nd) + register struct node *nd; +{ + fprint(STDERR, "("); + if (nd) { + printnode(nd->nd_left); + fprint(STDERR, " %s ", symbol2str(nd->nd_symb)); + printnode(nd->nd_right); + } + fprint(STDERR, ")"); +} + +PrNode(nd) + struct node *nd; +{ + printnode(nd); + fprint(STDERR, "\n"); +} +#endif DEBUG diff --git a/lang/m2/comp/program.g b/lang/m2/comp/program.g index 5c17fd6f1..5e33d6f1f 100644 --- a/lang/m2/comp/program.g +++ b/lang/m2/comp/program.g @@ -114,7 +114,7 @@ DefinitionModule if (!SYSTEMModule) open_scope(CLOSEDSCOPE, 0); df->mod_scope = CurrentScope->sc_scope; DefinitionModule = 1; - DO_DEBUG(debug(1, "Definition module \"%s\"", id->id_text)); + DO_DEBUG(1, debug("Definition module \"%s\"", id->id_text)); } ';' import(0)* diff --git a/lang/m2/comp/scope.C b/lang/m2/comp/scope.C index 1a2badcd5..697e810ca 100644 --- a/lang/m2/comp/scope.C +++ b/lang/m2/comp/scope.C @@ -11,6 +11,7 @@ static char *RcsId = "$Header$"; #include "scope.h" #include "type.h" #include "def.h" +#include "main.h" #include "debug.h" static int maxscope; /* maximum assigned scope number */ @@ -35,7 +36,7 @@ open_scope(scopetype, scope) sc->sc_scope = scope == 0 ? ++maxscope : scope; sc->sc_forw = 0; sc->sc_def = 0; assert(scopetype == OPENSCOPE || scopetype == CLOSEDSCOPE); - DO_DEBUG(debug(1, "Opening a %s scope", + DO_DEBUG(1, debug("Opening a %s scope", scopetype == OPENSCOPE ? "open" : "closed")); sc1 = CurrentScope; if (scopetype == CLOSEDSCOPE) { @@ -55,7 +56,7 @@ close_scope() register struct scope *sc = CurrentScope; assert(sc != 0); - DO_DEBUG(debug(1, "Closing a scope")); + DO_DEBUG(1, debug("Closing a scope")); if (sc->sc_forw) rem_forwards(sc->sc_forw); if (sc->next && (sc->next->sc_scope == 0)) { struct scope *sc1 = sc; diff --git a/lang/m2/comp/tokenname.c b/lang/m2/comp/tokenname.c index b4ce2b5c8..9e0ca1cb5 100644 --- a/lang/m2/comp/tokenname.c +++ b/lang/m2/comp/tokenname.c @@ -80,6 +80,7 @@ struct tokenname tkinternal[] = { /* internal keywords */ {ENUMERATION, ""}, {ERRONEOUS, ""}, {PROCVAR, ""}, + {INTORCARD, ""}, {0, "0"} }; diff --git a/lang/m2/comp/type.H b/lang/m2/comp/type.H index 2de207c91..c67a8367b 100644 --- a/lang/m2/comp/type.H +++ b/lang/m2/comp/type.H @@ -77,7 +77,10 @@ extern struct type *longreal_type, *word_type, *address_type, - *error_type; + *intorcard_type, + *string_type, + *bitset_type, + *error_type; /* All from type.c */ extern int wrd_align, @@ -86,7 +89,7 @@ extern int real_align, lreal_align, ptr_align, - record_align; + record_align; /* All from type.c */ extern arith wrd_size, @@ -94,14 +97,14 @@ extern arith lint_size, real_size, lreal_size, - ptr_size; + ptr_size; /* All from type.c */ extern arith - align(); + align(); /* type.c */ struct type *create_type(), *construct_type(), - *standard_type(); + *standard_type(); /* All from type.c */ #define NULLTYPE ((struct type *) 0) diff --git a/lang/m2/comp/type.c b/lang/m2/comp/type.c index 30097075b..c56486139 100644 --- a/lang/m2/comp/type.c +++ b/lang/m2/comp/type.c @@ -44,6 +44,9 @@ struct type *longreal_type, *word_type, *address_type, + *intorcard_type, + *string_type, + *bitset_type, *error_type; struct paramlist *h_paramlist; @@ -123,6 +126,8 @@ standard_type(fund, align, size) init_types() { + register struct type *tp; + char_type = standard_type(CHAR, 1, (arith) 1); bool_type = standard_type(BOOLEAN, 1, (arith) 1); int_type = standard_type(INTEGER, int_align, int_size); @@ -131,9 +136,15 @@ init_types() real_type = standard_type(REAL, real_align, real_size); longreal_type = standard_type(LONGREAL, lreal_align, lreal_size); word_type = standard_type(WORD, wrd_align, wrd_size); + intorcard_type = standard_type(INTORCARD, int_align, int_size); + string_type = standard_type(STRING, 1, (arith) -1); address_type = construct_type(POINTER, word_type); + tp = construct_type(SUBRANGE, int_type); + tp->sub_lb = 0; + tp->sub_ub = wrd_size * 8 - 1; + bitset_type = construct_type(SET, tp); + bitset_type->tp_size = wrd_size; error_type = standard_type(ERRONEOUS, 1, (arith) 1); - } int diff --git a/lang/m2/comp/typequiv.c b/lang/m2/comp/typequiv.c index 96f9e38a6..b1bf08af8 100644 --- a/lang/m2/comp/typequiv.c +++ b/lang/m2/comp/typequiv.c @@ -52,3 +52,32 @@ TstProcEquiv(tp1, tp2) if (p1 != p2) return 0; return 1; } + +int +TstCompat(tp1, tp2) + register struct type *tp1, *tp2; +{ + /* test if two types are compatible. See section 6.3 of the + Modula-2 Report for a definition of "compatible". + */ + if (TstTypeEquiv(tp1, tp2)) return 1; + if (tp2->tp_fund == SUBRANGE) tp1 = tp1->next; + if (tp2->tp_fund == SUBRANGE) tp1 = tp1->next; + return tp1 == tp2 + || + ( tp1 == address_type + && + ( tp2 == card_type + || tp2 == intorcard_type + || tp2->tp_fund == POINTER + ) + ) + || + ( tp2 == address_type + && + ( tp1 == card_type + || tp1 == intorcard_type + || tp1->tp_fund == POINTER + ) + ); +}