195 lines
4.5 KiB
C
195 lines
4.5 KiB
C
/*
|
|
* File function.c: 2.1 (83/03/20,16:02:04)
|
|
*/
|
|
|
|
#include <stdio.h>
|
|
#include "defs.h"
|
|
#include "data.h"
|
|
|
|
int argtop;
|
|
|
|
#define ARGOFFSET 20 /* for MIPS32 */
|
|
|
|
/**
|
|
* begin a function
|
|
* called from "parse", this routine tries to make a function out
|
|
* of what follows
|
|
* modified version. p.l. woods
|
|
*/
|
|
newfunc() {
|
|
char n[NAMESIZE];
|
|
int idx, type;
|
|
fexitlab = getlabel();
|
|
|
|
if (!symname(n)) {
|
|
error("illegal function or declaration");
|
|
kill();
|
|
return;
|
|
}
|
|
if (idx = findglb(n)) {
|
|
if (symbol_table[idx].identity != FUNCTION)
|
|
multidef(n);
|
|
else if (symbol_table[idx].offset == FUNCTION)
|
|
multidef(n);
|
|
else
|
|
symbol_table[idx].offset = FUNCTION;
|
|
} else
|
|
add_global(n, FUNCTION, CINT, FUNCTION, PUBLIC, 1);
|
|
|
|
if (!match("("))
|
|
error("missing open paren");
|
|
|
|
output_string(n);
|
|
output_label_terminator();
|
|
newline();
|
|
local_table_index = NUMBER_OF_GLOBALS; //locptr = STARTLOC;
|
|
argstk = 0;
|
|
|
|
// ANSI style argument declaration
|
|
if (doAnsiArguments() == 0) {
|
|
// K&R style argument declaration
|
|
while (! match(")")) {
|
|
if (symname(n)) {
|
|
if (findloc(n))
|
|
multidef(n);
|
|
else {
|
|
add_local(n, 0, 0, ARGOFFSET + argstk, AUTO, 1);
|
|
argstk = argstk + INTSIZE;
|
|
}
|
|
} else {
|
|
error("illegal argument name");
|
|
junk();
|
|
}
|
|
blanks();
|
|
if (!streq(line + lptr, ")")) {
|
|
if (!match(","))
|
|
error("expected comma");
|
|
}
|
|
if (endst())
|
|
break;
|
|
}
|
|
stkp = 0;
|
|
argtop = argstk;
|
|
while (argstk) {
|
|
if (type = get_type()) {
|
|
getarg(type);
|
|
need_semicolon();
|
|
} else {
|
|
error("wrong number args");
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
fentry(argtop);
|
|
statement(YES);
|
|
print_label(fexitlab);
|
|
output_label_terminator();
|
|
newline();
|
|
gen_modify_stack(0);
|
|
gen_ret();
|
|
stkp = 0;
|
|
local_table_index = NUMBER_OF_GLOBALS; //locptr = STARTLOC;
|
|
}
|
|
|
|
/**
|
|
* 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
|
|
* @param t argument type (char, int)
|
|
* @return
|
|
*/
|
|
getarg(int t) {
|
|
int j, legalname, argptr;
|
|
char n[NAMESIZE];
|
|
|
|
for (;;) {
|
|
if (argstk == 0)
|
|
return;
|
|
|
|
if (match("*"))
|
|
j = POINTER;
|
|
else
|
|
j = VARIABLE;
|
|
|
|
if (! (legalname = symname(n)))
|
|
illname();
|
|
|
|
if (match("[")) {
|
|
while (inbyte() != ']')
|
|
if (endst())
|
|
break;
|
|
j = POINTER;
|
|
}
|
|
if (legalname) {
|
|
if (argptr = findloc(n)) {
|
|
symbol_table[argptr].identity = j;
|
|
symbol_table[argptr].type = t;
|
|
} else
|
|
error("expecting argument name");
|
|
}
|
|
argstk = argstk - INTSIZE;
|
|
if (endst())
|
|
return;
|
|
if (! match(","))
|
|
error("expected comma");
|
|
}
|
|
}
|
|
|
|
doAnsiArguments() {
|
|
int type;
|
|
type = get_type();
|
|
if (type == 0) {
|
|
return 0; // no type detected, revert back to K&R style
|
|
}
|
|
argstk = 0;
|
|
for (;;)
|
|
{
|
|
if (type) {
|
|
doLocalAnsiArgument(type);
|
|
} else {
|
|
error("wrong number args");
|
|
break;
|
|
}
|
|
if (match(",")) {
|
|
type = get_type();
|
|
continue;
|
|
}
|
|
if (match(")")) {
|
|
break;
|
|
}
|
|
}
|
|
argtop = argstk;
|
|
}
|
|
|
|
doLocalAnsiArgument(int type) {
|
|
char symbol_name[NAMESIZE];
|
|
int identity, argptr, ptr;
|
|
|
|
if (match("*")) {
|
|
identity = POINTER;
|
|
} else {
|
|
identity = VARIABLE;
|
|
}
|
|
if (symname(symbol_name)) {
|
|
if (findloc(symbol_name)) {
|
|
multidef(symbol_name);
|
|
} else {
|
|
argptr = add_local (symbol_name, identity, type, ARGOFFSET + argstk, AUTO, 1);
|
|
argstk += INTSIZE;
|
|
}
|
|
} else {
|
|
error("illegal argument name");
|
|
junk();
|
|
}
|
|
if (match("[")) {
|
|
while (inbyte() != ']') {
|
|
if (endst()) {
|
|
break;
|
|
}
|
|
}
|
|
identity = POINTER;
|
|
symbol_table[argptr].identity = identity;
|
|
}
|
|
}
|