Microsoft-3D-Movie-Maker/kauai/SRC/SCRCOM.H

277 lines
9.2 KiB
C++

/* Copyright (c) Microsoft Corporation.
Licensed under the MIT License. */
/* Copyright (c) Microsoft Corporation.
Licensed under the MIT License. */
/***************************************************************************
Author: ShonK
Project: Kauai
Reviewed:
Copyright (c) Microsoft Corporation
Script compiler declarations.
***************************************************************************/
#ifndef SCRCOM_H
#define SCRCOM_H
/***************************************************************************
Opcodes for scripts - these are the opcodes that can actually exist in
script. They don't necessarily map directly to the compiler's notion of
an operator.
***************************************************************************/
//if you change this enum, bump the version numbers below
enum
{
opNil,
//ops that act on variables come first
kopPushLocVar,
kopPopLocVar,
kopPushThisVar,
kopPopThisVar,
kopPushGlobalVar,
kopPopGlobalVar,
kopPushRemoteVar,
kopPopRemoteVar,
kopMinArray = 0x80,
kopPushLocArray = kopMinArray,
kopPopLocArray,
kopPushThisArray,
kopPopThisArray,
kopPushGlobalArray,
kopPopGlobalArray,
kopPushRemoteArray,
kopPopRemoteArray,
kopLimArray,
kopLimVarSccb = kopLimArray,
//ops that just act on the stack - no variables
// for the comments below, a is the top value on the execution stack
// b is the next to top value on the stack, and c is next on the stack
kopAdd = 0x100, // addition: b + a
kopSub, // subtraction: b - a
kopMul, // multiplication: b * a
kopDiv, // integer division: b / a
kopMod, // mod: b % a
kopNeg, // unary negation: -a
kopInc, // unary increment: a + 1
kopDec, // unary decrement: a - 1
kopShr, // shift right: b >> a
kopShl, // shift left: b << a
kopBOr, // bitwise or: b | a
kopBAnd, // bitwise and: b & a
kopBXor, // bitwise exclusive or: b ^ a
kopBNot, // unary bitwise not: ~a
kopLXor, // logical exclusive or: (b != 0) != (a != 0)
kopLNot, // unary logical not: !a
kopEq, // equality: b == a
kopNe, // not equal: b != a
kopGt, // greater than: b > a
kopLt, // less than: b < a
kopGe, // greater or equal: b >= a
kopLe, // less or equal: b <= a
kopAbs, // unary absolute value: LwAbs(a)
kopRnd, // a random number between 0 and a - 1 (inclusive)
kopMulDiv, // a * b / c without loss of precision
kopDup, // duplicates the top value
kopPop, // discards the top value
kopSwap, // swaps the top two values
kopRot, // rotates b values by a (c is placed a slots deeper in the stack)
kopRev, // reverses the next a slots on the stack
kopDupList, // duplicates the next a slots on the stack
kopPopList, // pops the next a slots on the stack
kopRndList, // picks one of the next a stack values at random
kopSelect, // picks the b'th entry among the next a stack values
kopGoEq, // if (b == a) jumps to label c
kopGoNe, // if (b != a) jumps to label c
kopGoGt, // if (b > a) jumps to label c
kopGoLt, // if (b < a) jumps to label c
kopGoGe, // if (b >= a) jumps to label c
kopGoLe, // if (b <= a) jumps to label c
kopGoZ, // if (a == 0) jumps to label b
kopGoNz, // if (a != 0) jumps to label b
kopGo, // jumps to label a
kopExit, // terminates the script
kopReturn, // terminates the script with return value a
kopSetReturn, // sets the return value to a
kopShuffle, // shuffles the numbers 0,1,..,a-1 for calls to NextCard
kopShuffleList, // shuffles the top a values for calls to NextCard
kopNextCard, // returns the next value from the shuffled values
// when all values have been used, the values are reshuffled
kopMatch, // a is a count of pairs, b is the key, c is the default value
// if b matches the first of any of the a pairs, the second
// value of the pair is pushed. if not, c is pushed.
kopPause, // pause the script (can be resumed later from C code)
kopCopyStr, // copy a string within the registry
kopMoveStr, // move a string within the registry
kopNukeStr, // delete a string from the registry
kopMergeStrs, // merge a string table into the registry
kopScaleTime, // scale the application clock
kopNumToStr, // convert a number to a decimal string
kopStrToNum, // convert a string to a number
kopConcatStrs, // concatenate two strings
kopLenStr, // return the number of characters in the string
kopCopySubStr, // copy a piece of the string
kopLimSccb
};
// structure to map a string to an opcode (post-fix)
struct SZOP
{
long op;
PSZ psz;
};
// structure to map a string to an opcode and argument information (in-fix)
struct AROP
{
long op;
PSZ psz;
long clwFixed; //number of fixed arguments
long clwVar; //number of arguments per variable group
long cactMinVar; //minimum number of variable groups
bool fVoid; //return a value?
};
// script version numbers
// if you bump these, also bump the numbers in scrcomg.h
const short kswCurSccb = 0xA; //this version
const short kswBackSccb = 0xA; //we can be read back to this version
const short kswMinSccb = 0xA; //we can read back to this version
// high byte of a label value
const byte kbLabel = 0xCC;
/***************************************************************************
Run-time variable name. The first 8 characters of the name are
significant. These 8 characters are packed into lu2 and the low
2 bytes of lu1, so clients can store the info in 6 bytes. The high
2 bytes of lu1 are used for array subscripts.
***************************************************************************/
struct RTVN
{
ulong lu1;
ulong lu2;
void SetFromStn(PSTN pstn);
void GetStn(PSTN pstn);
};
/***************************************************************************
The script compiler base class.
***************************************************************************/
typedef class SCCB *PSCCB;
#define SCCB_PAR BASE
#define kclsSCCB 'SCCB'
class SCCB : public SCCB_PAR
{
RTCLASS_DEC
ASSERT
MARKMEM
protected:
enum
{
fsccNil = 0,
fsccWantVoid = 1,
fsccTop = 2
};
PLEXB _plexb; // the lexer
PSCPT _pscpt; // the script we're building
PGL _pgletnTree; // expression tree (in-fix only)
PGL _pgletnStack; // token stack for building expression tree (in-fix only)
PGL _pglcstd; // control structure stack (in-fix only)
PGST _pgstNames; // encountered names (in-fix only)
PGST _pgstLabel; // encountered labels, sorted, extra long is label value
PGST _pgstReq; // label references, extra long is address of reference
long _ilwOpLast; // address of the last opcode
long _lwLastLabel; // for internal temporary labels
bool _fError: 1; // whether an error has occured during compiling
bool _fForceOp: 1; // when pushing a constant, make sure the last long
// is an opcode (because a label references this loc)
bool _fHitEnd: 1; // we've exhausted our input stream
long _ttEnd; // stop compiling when we see this
PMSNK _pmsnk; // the message sink - for error reporting when compiling
bool _FInit(PLEXB plexb, bool fInFix, PMSNK pmsnk);
void _Free(void);
// general compilation methods
void _PushLw(long lw);
void _PushString(PSTN pstn);
void _PushOp(long op);
void _EndOp(void);
void _PushVarOp(long op, RTVN *prtvn);
bool _FFindLabel(PSTN pstn, long *plwLoc);
void _AddLabel(PSTN pstn);
void _PushLabelRequest(PSTN pstn);
void _AddLabelLw(long lw);
void _PushLabelRequestLw(long lw);
virtual void _ReportError(PSZ psz);
virtual short _SwCur(void);
virtual short _SwBack(void);
virtual short _SwMin(void);
virtual bool _FGetTok(PTOK ptok);
// post-fix compiler routines
virtual void _CompilePost(void);
long _OpFromStnRgszop(PSTN pstn, SZOP *prgszop);
virtual long _OpFromStn(PSTN pstn);
bool _FGetStnFromOpRgszop(long op, PSTN pstn, SZOP *prgszop);
virtual bool _FGetStnFromOp(long op, PSTN pstn);
// in-fix compiler routines
virtual void _CompileIn(void);
bool _FResolveToOpl(long opl, long oplMin, long *pietn);
void _EmitCode(long ietnTop, ulong grfscc, long *pclwArg);
void _EmitVarAccess(long ietn, RTVN *prtvn,
long *popPush, long *popPop, long *pclwStack);
virtual bool _FGetOpFromName(PSTN pstn, long *pop, long *pclwFixed,
long *pclwVar, long *pcactMinVar, bool *pfVoid);
bool _FGetArop(PSTN pstn, AROP *prgarop, long *pop, long *pclwFixed,
long *pclwVar, long *pcactMinVar, bool *pfVoid);
void _PushLabelRequestIetn(long ietn);
void _AddLabelIetn(long ietn);
void _PushOpFromName(long ietn, ulong grfscc, long clwArg);
void _GetIstnNameFromIetn(long ietn, long *pistn);
void _GetRtvnFromName(long istn, RTVN *prtvn);
bool _FKeyWord(PSTN pstn);
void _GetStnFromIstn(long istn, PSTN pstn);
void _AddNameRef(PSTN pstn, long *pistn);
long _CstFromName(long ietn);
void _BeginCst(long cst, long ietn);
bool _FHandleCst(long ietn);
bool _FAddToTree(struct ETN *petn, long *pietn);
bool _FConstEtn(long ietn, long *plw);
bool _FCombineConstValues(long op, long lw1, long lw2, long *plw);
void _SetDepth(struct ETN *petn, bool fCommute = fFalse);
void _PushStringIstn(long istn);
public:
SCCB(void);
~SCCB(void);
virtual PSCPT PscptCompileLex(PLEXB plexb, bool fInFix, PMSNK pmsnk,
long ttEnd = ttNil);
virtual PSCPT PscptCompileFil(PFIL pfil, bool fInFix, PMSNK pmsnk);
virtual PSCPT PscptCompileFni(FNI *pfni, bool fInFix, PMSNK pmsnk);
virtual bool FDisassemble(PSCPT pscpt, PMSNK pmsnk, PMSNK pmsnkError = pvNil);
};
#endif //!SCRCOM_H