/* $Id: $ */
/* Copyright (C) 1998 Sverre Hvammen Johansen,
* Department of Informatics, University of Oslo.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; version 2.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */
#include <stdio.h>
#include "gen.h"
#include "trans.h"
/******************************************************************************
SORTPROCARR */
static void sortProcArr (parentSent) struct SENT *parentSent;
{
int line= parentSent->line;
struct SENT *proc=NULL, *sent, *nextsent, *new;
for (sent= parentSent->first; sent!=NULL ;sent= nextsent)
{
nextsent= sent->next;
switch (sent->token)
{
case MCONST:
removeSent (parentSent, sent);
break;
case MENDSWITCH:
case MPROCEDURE:
case MCLASS:
removeSent (parentSent, sent);
insertAfterSent (parentSent, proc, sent);
proc= sent;
break;
case MENDARRAY:
line= sent->line;
break;
default:
goto exit;
}
}
exit:
switch (parentSent->token)
{
case MBLOCK:
new= newSent (MBLOCKENTRY);
break;
case MPROCEDURE:
new= newSent (MPROCEDUREENTRY);
break;
default:
new= newSent (MENTRY);
break;
}
new->cblock= parentSent->cblock;
insertAfterSent (parentSent, proc, new);
if (parentSent->token==MCLASS || parentSent->token==MPRBLOCK)
{
new= newSent (MENDDECL);
new->cblock= parentSent->cblock;
insertBeforeSent (parentSent, sent, new);
if (parentSent->token==MCLASS && !cblock->inner)
{
new= newSent (MINNER);
new->cblock= parentSent->cblock;
insertBeforeSent (parentSent, NULL, new);
}
}
}
/******************************************************************************
SENTLISTTRANS */
static void sentListTrans (parentSent) struct SENT *parentSent;
{
struct SENT *sent;
for (sent= parentSent->first; sent!=NULL; sent= sent->next)
{
lineno= sent->line;
nonetest= sent->nonetest;
indextest= sent->indextest;
stripsideeffects= sent->stripsideeffects;
sentTrans (sent);
cblock= parentSent->cblock;
if (cblock) cblev= cblock->blev;
}
lineno= parentSent->lastLine;
}
/******************************************************************************
MODULETRANS */
static void moduleTrans (sent) struct SENT *sent;
{
if (! separat_comp)
insertBeforeSent (sent, NULL, newSent (MGOTOSTOP));
sentListTrans (sent);
}
/******************************************************************************
BLOCKTRANS */
static void blockTrans (sent) struct SENT *sent;
{
cblock= sent->cblock;
sortProcArr (sent);
sentListTrans (sent);
}
/******************************************************************************
PRBLOCKTRANS */
static void prblockTrans (sent) struct SENT *sent;
{
cblock= sent->cblock;
sortProcArr (sent);
sent->iexp= transcall (sent->exp->up, sent->exp);
sentListTrans (sent);
}
/******************************************************************************
PROCEDURETRANS */
static void procedureTrans (sent) struct SENT *sent;
{
cblock= sent->cblock;
sortProcArr (sent);
sentListTrans (sent);
}
/******************************************************************************
CLASSTRANS */
static void classTrans (sent) struct SENT *sent;
{
cblock= sent->cblock;
sortProcArr (sent);
sentListTrans (sent);
}
/******************************************************************************
INSPECTTRANS */
static void inspectTrans (sent) struct SENT *sent;
{
cblock= sent->cblock;
sent->iexp= transcall (sent->exp->up, sent->exp);
sentListTrans (sent);
}
/******************************************************************************
DOTRANS */
static void doTrans (sent) struct SENT *sent;
{
cblock= sent->cblock;
sentListTrans (sent);
}
/******************************************************************************
WHENTRANS */
static void whenTrans (sent) struct SENT *sent;
{
cblock= sent->cblock;
sentListTrans (sent);
}
/******************************************************************************
OTHERWISETRANS */
static void otherwiseTrans (sent) struct SENT *sent;
{
cblock= sent->cblock;
sentListTrans (sent);
}
/******************************************************************************
FORELEMTRANS */
static void forelemTrans (re, rex) struct EXP *re, *rex;
{
struct EXP *rey, *red;
struct EXP *reinit, *retest, *restep;
int konst_step, notnegativ;
rey= rex->left;
switch (rey->token)
{
case MSTEP:
notnegativ = !(rey->right->left->token == MUSUBI ||
(rey->right->left->token == MINTEGERKONST &&
rey->right->left->value.ival < 0));
konst_step = rey->right->left->token == MINTEGERKONST;
restep= transcall (rey->right, rey->right->left);
restep= concexp (restep, transcall (rey->right, rey->right->right));
reinit= transcall (rey, rey->left);
reinit= concexp (reinit, red= makeexp(MASSIGND,copytree (re->left),
rey->left));
red->type= red->right->type;
reinit= concexp (reinit, copytree (restep));
retest= makeexp (re->type==TINTG?rey->right->right->type==TREAL?
MSIGNDX:MSIGNDI:MSIGNDR,
copytree (re->left), rey->right->right);
if (!konst_step)
retest= makeexp (MMUL, (notnegativ?rey->right->left:
rey->right->left->left), retest);
retest= makeexp (notnegativ?MLE:MGE, retest,
makeexp (MINTEGERKONST, NULL, NULL));
restep= concexp (restep, red= makeexp(MASSIGNADD,copytree (re->left),
rey->right->left));
red->type= red->right->type;
rey->left= reinit;
rey->right->left= retest;
rey->right->right= restep;
break;
case MFORWHILE:
restep= transcall (rey, rey->left);
restep= concexp (restep, makeexp (re->left->type==TTEXT?re->token==MFOR?
MVALASSIGNT:MREFASSIGNT:MASSIGND,
copytree (re->left),rey->left));
restep= concexp (restep, transcall (rey, rey->right));
rey->left= restep;
break;
default:
restep= transcall (rex, rey);
restep= concexp (restep, makeexp (re->left->type==TTEXT?re->token==MFOR?
MVALASSIGNT:MREFASSIGNT:MASSIGND,
copytree (re->left),rey));
rex->left= restep;
break;
}
}
/******************************************************************************
FORDOTRANS */
static void fordoTrans (sent) struct SENT *sent;
{
struct EXP *re, *rex;
cblock= sent->cblock;
re= sent->exp;
for (rex = re->right; rex->token != MENDSEP; rex = rex->right)
forelemTrans (re, rex);
sentListTrans (sent);
}
/******************************************************************************
WHILETRANS */
static void whileTrans (sent) struct SENT *sent;
{
sent->iexp= transcall (sent->exp->up, sent->exp);
sentListTrans (sent);
}
/******************************************************************************
IFTRANS */
static void ifTrans (sent) struct SENT *sent;
{
sent->iexp= transcall (sent->exp->up, sent->exp);
sentListTrans (sent);
}
/******************************************************************************
ELSETRANS */
static void elseTrans (sent) struct SENT *sent;
{
sentListTrans (sent);
}
/******************************************************************************
THENTRANS */
static void thenTrans (sent) struct SENT *sent;
{
sentListTrans (sent);
}
/******************************************************************************
GOTOTRANS */
static void gotoTrans (sent) struct SENT *sent;
{
sent->iexp= transcall (sent->exp->up, sent->exp);
}
/******************************************************************************
INNERTRANS */
static void innerTrans (sent) struct SENT *sent;
{
}
/******************************************************************************
ENDSWITCHTRANS */
static void endswitchTrans (sent) struct SENT *sent;
{
#if 1
struct EXP *rex, *rey;
for (rex = sent->exp->right; rex->token != MENDSEP; rex = rex->right)
{
rey= transcall (rex, rex->left); fprintf (ccode, ";");
if (rey!=NULL)
{
rex->left= makeexp (MSENTCONC, rey, rex->left);
rex->left->up= rex;
}
}
#endif
}
/******************************************************************************
ENDASSIGNTRANS */
static void endassignTrans (sent) struct SENT *sent;
{
sent->iexp= transcall (sent->exp->up, sent->exp);
}
/******************************************************************************
ENDARRAYTRANS */
static void endarrayTrans (sent) struct SENT *sent;
{
sent->iexp= transcall (sent->exp, sent->exp->right);
}
/******************************************************************************
ENDLABELTRANS */
static void endlabelTrans (sent) struct SENT *sent;
{
}
/******************************************************************************
GOTOSTOPTRANS */
gotoStopTrans (sent) struct SENT *sent;
{
}
/******************************************************************************
THUNKTRANS */
thunkTrans (sent) struct SENT *sent;
{
cblock= sent->cblock;
inthunk= sent->exp->value.thunk.inthunk;
#if 1
sent->iexp= transcall (sent->exp, sent->exp->left);
#endif
inthunk= 0;
}
/******************************************************************************
SENTTRANS */
void sentTrans (sent) struct SENT *sent;
{
switch (sent->token)
{
case MMODULE:
moduleTrans (sent);
break;
case MCONST:
break;
case MBLOCK:
blockTrans (sent);
break;
case MPRBLOCK:
prblockTrans (sent);
break;
case MPROCEDURE:
procedureTrans (sent);
break;
case MCLASS:
classTrans (sent);
break;
case MINSPECT:
inspectTrans (sent);
break;
case MDO:
doTrans (sent);
break;
case MWHEN:
whenTrans (sent);
break;
case MOTHERWISE:
otherwiseTrans (sent);
break;
case MFORDO:
fordoTrans (sent);
break;
case MWHILE:
whileTrans (sent);
break;
case MIF:
ifTrans (sent);
break;
case MELSE:
elseTrans (sent);
break;
case MTHEN:
thenTrans (sent);
break;
case MGOTO:
gotoTrans (sent);
break;
case MINNER:
innerTrans (sent);
break;
case MENDSWITCH:
endswitchTrans (sent);
break;
case MENDASSIGN:
endassignTrans (sent);
break;
case MENDARRAY:
endarrayTrans (sent);
break;
case MENDLABEL:
endlabelTrans (sent);
break;
case MGOTOSTOP:
gotoStopTrans (sent);
break;
case MTHUNKSIMPLEADDRESS:
case MTHUNKSIMPLEVALUE:
case MTHUNKLABLE:
case MTHUNKARRAY:
case MTHUNKPROCEDURE:
thunkTrans (sent);
break;
}
}
syntax highlighted by Code2HTML, v. 0.9.1