cfad47cfa3/t3compiler/tads3/tct3drv.h
Commiter: Nikos Chantziaras
Author: Nikos Chantziaras
Revision: cfad47cfa3
File Size: 56.8 KB
(June 01, 2009 20:54 UTC) Almost 3 years ago
Initial commit.
Showing without highlighting since it looks like a big file and may slow your browser - show with highlighting
Show/hide line numbers/* $Header: d:/cvsroot/tads/tads3/TCT3DRV.H,v 1.4 1999/07/11 00:46:57 MJRoberts Exp $ */
/*
* Copyright (c) 1999, 2002 Michael J. Roberts. All Rights Reserved.
*
* Please see the accompanying license file, LICENSE.TXT, for information
* on using and copying this software.
*/
/*
Name
tct3drv.h - derived final T3-specific parse node classes
Function
Notes
Modified
05/10/99 MJRoberts - Creation
*/
#ifndef TCT3DRV_H
#define TCT3DRV_H
#include <assert.h>
/* include our T3-specific intermediate classes */
#include "tct3int.h"
/* include the target-independent derived classes */
#include "tcpndrv.h"
/* ------------------------------------------------------------------------ */
/*
* "self"
*/
class CTPNSelf: public CTPNSelfBase
{
public:
/* generate code */
void gen_code(int discard, int for_condition);
/* generate a member expression */
void gen_code_member(int discard,
class CTcPrsNode *prop_expr, int prop_is_expr,
int argc, int varargs);
/* get the object value for a '.' expression */
vm_obj_id_t gen_code_obj_predot(int *is_self);
};
/* ------------------------------------------------------------------------ */
/*
* "replaced"
*/
class CTPNReplaced: public CTPNReplacedBase
{
public:
/* generate code */
void gen_code(int discard, int for_condition);
/* generate a function call expression */
void gen_code_call(int discard, int argc, int varargs);
};
/* ------------------------------------------------------------------------ */
/*
* "targetprop"
*/
class CTPNTargetprop: public CTPNTargetpropBase
{
public:
/* generate code */
void gen_code(int discard, int for_condition);
};
/* ------------------------------------------------------------------------ */
/*
* "targetobj"
*/
class CTPNTargetobj: public CTPNTargetobjBase
{
public:
/* generate code */
void gen_code(int discard, int for_condition);
};
/* ------------------------------------------------------------------------ */
/*
* "definingobj"
*/
class CTPNDefiningobj: public CTPNDefiningobjBase
{
public:
/* generate code */
void gen_code(int discard, int for_condition);
};
/* ------------------------------------------------------------------------ */
/*
* "inherited"
*/
class CTPNInh: public CTPNInhBase
{
public:
/* generate code */
void gen_code(int discard, int for_condition);
/* generate a member expression */
void gen_code_member(int discard,
class CTcPrsNode *prop_expr, int prop_is_expr,
int argc, int varargs);
protected:
/* generate a multi-method inherited() call */
void gen_code_mminh(CTcSymFunc *func, int discard,
class CTcPrsNode *prop_expr, int prop_is_expr,
int argc, int varargs);
};
/*
* "inherited" with explicit superclass
*/
class CTPNInhClass: public CTPNInhClassBase
{
public:
CTPNInhClass(const char *sym, size_t len)
: CTPNInhClassBase(sym, len) { }
/* generate code */
void gen_code(int discard, int for_condition);
/* generate a member expression */
void gen_code_member(int discard,
class CTcPrsNode *prop_expr, int prop_is_expr,
int argc, int varargs);
};
/*
* "delegated"
*/
class CTPNDelegated: public CTPNDelegatedBase
{
public:
CTPNDelegated(CTcPrsNode *delegatee)
: CTPNDelegatedBase(delegatee) { }
/* generate code */
void gen_code(int discard, int for_condition);
/* generate a member expression */
void gen_code_member(int discard,
class CTcPrsNode *prop_expr, int prop_is_expr,
int argc, int varargs);
};
/* ------------------------------------------------------------------------ */
/*
* "argcount" node
*/
class CTPNArgc: public CTPNArgcBase
{
public:
void gen_code(int discard, int for_condition);
};
/* ------------------------------------------------------------------------ */
/*
* constant node
*/
class CTPNConst: public CTPNConstBase
{
public:
CTPNConst(CTcConstVal *val) : CTPNConstBase(val) { }
/* generate code for the constant */
void gen_code(int discard, int for_condition);
/* generate code for operator 'new' applied to this expression */
void gen_code_new(int discard, int argc, int varargs, int from_call,
int is_transient);
/* evaluate a property ID */
vm_prop_id_t gen_code_propid(int check_only, int is_expr);
/* generate a member expression */
void gen_code_member(int discard,
class CTcPrsNode *prop_expr, int prop_is_expr,
int argc, int varargs);
/* generate a function call expression */
void gen_code_call(int discard, int argc, int varargs);
/* get the object value for a '.' expression */
vm_obj_id_t gen_code_obj_predot(int *is_self);
/* generate code to push an integer constant */
static void s_gen_code_int(long intval);
};
/*
* Debugger constant node
*/
class CTPNDebugConst: public CTPNConst
{
public:
CTPNDebugConst(CTcConstVal *val) : CTPNConst(val) { }
/* generate code for the constant */
void gen_code(int discard, int for_condition);
};
/* ------------------------------------------------------------------------ */
/*
* Unary Operators
*/
/* bitwise NOT */
CTPNUnary_def(CTPNBNot);
/* arithmetic positive */
CTPNUnary_def(CTPNPos);
/* arithmetic negative */
CTPNUnary_def(CTPNNeg);
/* pre-increment */
CTPNUnary_side_def(CTPNPreInc);
/* pre-decrement */
CTPNUnary_side_def(CTPNPreDec);
/* post-increment */
CTPNUnary_side_def(CTPNPostInc);
/* post-decrement */
CTPNUnary_side_def(CTPNPostDec);
/* delete */
CTPNUnary_side_def(CTPNDelete);
/* boolean-ize */
CTPNUnary_def(CTPNBoolize);
/* ------------------------------------------------------------------------ */
/*
* NEW operator
*/
class CTPNNew: public CTPNUnary
{
public:
CTPNNew(class CTcPrsNode *sub, int is_transient)
: CTPNUnary(sub)
{
/* remember 'transient' status */
transient_ = is_transient;
}
/* generate code */
void gen_code(int discard, int for_condition);
/* note that we have side effects */
virtual int has_side_effects() const { return TRUE; }
protected:
/* flag: it's a 'new transient' operator */
int transient_;
};
/* ------------------------------------------------------------------------ */
/*
* NOT operator
*/
class CTPNNot: public CTPNNotBase
{
public:
CTPNNot(CTcPrsNode *sub) : CTPNNotBase(sub) { }
/* generate code */
void gen_code(int discard, int for_condition);
};
/* ------------------------------------------------------------------------ */
/*
* Binary Operators
*/
class CTPNComma: public CTPNCommaBase
{
public:
CTPNComma(class CTcPrsNode *lhs, CTcPrsNode *rhs)
: CTPNCommaBase(lhs, rhs) { }
/* generate code */
void gen_code(int discard, int for_condition);
};
/* bitwise OR */
CTPNBin_def(CTPNBOr);
/* bitwise AND */
CTPNBin_def(CTPNBAnd);
/* bitwise XOR */
CTPNBin_def(CTPNBXor);
/* greater than */
CTPNBin_def(CTPNGt);
/* greater or equal */
CTPNBin_def(CTPNGe);
/* less than */
CTPNBin_def(CTPNLt);
/* less or equal */
CTPNBin_def(CTPNLe);
/* bit shift left */
CTPNBin_def(CTPNShl);
/* bit shift right */
CTPNBin_def(CTPNShr);
/* multiply */
CTPNBin_def(CTPNMul);
/* divide */
CTPNBin_def(CTPNDiv);
/* modulo */
CTPNBin_def(CTPNMod);
/* ------------------------------------------------------------------------ */
/*
* Addition
*/
class CTPNAdd: public CTPNAddBase
{
public:
CTPNAdd(class CTcPrsNode *left, class CTcPrsNode *right)
: CTPNAddBase(left, right) { }
/* generate code */
void gen_code(int discard, int for_condition);
};
/* ------------------------------------------------------------------------ */
/*
* Subtraction
*/
class CTPNSub: public CTPNSubBase
{
public:
CTPNSub(class CTcPrsNode *left, class CTcPrsNode *right)
: CTPNSubBase(left, right) { }
/* generate code */
void gen_code(int discard, int for_condition);
};
/* ------------------------------------------------------------------------ */
/*
* Equality Comparison
*/
class CTPNEq: public CTPNEqBase
{
public:
CTPNEq(class CTcPrsNode *left, class CTcPrsNode *right)
: CTPNEqBase(left, right) { }
/* generate code */
void gen_code(int discard, int for_condition);
};
/* ------------------------------------------------------------------------ */
/*
* Inequality Comparison
*/
class CTPNNe: public CTPNNeBase
{
public:
CTPNNe(class CTcPrsNode *left, class CTcPrsNode *right)
: CTPNNeBase(left, right) { }
/* generate code */
void gen_code(int discard, int for_condition);
};
/* ------------------------------------------------------------------------ */
/*
* 'is in'
*/
class CTPNIsIn: public CTPNIsInBase
{
public:
CTPNIsIn(class CTcPrsNode *left, class CTPNArglist *right)
: CTPNIsInBase(left, right) { }
/* generate code */
void gen_code(int discard, int for_condition);
};
/* ------------------------------------------------------------------------ */
/*
* 'not in'
*/
class CTPNNotIn: public CTPNNotInBase
{
public:
CTPNNotIn(class CTcPrsNode *left, class CTPNArglist *right)
: CTPNNotInBase(left, right) { }
/* generate code */
void gen_code(int discard, int for_condition);
};
/* ------------------------------------------------------------------------ */
/*
* Logical AND (short-circuit logic)
*/
class CTPNAnd: public CTPNAndBase
{
public:
CTPNAnd(class CTcPrsNode *left, class CTcPrsNode *right)
: CTPNAndBase(left, right) { }
/* generate code */
void gen_code(int discard, int for_condition);
/* generate a condition */
virtual void gen_code_cond(struct CTcCodeLabel *then_label,
struct CTcCodeLabel *else_label);
};
/* ------------------------------------------------------------------------ */
/*
* Logical OR (short-circuit logic)
*/
class CTPNOr: public CTPNOrBase
{
public:
CTPNOr(class CTcPrsNode *left, class CTcPrsNode *right)
: CTPNOrBase(left, right) { }
/* generate code */
void gen_code(int discard, int for_condition);
/* generate a condition */
virtual void gen_code_cond(struct CTcCodeLabel *then_label,
struct CTcCodeLabel *else_label);
};
/* ------------------------------------------------------------------------ */
/*
* Assignment Operators
*/
/* simple assignment */
class CTPNAsi: public CTPNAsiBase
{
public:
CTPNAsi(class CTcPrsNode *left, class CTcPrsNode *right)
: CTPNAsiBase(left, right) { }
/* generate code */
void gen_code(int discard, int for_condition);
};
/* add and assign */
CTPNBin_side_def(CTPNAddAsi);
/* subtract and assign */
CTPNBin_side_def(CTPNSubAsi);
/* multiple and assign */
CTPNBin_side_def(CTPNMulAsi);
/* divide and assign */
CTPNBin_side_def(CTPNDivAsi);
/* modulo and assign */
CTPNBin_side_def(CTPNModAsi);
/* bitwise AND and assign */
CTPNBin_side_def(CTPNBAndAsi);
/* bitwise OR and assign */
CTPNBin_side_def(CTPNBOrAsi);
/* bitwise XOR and assign */
CTPNBin_side_def(CTPNBXorAsi);
/* bit shift left and assign */
CTPNBin_side_def(CTPNShlAsi);
/* bit shift right and assign */
CTPNBin_side_def(CTPNShrAsi);
/* ------------------------------------------------------------------------ */
/*
* Array/list Subscript
*/
class CTPNSubscript: public CTPNSubscriptBase
{
public:
CTPNSubscript(CTcPrsNode *lhs, CTcPrsNode *rhs)
: CTPNSubscriptBase(lhs, rhs) { }
/* generate code */
void gen_code(int discard, int for_condition);
/* generate code to assign a value to the symbol */
int gen_code_asi(int discard, tc_asitype_t typ, CTcPrsNode *rhs,
int ignore_errors);
};
/* ------------------------------------------------------------------------ */
/*
* Address-of Operator
*/
class CTPNAddr: public CTPNAddrBase
{
public:
CTPNAddr(CTcPrsNode *sub)
: CTPNAddrBase(sub) { }
/* generate code */
void gen_code(int discard, int for_condition)
{
/*
* if we're not discarding the value, tell the subnode to
* generate its address; if the value is being discarded, do
* nothing, since taking an address has no side effects
*/
if (!discard)
sub_->gen_code_addr();
}
/* generate a member expression */
void gen_code_member(int discard,
class CTcPrsNode *prop_expr, int prop_is_expr,
int argc, int varargs)
{
/*
* let the subnode do the work, since "&obj" is the same as
* "obj" in any context
*/
sub_->gen_code_member(discard, prop_expr, prop_is_expr,
argc, varargs);
}
/* evaluate a property ID */
vm_prop_id_t gen_code_propid(int check_only, int is_expr)
{
/*
* let the subexpression handle it, so that we treat "x.&prop"
* the same as "x.prop"
*/
return sub_->gen_code_propid(check_only, is_expr);
}
/* get the object value for a '.' expression */
vm_obj_id_t gen_code_obj_predot(int *is_self)
{
/*
* let the subexpression handle it, since "x.&prop" is the same
* as "x.prop"
*/
return sub_->gen_code_obj_predot(is_self);
}
};
/* ------------------------------------------------------------------------ */
/*
* Conditional Operator
*/
class CTPNIf: public CTPNIfBase
{
public:
CTPNIf(class CTcPrsNode *first, class CTcPrsNode *second,
class CTcPrsNode *third)
: CTPNIfBase(first, second, third) { }
/* generate code for the conditional */
void gen_code(int discard, int for_condition);
};
/* ------------------------------------------------------------------------ */
/*
* Symbol node
*/
class CTPNSym: public CTPNSymBase
{
public:
CTPNSym(const char *sym, size_t len)
: CTPNSymBase(sym, len) { }
/* generate code for the symbol evaluated as an rvalue */
void gen_code(int discard, int for_condition);
/* generate code to assign a value to the symbol */
int gen_code_asi(int discard, tc_asitype_t typ, CTcPrsNode *rhs,
int ignore_errors);
/* generate code to take the address of the symbol */
void gen_code_addr();
/* generate code to call the symbol */
void gen_code_call(int discard, int argc, int varargs);
/* generate code for operator 'new' applied to this expression */
void gen_code_new(int discard, int argc, int varargs, int from_call,
int is_transient);
/* evaluate a property ID */
vm_prop_id_t gen_code_propid(int check_only, int is_expr);
/* generate a member expression */
void gen_code_member(int discard,
class CTcPrsNode *prop_expr, int prop_is_expr,
int argc, int varargs);
/* get the object value for a '.' expression */
vm_obj_id_t gen_code_obj_predot(int *is_self);
};
/* ------------------------------------------------------------------------ */
/*
* Resolved symbol
*/
class CTPNSymResolved: public CTPNSymResolvedBase
{
public:
CTPNSymResolved(CTcSymbol *sym)
: CTPNSymResolvedBase(sym) { }
/* generate code for the symbol evaluated as an rvalue */
void gen_code(int discard, int for_condition);
/* generate code to assign a value to the symbol */
int gen_code_asi(int discard, tc_asitype_t typ, CTcPrsNode *rhs,
int ignore_errors);
/* generate code to take the address of the symbol */
void gen_code_addr();
/* generate code to call the symbol */
void gen_code_call(int discard, int argc, int varargs);
/* generate code for operator 'new' applied to this expression */
void gen_code_new(int discard, int argc, int varargs, int from_call,
int is_transient);
/* evaluate a property ID */
vm_prop_id_t gen_code_propid(int check_only, int is_expr);
/* generate a member expression */
void gen_code_member(int discard,
class CTcPrsNode *prop_expr, int prop_is_expr,
int argc, int varargs);
/* get the object value for a '.' expression */
vm_obj_id_t gen_code_obj_predot(int *is_self);
};
/* ------------------------------------------------------------------------ */
/*
* Resolved debugger local variable symbol
*/
class CTPNSymDebugLocal: public CTPNSymDebugLocalBase
{
public:
CTPNSymDebugLocal(const struct tcprsdbg_sym_info *info)
: CTPNSymDebugLocalBase(info)
{
}
/* generate code */
void gen_code(int discard, int for_condition);
/* generate code for assigning into this node */
int gen_code_asi(int discard, tc_asitype_t typ,
class CTcPrsNode *rhs, int ignore_errors);
};
/* ------------------------------------------------------------------------ */
/*
* double-quoted string expression
*/
class CTPNDstr: public CTPNDstrBase
{
public:
CTPNDstr(const char *str, size_t len)
: CTPNDstrBase(str, len) { }
void gen_code(int discard, int for_condition);
};
/*
* debug version of string
*/
class CTPNDebugDstr: public CTPNDstr
{
public:
CTPNDebugDstr(const char *str, size_t len)
: CTPNDstr(str, len) { }
void gen_code(int discard, int for_condition);
};
/*
* double-quoted string embedding
*/
class CTPNDstrEmbed: public CTPNDstrEmbedBase
{
public:
CTPNDstrEmbed(CTcPrsNode *sub);
void gen_code(int discard, int for_condition);
};
/* ------------------------------------------------------------------------ */
/*
* Argument List
*/
class CTPNArglist: public CTPNArglistBase
{
public:
CTPNArglist(int argc, class CTPNArg *list_head)
: CTPNArglistBase(argc, list_head) { }
void gen_code(int, int)
{
/*
* this isn't used - we always generate explicitly via
* gen_code_arglist()
*/
assert(FALSE);
}
/* generate code for an argument list */
void gen_code_arglist(int *varargs);
};
/*
* Argument List Entry
*/
class CTPNArg: public CTPNArgBase
{
public:
CTPNArg(CTcPrsNode *expr)
: CTPNArgBase(expr) { }
void gen_code(int discard, int for_condition);
};
/* ------------------------------------------------------------------------ */
/*
* Function/method call
*/
class CTPNCall: public CTPNCallBase
{
public:
CTPNCall(CTcPrsNode *func, class CTPNArglist *arglist);
/* generate code */
void gen_code(int discard, int for_condition);
/* generate code for operator 'new' applied to this expression */
void gen_code_new(int discard, int argc, int varargs, int from_call,
int is_transient);
};
/* ------------------------------------------------------------------------ */
/*
* Member expression with no arguments
*/
class CTPNMember: public CTPNMemberBase
{
public:
CTPNMember(CTcPrsNode *lhs, CTcPrsNode *rhs, int rhs_is_expr)
: CTPNMemberBase(lhs, rhs, rhs_is_expr) { }
/* generate code */
void gen_code(int discard, int for_condition);
/* generate code to assign a value to the symbol */
int gen_code_asi(int discard, tc_asitype_t typ, CTcPrsNode *rhs,
int ignore_errors);
};
/*
* Member evaluation with argument list
*/
class CTPNMemArg: public CTPNMemArgBase
{
public:
CTPNMemArg(CTcPrsNode *obj_expr, CTcPrsNode *prop_expr, int prop_is_expr,
class CTPNArglist *arglist)
: CTPNMemArgBase(obj_expr, prop_expr, prop_is_expr, arglist) { }
void gen_code(int discard, int for_condition);
};
/* ------------------------------------------------------------------------ */
/*
* List
*/
class CTPNList: public CTPNListBase
{
public:
void gen_code(int discard, int for_condition);
};
/*
* List Element
*/
class CTPNListEle: public CTPNListEleBase
{
public:
CTPNListEle(CTcPrsNode *expr)
: CTPNListEleBase(expr) { }
void gen_code(int discard, int for_condition);
};
/* ------------------------------------------------------------------------ */
/*
* Derived T3-specific symbol classes
*/
/*
* undefined symbol
*/
class CTcSymUndef: public CTcSymUndefBase
{
public:
CTcSymUndef(const char *str, size_t len, int copy)
: CTcSymUndefBase(str, len, copy) { }
/*
* generate code to evaluate the symbol; since it's undefined, this
* doesn't generate any code at all
*/
virtual void gen_code(int) { }
/*
* Generate code to assign to the symbol. The symbol is undefined,
* so we can't generate any code; but we'll indicate to the caller
* that the assignment is fully processed anyway, since there's no
* need for the caller to try generating any code either.
*/
virtual int gen_code_asi(int, tc_asitype_t, class CTcPrsNode *, int)
{
return TRUE;
}
/*
* Generate code for taking the address of the symbol. The symbol
* has no address, so this generates no code.
*/
virtual void gen_code_addr() { }
/*
* generate code to call the symbol - we can't generate any code for
* this, but don't bother issuing an error since we will have shown
* an error for the undefined symbol in the first place
*/
virtual void gen_code_call(int, int, int) { }
/*
* generate code for operator 'new' applied to this expression - we
* can't generate any code, but suppress errors as usual
*/
void gen_code_new(int, int, int, int) { }
/* generate a member expression */
void gen_code_member(int, class CTcPrsNode *, int, int, int) { }
/* get the object value for a '.' expression */
vm_obj_id_t gen_code_obj_predot(int *is_self)
{
*is_self = FALSE;
return VM_INVALID_OBJ;
}
};
/*
* function
*/
class CTcSymFunc: public CTcSymFuncBase
{
public:
CTcSymFunc(const char *str, size_t len, int copy,
int argc, int varargs, int has_retval,
int is_multimethod, int is_mm_base, int is_extern)
: CTcSymFuncBase(str, len, copy, argc, varargs, has_retval,
is_multimethod, is_mm_base, is_extern)
{
/*
* we don't have a valid absolute address - by default, we use
* the anchor
*/
abs_addr_valid_ = FALSE;
abs_addr_ = 0;
}
/* generate code to evaluate the symbol */
virtual void gen_code(int discard);
/* we can take the address of this symbol type */
virtual void gen_code_addr();
/* generate a call */
virtual void gen_code_call(int discard, int argc, int varargs);
/*
* Get my code pool address. This is valid only after the linking
* phase has been completed and all fixups have been applied. (The
* normal use for this is to generate image file elements not
* subject to fixup, such as the entrypoint record. Normally,
* references to the symbol that require the code pool address would
* simply generate a fixup rather than asking for the true address,
* since a fixup can be generated at any time during code
* generation.)
*/
ulong get_code_pool_addr() const;
/* write the symbol to an image file's global symbol table */
int write_to_image_file_global(class CVmImageWriter *image_writer);
/*
* Set the absolute code pool address. This can only be used when
* the symbol is loaded from a fully-linked image file; in most
* cases, this routine is not needed, because the function's address
* will be kept with its associated anchor to allow for relocation
* of the function during the linking process.
*/
void set_abs_addr(ulong addr)
{
/* remember the address */
abs_addr_ = addr;
/* note that the absolute address is valid */
abs_addr_valid_ = TRUE;
}
/* add a runtime symbol table entry */
void add_runtime_symbol(class CVmRuntimeSymbols *symtab);
protected:
/*
* Absolute code pool address, and a flag indicating whether the
* address is valid. When we load a function symbol from a
* fully-linked image file (specifically, when we load the symbol
* from the debug records of an image file), the address of the
* function is fully resolved and doesn't require fixups via the
* anchor mechanism. In these cases, we'll simply remember the
* resolved address here.
*/
ulong abs_addr_;
uint abs_addr_valid_ : 1;
};
/*
* metaclass
*/
class CTcSymMetaclass: public CTcSymMetaclassBase
{
public:
CTcSymMetaclass(const char *str, size_t len, int copy, int meta_idx,
tctarg_obj_id_t class_obj)
: CTcSymMetaclassBase(str, len, copy, meta_idx, class_obj)
{
}
/* generate code to evaluate the symbol */
virtual void gen_code(int discard);
/* generate code for operator 'new' */
void gen_code_new(int discard, int argc, int varargs, int is_transient);
/* generate a member expression */
void gen_code_member(int discard,
class CTcPrsNode *prop_expr, int prop_is_expr,
int argc, int varargs);
/* get the object value for a '.' expression */
vm_obj_id_t gen_code_obj_predot(int *is_self)
{
/* simply generate our code as normal */
gen_code(FALSE);
/* indicate that the caller must use generated code */
*is_self = FALSE;
return VM_INVALID_OBJ;
}
/* write the symbol to an image file's global symbol table */
int write_to_image_file_global(class CVmImageWriter *image_writer);
/*
* fix up the inheritance chain in the modifier objects - each
* object file has its own independent inheritance list, so we can
* only build the complete and connected list after loading them all
*/
void fix_mod_obj_sc_list();
/* add a runtime symbol table entry */
void add_runtime_symbol(class CVmRuntimeSymbols *symtab);
};
/*
* object
*/
class CTcSymObj: public CTcSymObjBase
{
public:
CTcSymObj(const char *str, size_t len, int copy, vm_obj_id_t obj_id,
int is_extern, tc_metaclass_t meta, class CTcDictEntry *dict)
: CTcSymObjBase(str, len, copy, obj_id, is_extern, meta, dict)
{
}
/* we have a valid object value */
virtual vm_obj_id_t get_val_obj() const { return get_obj_id(); }
/* generate code to evaluate the symbol */
virtual void gen_code(int discard);
/* we can take the address of this symbol type */
virtual void gen_code_addr();
/* generate code for operator 'new' */
void gen_code_new(int discard, int argc, int varargs, int is_transient);
/* static code to generate code for 'new' */
static void s_gen_code_new(int discard, vm_obj_id_t obj_id,
tc_metaclass_t meta,
int argc, int varargs, int is_transient);
/* generate a member expression */
void gen_code_member(int discard,
class CTcPrsNode *prop_expr, int prop_is_expr,
int argc, int varargs);
/* static code to generate a member expression */
static void s_gen_code_member(int discard,
class CTcPrsNode *prop_expr,
int prop_is_expr, int argc,
vm_obj_id_t obj_id, int varargs);
/* get the object value for a '.' expression */
vm_obj_id_t gen_code_obj_predot(int *is_self);
/* delete a property from our modified base classes */
virtual void delete_prop_from_mod_base(tctarg_prop_id_t prop_id);
/* mark the compiled data for the object as a 'class' object */
virtual void mark_compiled_as_class();
/* write the symbol to an image file's global symbol table */
int write_to_image_file_global(class CVmImageWriter *image_writer);
/* build my dictionary */
virtual void build_dictionary();
/* add a runtime symbol table entry */
void add_runtime_symbol(class CVmRuntimeSymbols *symtab);
};
/*
* property
*/
class CTcSymProp: public CTcSymPropBase
{
public:
CTcSymProp(const char *str, size_t len, int copy, tctarg_prop_id_t prop)
: CTcSymPropBase(str, len, copy, prop) { }
/* generate code to evaluate the symbol */
virtual void gen_code(int discard);
/* we can take the address of this symbol type */
virtual void gen_code_addr();
/* assign to the property */
virtual int gen_code_asi(int discard, tc_asitype_t typ,
class CTcPrsNode *rhs, int ignore_errors);
/* generate a call */
virtual void gen_code_call(int discard, int argc, int varargs);
/* evaluate a property ID */
vm_prop_id_t gen_code_propid(int check_only, int is_expr);
/* generate a member expression */
void gen_code_member(int discard,
class CTcPrsNode *prop_expr, int prop_is_expr,
int argc, int varargs);
/* get the object value for a '.' expression */
vm_obj_id_t gen_code_obj_predot(int *is_self)
{
/* simply generate our code as normal */
gen_code(FALSE);
/* indicate that the caller must use generated code */
*is_self = FALSE;
return VM_INVALID_OBJ;
}
/* write the symbol to an image file's global symbol table */
int write_to_image_file_global(class CVmImageWriter *image_writer);
/* add a runtime symbol table entry */
void add_runtime_symbol(class CVmRuntimeSymbols *symtab);
};
/*
* Enumerator
*/
class CTcSymEnum: public CTcSymEnumBase
{
public:
CTcSymEnum(const char *str, size_t len, int copy, ulong id, int is_token)
: CTcSymEnumBase(str, len, copy, id, is_token)
{
}
/* generate code */
virtual void gen_code(int discard);
/* write the symbol to an image file's global symbol table */
int write_to_image_file_global(class CVmImageWriter *image_writer);
/* add a runtime symbol table entry */
void add_runtime_symbol(class CVmRuntimeSymbols *symtab);
};
/*
* local variable/parameter
*/
class CTcSymLocal: public CTcSymLocalBase
{
public:
CTcSymLocal(const char *str, size_t len, int copy,
int is_param, int var_num)
: CTcSymLocalBase(str, len, copy, is_param, var_num) { }
/* generate code to evaluate the symbol */
virtual void gen_code(int discard);
/* generate code to store the value at top of stack in the variable */
void gen_code_setlcl_stk() { s_gen_code_setlcl_stk(var_num_, is_param_); }
/* generate code to get a local with a given ID */
static void s_gen_code_getlcl(int local_id, int is_param);
/* generate code to store a local with a given ID */
static void s_gen_code_setlcl_stk(int local_id, int is_param);
/* generate code to store the value at top of stack in the local */
void gen_code_setlcl();
/* assign to the variable */
virtual int gen_code_asi(int discard, tc_asitype_t typ,
class CTcPrsNode *rhs, int ignore_errors);
/*
* generate a call - invoking a local as a function assumes that the
* local contains a method or function pointer
*/
virtual void gen_code_call(int discard, int argc, int varargs);
/* evaluate a property ID */
vm_prop_id_t gen_code_propid(int check_only, int is_expr);
/* generate a member expression */
void gen_code_member(int discard,
class CTcPrsNode *prop_expr, int prop_is_expr,
int argc, int varargs);
/* get the object value for a '.' expression */
vm_obj_id_t gen_code_obj_predot(int *is_self)
{
/* simply generate our code as normal */
gen_code(FALSE);
/* indicate that the caller must use generated code */
*is_self = FALSE;
return VM_INVALID_OBJ;
}
/* write the symbol to a debug frame */
virtual int write_to_debug_frame();
};
/*
* built-in function
*/
class CTcSymBif: public CTcSymBifBase
{
public:
CTcSymBif(const char *str, size_t len, int copy,
int func_set_id, int func_idx, int has_retval,
int min_argc, int max_argc, int varargs)
: CTcSymBifBase(str, len, copy, func_set_id, func_idx,
has_retval, min_argc, max_argc, varargs) { }
/* generate code to evaluate the symbol */
virtual void gen_code(int discard);
/* generate a call */
virtual void gen_code_call(int discard, int argc, int varargs);
/* write the symbol to an image file's global symbol table */
int write_to_image_file_global(class CVmImageWriter *image_writer);
};
/*
* external function
*/
class CTcSymExtfn: public CTcSymExtfnBase
{
public:
CTcSymExtfn(const char *str, size_t len, int copy,
int argc, int varargs, int has_retval)
: CTcSymExtfnBase(str, len, copy, argc, varargs, has_retval) { }
/* generate code to evaluate the symbol */
virtual void gen_code(int discard);
/* generate a call */
virtual void gen_code_call(int discard, int argc, int varargs);
/* write the symbol to an image file's global symbol table */
int write_to_image_file_global(class CVmImageWriter *image_writer);
};
/*
* code label
*/
class CTcSymLabel: public CTcSymLabelBase
{
public:
CTcSymLabel(const char *str, size_t len, int copy)
: CTcSymLabelBase(str, len, copy) { }
/* generate code to evaluate the symbol */
virtual void gen_code(int discard);
};
/* ------------------------------------------------------------------------ */
/*
* Anonymous function
*/
class CTPNAnonFunc: public CTPNAnonFuncBase
{
public:
CTPNAnonFunc(class CTPNCodeBody *code_body, int has_retval)
: CTPNAnonFuncBase(code_body, has_retval)
{
}
/* generate code */
virtual void gen_code(int discard, int for_condition);
};
/* ------------------------------------------------------------------------ */
/*
* Code Body
*/
class CTPNCodeBody: public CTPNCodeBodyBase
{
public:
CTPNCodeBody(class CTcPrsSymtab *lcltab, class CTcPrsSymtab *gototab,
class CTPNStm *stm, int argc, int varargs,
int varargs_list, class CTcSymLocal *varargs_list_local,
int local_cnt, int self_valid,
struct CTcCodeBodyRef *enclosing_code_body)
: CTPNCodeBodyBase(lcltab, gototab, stm, argc, varargs,
varargs_list, varargs_list_local,
local_cnt, self_valid, enclosing_code_body)
{
/* presume I'm not a constructor */
is_constructor_ = FALSE;
/* presume I won't need a 'finally' return value holder local */
allocated_fin_ret_lcl_ = FALSE;
fin_ret_lcl_ = 0;
/* presume it won't be static */
is_static_ = FALSE;
/* no nested symbol table list yet */
first_nested_symtab_ = 0;
}
/*
* Mark the code body as belonging to a constructor. A constructor
* must return its 'self' object as the return value.
*/
void set_constructor(int f) { is_constructor_ = f; }
/*
* mark the code body as static - this indicates that it is a static
* initializer
*/
void set_static() { is_static_ = TRUE; }
/* generate code */
virtual void gen_code(int discard, int for_condition);
/* check locals */
virtual void check_locals();
/*
* Allocate a local variable for temporarily saving the expression
* value of a 'return' statement while calling the enclosing
* 'finally' block(s). Returns the variable ID. Only one such
* local is needed per code body, so if we've already allocated one
* for another 'return' statement, we'll just return the same one we
* allocated previously.
*/
uint alloc_fin_ret_lcl()
{
/* if we haven't allocated it yet, do so now */
if (!allocated_fin_ret_lcl_)
{
/* use the next available local */
fin_ret_lcl_ = local_cnt_++;
/* note that we've allocated it */
allocated_fin_ret_lcl_ = TRUE;
}
/* return the local ID */
return fin_ret_lcl_;
}
protected:
/*
* callback for enumerating local frame symbol table entries - write
* each entry to the code stream as a debug record
*/
static void write_local_to_debug_frame(void *ctx, class CTcSymbol *sym);
/*
* enumerator for checking for parameter symbols that belong in the
* local context
*/
static void enum_for_param_ctx(void *ctx, class CTcSymbol *sym);
/* write the debug information table to the code stream */
void build_debug_table(ulong start_ofs);
/* show disassembly */
void show_disassembly(unsigned long start_ofs,
unsigned long code_start_ofs,
unsigned long code_end_ofs);
/* head of list of nested symbol tables */
class CTcPrsSymtab *first_nested_symtab_;
/*
* ID of local variable for temporarily storing the expression value
* of a 'return' statement while calling the enclosing 'finally'
* block(s); valid only when allocated_fin_ret_lcl_ is true
*/
uint fin_ret_lcl_;
/* flag: I'm a constructor */
uint is_constructor_ : 1;
/*
* flag: I've allocated a local for saving the expression value of a
* 'return' statement while calling the enclosing 'finally' block(s)
*/
uint allocated_fin_ret_lcl_ : 1;
/* flag: I'm a static property initializer */
uint is_static_ : 1;
};
/* ------------------------------------------------------------------------ */
/*
* Compound Statement
*/
class CTPNStmComp: public CTPNStmCompBase
{
public:
CTPNStmComp(class CTPNStm *first_stm, class CTcPrsSymtab *symtab)
: CTPNStmCompBase(first_stm, symtab) { }
};
/* ------------------------------------------------------------------------ */
/*
* Null statement
*/
class CTPNStmNull: public CTPNStmNullBase
{
public:
CTPNStmNull() { }
};
/* ------------------------------------------------------------------------ */
/*
* Expression statement
*/
class CTPNStmExpr: public CTPNStmExprBase
{
public:
CTPNStmExpr(class CTcPrsNode *expr)
: CTPNStmExprBase(expr) { }
};
/* ------------------------------------------------------------------------ */
/*
* Static property initializer statement
*/
class CTPNStmStaticPropInit: public CTPNStmStaticPropInitBase
{
public:
CTPNStmStaticPropInit(class CTcPrsNode *expr,
tctarg_prop_id_t prop)
: CTPNStmStaticPropInitBase(expr, prop) { }
/* generate code */
virtual void gen_code(int discard, int for_condition);
};
/* ------------------------------------------------------------------------ */
/*
* 'if' statement
*/
class CTPNStmIf: public CTPNStmIfBase
{
public:
CTPNStmIf(class CTcPrsNode *cond_expr,
class CTPNStm *then_part, class CTPNStm *else_part)
: CTPNStmIfBase(cond_expr, then_part, else_part) { }
/* generate code */
virtual void gen_code(int discard, int for_condition);
};
/* ------------------------------------------------------------------------ */
/*
* 'for' statement
*/
class CTPNStmFor: public CTPNStmForBase
{
public:
CTPNStmFor(class CTcPrsNode *init_expr,
class CTcPrsNode *cond_expr,
class CTcPrsNode *reinit_expr,
class CTcPrsSymtab *symtab,
class CTPNStmEnclosing *enclosing_stm)
: CTPNStmForBase(init_expr, cond_expr, reinit_expr,
symtab, enclosing_stm)
{
}
/* generate code */
virtual void gen_code(int discard, int for_condition);
/* generate code for 'break' */
virtual int gen_code_break(const textchar_t *lbl, size_t lbl_len)
{ return gen_code_break_loop(break_lbl_, lbl, lbl_len); }
/* generate code for 'continue' */
virtual int gen_code_labeled_continue()
{ return gen_code_continue_loop(cont_lbl_, 0, 0); }
/* generate code for a labeled 'continue' */
virtual int gen_code_continue(const textchar_t *lbl, size_t lbl_len)
{ return gen_code_continue_loop(cont_lbl_, lbl, lbl_len); }
protected:
/* our 'break' label */
struct CTcCodeLabel *break_lbl_;
/* our 'continue' label */
struct CTcCodeLabel *cont_lbl_;
};
/* ------------------------------------------------------------------------ */
/*
* 'for' statement
*/
class CTPNStmForeach: public CTPNStmForeachBase
{
public:
CTPNStmForeach(class CTcPrsNode *iter_expr,
class CTcPrsNode *coll_expr,
class CTcPrsSymtab *symtab,
class CTPNStmEnclosing *enclosing_stm,
int iter_local_id)
: CTPNStmForeachBase(iter_expr, coll_expr, symtab, enclosing_stm,
iter_local_id)
{
}
/* generate code */
virtual void gen_code(int discard, int for_condition);
/* generate code for 'break' */
virtual int gen_code_break(const textchar_t *lbl, size_t lbl_len)
{ return gen_code_break_loop(break_lbl_, lbl, lbl_len); }
/* generate code for 'continue' */
virtual int gen_code_labeled_continue()
{ return gen_code_continue_loop(cont_lbl_, 0, 0); }
/* generate code for a labeled 'continue' */
virtual int gen_code_continue(const textchar_t *lbl, size_t lbl_len)
{ return gen_code_continue_loop(cont_lbl_, lbl, lbl_len); }
protected:
/* our 'break' label */
struct CTcCodeLabel *break_lbl_;
/* our 'continue' label */
struct CTcCodeLabel *cont_lbl_;
};
/* ------------------------------------------------------------------------ */
/*
* 'break' statement
*/
class CTPNStmBreak: public CTPNStmBreakBase
{
public:
CTPNStmBreak() { }
/* generate code */
virtual void gen_code(int discard, int for_condition);
};
/* ------------------------------------------------------------------------ */
/*
* 'continue' statement
*/
class CTPNStmContinue: public CTPNStmContinueBase
{
public:
CTPNStmContinue() { }
/* generate code */
virtual void gen_code(int discard, int for_condition);
};
/* ------------------------------------------------------------------------ */
/*
* 'while' statement
*/
class CTPNStmWhile: public CTPNStmWhileBase
{
public:
CTPNStmWhile(class CTcPrsNode *cond_expr,
class CTPNStmEnclosing *enclosing_stm)
: CTPNStmWhileBase(cond_expr, enclosing_stm) { }
/* generate code */
virtual void gen_code(int discard, int for_condition);
/* generate code for 'break' */
virtual int gen_code_break(const textchar_t *lbl, size_t lbl_len)
{ return gen_code_break_loop(break_lbl_, lbl, lbl_len); }
/* generate code for 'continue' */
virtual int gen_code_labeled_continue()
{ return gen_code_continue_loop(cont_lbl_, 0, 0); }
/* generate code for a labeled 'continue' */
virtual int gen_code_continue(const textchar_t *lbl, size_t lbl_len)
{ return gen_code_continue_loop(cont_lbl_, lbl, lbl_len); }
protected:
/* our 'break' label */
struct CTcCodeLabel *break_lbl_;
/* our 'continue' label */
struct CTcCodeLabel *cont_lbl_;
};
/* ------------------------------------------------------------------------ */
/*
* 'do-while' statement
*/
class CTPNStmDoWhile: public CTPNStmDoWhileBase
{
public:
CTPNStmDoWhile(class CTPNStmEnclosing *enclosing_stm)
: CTPNStmDoWhileBase(enclosing_stm) { }
/* generate code */
virtual void gen_code(int discard, int for_condition);
/* generate code for 'break' */
virtual int gen_code_break(const textchar_t *lbl, size_t lbl_len)
{ return gen_code_break_loop(break_lbl_, lbl, lbl_len); }
/* generate code for 'continue' */
virtual int gen_code_labeled_continue()
{ return gen_code_continue_loop(cont_lbl_, 0, 0); }
/* generate code for a labeled 'continue' */
virtual int gen_code_continue(const textchar_t *lbl, size_t lbl_len)
{ return gen_code_continue_loop(cont_lbl_, lbl, lbl_len); }
protected:
/* our 'break' label */
struct CTcCodeLabel *break_lbl_;
/* our 'continue' label */
struct CTcCodeLabel *cont_lbl_;
};
/* ------------------------------------------------------------------------ */
/*
* 'return' statement
*/
class CTPNStmReturn: public CTPNStmReturnBase
{
public:
CTPNStmReturn(class CTcPrsNode *expr)
: CTPNStmReturnBase(expr) { }
/* generate code */
virtual void gen_code(int discard, int for_condition);
};
/* ------------------------------------------------------------------------ */
/*
* 'switch' statement
*/
class CTPNStmSwitch: public CTPNStmSwitchBase
{
public:
CTPNStmSwitch(class CTPNStmEnclosing *enclosing_stm)
: CTPNStmSwitchBase(enclosing_stm)
{
/* the 'case' and 'default' slot pointers aren't valid yet */
case_slot_ofs_ = 0;
default_slot_ofs_ = 0;
}
/* generate code */
virtual void gen_code(int discard, int for_condition);
/*
* Get the next case slot offset, and consume the slot. Each call
* consumes one slot. This is valid only during code generation in
* the switch body; 'case' labels use this to figure out where to
* write their data.
*/
ulong alloc_case_slot()
{
ulong ret;
/* note the value to return */
ret = case_slot_ofs_;
/* move our internal counter to the next slot */
case_slot_ofs_ += VMB_DATAHOLDER + VMB_UINT2;
/* return the allocated slot */
return ret;
}
/* get the code offset of the 'default' case slot */
ulong get_default_slot() const { return default_slot_ofs_; }
/* generate code for 'break' */
virtual int gen_code_break(const textchar_t *lbl, size_t lbl_len)
{
/*
* if there's no label, and we don't have a 'break' label
* ourselves, it must mean that we're processing an unreachable
* 'break' - we can simply do nothing in this case and pretend we
* succeeded
*/
if (lbl == 0 && break_lbl_ == 0)
return TRUE;
/* break to our break label */
return gen_code_break_loop(break_lbl_, lbl, lbl_len);
}
protected:
/*
* code offset of the next 'case' slot to be allocated from the
* switch's case table - this is only valid during generation of the
* body, because we set this up during generation of the switch
* itself
*/
ulong case_slot_ofs_;
/* code offset of the 'default' slot */
ulong default_slot_ofs_;
/* our 'break' label */
struct CTcCodeLabel *break_lbl_;
};
/* ------------------------------------------------------------------------ */
/*
* code label statement
*/
class CTPNStmLabel: public CTPNStmLabelBase
{
public:
CTPNStmLabel(class CTcSymLabel *lbl, class CTPNStmEnclosing *enclosing);
/* generate code */
virtual void gen_code(int discard, int for_condition);
/* generate code for 'break' */
virtual int gen_code_break(const textchar_t *lbl, size_t lbl_len);
/* generate code for 'continue' */
virtual int gen_code_continue(const textchar_t *lbl, size_t lbl_len);
/*
* Generate code for a labeled 'continue'. We'll simply generate
* code for a labeled continue in our enclosed statement.
*
* (This is normally a routine that *we* call on our contained
* statement in response to a 'continue' being targeted at this
* label. This can be invoked on us, however, when a statement has
* multiple labels, and the outer label is mentioned in the 'break'
* -- the outer label will call this routine on the inner label,
* which is us, so we simply need to pass it along to the enclosed
* statement.)
*/
virtual int gen_code_labeled_continue()
{ return (stm_ != 0 ? stm_->gen_code_labeled_continue() : FALSE); }
/* get my 'goto' label */
struct CTcCodeLabel *get_goto_label();
protected:
/* the byte label to jump to this statement */
struct CTcCodeLabel *goto_label_;
/* the byte label to break from this statement */
struct CTcCodeLabel *break_label_;
};
/* ------------------------------------------------------------------------ */
/*
* 'case' label statement
*/
class CTPNStmCase: public CTPNStmCaseBase
{
public:
CTPNStmCase() { }
/* generate code */
virtual void gen_code(int discard, int for_condition);
};
/* ------------------------------------------------------------------------ */
/*
* 'default' label statement
*/
class CTPNStmDefault: public CTPNStmDefaultBase
{
public:
CTPNStmDefault() { }
/* generate code */
virtual void gen_code(int discard, int for_condition);
};
/* ------------------------------------------------------------------------ */
/*
* 'try' block
*/
class CTPNStmTry: public CTPNStmTryBase
{
public:
CTPNStmTry(class CTPNStmEnclosing *enclosing)
: CTPNStmTryBase(enclosing)
{
}
/* generate code */
virtual void gen_code(int discard, int for_condition);
/* generate code for 'break' */
virtual int gen_code_break(const textchar_t *lbl, size_t lbl_len);
/* generate code for 'continue' */
virtual int gen_code_continue(const textchar_t *lbl, size_t lbl_len);
/*
* Generate the code necessary to unwind for returning. We must
* generate a call to our 'finally' code, then unwind any enclosing
* statements.
*/
virtual void gen_code_unwind_for_return()
{
/* call 'finally' on the way out */
gen_jsr_finally();
/* inherit default to unwind enclosing statements */
CTPNStmTryBase::gen_code_unwind_for_return();
}
/* determine if we'll generate code for unwinding from a return */
virtual int will_gen_code_unwind_for_return() const
{
/* we'll generate a call to our 'finally' block if we have one */
if (finally_stm_ != 0)
return TRUE;
/* we'll also generate code if any enclosing statement does */
return CTPNStmTryBase::will_gen_code_unwind_for_return();
}
/* generate the code necessary to transfer out of the block */
virtual void gen_code_for_transfer_out()
{
/* call 'finally' on the way out */
gen_jsr_finally();
}
/*
* generate a local subroutine call to our 'finally' block, if we
* have a 'finally' block - this should be invoked whenever code
* within the protected block or a 'catch' block executes a break,
* continue, return, or goto out of the protected region, or when
* merely falling off the end of the protected block or a 'catch'
* block.
*/
void gen_jsr_finally();
/* get my 'finally' label */
struct CTcCodeLabel *get_finally_lbl() const { return finally_lbl_; }
protected:
/* our 'finally' label */
struct CTcCodeLabel *finally_lbl_;
};
/* ------------------------------------------------------------------------ */
/*
* 'catch'
*/
class CTPNStmCatch: public CTPNStmCatchBase
{
public:
CTPNStmCatch() { }
/* generate code */
virtual void gen_code(int discard, int for_condition);
/* generate code for the 'catch' clause */
virtual void gen_code_catch(ulong protected_start_ofs,
ulong protected_end_ofs);
};
/* ------------------------------------------------------------------------ */
/*
* 'finally'
*/
class CTPNStmFinally: public CTPNStmFinallyBase
{
public:
CTPNStmFinally(CTPNStmEnclosing *enclosing,
int exc_local_id, int jsr_local_id)
: CTPNStmFinallyBase(enclosing, exc_local_id, jsr_local_id)
{
}
/* generate code */
virtual void gen_code(int discard, int for_condition);
/* generate code for the 'finally' clause */
virtual void gen_code_finally(ulong protected_start_ofs,
ulong protected_end_ofs,
class CTPNStmTry *try_stm);
/* check for transfer in via 'goto' statements */
virtual int check_enter_by_goto(class CTPNStmGoto *goto_stm,
class CTPNStmLabel *target);
};
/* ------------------------------------------------------------------------ */
/*
* 'throw' statement
*/
class CTPNStmThrow: public CTPNStmThrowBase
{
public:
CTPNStmThrow(class CTcPrsNode *expr)
: CTPNStmThrowBase(expr)
{
}
/* generate code */
virtual void gen_code(int discard, int for_condition);
};
/* ------------------------------------------------------------------------ */
/*
* 'goto' statement
*/
class CTPNStmGoto: public CTPNStmGotoBase
{
public:
CTPNStmGoto(const textchar_t *lbl, size_t lbl_len)
: CTPNStmGotoBase(lbl, lbl_len)
{
}
/* generate code */
virtual void gen_code(int discard, int for_condition);
};
/* ------------------------------------------------------------------------ */
/*
* 'dictionary' statement
*/
class CTPNStmDict: public CTPNStmDictBase
{
public:
CTPNStmDict(class CTcDictEntry *dict)
: CTPNStmDictBase(dict)
{
}
/* generate code */
virtual void gen_code(int, int) { }
};
/* ------------------------------------------------------------------------ */
/*
* Object Definition
*/
class CTPNStmObject: public CTPNStmObjectBase
{
public:
CTPNStmObject(class CTcSymObj *obj_sym, int is_class)
: CTPNStmObjectBase(obj_sym, is_class)
{
}
/* generate code */
virtual void gen_code(int discard, int for_condition);
/* check locals */
virtual void check_locals();
/*
* given the stream offset for the start of the object data in the
* stream, get information on the object from the stream data:
*
*. - get the number of properties in the stream data
*. - set the number of properties in the stream data, updating the
* stored data size in the metaclass header in the stream; returns
* the new data size
*. - get the number of superclasses in the stream data
*. - get a superclass object ID
*. - get the offset of the first property in the stream data
*. - get the offset of the property at the given index
*. - get the ID of the object's property at the given index
*. - set the ID of the object's property at the given index
*. - get the object flags from the tads-object header
*. - set the object flags in the tads-object heade
*/
static uint get_stream_prop_cnt(class CTcDataStream *stream,
ulong obj_ofs);
static size_t set_stream_prop_cnt(class CTcDataStream *stream,
ulong obj_ofs, uint prop_cnt);
static uint get_stream_sc_cnt(class CTcDataStream *stream,
ulong obj_ofs);
static vm_obj_id_t get_stream_sc(class CTcDataStream *stream,
ulong obj_ofs, uint sc_idx);
static void set_stream_sc(class CTcDataStream *stream,
ulong obj_ofs, uint sc_idx, vm_obj_id_t new_sc);
static ulong get_stream_first_prop_ofs(class CTcDataStream *stream,
ulong obj_ofs);
static ulong get_stream_prop_ofs(class CTcDataStream *stream,
ulong obj_ofs, uint prop_idx);
static vm_prop_id_t get_stream_prop_id(class CTcDataStream *stream,
ulong obj_ofs, uint prop_idx);
static enum vm_datatype_t
get_stream_prop_type(class CTcDataStream *stream,
ulong obj_ofs, uint prop_idx);
static ulong get_stream_prop_val_ofs(class CTcDataStream *stream,
ulong obj_ofs, uint prop_idx);
static void set_stream_prop_id(class CTcDataStream *stream,
ulong obj_ofs, uint prop_idx,
vm_prop_id_t new_id);
static uint get_stream_obj_flags(class CTcDataStream *stream,
ulong obj_ofs);
static void set_stream_obj_flags(class CTcDataStream *stream,
ulong obj_ofs, uint flags);
};
/*
* Property Value list entry
*/
class CTPNObjProp: public CTPNObjPropBase
{
public:
CTPNObjProp(class CTPNStmObject *obj_stm, class CTcSymProp *prop_sym,
class CTcPrsNode *expr, class CTPNCodeBody *code_body,
int is_static)
: CTPNObjPropBase(obj_stm, prop_sym, expr, code_body, is_static)
{
}
/* generate code */
virtual void gen_code(int discard, int for_condition);
/* check locals */
void check_locals();
};
/*
* Implicit constructor
*/
class CTPNStmImplicitCtor: public CTPNStmImplicitCtorBase
{
public:
CTPNStmImplicitCtor(class CTPNStmObject *obj_stm)
: CTPNStmImplicitCtorBase(obj_stm)
{
}
/* generate code */
virtual void gen_code(int discard, int for_condition);
};
#endif /* TCT3DRV_H */ |