00001 #ifndef _GSCRIPTING_PRIV_H_
00002 #define _GSCRIPTING_PRIV_H_
00003
00004 #include <stdio.h>
00005 #include "GScripting.h"
00006 #include "GRefCount.h"
00007
00008
00009 #define _i(name, opcode, desc) \
00010 name = opcode,
00011
00012 #define AllInstructions \
00013 _i(INop, 0, "Nop") \
00014 _i(IAssign, OpAssign, "OpAssign") \
00015 _i(IPlus, OpPlus, "OpPlus") \
00016 _i(IUnaryPlus, OpUnaryPlus, "OpUnaryPlus") \
00017 _i(IMinus, OpMinus, "OpMinus") \
00018 _i(IUnaryMinus, OpUnaryMinus, "OpUnaryMinus") \
00019 _i(IMul, OpMul, "OpMul") \
00020 _i(IDiv, OpDiv, "OpDiv") \
00021 _i(IMod, OpMod, "OpMod") \
00022 _i(ILessThan, OpLessThan, "OpLessThan") \
00023 _i(ILessThanEqual, OpLessThanEqual, "OpLessThanEqual") \
00024 _i(IGreaterThan, OpGreaterThan, "OpGreaterThan") \
00025 _i(IGreaterThanEqual, OpGreaterThanEqual, "OpGreaterThanEqual") \
00026 _i(IEquals, OpEquals, "OpEquals") \
00027 _i(INotEquals, OpNotEquals, "OpNotEquals") \
00028 _i(IPlusEquals, OpPlusEquals, "OpPlusEquals") \
00029 _i(IMinusEquals, OpMinusEquals, "OpMinusEquals") \
00030 _i(IMulEquals, OpMulEquals, "OpMulEquals") \
00031 _i(IDivEquals, OpDivEquals, "OpDivEquals") \
00032 _i(IPostInc, OpPostInc, "OpPostInc") \
00033 _i(IPostDec, OpPostDec, "OpPostDec") \
00034 _i(IPreInc, OpPreInc, "OpPreInc") \
00035 _i(IPreDec, OpPreDec, "OpPreDec") \
00036 _i(IAnd, OpAnd, "OpAnd") \
00037 _i(IOr, OpOr, "OpOr") \
00038 _i(INot, OpNot, "OpNot") \
00039 \
00040 \
00041 _i(ICallScript, 64, "CallScript") \
00042 \
00043 _i(ICallMethod, 65, "CallMethod") \
00044 \
00045 _i(ICallSystem, 66, "CallSystem") \
00046 _i(IDomGet, 67, "DomGet") \
00047 _i(IDomSet, 68, "DomSet") \
00048 _i(IPush, 69, "Push") \
00049 _i(IPop, 70, "Pop") \
00050 _i(IJump, 71, "Jump") \
00051 _i(IJumpZero, 72, "JumpZ") \
00052 _i(IArrayGet, 73, "ArrayGet") \
00053 _i(IArraySet, 74, "ArraySet") \
00054 _i(IRet, 75, "Return") \
00055
00056 enum GInstruction {
00057 AllInstructions
00058 };
00059
00060 enum OperatorType
00061 {
00062 OpPrefix,
00063 OpInfix,
00064 OpPostfix,
00065 };
00066
00067 extern char16 sChar[];
00068 extern char16 sInt[];
00069 extern char16 sUInt[];
00070 extern char16 sInt32[];
00071 extern char16 sUInt32[];
00072 extern char16 sInt64[];
00073 extern char16 sHWND[];
00074 extern char16 sDWORD[];
00075 extern char16 sLPTSTR[];
00076 extern char16 sLPCTSTR[];
00077 extern char16 sElse[];
00078 extern char16 sIf[];
00079 extern char16 sFunction[];
00080 extern char16 sExtern[];
00081 extern char16 sFor[];
00082 extern char16 sWhile[];
00083 extern char16 sReturn[];
00084 extern char16 sInclude[];
00085 extern char16 sDefine[];
00086 extern char16 sStruct[];
00087
00088 extern char16 sHash[];
00089 extern char16 sPeriod[];
00090 extern char16 sComma[];
00091 extern char16 sSemiColon[];
00092 extern char16 sStartRdBracket[];
00093 extern char16 sEndRdBracket[];
00094 extern char16 sStartSqBracket[];
00095 extern char16 sEndSqBracket[];
00096 extern char16 sStartCurlyBracket[];
00097 extern char16 sEndCurlyBracket[];
00098
00099 extern char *InstToString(GInstruction i);
00100
00101
00102
00103
00104
00105
00106
00107
00108
00109
00110
00111
00112
00113
00114
00115 #define MAX_REGISTER 8
00116 #define SCOPE_REGISTER 0
00117 #define SCOPE_LOCAL 1
00118 #define SCOPE_GLOBAL 2
00119
00121 struct GVarRef
00122 {
00124 unsigned Scope : 8;
00126 int Index : 24;
00127
00128 bool Valid()
00129 {
00130 return Index >= 0;
00131 }
00132
00133 void Empty()
00134 {
00135 Scope = 0;
00136 Index = -1;
00137 }
00138
00139 bool IsReg()
00140 {
00141 return Scope == SCOPE_REGISTER && Index >= 0 && Index < MAX_REGISTER;
00142 }
00143
00144 void SetReg(int i)
00145 {
00146 Scope = SCOPE_REGISTER;
00147 Index = i;
00148 }
00149
00150 bool operator ==(GVarRef &r)
00151 {
00152 return r.Scope == Scope && r.Index == Index;
00153 }
00154
00155 bool operator !=(GVarRef &r)
00156 {
00157 return r.Scope != Scope || r.Index != Index;
00158 }
00159
00160 const char *GetStr()
00161 {
00162 if (Index < 0)
00163 return "NoRef";
00164
00165 static char Buf[4][16];
00166 static int Cur = 0;
00167 static char Names[] = {'R', 'L', 'G'};
00168 char *b = Buf[Cur++];
00169 if (Cur >= 4) Cur = 0;
00170
00171 LgiAssert(Scope <= SCOPE_GLOBAL);
00172 sprintf(b, "%c%i", Names[Scope], Index);
00173 return b;
00174 }
00175 };
00176
00177 union GPtr
00178 {
00179 uint8 *u8;
00180 uint16 *u16;
00181 uint32 *u32;
00182 int8 *i8;
00183 int16 *i16;
00184 int32 *i32;
00185 double *dbl;
00186 float *flt;
00187 GVarRef *r;
00188 GHostFunc **fn;
00189 };
00190
00191 class SystemFunctions;
00192
00193 class GVariables : public GArray<GVariant>
00194 {
00195 friend class GVirtualMachinePriv;
00196
00197 GHashTbl<char*,int> Lut;
00198
00199 public:
00200 int Scope;
00201 int NullIndex;
00202
00203 GVariables(int scope)
00204 {
00205 Scope = scope;
00206 NullIndex = -1;
00207 }
00208
00209 int Var(char *n, bool create = false)
00210 {
00211 int p = Lut.Find(n);
00212 if (p)
00213 {
00214 return p - 1;
00215 }
00216
00217 if (create)
00218 {
00219 int Len = Length();
00220
00221 Lut.Add(n, Len + 1);
00222 Length(Len + 1);
00223
00224 return Len;
00225 }
00226
00227 return -1;
00228 }
00229 };
00230
00231 struct GFunctionInfo : public GRefCount
00232 {
00233 static int _Infos;
00234
00235 int StartAddr;
00236 int FrameSize;
00237 GVariant Name;
00238 GArray<GVariant> Params;
00239
00240 GFunctionInfo()
00241 {
00242 StartAddr = 0;
00243 FrameSize = 0;
00244
00245 }
00246
00247 ~GFunctionInfo()
00248 {
00249
00250 }
00251
00252 GFunctionInfo &operator =(GFunctionInfo &f)
00253 {
00254 StartAddr = f.StartAddr;
00255 FrameSize = f.FrameSize;
00256 Name = f.Name;
00257 for (int i=0; i<f.Params.Length(); i++)
00258 {
00259 Params[i] = f.Params[i];
00260 }
00261 return *this;
00262 }
00263 };
00264
00265 class GTypeDef : public GDom
00266 {
00267 friend class GCompilerPriv;
00268 friend class GVirtualMachinePriv;
00269
00270 struct GMember
00271 {
00272 int Offset;
00273 int Size;
00274 bool Pointer;
00275 int Array;
00276 GVariantType Type;
00277 GTypeDef *Nest;
00278
00279 GMember()
00280 {
00281 Offset = 0;
00282 Size = 0;
00283 Type = GV_NULL;
00284 Pointer = false;
00285 Array = 0;
00286 Nest = 0;
00287 }
00288 };
00289
00290 int Size;
00291 GVariant Name;
00292 GHashTbl<const char*, GMember*> Members;
00293
00294 public:
00295 char *Object;
00296
00297 GTypeDef(char16 *n)
00298 {
00299 Name = n;
00300 Size = 0;
00301 Object = 0;
00302 }
00303
00304 int Sizeof() { return Size; }
00305 bool GetVariant(const char *Name, GVariant &Value, char *Arr = 0);
00306 bool SetVariant(const char *Name, GVariant &Value, char *Arr = 0);
00307 };
00308
00310 class GCompiledCode
00311 {
00312 friend class GCompilerPriv;
00313 friend class GVirtualMachinePriv;
00314
00315 GVariables Globals;
00316 GArray<uint8> ByteCode;
00317 GArray< GAutoRefPtr<GFunctionInfo> > Methods;
00318 GHashTbl<char16*, GTypeDef*> Types;
00319 GHashTbl<int, int> Debug;
00320
00321 public:
00322 GCompiledCode();
00323 GCompiledCode(GCompiledCode ©);
00324 ~GCompiledCode();
00325
00327 int Length() { return ByteCode.Length(); }
00328 GCompiledCode &operator =(GCompiledCode &c);
00330 GFunctionInfo *GetMethod(const char *Name, bool Create = false);
00332 GVariant *Set(char *Name, GVariant &v);
00334 GTypeDef *GetType(char16 *Name) { return Types.Find(Name); }
00335 };
00336
00337 class GCompileTools
00338 {
00339 protected:
00340 OperatorType OpType(GOperator o)
00341 {
00342 switch (o)
00343 {
00344 case OpUnaryPlus:
00345 case OpUnaryMinus:
00346 case OpPreInc:
00347 case OpPreDec:
00348 case OpNot:
00349 return OpPrefix;
00350
00351 case OpPostInc:
00352 case OpPostDec:
00353 return OpPostfix;
00354 }
00355
00356 return OpInfix;
00357 }
00358
00359 int GetPrecedence(GOperator o)
00360 {
00361
00362
00363 switch (o)
00364 {
00365 case OpAssign:
00366 case OpMinusEquals:
00367 case OpPlusEquals:
00368 case OpMulEquals:
00369 case OpDivEquals:
00370 return 16;
00371
00372 case OpAnd:
00373 return 13;
00374
00375 case OpOr:
00376 return 14;
00377
00378 case OpEquals:
00379 case OpNotEquals:
00380 return 9;
00381
00382 case OpLessThan:
00383 case OpLessThanEqual:
00384 case OpGreaterThan:
00385 case OpGreaterThanEqual:
00386 return 8;
00387
00388 case OpPlus:
00389 case OpMinus:
00390 return 6;
00391
00392 case OpMul:
00393 case OpDiv:
00394 case OpMod:
00395 return 5;
00396
00397 case OpUnaryPlus:
00398 case OpUnaryMinus:
00399 case OpPreInc:
00400 case OpPreDec:
00401 case OpNot:
00402 return 3;
00403
00404 case OpPostInc:
00405 case OpPostDec:
00406 return 2;
00407 }
00408
00409 LgiAssert(!"Really?");
00410 return -1;
00411 }
00412
00413 GOperator IsOp(char16 *s, int PrevIsOp)
00414 {
00415 if (!s) return OpNull;
00416
00417 if (s[0] != 0 AND !s[1])
00418 {
00419
00420 switch (*s)
00421 {
00422 case '=': return OpAssign;
00423 case '*': return OpMul;
00424 case '/': return OpDiv;
00425 case '<': return OpLessThan;
00426 case '>': return OpGreaterThan;
00427 case '%': return OpMod;
00428 case '!': return OpNot;
00429 case '+':
00430 {
00431 if (PrevIsOp == 0)
00432 return OpPlus;
00433
00434 return OpUnaryPlus;
00435 }
00436 case '-':
00437 {
00438 if (PrevIsOp == 0)
00439 return OpMinus;
00440
00441 return OpUnaryMinus;
00442 }
00443 }
00444 }
00445 else if (s[0] != 0 AND s[1] == '=' AND !s[2])
00446 {
00447
00448 switch (*s)
00449 {
00450 case '!': return OpNotEquals;
00451 case '=': return OpEquals;
00452 case '<': return OpLessThanEqual;
00453 case '>': return OpGreaterThanEqual;
00454
00455 case '+': return OpPlusEquals;
00456 case '-': return OpMinusEquals;
00457 case '*': return OpMulEquals;
00458 case '/': return OpDivEquals;
00459 }
00460 }
00461 else if (s[0] == '+' AND s[1] == '+' AND !s[2])
00462 {
00463 if (PrevIsOp == 0)
00464 return OpPostInc;
00465
00466 return OpPreInc;
00467 }
00468 else if (s[0] == '-' AND s[1] == '-' AND !s[2])
00469 {
00470 if (PrevIsOp == 0)
00471 return OpPostDec;
00472
00473 return OpPreDec;
00474 }
00475 else if (s[0] == '&' AND s[1] == '&' AND !s[2])
00476 {
00477 return OpAnd;
00478 }
00479 else if (s[0] == '|' AND s[1] == '|' AND !s[2])
00480 {
00481 return OpOr;
00482 }
00483
00484 return OpNull;
00485 }
00486
00487 };
00488
00490 class GCompiler : public GScriptUtils
00491 {
00492 class GCompilerPriv *d;
00493
00494 public:
00496 GCompiler
00497 (
00499 SystemFunctions *sf
00500 );
00501 ~GCompiler();
00502
00504 GCompiledCode *Compile(GScriptContext *Context, char *FileName, char *Script, GStream *Log = 0, GCompiledCode *previous = 0);
00505 };
00506
00508 class GVirtualMachine : public GScriptUtils
00509 {
00510 class GVirtualMachinePriv *d;
00511
00512 public:
00513 GVirtualMachine(GScriptContext *Context);
00514 ~GVirtualMachine();
00515
00517 bool Execute
00518 (
00520 GCompiledCode *Code,
00522 GStream *Log = 0
00523 );
00524
00526 bool ExecuteFunction
00527 (
00529 GCompiledCode *Code,
00531 GFunctionInfo *Func,
00533 ArgumentArray &Args,
00535 GVariant *Ret,
00537 GStream *Log = 0
00538 );
00539 };
00540
00542 class SystemFunctions : public GScriptContext
00543 {
00544 GScriptEngine *Engine;
00545
00546 GView *CastGView(GVariant &v);
00547
00548 public:
00549 SystemFunctions()
00550 {
00551 Engine = 0;
00552 }
00553
00554 void SetEngine(GScriptEngine *Eng)
00555 {
00556 Engine = Eng;
00557 }
00558
00559 char *GetIncludeFile(char *FileName) { return 0; }
00560 GHostFunc *GetCommands();
00561
00562
00566 bool Strchr(GVariant *Ret, ArgumentArray &Args);
00570 bool Strstr(GVariant *Ret, ArgumentArray &Args);
00574 bool Strcmp(GVariant *Ret, ArgumentArray &Args);
00577 bool Substr(GVariant *Ret, ArgumentArray &Args);
00581 bool LoadString(GVariant *Ret, ArgumentArray &Args);
00583 bool Sprintf(GVariant *Ret, ArgumentArray &Args);
00585 bool FormatSize(GVariant *Ret, ArgumentArray &Args);
00587 bool Tokenize(GVariant *Ret, ArgumentArray &Args);
00588
00589
00590 bool New(GVariant *Ret, ArgumentArray &Args);
00591 bool Delete(GVariant *Ret, ArgumentArray &Args);
00592
00593
00595 bool NewHashTable(GVariant *Ret, ArgumentArray &Args);
00597 bool NewList(GVariant *Ret, ArgumentArray &Args);
00599 bool DeleteElement(GVariant *Ret, ArgumentArray &Args);
00600
00601
00603 bool ReadTextFile(GVariant *Ret, ArgumentArray &Args);
00605 bool WriteTextFile(GVariant *Ret, ArgumentArray &Args);
00610 bool SelectFiles(GVariant *Ret, ArgumentArray &Args);
00619 bool ListFiles(GVariant *Ret, ArgumentArray &Args);
00621 bool DeleteFile(GVariant *Ret, ArgumentArray &Args);
00622
00623
00625 bool Sleep(GVariant *Ret, ArgumentArray &Args);
00627 bool ClockTick(GVariant *Ret, ArgumentArray &Args);
00629 bool Now(GVariant *Ret, ArgumentArray &Args);
00630
00631
00634 bool Execute(GVariant *Ret, ArgumentArray &Args);
00637 bool System(GVariant *Ret, ArgumentArray &Args);
00640 bool GetInputDlg(GVariant *Ret, ArgumentArray &Args);
00641 };
00642
00643 #endif