📄 function.c
字号:
/* File function.c:e 2.1 (83/03/20,16:02:04) */
/*% cc -O -c %
*
*/
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "defs.h"
#include "data.h"
#include "headers.h"
static int getarg(char *vname, int t, int flag);
static int brkt_flag = 0;
/*
* begin a function
*
* called from "parse", this routine tries to make a function out
* of what follows
* modified version. p.l. woods
*
*/
static int argtop;
static int ptr, order;
void newfunc(void) {
char vname[NAMESIZE];
int k;
int argptr[10];
char tname[NAMESIZE];
int _fptr, fptr;
fexitlab = getlabel();
if (!symname(vname) ) {
error("illegal function or declaration");
kill();
return;
}
strcpy(tname, vname);
if (strcmp((char *)strupr(tname), "MAIN") == 0)
InMain = nflag = TRUE;
else
InMain = FALSE;
OrgFptr = 0;
RegPntr = 0;
if (ptr = findglb(vname)) {
symtab[ptr].used = 1;
if (symtab[ptr].ident != FUNCDEF)
multidef(vname);
else
symtab[ptr].offset = symtab[ptr].ident = FUNCTION;
OrgFptr = ptr;
}
else {
ptr = addglb(vname, FUNCTION, CINT, FUNCTION, PUBLIC, 0);
if (strcmp((char *)strupr(tname), "MAIN") == 0)
symtab[ptr].used = 1;
}
if (!match("("))
error("missing open paren");
if (stkchk && InMain)
CheckCode();
LabPrefix();
outstr(vname);
col();
nl();
if (stkchk && InMain)
prologue();
locptr = STARTLOC;
argtop = 0;
order = 0;
stkp = 0;
while (!match(")")) {
if (amatch("register")) {
if (amatch("char"))
argptr[order++] = getarg(vname, CCHAR, 0);
else
if (amatch("int"))
argptr[order++] = getarg(vname, CINT, 0);
else
if (amatch("long"))
argptr[order++] = getarg(vname, CLONG, 0);
else
argptr[order++] = getarg(vname, CINT, 0); // what else?
}
else
if (amatch("char"))
argptr[order++] = getarg(vname, CCHAR, 0);
else
if (amatch("int"))
argptr[order++] = getarg(vname, CINT, 0);
else
if (amatch("unsigned")) {
if (amatch("int"))
argptr[order++] = getarg(vname, UCINT, 0);
else
if (amatch("char"))
argptr[order++] = getarg(vname, UCCHAR, 0);
else {
error("Illegal argument type");
junk();
}
}
else
if (amatch("long"))
argptr[order++] = getarg(vname, CLONG, 0);
else
if (amatch("struct")) {
if (symname(vname)) {
fptr = findglb(vname);
argptr[order++] = getarg(vname, CSTRUCT, 0);
}
}
else
if (amatch("void")) {
if (testmatch("("))
argptr[order++] = getarg(vname, CINT, 0);
}
else
if (FindTypeDef()) {
if (symname(vname)) {
fptr = findglb(vname);
argptr[order++] = getarg(vname, CSTRUCT, 0);
}
}
else {
error("illegal argument type");
junk();
}
blanks();
if (!streq(line + lptr, ")")) {
if (!match(","))
error("expected comma");
}
if (endst())
break;
}
if (symtab[ptr].args != order)
error("Different number of arguments from definition");
argtop = 0;
while (order) {
order--;
k = symtab[argptr[order]].offset;
symtab[argptr[order]].offset = argtop;
argtop += k;
}
fptr = _fptr = ptr;
if (symtab[_fptr].storage == INTERRUPT)
PushState();
JumpPending = 0;
statement(YES);
fptr = 0;
if (LabelCount[fexitlab] > 0) {
printlabel(fexitlab);
col();
nl();
}
if (symtab[_fptr].storage == INTERRUPT)
PopState();
else {
modstk(0);
gret();
}
stkp = 0;
locptr = STARTLOC; // clear local stack
// Uncomment this line to have register variables re-used
// in every function:
ResetRegBoundary(); // clear any register stack
}
void funcdef(void) {
char vname[NAMESIZE];
if (!symname(vname) ) {
error("illegal function or declaration");
kill();
return;
}
if (ptr = findglb(vname)) {
if (symtab[ptr].ident != FUNCDEF)
multidef(vname);
else
if (symtab[ptr].offset == FUNCTION)
multidef(vname);
}
else
ptr = addglb(vname, FUNCDEF, CINT, FUNCDEF, PUBLIC, 0);
if (!match("("))
error("missing open paren");
while (!match(")")) {
if (amatch("register")) {
if (amatch("char"))
getarg(vname, CCHAR, 1);
else
if (amatch("int"))
getarg(vname, CINT, 1);
else
getarg(vname, CINT, 1); // what else?
}
else
if (amatch("char"))
getarg(vname, CCHAR, 1);
else
if (amatch("int"))
getarg(vname, CINT, 1);
else
if (amatch("unsigned")) {
if (amatch("char"))
getarg(vname, UCCHAR, 1);
else
if (amatch("int"))
getarg(vname, UCINT, 1);
else {
error("Illegal argument type");
junk();
}
}
else
if (amatch("long"))
getarg(vname, CLONG, 1);
else
if (amatch("struct")) {
if (symname(vname))
getarg(vname, CSTRUCT, 1);
}
else
if (amatch("void")) {
if (testmatch("("))
getarg(vname, CINT, 1);
else {
if (ch() == '*')
getarg(vname, CINT, 1);
else
symtab[ptr].args = 0;
}
}
else
if (FindTypeDef()) {
if (symname(vname))
getarg(vname, CSTRUCT, 1);
}
else {
error("illegal argument type");
junk();
}
blanks();
if (!streq(line + lptr, ")")) {
if (!match(","))
error("expected comma");
}
if (endst())
break;
}
}
/*
* declare argument types
*
* called from "newfunc", this routine adds an entry in the local
* symbol table for each named argument
* completely rewritten version. p.l. woods
*
*/
static int getarg(char *vname, int type, int flag) {
int ident;
int argptr, offset, pp;
if (match("(")) {
brkt_flag = 1;
getarg(vname, type, flag);
brkt_flag = 0;
return 0;
}
match("far"); // ignore any fars
pp = findglb(vname);
if (match("*")) {
if (match("*"))
ident = POINTERARRAY;
else
ident = POINTER;
}
else
ident = VARIABLE;
symname(vname);
if (match("[")) {
while (inbyte() != ']') {
if (endst())
break;
}
ident = POINTER;
}
if (brkt_flag) {
if (!match(")"))
error("No closing bracket");
if (ch() == '(' && nch() == ')') {
ident = FUNCPTR;
match("(");
match(")");
}
}
if (flag) {
// we are only defining these variables
order = symtab[ptr].args;
symtab[ptr].argtype[order].ident = ident;
symtab[ptr].argtype[order].type = type;
symtab[ptr].args++;
}
else {
if (symtab[ptr].argtype[order].ident == ident && symtab[ptr].argtype[order].type == type) {
if (ident == POINTER || ident == FUNCPTR)
offset = 2;
else
if (type == CLONG)
offset = 4;
// else
// if (type == CCHAR || type == UCCHAR)
// offset = 1;
else
offset = intsize();
if (argptr = addloc(vname, 0, 0, offset, AUTO, 0)) {
symtab[argptr].ident = ident;
symtab[argptr].type = type;
if (ident != POINTER && (type == CCHAR || type == UCCHAR))
symtab[argptr].funcpar = 1;
if (type == CSTRUCT)
symtab[argptr].pntrpntr = pp;
return argptr;
}
}
else
error("Argument does not match definition or definition missing");
}
return 0;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -