📄 modula-2.c
字号:
/*#@(#)modula-2.c 4.1 Ultrix 7/17/90*//* * Modula-2 specific symbol routines. */static char rcsid[] = "$Header: modula-2.c,v 1.4 84/03/27 10:22:04 linton Exp $";#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;/* * Initialize Modula-2 information. */public modula2_init (){ mod2 = language_define("modula-2", ".mod"); 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 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->type == t2->type and ( (t1->class == t2->class) or (t1->class == SCAL and t2->class == CONST) or (t1->class == CONST and t2->class == SCAL) ) ); return b;}private boolean openArrayMatch (t1, t2)register Symbol t1, t2;{ boolean b; b = (boolean) ( ( t1->class == ARRAY and t1->chain == t_open and t2->class == ARRAY and compatible(rtype(t2->chain)->type, t_int) and compatible(t1->type, t2->type) ) or ( t2->class == ARRAY and t2->chain == t_open 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) { tmp = t1; t1 = t2; t2 = tmp; } 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 ( 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) { printf("(enumeration constant, ord %ld)", s->symvalue.iconval); } else { printf("const %s = ", symname(s)); 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 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("function %s", symname(s)); listparams(s); printf(" : "); printtype(s, s->type, 0); break; case MODULE: printf("module %s", symname(s)); break; default: printf("%s : (class %s)", symname(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;{ register Symbol tmp; 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 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; default: printf("(class %d)", t->class); 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 (t == t_char or istypename(t, "char")) { 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) {
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -