📄 modula-2.c
字号:
/*#@(#)modula-2.c 4.2 Ultrix 11/9/90*//************************************************************************ * * * Copyright (c) 1986 by * * Digital Equipment Corporation, Maynard, MA * * All rights reserved. * * * * This software is furnished under a license and may be used and * * copied only in accordance with the terms of such license and * * with the inclusion of the above copyright notice. This * * software or any other copies thereof may not be provided or * * otherwise made available to any other person. No title to and * * ownership of the software is hereby transferred. * * * * This software is derived from software received from the * * University of California, Berkeley, and from Bell * * Laboratories. Use, duplication, or disclosure is subject to * * restrictions under license agreements with University of * * California and with AT&T. * * * * The information in this software is subject to change without * * notice and should not be construed as a commitment by Digital * * Equipment Corporation. * * * * Digital assumes no responsibility for the use or reliability * * of its software on equipment which is not supplied by Digital. * * * ************************************************************************//************************************************************************ * * * Modification History * * * * 002 - Merged in 4.3 changes. * * (vjh, April 29, 1986) * * * * 001 - Modified modula2_init() to use LanguageName constant in * * call to language_define(). * * (Victoria Holt, June 22, 1985) * * * ************************************************************************//* * Copyright (c) 1983 Regents of the University of California. * All rights reserved. The Berkeley software License Agreement * specifies the terms and conditions for redistribution. */#ifndef lintstatic char sccsid[] = "@(#)modula-2.c 5.1 (Berkeley) 5/31/85";#endif not lint/* * Modula-2 specific symbol routines. */#include "defs.h"#include "symbols.h"#include "modula-2.h"#include "languages.h"#include "tree.h"#include "eval.h"#include "mappings.h"#include "process.h"#include "runtime.h"#include "machine.h"#ifndef public#endifprivate Language mod2;private boolean initialized;#define ischar(t) ( \ (t) == t_char->type or \ ((t)->class == RANGE and istypename((t)->type, "char")) \)/* * Initialize Modula-2 information. */public modula2_init (){ mod2 = language_define("modula-2", MODULA2); language_setop(mod2, L_PRINTDECL, modula2_printdecl); language_setop(mod2, L_PRINTVAL, modula2_printval); language_setop(mod2, L_TYPEMATCH, modula2_typematch); language_setop(mod2, L_BUILDAREF, modula2_buildaref); language_setop(mod2, L_EVALAREF, modula2_evalaref); language_setop(mod2, L_MODINIT, modula2_modinit); language_setop(mod2, L_HASMODULES, modula2_hasmodules); language_setop(mod2, L_PASSADDR, modula2_passaddr); initialized = false;}/* * Typematch tests if two types are compatible. The issue * is a bit complicated, so several subfunctions are used for * various kinds of compatibility. */private boolean builtinmatch (t1, t2)register Symbol t1, t2;{ boolean b; b = (boolean) ( ( t2 == t_int->type and t1->class == RANGE and ( istypename(t1->type, "integer") or istypename(t1->type, "cardinal") ) ) or ( t2 == t_char->type and t1->class == RANGE and istypename(t1->type, "char") ) or ( t2 == t_real->type and t1->class == RANGE and ( istypename(t1->type, "real") or istypename(t1->type, "longreal") ) ) or ( t2 == t_boolean->type and t1->class == RANGE and istypename(t1->type, "boolean") ) ); return b;}private boolean rangematch (t1, t2)register Symbol t1, t2;{ boolean b; register Symbol rt1, rt2; if (t1->class == RANGE and t2->class == RANGE) { b = (boolean) ( t1->symvalue.rangev.lower == t2->symvalue.rangev.lower and t1->symvalue.rangev.upper == t2->symvalue.rangev.upper ); } else { b = false; } return b;}private boolean nilMatch (t1, t2)register Symbol t1, t2;{ boolean b; b = (boolean) ( (t1 == t_nil and t2->class == PTR) or (t1->class == PTR and t2 == t_nil) ); return b;}private boolean enumMatch (t1, t2)register Symbol t1, t2;{ boolean b; b = (boolean) ( (t1->class == SCAL and t2->class == CONST and t2->type == t1) or (t1->class == CONST and t2->class == SCAL and t1->type == t2) ); return b;}private boolean openArrayMatch (t1, t2)register Symbol t1, t2;{ boolean b; b = (boolean) ( ( t1->class == DYNARRAY and t1->symvalue.ndims == 1 and t2->class == ARRAY and compatible(rtype(t2->chain)->type, t_int) and compatible(t1->type, t2->type) ) or ( t2->class == DYNARRAY and t2->symvalue.ndims == 1 and t1->class == ARRAY and compatible(rtype(t1->chain)->type, t_int) and compatible(t1->type, t2->type) ) ); return b;}private boolean isConstString (t)register Symbol t;{ boolean b; b = (boolean) ( t->language == primlang and t->class == ARRAY and t->type == t_char ); return b;}private boolean stringArrayMatch (t1, t2)register Symbol t1, t2;{ boolean b; b = (boolean) ( ( isConstString(t1) and t2->class == ARRAY and compatible(t2->type, t_char->type) ) or ( isConstString(t2) and t1->class == ARRAY and compatible(t1->type, t_char->type) ) ); return b;}public boolean modula2_typematch (type1, type2)Symbol type1, type2;{ boolean b; Symbol t1, t2, tmp; t1 = rtype(type1); t2 = rtype(type2); if (t1 == t2) { b = true; } else { if (t1 == t_char->type or t1 == t_int->type or t1 == t_real->type or t1 == t_boolean->type ) { tmp = t1; t1 = t2; t2 = tmp; } b = (Boolean) ( builtinmatch(t1, t2) or rangematch(t1, t2) or nilMatch(t1, t2) or enumMatch(t1, t2) or openArrayMatch(t1, t2) or stringArrayMatch(t1, t2) ); } return b;}/* * Indent n spaces. */private indent (n)int n;{ if (n > 0) { printf("%*c", n, ' '); }}public modula2_printdecl (s)Symbol s;{ register Symbol t; Boolean semicolon; semicolon = true; if (s->class == TYPEREF) { resolveRef(t); } switch (s->class) { case CONST: if (s->type->class == SCAL) { semicolon = false; printf("enumeration constant with value "); eval(s->symvalue.constval); modula2_printval(s); } else { printf("const %s = ", symname(s)); eval(s->symvalue.constval); modula2_printval(s); } break; case TYPE: printf("type %s = ", symname(s)); printtype(s, s->type, 0); break; case TYPEREF: printf("type %s", symname(s)); break; case VAR: if (isparam(s)) { printf("(parameter) %s : ", symname(s)); } else { printf("var %s : ", symname(s)); } printtype(s, s->type, 0); break; case REF: printf("(var parameter) %s : ", symname(s)); printtype(s, s->type, 0); break; case RANGE: case ARRAY: case DYNARRAY: case SUBARRAY: case RECORD: case VARNT: case PTR: printtype(s, s, 0); semicolon = false; break; case FVAR: printf("(function variable) %s : ", symname(s)); printtype(s, s->type, 0); break; case FIELD: printf("(field) %s : ", symname(s)); printtype(s, s->type, 0); break; case PROC: printf("procedure %s", symname(s)); listparams(s); break; case PROG: printf("program %s", symname(s)); listparams(s); break; case FUNC: printf("procedure %s", symname(s)); listparams(s); printf(" : "); printtype(s, s->type, 0); break; case MODULE: printf("module %s", symname(s)); break; default: printf("[%s]", classname(s)); break; } if (semicolon) { putchar(';'); } putchar('\n');}/* * Recursive whiz-bang procedure to print the type portion * of a declaration. * * The symbol associated with the type is passed to allow * searching for type names without getting "type blah = blah". */private printtype (s, t, n)Symbol s;Symbol t;int n;{ Symbol tmp; int i; if (t->class == TYPEREF) { resolveRef(t); } switch (t->class) { case VAR: case CONST: case FUNC: case PROC: panic("printtype: class %s", classname(t)); break; case ARRAY: printf("array["); tmp = t->chain; if (tmp != nil) { for (;;) { printtype(tmp, tmp, n); tmp = tmp->chain; if (tmp == nil) { break; } printf(", "); } } printf("] of "); printtype(t, t->type, n); break; case DYNARRAY: printf("dynarray of "); for (i = 1; i < t->symvalue.ndims; i++) { printf("array of "); } printtype(t, t->type, n); break; case SUBARRAY: printf("subarray of "); for (i = 1; i < t->symvalue.ndims; i++) { printf("array of "); } printtype(t, t->type, n); break; case RECORD: printRecordDecl(t, n); break; case FIELD: if (t->chain != nil) { printtype(t->chain, t->chain, n); } printf("\t%s : ", symname(t)); printtype(t, t->type, n); printf(";\n"); break; case RANGE: printRangeDecl(t); break; case PTR: printf("pointer to "); printtype(t, t->type, n); break; case TYPE: if (t->name != nil and ident(t->name)[0] != '\0') { printname(stdout, t); } else { printtype(t, t->type, n); } break; case SCAL: printEnumDecl(t, n); break; case SET: printf("set of "); printtype(t, t->type, n); break; case TYPEREF: break; case FPROC: case FFUNC: printf("procedure"); break; default: printf("[%s]", classname(t)); break; }}/* * Print out a record declaration. */private printRecordDecl (t, n)Symbol t;int n;{ register Symbol f; if (t->chain == nil) { printf("record end"); } else { printf("record\n"); for (f = t->chain; f != nil; f = f->chain) { indent(n+4); printf("%s : ", symname(f)); printtype(f->type, f->type, n+4); printf(";\n"); } indent(n); printf("end"); }}/* * Print out the declaration of a range type. */private printRangeDecl (t)Symbol t;{ long r0, r1; r0 = t->symvalue.rangev.lower; r1 = t->symvalue.rangev.upper; if (ischar(t)) { if (r0 < 0x20 or r0 > 0x7e) { printf("%ld..", r0); } else { printf("'%c'..", (char) r0); } if (r1 < 0x20 or r1 > 0x7e) { printf("\\%lo", r1); } else { printf("'%c'", (char) r1); } } else if (r0 > 0 and r1 == 0) { printf("%ld byte real", r0); } else if (r0 >= 0) { printf("%lu..%lu", r0, r1); } else { printf("%ld..%ld", r0, r1); }}/* * Print out an enumeration declaration. */private printEnumDecl (e, n)Symbol e;int n;{ Symbol t; printf("("); t = e->chain; if (t != nil) { printf("%s", symname(t)); t = t->chain; while (t != nil) { printf(", %s", symname(t)); t = t->chain; } } printf(")");}/* * List the parameters of a procedure or function. * No attempt is made to combine like types. */private listparams (s)Symbol s;{ Symbol t; if (s->chain != nil) { putchar('('); for (t = s->chain; t != nil; t = t->chain) { switch (t->class) { case REF: printf("var "); break; case FPROC: case FFUNC: printf("procedure "); break; case VAR: break; default: panic("unexpected class %d for parameter", t->class); } printf("%s", symname(t)); if (s->class == PROG) { printf(", "); } else { printf(" : "); printtype(t, t->type, 0); if (t->chain != nil) { printf("; "); } } } putchar(')'); }}/* * Test if a pointer type should be treated as a null-terminated string. * The type given is the type that is pointed to. */private boolean isCstring (type)Symbol type;{ boolean b; register Symbol a, t; a = rtype(type); if (a->class == ARRAY) { t = rtype(a->chain); b = (boolean) ( t->class == RANGE and istypename(a->type, "char") and (t->symvalue.rangev.upper - t->symvalue.rangev.lower + 1) <= 0 ); } else { b = false; } return b;}/* * Modula 2 interface to printval. */
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -