newer version

This commit is contained in:
ceriel
1986-04-22 22:36:16 +00:00
parent de21842485
commit fef8659bf1
19 changed files with 420 additions and 121 deletions

View File

@@ -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
*/
/* ??? */
}