xref: /plan9/sys/src/cmd/acid/dot.c (revision 4de34a7edde43207e841ec91ecd12e6cf5f5ebe7)
1bd389b36SDavid du Colombier #include <u.h>
2bd389b36SDavid du Colombier #include <libc.h>
3bd389b36SDavid du Colombier #include <bio.h>
4bd389b36SDavid du Colombier #include <ctype.h>
5bd389b36SDavid du Colombier #include <mach.h>
6bd389b36SDavid du Colombier #define Extern extern
7bd389b36SDavid du Colombier #include "acid.h"
8bd389b36SDavid du Colombier 
9bd389b36SDavid du Colombier Type*
srch(Type * t,char * s)10bd389b36SDavid du Colombier srch(Type *t, char *s)
11bd389b36SDavid du Colombier {
12219b2ee8SDavid du Colombier 	Type *f;
13219b2ee8SDavid du Colombier 
14219b2ee8SDavid du Colombier 	f = 0;
15bd389b36SDavid du Colombier 	while(t) {
16219b2ee8SDavid du Colombier 		if(strcmp(t->tag->name, s) == 0) {
17219b2ee8SDavid du Colombier 			if(f == 0 || t->depth < f->depth)
18219b2ee8SDavid du Colombier 				f = t;
19219b2ee8SDavid du Colombier 		}
20bd389b36SDavid du Colombier 		t = t->next;
21bd389b36SDavid du Colombier 	}
22219b2ee8SDavid du Colombier 	return f;
23bd389b36SDavid du Colombier }
24bd389b36SDavid du Colombier 
25bd389b36SDavid du Colombier void
odot(Node * n,Node * r)26219b2ee8SDavid du Colombier odot(Node *n, Node *r)
27bd389b36SDavid du Colombier {
28bd389b36SDavid du Colombier 	char *s;
29bd389b36SDavid du Colombier 	Type *t;
30bd389b36SDavid du Colombier 	Node res;
31*4de34a7eSDavid du Colombier 	uvlong addr;
32bd389b36SDavid du Colombier 
33bd389b36SDavid du Colombier 	s = n->sym->name;
34219b2ee8SDavid du Colombier 	if(s == 0)
35219b2ee8SDavid du Colombier 		fatal("dodot: no tag");
36bd389b36SDavid du Colombier 
37bd389b36SDavid du Colombier 	expr(n->left, &res);
38bd389b36SDavid du Colombier 	if(res.comt == 0)
39bd389b36SDavid du Colombier 		error("no type specified for (expr).%s", s);
40bd389b36SDavid du Colombier 
41219b2ee8SDavid du Colombier 	if(res.type != TINT)
42219b2ee8SDavid du Colombier 		error("pointer must be integer for (expr).%s", s);
43219b2ee8SDavid du Colombier 
44bd389b36SDavid du Colombier 	t = srch(res.comt, s);
45bd389b36SDavid du Colombier 	if(t == 0)
46bd389b36SDavid du Colombier 		error("no tag for (expr).%s", s);
47bd389b36SDavid du Colombier 
48219b2ee8SDavid du Colombier 	/* Propagate types */
49219b2ee8SDavid du Colombier 	if(t->type)
50219b2ee8SDavid du Colombier 		r->comt = t->type->lt;
51bd389b36SDavid du Colombier 
52bd389b36SDavid du Colombier 	addr = res.ival+t->offset;
53bd389b36SDavid du Colombier 	if(t->fmt == 'a') {
54219b2ee8SDavid du Colombier 		r->op = OCONST;
55bd389b36SDavid du Colombier 		r->fmt = 'a';
56bd389b36SDavid du Colombier 		r->type = TINT;
57bd389b36SDavid du Colombier 		r->ival = addr;
58bd389b36SDavid du Colombier 	}
59bd389b36SDavid du Colombier 	else
60bd389b36SDavid du Colombier 		indir(cormap, addr, t->fmt, r);
61219b2ee8SDavid du Colombier 
62bd389b36SDavid du Colombier }
63bd389b36SDavid du Colombier 
64219b2ee8SDavid du Colombier static Type **tail;
65219b2ee8SDavid du Colombier static Lsym *base;
66219b2ee8SDavid du Colombier 
67bd389b36SDavid du Colombier void
buildtype(Node * m,int d)68219b2ee8SDavid du Colombier buildtype(Node *m, int d)
69bd389b36SDavid du Colombier {
70219b2ee8SDavid du Colombier 	Type *t;
71bd389b36SDavid du Colombier 
72219b2ee8SDavid du Colombier 	if(m == ZN)
73219b2ee8SDavid du Colombier 		return;
74bd389b36SDavid du Colombier 
75219b2ee8SDavid du Colombier 	switch(m->op) {
76219b2ee8SDavid du Colombier 	case OLIST:
77219b2ee8SDavid du Colombier 		buildtype(m->left, d);
78219b2ee8SDavid du Colombier 		buildtype(m->right, d);
79bd389b36SDavid du Colombier 		break;
80219b2ee8SDavid du Colombier 
81219b2ee8SDavid du Colombier 	case OCTRUCT:
82219b2ee8SDavid du Colombier 		buildtype(m->left, d+1);
83219b2ee8SDavid du Colombier 		break;
84219b2ee8SDavid du Colombier 	default:
85219b2ee8SDavid du Colombier 		t = malloc(sizeof(Type));
86219b2ee8SDavid du Colombier 		t->next = 0;
87219b2ee8SDavid du Colombier 		t->depth = d;
88219b2ee8SDavid du Colombier 		t->tag = m->sym;
89219b2ee8SDavid du Colombier 		t->base = base;
90219b2ee8SDavid du Colombier 		t->offset = m->ival;
91219b2ee8SDavid du Colombier 		if(m->left) {
92219b2ee8SDavid du Colombier 			t->type = m->left->sym;
93219b2ee8SDavid du Colombier 			t->fmt = 'a';
94bd389b36SDavid du Colombier 		}
95219b2ee8SDavid du Colombier 		else {
96219b2ee8SDavid du Colombier 			t->type = 0;
97219b2ee8SDavid du Colombier 			if(m->right)
98219b2ee8SDavid du Colombier 				t->type = m->right->sym;
99219b2ee8SDavid du Colombier 			t->fmt = m->fmt;
100bd389b36SDavid du Colombier 		}
101bd389b36SDavid du Colombier 
102bd389b36SDavid du Colombier 		*tail = t;
103bd389b36SDavid du Colombier 		tail = &t->next;
104bd389b36SDavid du Colombier 	}
105bd389b36SDavid du Colombier }
106bd389b36SDavid du Colombier 
107bd389b36SDavid du Colombier void
defcomplex(Node * tn,Node * m)108219b2ee8SDavid du Colombier defcomplex(Node *tn, Node *m)
109bd389b36SDavid du Colombier {
110219b2ee8SDavid du Colombier 	tail = &tn->sym->lt;
111219b2ee8SDavid du Colombier 	base = tn->sym;
112219b2ee8SDavid du Colombier 	buildtype(m, 0);
113219b2ee8SDavid du Colombier }
114bd389b36SDavid du Colombier 
115219b2ee8SDavid du Colombier void
decl(Node * n)116219b2ee8SDavid du Colombier decl(Node *n)
117219b2ee8SDavid du Colombier {
118219b2ee8SDavid du Colombier 	Node *l;
119219b2ee8SDavid du Colombier 	Value *v;
120219b2ee8SDavid du Colombier 	Frtype *f;
121219b2ee8SDavid du Colombier 	Lsym *type;
122bd389b36SDavid du Colombier 
123219b2ee8SDavid du Colombier 	type = n->sym;
124219b2ee8SDavid du Colombier 	if(type->lt == 0)
125219b2ee8SDavid du Colombier 		error("%s is not a complex type", type->name);
126219b2ee8SDavid du Colombier 
127219b2ee8SDavid du Colombier 	l = n->left;
128219b2ee8SDavid du Colombier 	if(l->op == ONAME) {
129219b2ee8SDavid du Colombier 		v = l->sym->v;
130219b2ee8SDavid du Colombier 		v->comt = type->lt;
131219b2ee8SDavid du Colombier 		v->fmt = 'a';
132bd389b36SDavid du Colombier 		return;
133bd389b36SDavid du Colombier 	}
134219b2ee8SDavid du Colombier 
135219b2ee8SDavid du Colombier 	/*
136219b2ee8SDavid du Colombier 	 * Frame declaration
137219b2ee8SDavid du Colombier 	 */
138219b2ee8SDavid du Colombier 	for(f = l->sym->local; f; f = f->next) {
139219b2ee8SDavid du Colombier 		if(f->var == l->left->sym) {
140219b2ee8SDavid du Colombier 			f->type = n->sym->lt;
141bd389b36SDavid du Colombier 			return;
142bd389b36SDavid du Colombier 		}
143219b2ee8SDavid du Colombier 	}
144219b2ee8SDavid du Colombier 	f = malloc(sizeof(Frtype));
145219b2ee8SDavid du Colombier 	if(f == 0)
146219b2ee8SDavid du Colombier 		fatal("out of memory");
147bd389b36SDavid du Colombier 
148219b2ee8SDavid du Colombier 	f->type = type->lt;
149219b2ee8SDavid du Colombier 
150219b2ee8SDavid du Colombier 	f->var = l->left->sym;
151219b2ee8SDavid du Colombier 	f->next = l->sym->local;
152219b2ee8SDavid du Colombier 	l->sym->local = f;
153bd389b36SDavid du Colombier }
154