/ [mix] / trunk / symbol.c
To checkout: svn checkout http://svn.gnu.org.ua/sources/mix/trunk/symbol.c
Puszcza

Contents of /trunk/symbol.c

Parent Directory Parent Directory | Revision Log Revision Log


Revision 2 - (show annotations)
Wed Mar 30 16:43:11 2005 UTC (16 years, 10 months ago) by gray
File MIME type: text/plain
File size: 3436 byte(s)
Initial revision

1 #include <stdlib.h>
2 #include <string.h>
3 #include "mixasm.h"
4
5 Symbol *symlist = 0; /* symbol table: linked list */
6
7 Symbol *
8 lookup(char *s) /* find s in symbol table */
9 {
10 Symbol *sp;
11
12 for (sp = symlist; sp != (Symbol *) 0; sp = sp->next)
13 if (strcmp(sp->name, s) == 0)
14 return sp;
15 return 0; /* 0 ==> not found */
16 }
17
18 Symbol *
19 install(char *s, int v, int l) /* install s in symbol table */
20 {
21 Symbol *sp;
22 char *emalloc();
23
24 sp = (Symbol *) emalloc(sizeof(Symbol));
25 sp->name = emalloc(strlen(s)+1); /* +1 for '\0' */
26 strcpy(sp->name, s);
27 sp->value = v;
28 sp->line = l;
29 sp->reflist = 0;
30 sp->next = symlist; /* put at front of list */
31 symlist = sp;
32 return sp;
33 }
34
35 char *
36 emalloc(unsigned n) /* check return from malloc */
37 {
38 char *p;
39
40 p = malloc(n);
41 if (p == 0)
42 yyerror("out of memory");
43 return p;
44 }
45
46
47 ref *
48 addref(ref *p, int loc, int line)
49 {
50 ref *sp;
51
52 sp = (ref *) emalloc(sizeof(ref));
53 sp->next = p;
54 sp->address = loc;
55 sp->line = line;
56 return sp;
57 }
58
59 /* The following is based on a quicksort routine for linked-lists
60 * by Jon Guthrie.
61 */
62 #define getnext(a) ((a)->next)
63 #define setnext(a,l) (a->next = l, l = a)
64
65 List *
66 sortl(List *list, int (*compare)())
67 {
68 List *low_list, *high_list, *current, *pivot, *temp;
69 int result;
70
71 if (!list)
72 return NULL;
73
74 /*
75 * Find the first element that doesn't have the same value as the first
76 * element.
77 */
78 current = list;
79 do {
80 current = getnext(current);
81 if (!current)
82 return list;
83 } while (0 == (result = compare(list, current)));
84
85 /*
86 * My pivot value is the lower of the two. This insures that the sort
87 * will always terminate by guaranteeing that there will be at least one
88 * member of both of the sublists.
89 */
90 if (result > 0)
91 pivot = current;
92 else
93 pivot = list;
94
95 /* Initialize the sublist pointers */
96 low_list = high_list = NULL;
97
98 /*
99 * Now, separate the items into the two sublists
100 */
101 current = list;
102 while (current) {
103 temp = getnext(current);
104 if (compare(pivot, current) < 0) {
105 /* add one to the high list */
106 setnext(current, high_list);
107 high_list = current;
108 } else {
109 /* add one to the low list */
110 setnext(current, low_list);
111 low_list = current;
112 }
113 current = temp;
114 }
115
116 /* And, recursively call the sort for each of the two sublists. */
117 low_list = sortl(low_list, compare);
118 high_list = sortl(high_list, compare);
119
120 /*
121 * Now, I have to put the "high" list after the end of the "low" list.
122 * To do that, I first have to find the end of the "low" list...
123 */
124 current = temp = low_list;
125 while (1) {
126 current = getnext(current);
127 if (!current)
128 break;
129 temp = current;
130 }
131
132 /* Then, I put the "high" list at the end of the low list */
133 setnext(temp, high_list);
134 return low_list;
135 }
136
137 int
138 compsym(Symbol *a, Symbol *b)
139 {
140 return a->value - b->value;
141 }
142
143 int
144 compref(struct ref *a, struct ref *b)
145 {
146 return a->line - b->line;
147 }
148
149 void
150 sort_symbols()
151 {
152 symlist = (Symbol*)sortl((List*)symlist, compsym);
153 }
154
155 void
156 sort_refs(Symbol *s)
157 {
158 s->xref = (struct ref *)sortl((List*)s->xref, compref);
159 }

Properties

Name Value
svn:eol-style native
svn:keywords Author Date Id Revision

Send suggestions and bug reports to Sergey Poznyakoff
ViewVC Help
Powered by ViewVC 1.1.20