modified: SpatialOmicsCoord.py
[GalaxyCodeBases.git] / c_cpp / etc / calc / label.c
blob24c3d532d7d9b0deeb55123e3a03b626c84671e1
1 /*
2 * label - label handling routines
4 * Copyright (C) 1999-2007 David I. Bell
6 * Calc is open software; you can redistribute it and/or modify it under
7 * the terms of the version 2.1 of the GNU Lesser General Public License
8 * as published by the Free Software Foundation.
10 * Calc is distributed in the hope that it will be useful, but WITHOUT
11 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
12 * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General
13 * Public License for more details.
15 * A copy of version 2.1 of the GNU Lesser General Public License is
16 * distributed with calc under the filename COPYING-LGPL. You should have
17 * received a copy with calc; if not, write to Free Software Foundation, Inc.
18 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
20 * @(#) $Revision: 30.1 $
21 * @(#) $Id: label.c,v 30.1 2007/03/16 11:09:46 chongo Exp $
22 * @(#) $Source: /usr/local/src/bin/calc/RCS/label.c,v $
24 * Under source code control: 1990/02/15 01:48:17
25 * File existed as early as: before 1990
27 * Share and enjoy! :-) http://www.isthe.com/chongo/tech/comp/calc/
31 #include "calc.h"
32 #include "token.h"
33 #include "label.h"
34 #include "str.h"
35 #include "opcodes.h"
36 #include "func.h"
38 STATIC long labelcount; /* number of user labels defined */
39 STATIC STRINGHEAD labelnames; /* list of user label names */
40 STATIC LABEL labels[MAXLABELS]; /* list of user labels */
44 * Initialize the table of labels for a function.
46 void
47 initlabels(void)
49 labelcount = 0;
50 initstr(&labelnames);
55 * Define a user named label to have the offset of the next opcode.
57 * given:
58 * name label name
60 void
61 definelabel(char *name)
63 register LABEL *lp; /* current label */
64 long i; /* current label index */
66 i = findstr(&labelnames, name);
67 if (i >= 0) {
68 lp = &labels[i];
69 if (lp->l_offset >= 0) {
70 scanerror(T_NULL, "Label \"%s\" is multiply defined",
71 name);
72 return;
74 setlabel(lp);
75 return;
77 if (labelcount >= MAXLABELS) {
78 scanerror(T_NULL, "Too many labels in use");
79 return;
81 lp = &labels[labelcount++];
82 lp->l_chain = -1L;
83 lp->l_offset = (long)curfunc->f_opcodecount;
84 lp->l_name = addstr(&labelnames, name);
85 clearopt();
90 * Add the offset corresponding to the specified user label name to the
91 * opcode table for a function. If the label is not yet defined, then a
92 * chain of undefined offsets is built using the offset value, and it
93 * will be fixed up when the label is defined.
95 * given:
96 * name user symbol name
98 void
99 addlabel(char *name)
101 register LABEL *lp; /* current label */
102 long i; /* counter */
104 for (i = labelcount, lp = labels; --i >= 0; lp++) {
105 if (strcmp(name, lp->l_name))
106 continue;
107 uselabel(lp);
108 return;
110 if (labelcount >= MAXLABELS) {
111 scanerror(T_NULL, "Too many labels in use");
112 return;
114 lp = &labels[labelcount++];
115 lp->l_offset = -1L;
116 lp->l_chain = -1L;
117 lp->l_name = addstr(&labelnames, name);
118 uselabel(lp);
123 * Check to make sure that all labels are defined.
125 void
126 checklabels(void)
128 register LABEL *lp; /* label being checked */
129 long i; /* counter */
131 for (i = labelcount, lp = labels; --i >= 0; lp++) {
132 if (lp->l_offset >= 0)
133 continue;
134 scanerror(T_NULL, "Label \"%s\" was never defined",
135 lp->l_name);
141 * Clear an internal label for use.
143 * given:
144 * lp label being cleared
146 void
147 clearlabel(LABEL *lp)
149 lp->l_offset = -1L;
150 lp->l_chain = -1L;
151 lp->l_name = NULL;
156 * Set any label to have the value of the next opcode in the current
157 * function being defined. If there were forward references to it,
158 * all such references are patched up.
160 * given:
161 * lp label being set
163 void
164 setlabel(LABEL *lp)
166 register FUNC *fp; /* current function */
167 long curfix; /* offset of current location being fixed */
168 long nextfix; /* offset of next location to fix up */
169 unsigned long offset; /* offset of this label */
171 fp = curfunc;
172 offset = fp->f_opcodecount;
173 nextfix = (long)lp->l_chain;
174 while (nextfix >= 0) {
175 curfix = nextfix;
176 nextfix = (long)fp->f_opcodes[curfix];
177 fp->f_opcodes[curfix] = offset;
179 lp->l_chain = -1L;
180 lp->l_offset = (long)offset;
181 clearopt();
186 * Use the specified label at the current location in the function
187 * being compiled. This adds one word to the current function being
188 * compiled. If the label is not yet defined, a patch chain is built
189 * so the reference can be fixed when the label is defined.
191 * given:
192 * lp label being used
194 void
195 uselabel(LABEL *lp)
197 unsigned long offset; /* offset being added */
199 offset = curfunc->f_opcodecount;
200 if (lp->l_offset >= 0) {
201 curfunc->f_opcodes[curfunc->f_opcodecount++] = lp->l_offset;
202 return;
204 curfunc->f_opcodes[curfunc->f_opcodecount++] = lp->l_chain;
205 lp->l_chain = (long)offset;
208 /* END CODE */