newer version
This commit is contained in:
@@ -16,11 +16,14 @@ static char *RcsId = "$Header$";
|
||||
#include "main.h"
|
||||
#include "LLlex.h"
|
||||
#include "node.h"
|
||||
#include "Lpars.h"
|
||||
|
||||
#include "debug.h"
|
||||
|
||||
extern arith align();
|
||||
static int prclev = 0;
|
||||
static label instructionlabel = 0;
|
||||
static label datalabel = 0;
|
||||
|
||||
WalkModule(module)
|
||||
register struct def *module;
|
||||
@@ -33,10 +36,12 @@ WalkModule(module)
|
||||
|
||||
scope = CurrentScope;
|
||||
CurrentScope = module->mod_scope;
|
||||
|
||||
if (!prclev && module->mod_number) {
|
||||
/* This module is a local module, but not within a
|
||||
procedure. Generate code to allocate storage for its
|
||||
variables
|
||||
variables. This is done by generating a "bss",
|
||||
with label "_<modulenumber><modulename>".
|
||||
*/
|
||||
arith size = align(CurrentScope->sc_off, word_size);
|
||||
|
||||
@@ -69,7 +74,7 @@ WalkModule(module)
|
||||
CurrentScope->sc_off = 0;
|
||||
C_pro_narg(CurrentScope->sc_name);
|
||||
MkCalls(CurrentScope->sc_def);
|
||||
WalkNode(module->mod_body);
|
||||
WalkNode(module->mod_body, (label) 0);
|
||||
C_end(align(-CurrentScope->sc_off, word_size));
|
||||
|
||||
CurrentScope = scope;
|
||||
@@ -91,12 +96,13 @@ WalkProcedure(procedure)
|
||||
|
||||
/* Generate code for this procedure
|
||||
*/
|
||||
C_pro_narg(procedure->prc_name);
|
||||
C_pro_narg(CurrentScope->sc_name);
|
||||
/* generate calls to initialization routines of modules defined within
|
||||
this procedure
|
||||
*/
|
||||
instructionlabel = 1;
|
||||
MkCalls(CurrentScope->sc_def);
|
||||
WalkNode(procedure->prc_body);
|
||||
WalkNode(procedure->prc_body, (label) 0);
|
||||
C_end(align(-CurrentScope->sc_off, word_size));
|
||||
CurrentScope = scope;
|
||||
prclev--;
|
||||
@@ -126,17 +132,151 @@ MkCalls(df)
|
||||
while (df) {
|
||||
if (df->df_kind == D_MODULE) {
|
||||
C_lxl((arith) 0);
|
||||
C_cal(df->df_scope->sc_name);
|
||||
C_cal(df->mod_scope->sc_name);
|
||||
}
|
||||
df = df->df_nextinscope;
|
||||
}
|
||||
}
|
||||
|
||||
WalkNode(nd)
|
||||
struct node *nd;
|
||||
WalkNode(nd, lab)
|
||||
register struct node *nd;
|
||||
label lab;
|
||||
{
|
||||
/* Node "nd" represents either a statement or a statement list.
|
||||
Generate code for it.
|
||||
Walk through it.
|
||||
"lab" represents the label that must be jumped to on
|
||||
encountering an EXIT statement.
|
||||
*/
|
||||
|
||||
while (nd->nd_class == Link) { /* statement list */
|
||||
WalkStat(nd->nd_left, lab);
|
||||
nd = nd->nd_right;
|
||||
}
|
||||
|
||||
WalkStat(nd, lab);
|
||||
}
|
||||
|
||||
WalkStat(nd, lab)
|
||||
register struct node *nd;
|
||||
label lab;
|
||||
{
|
||||
/* Walk through a statement, generating code for it.
|
||||
"lab" represents the label that must be jumped to on
|
||||
encountering an EXIT statement.
|
||||
*/
|
||||
register struct node *left = nd->nd_left;
|
||||
register struct node *right = nd->nd_right;
|
||||
|
||||
if (nd->nd_class == Call) {
|
||||
/* ??? */
|
||||
return;
|
||||
}
|
||||
|
||||
assert(nd->nd_class == Stat);
|
||||
|
||||
switch(nd->nd_symb) {
|
||||
case BECOMES:
|
||||
/* ??? */
|
||||
break;
|
||||
|
||||
case IF:
|
||||
{ label l1, l2;
|
||||
|
||||
l1 = instructionlabel++;
|
||||
l2 = instructionlabel++;
|
||||
ExpectBool(left);
|
||||
assert(right->nd_symb == THEN);
|
||||
C_zeq(l1);
|
||||
WalkNode(right->nd_left, lab);
|
||||
|
||||
if (right->nd_right) { /* ELSE part */
|
||||
C_bra(l2);
|
||||
C_df_ilb(l1);
|
||||
WalkNode(right->nd_right, lab);
|
||||
C_df_ilb(l2);
|
||||
}
|
||||
else C_df_ilb(l1);
|
||||
break;
|
||||
}
|
||||
|
||||
case CASE:
|
||||
/* ??? */
|
||||
break;
|
||||
|
||||
case WHILE:
|
||||
{ label l1, l2;
|
||||
|
||||
l1 = instructionlabel++;
|
||||
l2 = instructionlabel++;
|
||||
C_df_ilb(l1);
|
||||
ExpectBool(left);
|
||||
C_zeq(l2);
|
||||
WalkNode(right, lab);
|
||||
C_bra(l1);
|
||||
C_df_ilb(l2);
|
||||
break;
|
||||
}
|
||||
|
||||
case REPEAT:
|
||||
{ label l1;
|
||||
|
||||
l1 = instructionlabel++;
|
||||
C_df_ilb(l1);
|
||||
WalkNode(left, lab);
|
||||
ExpectBool(right);
|
||||
C_zeq(l1);
|
||||
break;
|
||||
}
|
||||
|
||||
case LOOP:
|
||||
{ label l1, l2;
|
||||
|
||||
l1 = instructionlabel++;
|
||||
l2 = instructionlabel++;
|
||||
C_df_ilb(l1);
|
||||
WalkNode(left, l2);
|
||||
C_bra(l1);
|
||||
C_df_ilb(l2);
|
||||
break;
|
||||
}
|
||||
|
||||
case FOR:
|
||||
/* ??? */
|
||||
break;
|
||||
|
||||
case WITH:
|
||||
/* ??? */
|
||||
break;
|
||||
|
||||
case EXIT:
|
||||
assert(lab != 0);
|
||||
|
||||
C_bra(lab);
|
||||
break;
|
||||
|
||||
case RETURN:
|
||||
/* ??? */
|
||||
break;
|
||||
|
||||
default:
|
||||
assert(0);
|
||||
}
|
||||
}
|
||||
|
||||
ExpectBool(nd)
|
||||
struct node *nd;
|
||||
{
|
||||
/* "nd" must indicate a boolean expression. Check this and
|
||||
generate code to evaluate the expression.
|
||||
*/
|
||||
|
||||
chk_expr(nd);
|
||||
|
||||
if (nd->nd_type != bool_type) {
|
||||
node_error(nd, "boolean expression expected");
|
||||
}
|
||||
|
||||
/* generate code
|
||||
*/
|
||||
/* ??? */
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user