/* $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 <obstack.h>
#include "const.h"
#include "mellbuilder.h"
#include "builder.h"
char *xmalloc();
void free();
#define obstack_chunk_alloc xmalloc
#define obstack_chunk_free free
int token;
static struct obstack osStack;
static struct obstack osExpr;
/******************************************************************************
EBUILDERINIT */
ebuilderInit()
{
obstack_init(&osStack);
obstack_init(&osExpr);
lineno= 1;
}
/******************************************************************************
NEWEXP */
struct EXP *newexp()
{
struct EXP *re;
re= (struct EXP *)obstack_alloc (&osExpr, sizeof (struct EXP));
memset (re, 0, sizeof (struct EXP));
re->line= lineno;
return re;
}
/******************************************************************************
MAKEEXP */
struct EXP *makeexp (token, left, right) int token; struct EXP *left, *right;
{
struct EXP *re;
re= newexp();
re->token= token;
re->left= left;
if (left) left->up= re;
re->right= right;
if (right) right->up= re;
return (re);
}
/******************************************************************************
CONCEXP */
struct EXP * concexp (left, right) struct EXP *left, *right;
{
if (left==NULL) return right;
if (right==NULL) return left;
return makeexp (MSENTCONC, left, right);
}
/******************************************************************************
REPLACENODE */
struct EXP *replacenode (rep, token) struct EXP **rep; int token;
{
struct EXP *rex;
rex= newexp ();
if (is_after_dot ((*rep))) *rex= *(*rep)->up;
else
*rex= **rep;
remove_dot (rep);
if (rex->right) rex->right->up=rex;
if (rex->left) rex->left->up=rex;
(*rep)->token= token;
return (rex);
}
/******************************************************************************
COPYTREE */
struct EXP *
copytree (re)
struct EXP *re;
{
struct EXP *rex;
if (re == NULL) return NULL;
rex = newexp();
if (re->left != NULL)
{
rex->left = copytree (re->left);
rex->left->up = rex;
}
else
rex->left = NULL;
if (re->right != NULL)
{
rex->right = copytree (re->right);
rex->right->up = rex;
}
else
rex->right = NULL;
rex->token = re->token;
rex->line = re->line;
rex->value = re->value;
rex->type = re->type;
rex->danger = re->danger;
rex->up = re->up;
rex->rd = re->rd;
rex->qual = re->qual;
rex->seenthrough = re->seenthrough;
return (rex);
}
/******************************************************************************
REMOVE_DOT */
remove_dot (rep)
struct EXP **rep;
{
if (is_after_dot ((*rep)))
{
*rep = (*rep)->up;
(*rep)->value = (*rep)->right->value;
(*rep)->token = (*rep)->right->token;
(*rep)->left = (*rep)->right = NULL;
}
}
/******************************************************************************
ECLEAN */
static eclean()
{
void *p;
p= obstack_finish (&osStack);
obstack_free (&osStack, p);
}
/******************************************************************************
EPUSH */
static epush(re)struct EXP *re;
{
#if 0
obstack_ptr_grow (&osStack, re);
#else
obstack_grow(&osStack, &re, sizeof (void *));
#endif
}
/******************************************************************************
EPOP */
static struct EXP *epop()
{
struct EXP *re;
re= * ((struct EXP * *)obstack_next_free (&osStack) - 1);
obstack_blank (&osStack, - sizeof (void *));
return (re);
}
/******************************************************************************
ELOOK */
struct EXP *elook()
{
return *((struct EXP * *)obstack_next_free (&osStack) - 1);
}
/******************************************************************************
EBUILD */
/* Bygger opp et uttrykstree, Alle operatorene leses postfix */
ebuild ()
{
struct EXP *re;
eclean();
while (TRUE)
{
switch (token)
{
case MNOT:
case MUADD:
case MUSUB:
case MNOOP:
case MQUA:
epush(re= makeexp(token, epop(), NULL));
/* Sjekke dobbel unær
* Eventuelt optimalisere bort noen noop */
break;
case MTEXTKONST:
case MCHARACTERKONST:
case MREALKONST:
case MINTEGERKONST:
case MBOOLEANKONST:
case MENDSEP:
case MNONE:
case MIDENTIFIER:
case MTHIS:
case MLABEL:
epush(re= makeexp(token, NULL, NULL));
break;
case MNEWARG:
case MARGUMENT:
epush(re= makeexp(token, NULL, epop()));
break;
case MNEWLINE:
lineno++;
goto newtoken;
break;
case MFLAG:
setFlag ();
break;
default:
if (setntokens (token) || token == MERROR || token == MSTOP)
{
#ifdef DEBUG
if (token == MERROR)
dumpexp ();
#endif
re= elook()->up= makeexp(token, NULL, NULL);
re->up= re;
return;
}
/* VANELIG BEHANDLING */
{
struct EXP *right= epop();
epush (re= makeexp (token, epop(), right));
}
}
if (expridtokens (token))
re->value.ival= (long) minId();
else
if (token == MTEXTKONST)
{
re->value.tval.txt= minTval();
re->value.tval.id= NOTEXT;
}
else
if (token == MREALKONST)
re->value.rval= minRval();
else
if (exprvaltokens (token))
re->value.ival= minIval();
newtoken:
token= min();
}
}
syntax highlighted by Code2HTML, v. 0.9.1