xref: /csrg-svn/old/dbx/pascal.c (revision 16615)
19675Slinton /* Copyright (c) 1982 Regents of the University of California */
29675Slinton 
39689Slinton static char sccsid[] = "@(#)pascal.c 1.2 12/15/82";
49675Slinton 
5*16615Ssam static char rcsid[] = "$Header: pascal.c,v 1.3 84/03/27 10:23:04 linton Exp $";
6*16615Ssam 
79675Slinton /*
89675Slinton  * Pascal-dependent symbol routines.
99675Slinton  */
109675Slinton 
119675Slinton #include "defs.h"
129675Slinton #include "symbols.h"
139675Slinton #include "pascal.h"
149675Slinton #include "languages.h"
159675Slinton #include "tree.h"
169675Slinton #include "eval.h"
179675Slinton #include "mappings.h"
189675Slinton #include "process.h"
199675Slinton #include "runtime.h"
209675Slinton #include "machine.h"
219675Slinton 
229675Slinton #ifndef public
239675Slinton #endif
249675Slinton 
25*16615Ssam private Language pasc;
26*16615Ssam 
279675Slinton /*
289675Slinton  * Initialize Pascal information.
299675Slinton  */
309675Slinton 
319675Slinton public pascal_init()
329675Slinton {
33*16615Ssam     pasc = language_define("pascal", ".p");
34*16615Ssam     language_setop(pasc, L_PRINTDECL, pascal_printdecl);
35*16615Ssam     language_setop(pasc, L_PRINTVAL, pascal_printval);
36*16615Ssam     language_setop(pasc, L_TYPEMATCH, pascal_typematch);
37*16615Ssam     language_setop(pasc, L_BUILDAREF, pascal_buildaref);
38*16615Ssam     language_setop(pasc, L_EVALAREF, pascal_evalaref);
39*16615Ssam     language_setop(pasc, L_MODINIT, pascal_modinit);
40*16615Ssam     language_setop(pasc, L_HASMODULES, pascal_hasmodules);
41*16615Ssam     language_setop(pasc, L_PASSADDR, pascal_passaddr);
42*16615Ssam     initTypes();
439675Slinton }
449675Slinton 
459675Slinton /*
469675Slinton  * Compatible tests if two types are compatible.  The issue
479675Slinton  * is complicated a bit by ranges.
489675Slinton  *
499675Slinton  * Integers and reals are not compatible since they cannot always be mixed.
509675Slinton  */
519675Slinton 
529675Slinton public Boolean pascal_typematch(type1, type2)
539675Slinton Symbol type1, type2;
549675Slinton {
559675Slinton     Boolean b;
569675Slinton     register Symbol t1, t2;
579675Slinton 
589675Slinton     t1 = rtype(t1);
599675Slinton     t2 = rtype(t2);
609675Slinton     b = (Boolean)
619675Slinton 	(t1->type == t2->type and (
629675Slinton 	    (t1->class == RANGE and t2->class == RANGE) or
639675Slinton 	    (t1->class == SCAL and t2->class == CONST) or
649675Slinton 	    (t1->class == CONST and t2->class == SCAL) or
659675Slinton 	    (t1->type == t_char and t1->class == ARRAY and t2->class == ARRAY)
669675Slinton 	) or
679675Slinton 	(t1 == t_nil and t2->class == PTR) or
689675Slinton 	(t1->class == PTR and t2 == t_nil)
699675Slinton     );
709675Slinton     return b;
719675Slinton }
729675Slinton 
739675Slinton public pascal_printdecl(s)
749675Slinton Symbol s;
759675Slinton {
769675Slinton     register Symbol t;
779675Slinton     Boolean semicolon;
789675Slinton 
799675Slinton     semicolon = true;
809675Slinton     switch (s->class) {
819675Slinton 	case CONST:
829675Slinton 	    if (s->type->class == SCAL) {
839675Slinton 		printf("(enumeration constant, ord %ld)",
849675Slinton 		    s->symvalue.iconval);
859675Slinton 	    } else {
869675Slinton 		printf("const %s = ", symname(s));
879675Slinton 		printval(s);
889675Slinton 	    }
899675Slinton 	    break;
909675Slinton 
919675Slinton 	case TYPE:
929675Slinton 	    printf("type %s = ", symname(s));
939675Slinton 	    printtype(s, s->type);
949675Slinton 	    break;
959675Slinton 
969675Slinton 	case VAR:
979675Slinton 	    if (isparam(s)) {
989675Slinton 		printf("(parameter) %s : ", symname(s));
999675Slinton 	    } else {
1009675Slinton 		printf("var %s : ", symname(s));
1019675Slinton 	    }
1029675Slinton 	    printtype(s, s->type);
1039675Slinton 	    break;
1049675Slinton 
1059675Slinton 	case REF:
1069675Slinton 	    printf("(var parameter) %s : ", symname(s));
1079675Slinton 	    printtype(s, s->type);
1089675Slinton 	    break;
1099675Slinton 
1109675Slinton 	case RANGE:
1119675Slinton 	case ARRAY:
1129675Slinton 	case RECORD:
1139675Slinton 	case VARNT:
1149675Slinton 	case PTR:
1159675Slinton 	    printtype(s, s);
1169675Slinton 	    semicolon = false;
1179675Slinton 	    break;
1189675Slinton 
1199675Slinton 	case FVAR:
1209675Slinton 	    printf("(function variable) %s : ", symname(s));
1219675Slinton 	    printtype(s, s->type);
1229675Slinton 	    break;
1239675Slinton 
1249675Slinton 	case FIELD:
1259675Slinton 	    printf("(field) %s : ", symname(s));
1269675Slinton 	    printtype(s, s->type);
1279675Slinton 	    break;
1289675Slinton 
1299675Slinton 	case PROC:
1309675Slinton 	    printf("procedure %s", symname(s));
1319675Slinton 	    listparams(s);
1329675Slinton 	    break;
1339675Slinton 
1349675Slinton 	case PROG:
1359675Slinton 	    printf("program %s", symname(s));
1369675Slinton 	    t = s->chain;
1379675Slinton 	    if (t != nil) {
1389675Slinton 		printf("(%s", symname(t));
1399675Slinton 		for (t = t->chain; t != nil; t = t->chain) {
1409675Slinton 		    printf(", %s", symname(t));
1419675Slinton 		}
1429675Slinton 		printf(")");
1439675Slinton 	    }
1449675Slinton 	    break;
1459675Slinton 
1469675Slinton 	case FUNC:
1479675Slinton 	    printf("function %s", symname(s));
1489675Slinton 	    listparams(s);
1499675Slinton 	    printf(" : ");
1509675Slinton 	    printtype(s, s->type);
1519675Slinton 	    break;
1529675Slinton 
1539675Slinton 	default:
1549675Slinton 	    error("class %s in printdecl", classname(s));
1559675Slinton     }
1569675Slinton     if (semicolon) {
1579675Slinton 	putchar(';');
1589675Slinton     }
1599675Slinton     putchar('\n');
1609675Slinton }
1619675Slinton 
1629675Slinton /*
1639675Slinton  * Recursive whiz-bang procedure to print the type portion
1649675Slinton  * of a declaration.  Doesn't work quite right for variant records.
1659675Slinton  *
1669675Slinton  * The symbol associated with the type is passed to allow
1679675Slinton  * searching for type names without getting "type blah = blah".
1689675Slinton  */
1699675Slinton 
1709675Slinton private printtype(s, t)
1719675Slinton Symbol s;
1729675Slinton Symbol t;
1739675Slinton {
1749675Slinton     register Symbol tmp;
1759675Slinton 
1769675Slinton     switch (t->class) {
1779675Slinton 	case VAR:
1789675Slinton 	case CONST:
1799675Slinton 	case FUNC:
1809675Slinton 	case PROC:
1819675Slinton 	    panic("printtype: class %s", classname(t));
1829675Slinton 	    break;
1839675Slinton 
1849675Slinton 	case ARRAY:
1859675Slinton 	    printf("array[");
1869675Slinton 	    tmp = t->chain;
1879675Slinton 	    if (tmp != nil) {
1889675Slinton 		for (;;) {
1899675Slinton 		    printtype(tmp, tmp);
1909675Slinton 		    tmp = tmp->chain;
1919675Slinton 		    if (tmp == nil) {
1929675Slinton 			break;
1939675Slinton 		    }
1949675Slinton 		    printf(", ");
1959675Slinton 		}
1969675Slinton 	    }
1979675Slinton 	    printf("] of ");
1989675Slinton 	    printtype(t, t->type);
1999675Slinton 	    break;
2009675Slinton 
2019675Slinton 	case RECORD:
2029675Slinton 	    printf("record\n");
2039675Slinton 	    if (t->chain != nil) {
2049675Slinton 		printtype(t->chain, t->chain);
2059675Slinton 	    }
2069675Slinton 	    printf("end");
2079675Slinton 	    break;
2089675Slinton 
2099675Slinton 	case FIELD:
2109675Slinton 	    if (t->chain != nil) {
2119675Slinton 		printtype(t->chain, t->chain);
2129675Slinton 	    }
2139675Slinton 	    printf("\t%s : ", symname(t));
2149675Slinton 	    printtype(t, t->type);
2159675Slinton 	    printf(";\n");
2169675Slinton 	    break;
2179675Slinton 
2189675Slinton 	case RANGE: {
2199675Slinton 	    long r0, r1;
2209675Slinton 
2219675Slinton 	    r0 = t->symvalue.rangev.lower;
2229675Slinton 	    r1 = t->symvalue.rangev.upper;
223*16615Ssam 	    if (t == t_char or istypename(t,"char")) {
2249675Slinton 		if (r0 < 0x20 or r0 > 0x7e) {
2259675Slinton 		    printf("%ld..", r0);
2269675Slinton 		} else {
2279675Slinton 		    printf("'%c'..", (char) r0);
2289675Slinton 		}
2299675Slinton 		if (r1 < 0x20 or r1 > 0x7e) {
2309675Slinton 		    printf("\\%lo", r1);
2319675Slinton 		} else {
2329675Slinton 		    printf("'%c'", (char) r1);
2339675Slinton 		}
2349675Slinton 	    } else if (r0 > 0 and r1 == 0) {
2359675Slinton 		printf("%ld byte real", r0);
2369675Slinton 	    } else if (r0 >= 0) {
2379675Slinton 		printf("%lu..%lu", r0, r1);
2389675Slinton 	    } else {
2399675Slinton 		printf("%ld..%ld", r0, r1);
2409675Slinton 	    }
2419675Slinton 	    break;
2429675Slinton 	}
2439675Slinton 
2449675Slinton 	case PTR:
2459675Slinton 	    putchar('*');
2469675Slinton 	    printtype(t, t->type);
2479675Slinton 	    break;
2489675Slinton 
2499675Slinton 	case TYPE:
2509675Slinton 	    if (symname(t) != nil) {
2519675Slinton 		printf("%s", symname(t));
2529675Slinton 	    } else {
2539675Slinton 		printtype(t, t->type);
2549675Slinton 	    }
2559675Slinton 	    break;
2569675Slinton 
2579675Slinton 	case SCAL:
2589675Slinton 	    printf("(");
259*16615Ssam 	    t = t->chain;
2609675Slinton 	    if (t != nil) {
2619675Slinton 		printf("%s", symname(t));
2629675Slinton 		t = t->chain;
2639675Slinton 		while (t != nil) {
2649675Slinton 		    printf(", %s", symname(t));
2659675Slinton 		    t = t->chain;
2669675Slinton 		}
2679675Slinton 	    } else {
2689675Slinton 		panic("empty enumeration");
2699675Slinton 	    }
2709675Slinton 	    printf(")");
2719675Slinton 	    break;
2729675Slinton 
2739675Slinton 	default:
2749675Slinton 	    printf("(class %d)", t->class);
2759675Slinton 	    break;
2769675Slinton     }
2779675Slinton }
2789675Slinton 
2799675Slinton /*
2809675Slinton  * List the parameters of a procedure or function.
2819675Slinton  * No attempt is made to combine like types.
2829675Slinton  */
2839675Slinton 
2849675Slinton private listparams(s)
2859675Slinton Symbol s;
2869675Slinton {
2879675Slinton     Symbol t;
2889675Slinton 
2899675Slinton     if (s->chain != nil) {
2909675Slinton 	putchar('(');
2919675Slinton 	for (t = s->chain; t != nil; t = t->chain) {
2929675Slinton 	    switch (t->class) {
2939675Slinton 		case REF:
2949675Slinton 		    printf("var ");
2959675Slinton 		    break;
2969675Slinton 
2979675Slinton 		case FPROC:
2989675Slinton 		    printf("procedure ");
2999675Slinton 		    break;
3009675Slinton 
3019675Slinton 		case FFUNC:
3029675Slinton 		    printf("function ");
3039675Slinton 		    break;
3049675Slinton 
3059675Slinton 		case VAR:
3069675Slinton 		    break;
3079675Slinton 
3089675Slinton 		default:
3099675Slinton 		    panic("unexpected class %d for parameter", t->class);
3109675Slinton 	    }
3119675Slinton 	    printf("%s : ", symname(t));
3129675Slinton 	    printtype(t, t->type);
3139675Slinton 	    if (t->chain != nil) {
3149675Slinton 		printf("; ");
3159675Slinton 	    }
3169675Slinton 	}
3179675Slinton 	putchar(')');
3189675Slinton     }
3199675Slinton }
3209675Slinton 
3219675Slinton /*
3229675Slinton  * Print out the value on the top of the expression stack
3239675Slinton  * in the format for the type of the given symbol.
3249675Slinton  */
3259675Slinton 
3269675Slinton public pascal_printval(s)
3279675Slinton Symbol s;
3289675Slinton {
3299675Slinton     Symbol t;
3309675Slinton     Address a;
3319675Slinton     int len;
3329675Slinton     double r;
3339675Slinton 
3349675Slinton     switch (s->class) {
335*16615Ssam 	case CONST:
3369675Slinton 	case TYPE:
337*16615Ssam 	case VAR:
338*16615Ssam 	case REF:
339*16615Ssam 	case FVAR:
340*16615Ssam 	case TAG:
341*16615Ssam 	case FIELD:
3429675Slinton 	    pascal_printval(s->type);
3439675Slinton 	    break;
3449675Slinton 
3459675Slinton 	case ARRAY:
3469675Slinton 	    t = rtype(s->type);
347*16615Ssam 	    if (t->class==RANGE and istypename(t->type,"char")) {
3489675Slinton 		len = size(s);
3499675Slinton 		sp -= len;
3509675Slinton 		printf("'%.*s'", len, sp);
3519675Slinton 		break;
3529675Slinton 	    } else {
3539675Slinton 		printarray(s);
3549675Slinton 	    }
3559675Slinton 	    break;
3569675Slinton 
3579675Slinton 	case RECORD:
3589675Slinton 	    printrecord(s);
3599675Slinton 	    break;
3609675Slinton 
3619675Slinton 	case VARNT:
3629675Slinton 	    error("can't print out variant records");
3639675Slinton 	    break;
3649675Slinton 
3659675Slinton 
3669675Slinton 	case RANGE:
3679675Slinton 	    if (s == t_boolean) {
3689675Slinton 		printf(((Boolean) popsmall(s)) == true ? "true" : "false");
369*16615Ssam 	    } else if (s == t_char or istypename(s,"char")) {
3709675Slinton 		printf("'%c'", pop(char));
3719675Slinton 	    } else if (s->symvalue.rangev.upper == 0 and
3729675Slinton 			s->symvalue.rangev.lower > 0) {
3739675Slinton 		switch (s->symvalue.rangev.lower) {
3749675Slinton 		    case sizeof(float):
3759675Slinton 			prtreal(pop(float));
3769675Slinton 			break;
3779675Slinton 
3789675Slinton 		    case sizeof(double):
3799675Slinton 			prtreal(pop(double));
3809675Slinton 			break;
3819675Slinton 
3829675Slinton 		    default:
3839675Slinton 			panic("bad real size %d", s->symvalue.rangev.lower);
3849675Slinton 			break;
3859675Slinton 		}
3869675Slinton 	    } else if (s->symvalue.rangev.lower >= 0) {
3879675Slinton 		printf("%lu", popsmall(s));
3889675Slinton 	    } else {
3899675Slinton 		printf("%ld", popsmall(s));
3909675Slinton 	    }
3919675Slinton 	    break;
3929675Slinton 
3939675Slinton 	case FILET:
3949675Slinton 	case PTR: {
3959675Slinton 	    Address addr;
3969675Slinton 
3979675Slinton 	    addr = pop(Address);
3989675Slinton 	    if (addr == 0) {
3999675Slinton 		printf("0, (nil)");
4009675Slinton 	    } else {
4019675Slinton 		printf("0x%x, 0%o", addr, addr);
4029675Slinton 	    }
4039675Slinton 	    break;
4049675Slinton 	}
4059675Slinton 
4069675Slinton 
4079675Slinton 	case SCAL: {
4089675Slinton 	    int scalar;
4099675Slinton 	    Boolean found;
4109675Slinton 
4119675Slinton 	    scalar = popsmall(s);
4129675Slinton 	    found = false;
4139675Slinton 	    for (t = s->chain; t != nil; t = t->chain) {
4149675Slinton 		if (t->symvalue.iconval == scalar) {
4159675Slinton 		    printf("%s", symname(t));
4169675Slinton 		    found = true;
4179675Slinton 		    break;
4189675Slinton 		}
4199675Slinton 	    }
4209675Slinton 	    if (not found) {
4219675Slinton 		printf("(scalar = %d)", scalar);
4229675Slinton 	    }
4239675Slinton 	    break;
4249675Slinton 	}
4259675Slinton 
4269675Slinton 	case FPROC:
4279675Slinton 	case FFUNC:
4289675Slinton 	{
4299675Slinton 	    Address a;
4309675Slinton 
4319675Slinton 	    a = fparamaddr(pop(long));
4329675Slinton 	    t = whatblock(a);
4339675Slinton 	    if (t == nil) {
4349675Slinton 		printf("(proc %d)", a);
4359675Slinton 	    } else {
4369675Slinton 		printf("%s", symname(t));
4379675Slinton 	    }
4389675Slinton 	    break;
4399675Slinton 	}
4409675Slinton 
4419675Slinton 	default:
4429675Slinton 	    if (ord(s->class) < ord(BADUSE) or ord(s->class) > ord(TYPEREF)) {
4439675Slinton 		panic("printval: bad class %d", ord(s->class));
4449675Slinton 	    }
4459675Slinton 	    error("don't know how to print a %s", classname(s));
4469675Slinton 	    /* NOTREACHED */
4479675Slinton     }
4489675Slinton }
449*16615Ssam 
450*16615Ssam /*
451*16615Ssam  * Construct a node for subscripting.
452*16615Ssam  */
453*16615Ssam 
454*16615Ssam public Node pascal_buildaref (a, slist)
455*16615Ssam Node a, slist;
456*16615Ssam {
457*16615Ssam     register Symbol t;
458*16615Ssam     register Node p;
459*16615Ssam     Symbol etype, atype, eltype;
460*16615Ssam     Node esub, r;
461*16615Ssam 
462*16615Ssam     r = a;
463*16615Ssam     t = rtype(a->nodetype);
464*16615Ssam     eltype = t->type;
465*16615Ssam     if (t->class != ARRAY) {
466*16615Ssam 	beginerrmsg();
467*16615Ssam 	prtree(stderr, a);
468*16615Ssam 	fprintf(stderr, " is not an array");
469*16615Ssam 	enderrmsg();
470*16615Ssam     } else {
471*16615Ssam 	p = slist;
472*16615Ssam 	t = t->chain;
473*16615Ssam 	for (; p != nil and t != nil; p = p->value.arg[1], t = t->chain) {
474*16615Ssam 	    esub = p->value.arg[0];
475*16615Ssam 	    etype = rtype(esub->nodetype);
476*16615Ssam 	    atype = rtype(t);
477*16615Ssam 	    if (not compatible(atype, etype)) {
478*16615Ssam 		beginerrmsg();
479*16615Ssam 		fprintf(stderr, "subscript ");
480*16615Ssam 		prtree(stderr, esub);
481*16615Ssam 		fprintf(stderr, " is the wrong type");
482*16615Ssam 		enderrmsg();
483*16615Ssam 	    }
484*16615Ssam 	    r = build(O_INDEX, r, esub);
485*16615Ssam 	    r->nodetype = eltype;
486*16615Ssam 	}
487*16615Ssam 	if (p != nil or t != nil) {
488*16615Ssam 	    beginerrmsg();
489*16615Ssam 	    if (p != nil) {
490*16615Ssam 		fprintf(stderr, "too many subscripts for ");
491*16615Ssam 	    } else {
492*16615Ssam 		fprintf(stderr, "not enough subscripts for ");
493*16615Ssam 	    }
494*16615Ssam 	    prtree(stderr, a);
495*16615Ssam 	    enderrmsg();
496*16615Ssam 	}
497*16615Ssam     }
498*16615Ssam     return r;
499*16615Ssam }
500*16615Ssam 
501*16615Ssam /*
502*16615Ssam  * Evaluate a subscript index.
503*16615Ssam  */
504*16615Ssam 
505*16615Ssam public int pascal_evalaref (s, i)
506*16615Ssam Symbol s;
507*16615Ssam long i;
508*16615Ssam {
509*16615Ssam     long lb, ub;
510*16615Ssam 
511*16615Ssam     s = rtype(rtype(s)->chain);
512*16615Ssam     lb = s->symvalue.rangev.lower;
513*16615Ssam     ub = s->symvalue.rangev.upper;
514*16615Ssam     if (i < lb or i > ub) {
515*16615Ssam 	error("subscript %d out of range [%d..%d]", i, lb, ub);
516*16615Ssam     }
517*16615Ssam     return (i - lb);
518*16615Ssam }
519*16615Ssam 
520*16615Ssam /*
521*16615Ssam  * Initial Pascal type information.
522*16615Ssam  */
523*16615Ssam 
524*16615Ssam #define NTYPES 4
525*16615Ssam 
526*16615Ssam private Symbol inittype[NTYPES];
527*16615Ssam private integer count;
528*16615Ssam 
529*16615Ssam private addType (s, lower, upper)
530*16615Ssam String s;
531*16615Ssam long lower, upper;
532*16615Ssam {
533*16615Ssam     register Symbol t;
534*16615Ssam 
535*16615Ssam     if (count > NTYPES) {
536*16615Ssam 	panic("too many initial types");
537*16615Ssam     }
538*16615Ssam     t = maketype(s, lower, upper);
539*16615Ssam     t->language = pasc;
540*16615Ssam     inittype[count] = t;
541*16615Ssam     ++count;
542*16615Ssam }
543*16615Ssam 
544*16615Ssam private initTypes ()
545*16615Ssam {
546*16615Ssam     count = 1;
547*16615Ssam     addType("integer", 0x80000000L, 0x7fffffffL);
548*16615Ssam     addType("char", 0L, 255L);
549*16615Ssam     addType("boolean", 0L, 1L);
550*16615Ssam     addType("real", 4L, 0L);
551*16615Ssam }
552*16615Ssam 
553*16615Ssam /*
554*16615Ssam  * Initialize typetable.
555*16615Ssam  */
556*16615Ssam 
557*16615Ssam public pascal_modinit (typetable)
558*16615Ssam Symbol typetable[];
559*16615Ssam {
560*16615Ssam     register integer i;
561*16615Ssam 
562*16615Ssam     for (i = 1; i < NTYPES; i++) {
563*16615Ssam 	typetable[i] = inittype[i];
564*16615Ssam     }
565*16615Ssam }
566*16615Ssam 
567*16615Ssam public boolean pascal_hasmodules ()
568*16615Ssam {
569*16615Ssam     return false;
570*16615Ssam }
571*16615Ssam 
572*16615Ssam public boolean pascal_passaddr (param, exprtype)
573*16615Ssam Symbol param, exprtype;
574*16615Ssam {
575*16615Ssam     return false;
576*16615Ssam }
577