📄 stmt.c
字号:
/* File stmt.c: 2.1 (83/03/20,16:02:17) */
/*% cc -O -c %
*
*/
#include <stdio.h>
#include <string.h>
#include "defs.h"
#include "data.h"
#include "headers.h"
static void loadjump(int label);
/*
* statement parser
*
* called whenever syntax requires a statement. this routine
* performs that statement and returns a number telling which one
*
* 'func' is true if we require a "function_statement", which
* must be compound, and must contain "statement_list" (even if
* "declaration_list" is omitted)
*/
int statement(int func) {
if ((ch() == 0) & feof(input))
return (0);
lastst = 0;
if (func)
if (match("{")) {
compound(YES);
return (lastst);
}
else {
error("function requires compound statement");
while (!match("}"))
inchar();
inchar();
return (-1);
}
if (match("{")) {
// stkp = 0;
compound(NO);
}
else
stst();
return (lastst);
}
// Declaration
int stdecl(void) {
if (match("//"))
while (ch())
lptr++;
else
if (amatch("register"))
doldcls(REGISTER);
else
if (amatch("auto") || amatch("void"))
doldcls(DEFAUTO);
else
if (amatch("static"))
doldcls(LSTATIC);
else
if (doldcls(AUTO))
;
else
return (NO);
return (YES);
}
int doldcls(int stclass) {
int Unsigned;
char *p1, *p2;
blanks();
Unsigned = 0;
if (amatch("unsigned")) {
Unsigned = 1;
if (!(testmatch("int") || testmatch("long") || testmatch("char"))) {
p1 = &line[strlen(line)+4];
p2 = &line[strlen(line)-1];
*p1-- = '\0';
while (p2 != &line[lptr]-1) {
*p1-- = *p2--;
}
*p1-- = ' ';
*p1-- = 't';
*p1-- = 'n';
*p1-- = 'i';
}
}
if (amatch("char")) {
if (Unsigned)
declloc(UCCHAR, stclass);
else
declloc(CCHAR, stclass);
}
else
if (amatch("int")) {
if (Unsigned)
declloc(UCINT, stclass);
else
declloc(CINT, stclass);
}
else
if (amatch("long"))
declloc(CLONG, stclass);
else
if (amatch("struct"))
declloc(STRUCTDEF, stclass);
else
if (FindTypeDef())
declloc(STRUCTDEF, stclass);
else
if (stclass == LSTATIC || stclass == DEFAUTO)
declloc(CINT, stclass);
else
return(0);
ns();
return(1);
}
/*
* non-declaration statement
*/
void stst(void) {
osymptr = 0;
DoPendingjump();
if (amatch("if")) {
doif();
lastst = STIF;
}
else
if (amatch("while")) {
dowhile();
lastst = STWHILE;
}
else
if (amatch("switch")) {
doswitch();
lastst = STSWITCH;
}
else
if (amatch("do")) {
dodo();
ns();
lastst = STDO;
}
else
if (amatch("for")) {
dofor();
lastst = STFOR;
}
else
if (amatch("return")) {
doreturn();
ns();
lastst = STRETURN;
}
else
if (amatch("break")) {
dobreak();
ns();
lastst = STBREAK;
}
else
if (amatch("continue")) {
docont();
ns();
lastst = STCONT;
}
else {
if (amatch("case")) {
docase();
lastst = statement(NO);
}
else
if (amatch("default")) {
dodefault();
lastst = statement(NO);
}
else
if (match("#asm")) {
doasm();
lastst = STASM;
}
else
if (match("{"))
compound(NO);
else {
Emitting = rhs = RHSisPntr = 0;
expression(YES);
/* if (match(":")) { // goto????
dolabel();
lastst = statement(NO);
}
else {
*/
ns();
lastst = STEXP;
/* }
*/
}
}
}
/*
* compound statement
*
* allow any number of statements to fall between "{" and "}"
*
* 'func' is true if we are in a "function_statement", which
* must contain "statement_list"
*/
//void compound(int func) {
void compound(int decls) {
// int decls;
// decls = YES;
ncmp++;
while (!match("}")) {
if (feof(input))
return;
if (decls) {
if (!stdecl()) {
decls = NO;
modstk(stkp * 2); // what's the 2 ???
}
}
else {
InX = rhs = RHSisPntr = 0;
stst();
}
}
ncmp--;
}
/*
* "if" statement
*/
void doif(void) {
int fstkp, flab1, flab2;
int flev;
flev = locptr;
fstkp = stkp;
flab1 = getlabel();
test(flab1, FALSE);
statement(NO);
DoPendingjump();
stkp = modstk(fstkp);
locptr = flev;
if (match("//"))
while (gch())
lptr++;
if (!amatch("else")) {
gnlabel(flab1);
return;
}
jump(flab2 = getlabel());
gnlabel(flab1);
statement(NO);
stkp = modstk(fstkp);
locptr = flev;
gnlabel(flab2);
}
/*
* "while" statement
*/
void dowhile(void) {
int ws[7];
ws[WSSYM] = locptr;
ws[WSSP] = stkp;
ws[WSTYP] = WSWHILE;
ws[WSTEST] = getlabel();
ws[WSEXIT] = getlabel();
addwhile(ws);
gnlabel(ws[WSTEST]);
test(ws[WSEXIT], FALSE);
statement(NO);
jump(ws[WSTEST]);
gnlabel(ws[WSEXIT]);
locptr = ws[WSSYM];
stkp = modstk(ws[WSSP]);
delwhile();
}
/*
* "do" statement
*/
void dodo(void) {
int ws[7];
ws[WSSYM] = locptr;
ws[WSSP] = stkp;
ws[WSTYP] = WSDO;
ws[WSBODY] = getlabel();
ws[WSTEST] = getlabel();
ws[WSEXIT] = getlabel();
addwhile(ws);
gnlabel(ws[WSBODY]);
statement(NO);
if (!match("while")) {
error("missing while");
return;
}
gnlabel(ws[WSTEST]);
backtest(ws[WSBODY], TRUE);
gnlabel(ws[WSEXIT]);
locptr = ws[WSSYM];
stkp = modstk(ws[WSSP]);
delwhile();
}
/*
* "for" statement
*/
void dofor(void) {
int ws[7], *pws;
ws[WSSYM] = locptr;
ws[WSSP] = stkp;
ws[WSTYP] = WSFOR;
ws[WSTEST] = getlabel();
ws[WSINCR] = getlabel();
ws[WSBODY] = getlabel();
ws[WSEXIT] = getlabel();
addwhile(ws);
pws = readwhile();
needbrack("(");
if (!match(";")) {
Emitting = rhs = RHSisPntr = 0;
expression(YES);
ns();
}
gnlabel(pws[WSTEST]);
if (!match(";")) {
Emitting = rhs = RHSisPntr = 0;
expression(YES);
// testjump(pws[WSBODY], TRUE, CINT);
jump(pws[WSEXIT]);
jump(pws[WSBODY]);
ns();
}
else
pws[WSTEST] = pws[WSBODY];
gnlabel(pws[WSINCR]);
if (!match(")")) {
Emitting = rhs = RHSisPntr = 0;
expression(YES);
needbrack(")");
jump(pws[WSTEST]);
}
else
pws[WSINCR] = pws[WSTEST];
gnlabel(pws[WSBODY]);
statement(NO);
jump(pws[WSINCR]);
gnlabel(pws[WSEXIT]);
locptr = pws[WSSYM];
stkp = modstk(pws[WSSP]);
delwhile();
}
/*
* "switch" statement
*/
void doswitch(void) {
int ws[7];
int *ptr;
ws[WSSYM] = locptr;
ws[WSSP] = stkp;
ws[WSTYP] = WSSWITCH;
ws[WSCASEP] = swstp;
ws[WSTAB] = getlabel();
ws[WSDEF] = ws[WSEXIT] = getlabel();
addwhile(ws);
immed(NULL);
printlabel(ws[WSTAB]);
nl();
gpush(CINT);
needbrack("(");
Emitting = rhs = RHSisPntr = 0;
expression(YES);
needbrack(")");
stkp = stkp + intsize(); /* '?case' will adjust the stack */
gjcase();
statement(NO);
ptr = readswitch();
jump(ptr[WSEXIT]);
dumpsw(ptr);
gnlabel(ptr[WSEXIT]);
locptr = ptr[WSSYM];
stkp = modstk(ptr[WSSP]);
swstp = ptr[WSCASEP];
delwhile();
}
/*
* "case" label
*/
void docase(void) {
int val;
val = 0;
if (readswitch()) {
if (!number(&val))
if (!pstr(&val))
error("bad case label");
addcase(val);
if (!match(":"))
error("missing colon");
}
else
error("no active switch");
}
/*
* "default" label
*/
void dodefault(void) {
int *ptr, lab;
if (ptr = readswitch()) {
ptr[WSDEF] = lab = getlabel();
gnlabel(lab);
if (!match(":"))
error("missing colon");
}
else
error("no active switch");
}
/*
* "return" statement
*/
void doreturn(void) {
if (endst() == 0) {
rhs = RHSisPntr = 0;
Emitting = 0;
Returning = OrgFptr;
expression(YES);
if (!(FuncArgType == VOID || FuncArgType == symtab[Returning].type))
error("Return type does not match definition");
Returning = 0;
}
// jump(fexitlab);
loadjump(fexitlab);
}
static void loadjump(int label) {
if (PendingJump)
error("Too many pending jumps");
PendingJump = label;
}
/*
* "break" statement
*/
void dobreak(void) {
int *ptr;
if ((ptr = readwhile()) == 0)
return;
modstk(ptr[WSSP]);
jump(ptr[WSEXIT]);
}
/*
* "continue" statement
*/
void docont(void) {
int *ptr;
if ((ptr = findwhile()) == 0)
return;
modstk(ptr[WSSP]);
if (ptr[WSTYP] == WSFOR)
jump(ptr[WSINCR]);
else
jump(ptr[WSTEST]);
}
/*
* dump switch table
*/
void dumpsw(int *ws) {
int i,j;
// gdata();
gnlabel(ws[WSTAB]);
if (ws[WSCASEP] != swstp) {
j = ws[WSCASEP];
while (j < swstp) {
defword();
i = 4;
while (i--) {
onum(swstcase[j]);
outbyte(',');
printlabel(swstlab[j++]);
if ((i == 0) | (j >= swstp)) {
nl();
break;
}
outbyte(',');
}
}
}
defword();
printlabel(ws[WSDEF]);
outstr(",0");
nl();
gtext();
}
void DoPendingjump(void) {
if (PendingJump) { // if there are any pending jumps
jump(PendingJump); // do them
PendingJump = 0;
}
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -