/* $Header$ */
/*
* Copyright © 1988-2004 Keith Packard and Bart Massey.
* All Rights Reserved. See the file COPYING in this directory
* for licensing information.
*/
/*
* expr.c
*
* handle expression trees
*/
#include "nickle.h"
#include "gram.h"
static void
ExprTreeMark (void *object)
{
ExprTree *et = object;
MemReference (et->expr.namespace);
MemReference (et->expr.type);
MemReference (et->left);
MemReference (et->right);
if (!profiling)
et->expr.ticks = et->expr.sub_ticks = 0;
}
static void
ExprConstMark (void *object)
{
ExprConst *ec = object;
MemReference (ec->expr.namespace);
MemReference (ec->expr.type);
MemReference (ec->constant);
if (!profiling)
ec->expr.ticks = ec->expr.sub_ticks = 0;
}
static void
ExprAtomMark (void *object)
{
ExprAtom *ea = object;
MemReference (ea->expr.namespace);
MemReference (ea->expr.type);
MemReference (ea->symbol);
if (!profiling)
ea->expr.ticks = ea->expr.sub_ticks = 0;
}
static void
ExprCodeMark (void *object)
{
ExprCode *ec = object;
MemReference (ec->expr.namespace);
MemReference (ec->expr.type);
MemReference (ec->code);
if (!profiling)
ec->expr.ticks = ec->expr.sub_ticks = 0;
}
static void
ExprDeclMark (void *object)
{
ExprDecl *ed = object;
MemReference (ed->expr.namespace);
MemReference (ed->expr.type);
MemReference (ed->decl);
MemReference (ed->type);
if (!profiling)
ed->expr.ticks = ed->expr.sub_ticks = 0;
}
DataType ExprTreeType = { ExprTreeMark, 0, "ExprTreeType" };
DataType ExprConstType = { ExprConstMark, 0, "ExprConstType" };
DataType ExprAtomType = { ExprAtomMark, 0, "ExprAtomType" };
DataType ExprCodeType = { ExprCodeMark, 0, "ExprCodeType" };
DataType ExprDeclType = { ExprDeclMark, 0, "ExprDeclType" };
static void
ExprBaseInit (Expr *e, int tag)
{
e->base.tag = tag;
e->base.file = LexFileName ();
e->base.line = LexFileLine ();
e->base.namespace = CurrentNamespace;
e->base.type = 0;
e->base.ticks = 0 ;
e->base.sub_ticks = 0;
}
Expr *
NewExprTree(int tag, Expr *left, Expr *right)
{
ENTER ();
Expr *e;
e = ALLOCATE (&ExprTreeType, sizeof (ExprTree));
ExprBaseInit (e, tag);
if (left)
{
if (left->base.file == e->base.file && left->base.line < e->base.line)
e->base.line = left->base.line;
}
else if (right)
{
if (right->base.file == e->base.file && right->base.line < e->base.line)
e->base.line = right->base.line;
}
e->tree.left = left;
e->tree.right = right;
RETURN ((Expr *) e);
}
Expr *
NewExprComma (Expr *left, Expr *right)
{
return NewExprTree (COMMA, left, right);
}
Expr *
NewExprConst (int tag, Value val)
{
ENTER ();
Expr *e;
e = ALLOCATE (&ExprConstType, sizeof (ExprConst));
ExprBaseInit (e, tag);
e->constant.constant = val;
RETURN (e);
}
Expr *
NewExprAtom (Atom atom, SymbolPtr symbol, Bool privateFound)
{
ENTER ();
Expr *e;
e = ALLOCATE (&ExprAtomType, sizeof (ExprAtom));
ExprBaseInit (e, NAME);
e->atom.atom = atom;
e->atom.symbol = symbol;
e->atom.privateFound = privateFound;
RETURN (e);
}
Expr *
NewExprCode (CodePtr code, ExprPtr name)
{
ENTER ();
Expr *e;
e = ALLOCATE (&ExprCodeType, sizeof (ExprCode));
ExprBaseInit (e, FUNC);
e->code.code = code;
code->base.name = name;
RETURN (e);
}
Expr *
NewExprDecl (int tag, DeclListPtr decl, Class class, Type *type, Publish publish)
{
ENTER ();
Expr *e;
e = ALLOCATE (&ExprDeclType, sizeof (ExprDecl));
ExprBaseInit (e, tag);
e->decl.decl = decl;
e->decl.class = class;
e->decl.type = type;
e->decl.publish = publish;
RETURN (e);
}
/*
* LALR grammars like to build things right to left, but
* sometimes we like the resulting data structure to be left to right
*/
Expr*
ExprRehang (Expr *e, Expr *right)
{
if (e->tree.left)
{
Expr *t, *left;
left = e->tree.right;
t = ExprRehang (e->tree.left, e);
e->tree.left = left;
e->tree.right = right;
return t;
}
else
{
e->tree.left = e->tree.right;
e->tree.right = right;
return e;
}
}
syntax highlighted by Code2HTML, v. 0.9.1