150 lines
4.7 KiB
C++
Executable File
150 lines
4.7 KiB
C++
Executable File
/* CodeTree.h - the CodeTree class - parser output
|
|
*
|
|
* Copyright (c) John Wainwright, 1996
|
|
*
|
|
*
|
|
*/
|
|
|
|
#ifndef _H_CODETREE
|
|
#define _H_CODETREE
|
|
|
|
class CodeTree : public Value
|
|
{
|
|
public:
|
|
Value* fn; /* the function to apply */
|
|
short count; /* number of arguments */
|
|
Value** arg_list; /* the argument list */
|
|
long pos; /* source stream pos */
|
|
|
|
CodeTree(CharStream* source, Value* codeFn, ...);
|
|
~CodeTree();
|
|
|
|
void gc_trace();
|
|
void collect() { delete this; }
|
|
ScripterExport void sprin1(CharStream* s);
|
|
|
|
ScripterExport Value* eval();
|
|
|
|
Value* add(Value* arg1, ...);
|
|
Value* append(Value* arg);
|
|
Value* put(int index, Value* arg);
|
|
};
|
|
|
|
/* Maker class, a special CodeTree node that encodes runtime object
|
|
* instantiation. contains a reference to a maker
|
|
* static method on the class to be instantiated. It is
|
|
* supplied an arg_list like any other codetree fn apply
|
|
*/
|
|
|
|
class Maker : public Value
|
|
{
|
|
value_cf maker; /* the maker class static fn */
|
|
short count; /* number of arguments */
|
|
Value** arg_list; /* the argument list */
|
|
|
|
public:
|
|
Maker(value_cf maker_fn, ...);
|
|
Maker(Value** arg_list, int count, value_cf maker_fn);
|
|
~Maker();
|
|
|
|
void gc_trace();
|
|
void collect() { delete this; }
|
|
ScripterExport void sprin1(CharStream* s);
|
|
|
|
ScripterExport Value* eval();
|
|
|
|
Value* add(Value* arg1, ...);
|
|
Value* append(Value* arg);
|
|
};
|
|
|
|
/* ------------- debugging support classes -------------- */
|
|
|
|
// SourceFileWrapper wraps a piece of code in a source file
|
|
// context. Evaling this pushes the 'source-file' thread-local,
|
|
// evals the wrapped code & pops source-file.
|
|
|
|
class SourceFileWrapper : public Value
|
|
{
|
|
public:
|
|
Value* file_name;
|
|
int pos;
|
|
Value* code;
|
|
MSZipPackage* package;
|
|
|
|
SourceFileWrapper(Value* file_name, Value* code, int pos = -1);
|
|
|
|
void gc_trace();
|
|
void collect() { delete this; }
|
|
ScripterExport void sprin1(CharStream* s) { code->sprin1(s); }
|
|
BOOL _is_function() { return code->_is_function(); }
|
|
|
|
Value* classOf_vf(Value** arg_list, int count) { return code->classOf_vf(arg_list, count); }
|
|
Value* superClassOf_vf(Value** arg_list, int count) { return code->superClassOf_vf(arg_list, count); }
|
|
Value* isKindOf_vf(Value** arg_list, int count) { return code->isKindOf_vf(arg_list, count); }
|
|
BOOL is_kind_of(ValueMetaClass* c) { return code->is_kind_of(c); }
|
|
ScripterExport Value* eval();
|
|
ScripterExport Value* eval_no_wrapper();
|
|
ScripterExport Value* apply(Value** arglist, int count, CallContext* cc=NULL);
|
|
};
|
|
|
|
// SourceLineMarker instances are stuck in code
|
|
// as lines are change
|
|
|
|
class SourceLineMarker : public Value
|
|
{
|
|
public:
|
|
int pos;
|
|
|
|
SourceLineMarker(int pos);
|
|
|
|
void collect() { delete this; }
|
|
ScripterExport void sprin1(CharStream* s) { s->printf(_T("<line %d>"), pos); }
|
|
|
|
ScripterExport Value* eval() { thread_local(source_pos) = pos; return &ok; }
|
|
};
|
|
|
|
// top-level code block, provides a storage for top-level locals
|
|
// R4: CodeBlocks can now optionally be 'structured', made of on-handlers and local decls
|
|
// So it now supports call_handler() methods and property access to get at locals.
|
|
// If structured, there must at least be an 'on execute' handler which becomes the main
|
|
// executable body of the CodeBlock, and simple eval()'s onthe codeblock turn into
|
|
// call_handler(n_execute...);
|
|
// Further, locals in a structured codeblock are now effectively static, as are
|
|
// locals in rollups and plugins, they are initialized once the first time the block
|
|
// is used and have a lifetime corresponding to the lifetime of the codeblock. The
|
|
// per-execution-lifetime locals should be moved into the body of the 'on execute'
|
|
// handler. -- JBW 2/29/00
|
|
|
|
|
|
class CodeBlock : public Value
|
|
{
|
|
public:
|
|
Value* code; // the code
|
|
Value** locals; // local var array
|
|
int local_count; // " " count
|
|
HashTable* local_scope; // local name space
|
|
HashTable* handlers; // handler tables
|
|
BOOL initialized; // if locals in structured macroScript have been inited
|
|
|
|
CodeBlock();
|
|
~CodeBlock();
|
|
#define is_codeblock(v) (v->tag == INTERNAL_CODEBLOCK_TAG)
|
|
|
|
void init(Value* code, HashTable* local_scope);
|
|
void init_locals();
|
|
|
|
void collect() { delete this; }
|
|
void gc_trace();
|
|
void sprin1(CharStream* s);
|
|
|
|
void add_local();
|
|
Value* call_handler(Value* handler_or_name, Value** arg_list, int count);
|
|
Value* get_handler(Value* name);
|
|
|
|
Value* eval();
|
|
Value* get_property(Value** arg_list, int count);
|
|
Value* set_property(Value** arg_list, int count);
|
|
};
|
|
|
|
#endif
|