ack/lang/m2/comp/walk.c

627 lines
12 KiB
C
Raw Normal View History

1986-04-21 17:27:06 +00:00
/* P A R S E T R E E W A L K E R */
1986-05-01 19:06:53 +00:00
#ifndef NORCSID
1986-04-21 17:27:06 +00:00
static char *RcsId = "$Header$";
1986-05-01 19:06:53 +00:00
#endif
1986-04-21 17:27:06 +00:00
/* Routines to walk through parts of the parse tree, and generate
code for these parts.
*/
1986-05-01 19:06:53 +00:00
#include "debug.h"
1986-04-21 17:27:06 +00:00
#include <em_arith.h>
#include <em_label.h>
1986-06-17 12:04:05 +00:00
#include <em_reg.h>
1986-04-21 17:27:06 +00:00
#include <assert.h>
#include "def.h"
#include "type.h"
#include "scope.h"
#include "main.h"
#include "LLlex.h"
#include "node.h"
1986-04-22 22:36:16 +00:00
#include "Lpars.h"
1986-05-16 17:15:36 +00:00
#include "desig.h"
1986-05-23 09:46:31 +00:00
#include "f_info.h"
1986-05-28 18:36:51 +00:00
#include "idf.h"
1986-06-17 12:04:05 +00:00
#include "chk_expr.h"
1986-06-20 14:36:49 +00:00
#include "walk.h"
1986-04-21 17:27:06 +00:00
1986-05-23 09:46:31 +00:00
extern arith NewPtr();
1986-05-28 18:36:51 +00:00
extern arith NewInt();
1986-05-16 17:15:36 +00:00
extern int proclevel;
1986-06-20 14:36:49 +00:00
label text_label;
label data_label;
1986-04-23 22:12:22 +00:00
static struct type *func_type;
1986-05-16 17:15:36 +00:00
struct withdesig *WithDesigs;
1986-05-28 18:36:51 +00:00
struct node *Modules;
1986-06-10 13:18:52 +00:00
struct scope *ProcScope;
1986-04-21 17:27:06 +00:00
1986-06-17 12:04:05 +00:00
STATIC
1986-05-23 09:46:31 +00:00
DoProfil()
{
static label filename_label = 0;
1986-05-30 18:48:00 +00:00
if (! options['L']) {
1986-05-23 09:46:31 +00:00
if (!filename_label) {
1986-06-20 14:36:49 +00:00
filename_label = ++data_label;
1986-05-23 09:46:31 +00:00
C_df_dlb(filename_label);
1986-06-04 09:01:48 +00:00
C_rom_scon(FileName, (arith) (strlen(FileName) + 1));
1986-05-23 09:46:31 +00:00
}
C_fil_dlb(filename_label, (arith) 0);
}
}
1986-04-21 17:27:06 +00:00
WalkModule(module)
register struct def *module;
{
/* Walk through a module, and all its local definitions.
Also generate code for its body.
*/
1986-05-23 19:25:21 +00:00
register struct scope *sc;
1986-06-26 09:39:36 +00:00
struct scopelist *savevis = CurrVis;
1986-04-21 17:27:06 +00:00
1986-04-28 18:06:58 +00:00
CurrVis = module->mod_vis;
1986-05-23 19:25:21 +00:00
sc = CurrentScope;
1986-04-22 22:36:16 +00:00
1986-06-26 09:39:36 +00:00
/* Walk through it's local definitions
1986-04-21 17:27:06 +00:00
*/
1986-05-23 19:25:21 +00:00
WalkDef(sc->sc_def);
1986-04-21 17:27:06 +00:00
/* Now, generate initialization code for this module.
First call initialization routines for modules defined within
this module.
*/
1986-05-23 19:25:21 +00:00
sc->sc_off = 0;
1986-06-20 14:36:49 +00:00
text_label = 1;
1986-06-26 09:39:36 +00:00
ProcScope = sc;
C_pro_narg(sc->sc_name);
1986-05-23 09:46:31 +00:00
DoProfil();
1986-06-20 14:36:49 +00:00
if (module == Defined) {
1986-05-28 18:36:51 +00:00
/* Body of implementation or program module.
Call initialization routines of imported modules.
Also prevent recursive calls of this one.
*/
1986-06-26 09:39:36 +00:00
register struct node *nd;
1986-05-28 18:36:51 +00:00
1986-06-04 09:01:48 +00:00
if (state == IMPLEMENTATION) {
1986-06-20 14:36:49 +00:00
label l1 = ++data_label;
1986-06-04 09:01:48 +00:00
/* we don't actually prevent recursive calls,
but do nothing if called recursively
*/
C_df_dlb(l1);
C_bss_cst(word_size, (arith) 0, 1);
C_loe_dlb(l1, (arith) 0);
1986-06-17 12:04:05 +00:00
C_zne((label) 1);
1986-06-04 09:01:48 +00:00
C_loc((arith) 1);
C_ste_dlb(l1, (arith) 0);
}
1986-05-28 18:36:51 +00:00
1986-06-26 09:39:36 +00:00
for (nd = Modules; nd; nd = nd->next) {
1986-05-28 18:36:51 +00:00
C_cal(nd->nd_IDF->id_text);
}
}
1986-05-23 19:25:21 +00:00
MkCalls(sc->sc_def);
1986-05-28 18:36:51 +00:00
proclevel++;
1986-06-26 09:39:36 +00:00
DO_DEBUG(options['X'], PrNode(module->mod_body, 0));
1986-04-22 22:36:16 +00:00
WalkNode(module->mod_body, (label) 0);
1986-05-14 09:03:51 +00:00
C_df_ilb((label) 1);
1986-05-28 18:36:51 +00:00
C_ret((arith) 0);
1986-05-23 19:25:21 +00:00
C_end(-sc->sc_off);
1986-05-28 18:36:51 +00:00
proclevel--;
1986-05-23 09:46:31 +00:00
TmpClose();
1986-04-21 17:27:06 +00:00
1986-06-26 09:39:36 +00:00
CurrVis = savevis;
1986-04-21 17:27:06 +00:00
}
WalkProcedure(procedure)
1986-05-28 18:36:51 +00:00
register struct def *procedure;
1986-04-21 17:27:06 +00:00
{
/* Walk through the definition of a procedure and all its
1986-06-26 09:39:36 +00:00
local definitions, checking and generating code.
1986-04-21 17:27:06 +00:00
*/
1986-06-20 14:36:49 +00:00
struct scopelist *savevis = CurrVis;
1986-05-23 19:25:21 +00:00
register struct scope *sc;
1986-06-17 12:04:05 +00:00
register struct type *tp;
register struct paramlist *param;
1986-06-20 14:36:49 +00:00
label func_res_label = 0;
1986-04-21 17:27:06 +00:00
1986-05-16 17:15:36 +00:00
proclevel++;
1986-04-28 18:06:58 +00:00
CurrVis = procedure->prc_vis;
1986-06-10 13:18:52 +00:00
ProcScope = sc = CurrentScope;
1986-06-26 09:39:36 +00:00
1986-06-20 14:36:49 +00:00
/* Generate code for all local modules and procedures
*/
1986-05-23 19:25:21 +00:00
WalkDef(sc->sc_def);
1986-04-21 17:27:06 +00:00
/* Generate code for this procedure
*/
1986-05-23 19:25:21 +00:00
C_pro_narg(sc->sc_name);
1986-05-23 09:46:31 +00:00
DoProfil();
1986-06-20 14:36:49 +00:00
/* Generate calls to initialization routines of modules defined within
1986-04-21 17:27:06 +00:00
this procedure
*/
1986-05-23 19:25:21 +00:00
MkCalls(sc->sc_def);
1986-06-20 14:36:49 +00:00
/* Make sure that arguments of size < word_size are on a
fixed place.
*/
for (param = ParamList(procedure->df_type);
param;
param = param->next) {
if (! IsVarParam(param)) {
tp = TypeOfParam(param);
if (!IsConformantArray(tp) && tp->tp_size < word_size) {
C_lol(param->par_def->var_off);
C_lal(param->par_def->var_off);
C_sti(tp->tp_size);
}
}
1986-05-28 18:36:51 +00:00
}
1986-06-20 14:36:49 +00:00
text_label = 1;
func_type = tp = ResultType(procedure->df_type);
if (IsConstructed(tp)) {
func_res_label = ++data_label;
C_df_dlb(func_res_label);
C_bss_cst(tp->tp_size, (arith) 0, 0);
}
1986-06-26 09:39:36 +00:00
DO_DEBUG(options['X'], PrNode(procedure->prc_body, 0));
1986-04-22 22:36:16 +00:00
WalkNode(procedure->prc_body, (label) 0);
1986-06-20 14:36:49 +00:00
C_ret((arith) 0);
1986-06-17 12:04:05 +00:00
if (tp) {
1986-06-20 14:36:49 +00:00
C_df_ilb((label) 1);
if (func_res_label) {
C_lae_dlb(func_res_label, (arith) 0);
C_sti(tp->tp_size);
C_lae_dlb(func_res_label, (arith) 0);
C_ret(pointer_size);
1986-05-14 09:03:51 +00:00
}
1986-06-20 14:36:49 +00:00
else C_ret(WA(tp->tp_size));
1986-05-14 09:03:51 +00:00
}
1986-06-20 14:36:49 +00:00
1986-06-26 09:39:36 +00:00
if (! options['n']) RegisterMessages(sc->sc_def);
1986-05-23 19:25:21 +00:00
C_end(-sc->sc_off);
1986-05-23 09:46:31 +00:00
TmpClose();
1986-06-20 14:36:49 +00:00
CurrVis = savevis;
1986-05-16 17:15:36 +00:00
proclevel--;
1986-04-21 17:27:06 +00:00
}
WalkDef(df)
register struct def *df;
{
/* Walk through a list of definitions
*/
1986-04-28 18:06:58 +00:00
1986-04-21 17:27:06 +00:00
while (df) {
if (df->df_kind == D_MODULE) {
WalkModule(df);
}
else if (df->df_kind == D_PROCEDURE) {
WalkProcedure(df);
}
1986-06-20 14:36:49 +00:00
else if (!proclevel && df->df_kind == D_VARIABLE) {
C_df_dnam(df->var_name);
C_bss_cst(
WA(df->df_type->tp_size),
(arith) 0, 0);
}
1986-04-21 17:27:06 +00:00
df = df->df_nextinscope;
}
}
MkCalls(df)
register struct def *df;
{
/* Generate calls to initialization routines of modules
*/
1986-04-28 18:06:58 +00:00
1986-04-21 17:27:06 +00:00
while (df) {
if (df->df_kind == D_MODULE) {
C_lxl((arith) 0);
1986-04-28 18:06:58 +00:00
C_cal(df->mod_vis->sc_scope->sc_name);
1986-05-28 18:36:51 +00:00
C_asp(pointer_size);
1986-04-21 17:27:06 +00:00
}
df = df->df_nextinscope;
}
}
1986-06-20 14:36:49 +00:00
WalkLink(nd, lab)
1986-04-22 22:36:16 +00:00
register struct node *nd;
label lab;
1986-04-21 17:27:06 +00:00
{
1986-06-20 14:36:49 +00:00
/* Walk node "nd", which is a link.
1986-04-22 22:36:16 +00:00
"lab" represents the label that must be jumped to on
encountering an EXIT statement.
*/
1986-04-28 18:06:58 +00:00
1986-06-20 14:36:49 +00:00
while (nd && nd->nd_class == Link) { /* statement list */
WalkNode(nd->nd_left, lab);
1986-04-22 22:36:16 +00:00
nd = nd->nd_right;
}
1986-06-20 14:36:49 +00:00
WalkNode(nd, lab);
}
WalkCall(nd)
register struct node *nd;
{
assert(nd->nd_class == Call);
if (! options['L']) C_lin((arith) nd->nd_lineno);
if (chk_call(nd)) {
if (nd->nd_type != 0) {
node_error(nd, "procedure call expected");
return;
}
CodeCall(nd);
}
1986-04-22 22:36:16 +00:00
}
WalkStat(nd, lab)
1986-05-23 19:25:21 +00:00
struct node *nd;
1986-04-22 22:36:16 +00:00
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;
1986-05-23 09:46:31 +00:00
1986-04-22 22:36:16 +00:00
assert(nd->nd_class == Stat);
1986-06-20 14:36:49 +00:00
if (! options['L']) C_lin((arith) nd->nd_lineno);
1986-04-22 22:36:16 +00:00
switch(nd->nd_symb) {
1986-05-28 18:36:51 +00:00
case BECOMES:
1986-05-30 18:48:00 +00:00
DoAssign(nd, left, right);
1986-04-22 22:36:16 +00:00
break;
case IF:
1986-05-21 18:32:20 +00:00
{ label l1, l2, l3;
1986-04-22 22:36:16 +00:00
1986-06-20 14:36:49 +00:00
l1 = ++text_label;
l2 = ++text_label;
l3 = ++text_label;
1986-05-21 18:32:20 +00:00
ExpectBool(left, l3, l1);
1986-04-22 22:36:16 +00:00
assert(right->nd_symb == THEN);
1986-05-21 18:32:20 +00:00
C_df_ilb(l3);
1986-04-22 22:36:16 +00:00
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:
1986-05-01 19:06:53 +00:00
CaseCode(nd, lab);
break;
1986-04-22 22:36:16 +00:00
case WHILE:
1986-05-21 18:32:20 +00:00
{ label l1, l2, l3;
1986-04-22 22:36:16 +00:00
1986-06-20 14:36:49 +00:00
l1 = ++text_label;
l2 = ++text_label;
l3 = ++text_label;
1986-04-22 22:36:16 +00:00
C_df_ilb(l1);
1986-05-21 18:32:20 +00:00
ExpectBool(left, l3, l2);
C_df_ilb(l3);
1986-04-22 22:36:16 +00:00
WalkNode(right, lab);
C_bra(l1);
C_df_ilb(l2);
break;
}
case REPEAT:
1986-05-21 18:32:20 +00:00
{ label l1, l2;
1986-04-22 22:36:16 +00:00
1986-06-20 14:36:49 +00:00
l1 = ++text_label;
l2 = ++text_label;
1986-04-22 22:36:16 +00:00
C_df_ilb(l1);
WalkNode(left, lab);
1986-05-21 18:32:20 +00:00
ExpectBool(right, l2, l1);
C_df_ilb(l2);
1986-04-22 22:36:16 +00:00
break;
}
case LOOP:
{ label l1, l2;
1986-06-20 14:36:49 +00:00
l1 = ++text_label;
l2 = ++text_label;
1986-04-22 22:36:16 +00:00
C_df_ilb(l1);
1986-06-10 13:18:52 +00:00
WalkNode(right, l2);
1986-04-22 22:36:16 +00:00
C_bra(l1);
C_df_ilb(l2);
break;
}
case FOR:
1986-05-28 18:36:51 +00:00
{
arith tmp = 0;
struct node *fnd;
1986-06-20 14:36:49 +00:00
label l1 = ++text_label;
label l2 = ++text_label;
1986-05-28 18:36:51 +00:00
1986-05-30 18:48:00 +00:00
if (! DoForInit(nd, left)) break;
1986-05-28 18:36:51 +00:00
fnd = left->nd_right;
if (fnd->nd_class != Value) {
1986-05-30 18:48:00 +00:00
CodePExpr(fnd);
1986-05-28 18:36:51 +00:00
tmp = NewInt();
C_stl(tmp);
}
C_bra(l1);
C_df_ilb(l2);
1986-06-26 09:39:36 +00:00
CheckAssign(nd->nd_type, int_type);
CodeDStore(nd);
1986-05-28 18:36:51 +00:00
WalkNode(right, lab);
1986-05-30 18:48:00 +00:00
CodePExpr(nd);
1986-06-26 09:39:36 +00:00
C_loc(left->nd_INT);
1986-05-28 18:36:51 +00:00
C_adi(int_size);
C_df_ilb(l1);
1986-06-26 09:39:36 +00:00
C_dup(int_size);
1986-05-28 18:36:51 +00:00
if (tmp) C_lol(tmp); else C_loc(fnd->nd_INT);
1986-05-30 18:48:00 +00:00
if (left->nd_INT > 0) {
1986-05-28 18:36:51 +00:00
C_ble(l2);
}
else C_bge(l2);
1986-06-26 09:39:36 +00:00
C_asp(int_size);
1986-05-28 18:36:51 +00:00
if (tmp) FreeInt(tmp);
}
1986-04-22 22:36:16 +00:00
break;
case WITH:
1986-04-28 18:06:58 +00:00
{
struct scopelist link;
1986-05-16 17:15:36 +00:00
struct withdesig wds;
1986-06-17 12:04:05 +00:00
struct desig ds;
1986-05-23 09:46:31 +00:00
arith tmp = 0;
1986-04-28 18:06:58 +00:00
1986-06-17 12:04:05 +00:00
WalkDesignator(left, &ds);
1986-04-28 18:06:58 +00:00
if (left->nd_type->tp_fund != T_RECORD) {
node_error(left, "record variable expected");
break;
}
1986-05-16 17:15:36 +00:00
wds.w_next = WithDesigs;
WithDesigs = &wds;
wds.w_scope = left->nd_type->rec_scope;
1986-06-17 12:04:05 +00:00
if (ds.dsg_kind != DSG_PFIXED) {
1986-05-23 09:46:31 +00:00
/* In this case, we use a temporary variable
*/
1986-06-17 12:04:05 +00:00
CodeAddress(&ds);
ds.dsg_kind = DSG_FIXED;
/* Create a designator structure for the
temporary.
*/
ds.dsg_offset = tmp = NewPtr();
ds.dsg_name = 0;
CodeStore(&ds, pointer_size);
ds.dsg_kind = DSG_PFIXED;
1986-05-23 09:46:31 +00:00
/* the record is indirectly available */
}
1986-06-17 12:04:05 +00:00
wds.w_desig = ds;
1986-05-16 17:15:36 +00:00
link.sc_scope = wds.w_scope;
1986-04-28 18:06:58 +00:00
link.next = CurrVis;
CurrVis = &link;
WalkNode(right, lab);
CurrVis = link.next;
1986-05-16 17:15:36 +00:00
WithDesigs = wds.w_next;
1986-05-23 09:46:31 +00:00
if (tmp) FreePtr(tmp);
1986-04-28 18:06:58 +00:00
break;
}
1986-04-22 22:36:16 +00:00
case EXIT:
assert(lab != 0);
C_bra(lab);
break;
case RETURN:
1986-04-23 22:12:22 +00:00
if (right) {
1986-06-10 13:18:52 +00:00
WalkExpr(right);
1986-06-20 14:36:49 +00:00
/* The type of the return-expression must be
assignment compatible with the result type of the
function procedure (See Rep. 9.11).
1986-04-28 18:06:58 +00:00
*/
if (!TstAssCompat(func_type, right->nd_type)) {
1986-04-23 22:12:22 +00:00
node_error(right, "type incompatibility in RETURN statement");
}
1986-06-20 14:36:49 +00:00
C_bra((label) 1);
1986-04-23 22:12:22 +00:00
}
1986-06-20 14:36:49 +00:00
else C_ret((arith) 0);
1986-04-22 22:36:16 +00:00
break;
default:
1986-06-17 12:04:05 +00:00
crash("(WalkStat)");
1986-04-22 22:36:16 +00:00
}
}
1986-06-20 14:36:49 +00:00
extern int NodeCrash();
int (*WalkTable[])() = {
NodeCrash,
NodeCrash,
NodeCrash,
NodeCrash,
NodeCrash,
WalkCall,
NodeCrash,
NodeCrash,
NodeCrash,
NodeCrash,
WalkStat,
WalkLink,
NodeCrash
};
1986-05-21 18:32:20 +00:00
ExpectBool(nd, true_label, false_label)
1986-05-23 19:25:21 +00:00
register struct node *nd;
1986-05-21 18:32:20 +00:00
label true_label, false_label;
1986-04-22 22:36:16 +00:00
{
/* "nd" must indicate a boolean expression. Check this and
generate code to evaluate the expression.
*/
1986-06-17 12:04:05 +00:00
struct desig ds;
1986-04-22 22:36:16 +00:00
1986-06-10 13:18:52 +00:00
if (!chk_expr(nd)) return;
1986-04-22 22:36:16 +00:00
1986-04-22 23:22:19 +00:00
if (nd->nd_type != bool_type && nd->nd_type != error_type) {
1986-04-22 22:36:16 +00:00
node_error(nd, "boolean expression expected");
}
1986-06-10 13:18:52 +00:00
1986-06-17 12:04:05 +00:00
ds = InitDesig;
CodeExpr(nd, &ds, true_label, false_label);
1986-04-23 22:12:22 +00:00
}
1986-04-22 22:36:16 +00:00
1986-06-10 13:18:52 +00:00
WalkExpr(nd)
1986-04-23 22:12:22 +00:00
struct node *nd;
{
/* Check an expression and generate code for it
1986-04-21 17:27:06 +00:00
*/
1986-04-23 22:12:22 +00:00
1986-05-01 19:06:53 +00:00
if (! chk_expr(nd)) return;
1986-06-10 13:18:52 +00:00
CodePExpr(nd);
1986-04-23 22:12:22 +00:00
}
1986-06-17 12:04:05 +00:00
WalkDesignator(nd, ds)
1986-04-25 10:14:08 +00:00
struct node *nd;
1986-06-17 12:04:05 +00:00
struct desig *ds;
1986-04-25 10:14:08 +00:00
{
/* Check designator and generate code for it
*/
1986-06-26 09:39:36 +00:00
if (! chk_variable(nd)) return;
1986-05-01 19:06:53 +00:00
1986-06-17 12:04:05 +00:00
*ds = InitDesig;
CodeDesig(nd, ds);
1986-05-30 18:48:00 +00:00
}
DoForInit(nd, left)
register struct node *nd, *left;
{
1986-06-20 14:36:49 +00:00
register struct def *df;
1986-05-28 18:36:51 +00:00
1986-05-30 18:48:00 +00:00
nd->nd_left = nd->nd_right = 0;
nd->nd_class = Name;
nd->nd_symb = IDENT;
1986-06-26 09:39:36 +00:00
if (! chk_variable(nd) ||
1986-05-30 18:48:00 +00:00
! chk_expr(left->nd_left) ||
1986-06-06 02:22:09 +00:00
! chk_expr(left->nd_right)) return 0;
1986-05-30 18:48:00 +00:00
1986-06-20 14:36:49 +00:00
df = nd->nd_def;
if (df->df_kind == D_FIELD) {
node_error(nd, "FOR-loop variable may not be a field of a record");
return 0;
}
if (!df->var_name && df->var_off >= 0) {
node_error(nd, "FOR-loop variable may not be a parameter");
return 0;
}
if (df->df_scope != CurrentScope) {
register struct scopelist *sc = CurrVis;
while (sc && sc->sc_scope != df->df_scope) {
sc = nextvisible(sc);
}
if (!sc) {
node_error(nd, "FOR-loop variable may not be imported");
return 0;
}
}
1986-05-30 18:48:00 +00:00
if (nd->nd_type->tp_size > word_size ||
!(nd->nd_type->tp_fund & T_DISCRETE)) {
node_error(nd, "illegal type of FOR loop variable");
return 0;
}
if (!TstCompat(nd->nd_type, left->nd_left->nd_type) ||
!TstCompat(nd->nd_type, left->nd_right->nd_type)) {
if (!TstAssCompat(nd->nd_type, left->nd_left->nd_type) ||
!TstAssCompat(nd->nd_type, left->nd_right->nd_type)) {
node_error(nd, "type incompatibility in FOR statement");
return 0;
}
node_warning(nd, "old-fashioned! compatibility required in FOR statement");
}
CodePExpr(left->nd_left);
1986-06-06 02:22:09 +00:00
return 1;
1986-05-28 18:36:51 +00:00
}
1986-05-30 18:48:00 +00:00
DoAssign(nd, left, right)
1986-05-28 18:36:51 +00:00
struct node *nd;
register struct node *left, *right;
{
1986-05-30 18:48:00 +00:00
/* May we do it in this order (expression first) ??? */
1986-06-17 12:04:05 +00:00
struct desig dsl, dsr;
1986-05-28 18:36:51 +00:00
1986-06-04 09:01:48 +00:00
if (!chk_expr(right)) return;
1986-06-26 09:39:36 +00:00
if (! chk_variable(left)) return;
1986-06-04 09:01:48 +00:00
TryToString(right, left->nd_type);
1986-06-17 12:04:05 +00:00
dsr = InitDesig;
CodeExpr(right, &dsr, NO_LABEL, NO_LABEL);
1986-05-28 18:36:51 +00:00
1986-05-30 18:48:00 +00:00
if (! TstAssCompat(left->nd_type, right->nd_type)) {
1986-05-28 18:36:51 +00:00
node_error(nd, "type incompatibility in assignment");
return;
}
if (complex(right->nd_type)) {
1986-06-17 12:04:05 +00:00
CodeAddress(&dsr);
1986-05-28 18:36:51 +00:00
}
else {
1986-06-17 12:04:05 +00:00
CodeValue(&dsr, right->nd_type->tp_size);
1986-05-28 18:36:51 +00:00
CheckAssign(left->nd_type, right->nd_type);
}
1986-06-17 12:04:05 +00:00
dsl = InitDesig;
CodeDesig(left, &dsl);
CodeAssign(nd, &dsr, &dsl);
}
RegisterMessages(df)
register struct def *df;
{
1986-06-26 09:39:36 +00:00
register struct type *tp;
1986-05-28 18:36:51 +00:00
1986-06-17 12:04:05 +00:00
for (; df; df = df->df_nextinscope) {
if (df->df_kind == D_VARIABLE && !(df->df_flags & D_NOREG)) {
/* Examine type and size
*/
1986-06-26 09:39:36 +00:00
tp = BaseType(df->df_type);
if ((df->df_flags & D_VARPAR) ||
tp->tp_fund == T_POINTER) {
C_ms_reg(df->var_off, pointer_size,
reg_pointer, 0);
}
else if ((tp->tp_fund & T_NUMERIC) &&
1986-06-17 12:04:05 +00:00
tp->tp_size <= dword_size) {
C_ms_reg(df->var_off,
tp->tp_size,
tp->tp_fund == T_REAL ?
reg_float : reg_any,
0);
}
}
}
1986-04-25 10:14:08 +00:00
}