📄 label.c
字号:
/* * 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. */#include "calc.h"#include "token.h"#include "label.h"#include "string.h"#include "opcodes.h"#include "func.h"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. */voidinitlabels(){ labelcount = 0; initstr(&labelnames);}/* * Define a user named label to have the offset of the next opcode. */voiddefinelabel(name) char *name; /* label name */{ register LABEL *lp; /* current label */ long i; /* current label index */ i = findstr(&labelnames, name); if (i >= 0) { lp = &labels[i]; if (lp->l_offset) { scanerror(T_NULL, "Label \"%s\" is multiply defined", name); return; } setlabel(lp); return; } if (labelcount >= MAXLABELS) { scanerror(T_NULL, "Too many labels in use"); return; } lp = &labels[labelcount++]; lp->l_chain = 0; lp->l_offset = curfunc->f_opcodecount; lp->l_name = addstr(&labelnames, name); clearopt();}/* * 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. */voidaddlabel(name) char *name; /* user symbol name */{ register LABEL *lp; /* current label */ long i; /* counter */ for (i = labelcount, lp = labels; --i >= 0; lp++) { if (strcmp(name, lp->l_name)) continue; uselabel(lp); return; } if (labelcount >= MAXLABELS) { scanerror(T_NULL, "Too many labels in use"); return; } lp = &labels[labelcount++]; lp->l_offset = 0; lp->l_chain = curfunc->f_opcodecount; lp->l_name = addstr(&labelnames, name); addop((long)0);}/* * Check to make sure that all labels are defined. */voidchecklabels(){ register LABEL *lp; /* label being checked */ long i; /* counter */ for (i = labelcount, lp = labels; --i >= 0; lp++) { if (lp->l_offset > 0) continue; scanerror(T_NULL, "Label \"%s\" was never defined", lp->l_name); }}/* * Clear an internal label for use. */voidclearlabel(lp) register LABEL *lp; /* label being cleared */{ lp->l_offset = 0; lp->l_chain = 0; lp->l_name = NULL;}/* * 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. */voidsetlabel(lp) 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 */ fp = curfunc; offset = fp->f_opcodecount; nextfix = lp->l_chain; while (nextfix > 0) { curfix = nextfix; nextfix = fp->f_opcodes[curfix]; fp->f_opcodes[curfix] = offset; } lp->l_chain = 0; lp->l_offset = offset; clearopt();}/* * 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. */voiduselabel(lp) register LABEL *lp; /* label being used */{ long offset; /* offset being added */ offset = curfunc->f_opcodecount; if (lp->l_offset > 0) { addop(lp->l_offset); return; } addop(lp->l_chain); lp->l_chain = offset;}/* END CODE */
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -