* Copyright (c) 1993 David I. Bell
* Permission is granted to use, distribute, or modify this source,
* provided that this copyright notice remains intact.
* Label handling routines.
static long labelcount
; /* number of user labels defined */
static STRINGHEAD labelnames
; /* list of user label names */
static LABEL labels
[MAXLABELS
]; /* list of user labels */
* Initialize the table of labels for a function.
* Define a user named label to have the offset of the next opcode.
char *name
; /* label name */
register LABEL
*lp
; /* current label */
long i
; /* current label index */
i
= findstr(&labelnames
, name
);
scanerror(T_NULL
, "Label \"%s\" is multiply defined",
if (labelcount
>= MAXLABELS
) {
scanerror(T_NULL
, "Too many labels in use");
lp
= &labels
[labelcount
++];
lp
->l_offset
= curfunc
->f_opcodecount
;
lp
->l_name
= addstr(&labelnames
, name
);
* Add the offset corresponding to the specified user label name to the
* opcode table for a function. If the label is not yet defined, then a
* chain of undefined offsets is built using the offset value, and it
* will be fixed up when the label is defined.
char *name
; /* user symbol name */
register LABEL
*lp
; /* current label */
for (i
= labelcount
, lp
= labels
; --i
>= 0; lp
++) {
if (strcmp(name
, lp
->l_name
))
if (labelcount
>= MAXLABELS
) {
scanerror(T_NULL
, "Too many labels in use");
lp
= &labels
[labelcount
++];
lp
->l_chain
= curfunc
->f_opcodecount
;
lp
->l_name
= addstr(&labelnames
, name
);
* Check to make sure that all labels are defined.
register LABEL
*lp
; /* label being checked */
for (i
= labelcount
, lp
= labels
; --i
>= 0; lp
++) {
scanerror(T_NULL
, "Label \"%s\" was never defined",
* Clear an internal label for use.
register LABEL
*lp
; /* label being cleared */
* Set any label to have the value of the next opcode in the current
* function being defined. If there were forward references to it,
* all such references are patched up.
register LABEL
*lp
; /* label being set */
register FUNC
*fp
; /* current function */
long curfix
; /* offset of current location being fixed */
long nextfix
; /* offset of next location to fix up */
long offset
; /* offset of this label */
offset
= fp
->f_opcodecount
;
nextfix
= fp
->f_opcodes
[curfix
];
fp
->f_opcodes
[curfix
] = offset
;
* Use the specified label at the current location in the function
* being compiled. This adds one word to the current function being
* compiled. If the label is not yet defined, a patch chain is built
* so the reference can be fixed when the label is defined.
register LABEL
*lp
; /* label being used */
long offset
; /* offset being added */
offset
= curfunc
->f_opcodecount
;