/* $Header$ */
/*
* Copyright © 1988-2004 Keith Packard and Bart Massey.
* All Rights Reserved. See the file COPYING in this directory
* for licensing information.
*/
#include "nickle.h"
static void MarkFuncCode (void *object)
{
FuncCodePtr fc = object;
MemReference (fc->base.type);
MemReference (fc->base.args);
MemReference (fc->base.name);
MemReference (fc->base.previous);
MemReference (fc->base.func);
MemReference (fc->base.doc);
MemReference (fc->code);
MemReference (fc->body.obj);
MemReference (fc->body.dynamics);
MemReference (fc->staticInit.obj);
MemReference (fc->staticInit.dynamics);
MemReference (fc->statics);
}
DataType FuncCodeType = { MarkFuncCode, 0, "FuncCodeType" };
static Bool
HasVarargs (ArgType *args)
{
while (args)
{
if (args->varargs)
return True;
args = args->next;
}
return False;
}
CodePtr
NewFuncCode (Type *type, ArgType *args, ExprPtr code, Value doc)
{
ENTER ();
CodePtr fc;
fc = ALLOCATE (&FuncCodeType, sizeof (FuncCode));
fc->base.builtin = False;
fc->base.type = type;
fc->base.argc = 0;
fc->base.varargs = HasVarargs (args);
fc->base.args = args;
fc->base.name = 0;
fc->base.previous = 0;
fc->base.func = fc;
fc->base.doc = doc;
fc->func.code = code;
fc->func.body.dynamics = 0;
fc->func.body.obj = 0;
fc->func.staticInit.obj = 0;
fc->func.staticInit.dynamics = 0;
fc->func.statics = 0;
fc->func.inStaticInit = False;
fc->func.inGlobalInit = False;
RETURN (fc);
}
static void MarkBuiltinCode (void *object)
{
BuiltinCodePtr bc = object;
MemReference (bc->base.type);
MemReference (bc->base.args);
MemReference (bc->base.name);
MemReference (bc->base.previous);
MemReference (bc->base.func);
MemReference (bc->base.doc);
}
DataType BuiltinCodeType = { MarkBuiltinCode, 0, "BuiltinCodeType" };
CodePtr
NewBuiltinCode (Type *type, ArgType *args, int argc,
BuiltinFunc builtin, Bool needsNext, char *doc)
{
ENTER ();
CodePtr bc;
bc = ALLOCATE (&BuiltinCodeType, sizeof (BuiltinCode));
bc->base.builtin = True;
bc->base.type = type;
bc->base.argc = argc;
bc->base.varargs = HasVarargs (args);
bc->base.args = args;
bc->base.name = 0;
bc->base.previous = 0;
bc->base.func = 0;
bc->base.doc = doc ? NewStrString (doc) : Void;
bc->builtin.needsNext = needsNext;
bc->builtin.b = builtin;
RETURN (bc);
}
static void
FuncMark (void *object)
{
Func *f = object;
MemReference (f->code);
MemReference (f->staticLink);
MemReference (f->statics);
}
void printCode (Value f, CodePtr code, int level);
static Bool
FuncPrint (Value f, Value av, char format, int base, int width, int prec, int fill)
{
Bool nest = False;
if (format == 'v')
nest = True;
PrettyCode (f, av->func.code, 0, class_undef, publish_private, 0, nest);
return True;
}
ValueRep FuncRep = {
{ FuncMark, 0, "FuncRep" }, /* base */
rep_func, /* tag */
{ /* binary */
0,
0,
0,
0,
0,
0,
0,
ValueEqual,
0,
0,
},
{ /* unary */
0,
0,
0,
},
0,
0,
FuncPrint,
0,
};
Value
NewFunc (CodePtr code, FramePtr staticLink)
{
ENTER ();
Value ret;
ret = ALLOCATE (&FuncRep.data, sizeof (Func));
ret->func.code = code;
ret->func.staticLink = staticLink;
ret->func.statics = 0;
/*
* Create the box containing static variables for this closure
*/
if (!code->base.builtin && code->func.statics)
ret->func.statics = NewTypedBox (False, code->func.statics);
RETURN (ret);
}
syntax highlighted by Code2HTML, v. 0.9.1