00001
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026 #ifndef NL_CODAGE_H
00027 #define NL_CODAGE_H
00028 #ifdef NL_OS_WINDOWS
00029 #pragma warning (disable: 4620)
00030 #pragma warning (disable: 4621)
00031 #endif
00032
00033
00034 #include "nel/ai/script/virtual_op_code.h"
00035 #include "nel/ai/script/context_debug.h"
00036
00037 namespace NLAISCRIPT
00038 {
00039
00040
00052 class CIndexStackPointer
00053 {
00054 protected:
00056 int _Sp;
00057
00058 private:
00060 std::list<int> _Marque;
00061
00062 public:
00063 CIndexStackPointer():_Sp(0)
00064 {
00065 }
00066
00068 virtual operator int ()
00069 {
00070 return _Sp;
00071 }
00072
00074 virtual void operator ++ ( int )
00075 {
00076 _Sp ++;
00077 }
00078
00080 virtual void operator -- ( int )
00081 {
00082 _Sp --;
00083 }
00084
00086 virtual void operator += (int k)
00087 {
00088 _Sp += k;
00089 }
00090
00092 virtual void operator -= (int k)
00093 {
00094 _Sp -= k;
00095 }
00096
00098 virtual void pushMark()
00099 {
00100 _Marque.push_back(_Sp);
00101 }
00102
00104 virtual int popMark()
00105 {
00106 int i = 0;
00107 i = _Marque.back();
00108 _Marque.pop_back();
00109 return i;
00110 }
00111
00112 virtual int markSize()
00113 {
00114 return _Marque.size();
00115 }
00116
00118 virtual int mark()
00119 {
00120 return _Marque.back();
00121 }
00122
00124 void clear()
00125 {
00126 _Sp = 0;
00127 _Marque.clear();
00128 }
00129
00130 virtual ~CIndexStackPointer()
00131 {
00132 }
00133
00134 };
00135
00136
00148 class CStackPointer: public CIndexStackPointer
00149 {
00150 private:
00152 int _Count;
00154 int _Bp;
00155
00157 int _Sh;
00158
00160 std::list<int> _Decalage;
00162 std::list<int> _Shift;
00163
00165 NLAIAGENT::IObjectIA **_Stack;
00166
00167 public:
00168 CStackPointer(int count = 1024*8)
00169 {
00170 _Count = count;
00171 _Stack = new NLAIAGENT::IObjectIA *[ count ];
00172 for(int i = 0; i < _Count; i ++)
00173 {
00174 _Stack[i] = NULL;
00175 }
00176 _Sp = 0;
00177 _Bp = 0;
00178 _Sh = 0;
00179 }
00180
00182 NLAIAGENT::IObjectIA *&operator [] (int i)
00183 {
00184 #ifdef NL_DEBUG
00185 if ( (_Sp + _Bp + _Sh) >= _Count )
00186 {
00187 throw NLAIE::CExceptionIndexError();
00188 }
00189 #endif
00190 return _Stack[i + _Bp + _Sh];
00191 }
00192
00194 operator NLAIAGENT::IObjectIA *()
00195 {
00196 #ifdef NL_DEBUG
00197 if ( (_Sp + _Bp + _Sh) >= _Count )
00198 {
00199 throw NLAIE::CExceptionIndexError();
00200 }
00201 #endif
00202 return _Stack[_Sp + _Bp + _Sh];
00203 }
00204
00206 virtual void operator -- (int)
00207 {
00208 #ifdef NL_DEBUG
00209 if ( (_Sp + _Bp + _Sh) >= _Count )
00210 {
00211 throw NLAIE::CExceptionIndexError();
00212 }
00213 #endif
00214 int i = _Sp + _Bp + _Sh;
00215 if(_Stack[i])
00216 {
00217 _Stack[i]->release();
00218 _Stack[i] = NULL;
00219 }
00220 _Sp --;
00221 }
00222
00224 virtual void operator -= (int k)
00225 {
00226 #ifdef NL_DEBUG
00227 if ( (_Sp + _Bp + _Sh) >= _Count )
00228 {
00229 throw NLAIE::CExceptionIndexError();
00230 }
00231 #endif
00232 int n = _Sp + _Bp + _Sh;
00233 for(int i = n - k; i < n; i ++)
00234 {
00235 if(_Stack[i])
00236 {
00237 _Stack[i]->release();
00238 _Stack[i] = NULL;
00239 }
00240 }
00241 _Sp -= k;
00242 }
00243
00245 void addStack(int bp)
00246 {
00247 _Bp += bp;
00248 _Sp -= bp;
00249 _Decalage.push_back(bp);
00250 }
00251
00253 void restoreStack()
00254 {
00255 int k = _Bp;
00256 _Bp -= _Decalage.back();
00257 _Decalage.pop_back();
00258 _Sp += k;
00259
00260 *this -= k;
00261 }
00262
00264 void setShift(int s)
00265 {
00266 _Sh += s;
00267 _Sp -= s;
00268 _Shift.push_back(s);
00269 }
00270
00272 void restoreShift()
00273 {
00274 int s = _Shift.back();
00275 _Shift.pop_back();
00276 _Sp += s;
00277 _Sh -= s;
00278 }
00279
00280
00282 bool restoreStackState()
00283 {
00284 return _Decalage.size() != 0;
00285 }
00286
00288 bool restoreShiftState()
00289 {
00290 return _Shift.size() != 0;
00291 }
00292
00293 ~CStackPointer()
00294 {
00295 if(_Stack)
00296 {
00297
00298 for(int i = _Bp; i < (_Sp + _Bp); i ++)
00299 {
00300 if(_Stack[i] != NULL)
00301 {
00302 _Stack[i]->release();
00303 _Stack[i] = NULL;
00304 }
00305 }
00306 delete []_Stack;
00307 _Stack = NULL;
00308 }
00309 }
00310 };
00311
00312
00313 class CCodeBrancheRun;
00314 typedef CStackPointer tStackRef;
00315 typedef CCodeBrancheRun tCodeRef;
00316
00317
00330 class CCodeContext : public NLAIAGENT::IObjectIA
00331 {
00332 public:
00333
00335 tStackRef &Stack;
00337 tStackRef &Heap;
00339 tCodeRef *Code;
00341 const NLAIAGENT::IObjectIA *Self;
00343 NLAIC::IIO *InputOutput;
00345 std::list<NLAIAGENT::IObjectIA *> Param;
00347 CContextDebug ContextDebug;
00348
00349 public:
00351 static const NLAIC::CIdentType IdCodeContext;
00352
00353 public:
00354
00355 CCodeContext(tStackRef &stackMem,tStackRef &heapMem,tCodeRef *codeMem,const NLAIAGENT::IObjectIA *thisClass,NLAIC::IIO *io):
00356 Stack(stackMem),
00357 Heap(heapMem),
00358 Code(codeMem),
00359 Self(thisClass),
00360 InputOutput(io)
00361 {
00362 if(InputOutput != NULL) InputOutput->incRef();
00363 }
00364
00366 void init()
00367 {
00368 ContextDebug.init();
00369 }
00370
00372 void setIO(NLAIC::IIO *io)
00373 {
00374 if(InputOutput != NULL) InputOutput->release();
00375 InputOutput = io;
00376 }
00377
00379
00380 const NLAIC::CIdentType &getType(void) const
00381 {
00382 return IdCodeContext;
00383 }
00384 const NLAIC::IBasicType *clone(void) const
00385 {
00386 CCodeContext *x = new CCodeContext(Stack,Heap,Code,Self,InputOutput);
00387 return x;
00388 }
00389 const NLAIC::IBasicType *newInstance(void) const
00390 {
00391 return clone();
00392 }
00393 void getDebugString(std::string &t) const
00394 {
00395 t = NLAIC::stringGetBuild("CCodeContext");
00396 }
00397 void save(NLMISC::IStream &f)
00398 {
00399 }
00400 void load(NLMISC::IStream &f)
00401 {
00402 }
00404
00406
00407 bool isEqual(const class NLAIAGENT::IBasicObjectIA &) const
00408 {
00409 return true;
00410 }
00412
00414
00415 const NLAIAGENT::IObjectIA::CProcessResult &run(void)
00416 {
00417 return NLAIAGENT::IObjectIA::ProcessRun;;
00418 }
00420
00421 ~CCodeContext()
00422 {
00423 if(InputOutput != NULL) InputOutput->release();
00424 }
00425 };
00426
00427 class IConstraint;
00428
00429
00442 class CBagOfCode
00443 {
00444 private:
00445 IOpCode *_Opcode;
00446 std::list<IConstraint *> _Constraint;
00447
00448 public:
00449 CBagOfCode(IOpCode *opcode):_Opcode(opcode)
00450 {
00451
00452 }
00453
00455 operator IOpCode *() const
00456 {
00457 return _Opcode;
00458 }
00459
00461 void setCode(IOpCode *op)
00462 {
00463 _Opcode = op;
00464 }
00465
00467 void addConstraint(IConstraint *c)
00468 {
00469 _Constraint.push_back(c);
00470 }
00471
00473 void addConstraint(CBagOfCode *b)
00474 {
00475 std::list<IConstraint *>::iterator it = b->_Constraint.begin();
00476 while(it != b->_Constraint.end())
00477 {
00478 _Constraint.push_back(*it++);
00479 }
00480 }
00481
00484 void setConstraintIndex(int i,CCodeBrancheRun *c);
00485
00486 ~CBagOfCode(){}
00487
00488
00489 };
00490
00491 typedef std::list<CBagOfCode *> tListCode;
00492 typedef std::list<CBagOfCode *>::iterator tListCodeIter;
00493
00494
00504 class CCodeBrancheRun: public ICodeBranche
00505 {
00506 public:
00507 static NLAIC::IIO *InputOutput;
00508
00509 protected:
00511 IOpCode **_TableCode;
00513 int _Ip;
00515 int _Count;
00517 NLAIAGENT::IObjectIA::CProcessResult _RunState;
00518
00519 protected:
00520
00522 void del()
00523 {
00524 if(_TableCode != NULL)
00525 {
00526 for(int i = 0 ;i < _Count; i ++)
00527 {
00528 if(_TableCode[i]) _TableCode[i]->release();
00529 }
00530 delete []_TableCode;
00531 }
00532 }
00533
00534 public:
00535 static const NLAIC::CIdentType IdCodeBrancheRun;
00536 public:
00537
00538
00540 CCodeBrancheRun(const CCodeBrancheRun &l):_TableCode(NULL),_Ip(0),_Count(l._Count)
00541 {
00542 _TableCode = new IOpCode * [_Count];
00543 for(int i = 0 ;i < _Count; i ++)
00544 {
00545 _TableCode[i] = (IOpCode *)l._TableCode[i];
00546 _TableCode[i]->incRef();
00547 }
00548 }
00549
00551 CCodeBrancheRun(const tListCode &l):
00552 _TableCode(NULL),_Ip(0),_Count(l.size())
00553 {
00554 initCode(l);
00555 }
00556
00558 CCodeBrancheRun(int N,const IOpCode &op);
00560 CCodeBrancheRun(int N);
00561
00563 CCodeBrancheRun(NLMISC::IStream &is):_TableCode(NULL),_Ip(0),_Count(0)
00564 {
00565 load(is);
00566 }
00567
00568 virtual ~CCodeBrancheRun()
00569 {
00570 del();
00571 }
00572
00573
00574 void initCode(const tListCode &l)
00575 {
00576 del();
00577 _Count = l.size();
00578
00579 tListCode::const_iterator i;
00580 _TableCode = new IOpCode * [l.size()];
00581 i = l.begin();
00582 int k = 0;
00583 while(i != l.end())
00584 {
00585 _TableCode[k ++] = (IOpCode *)*i++;
00586 }
00587 }
00588
00589 void initCode(const CCodeBrancheRun &l)
00590 {
00591 del();
00592
00593 _Ip = 0;
00594 _Count = l._Count;
00595
00596 _TableCode = new IOpCode * [_Count];
00597 for(int i = 0; i < _Count;i ++)
00598 {
00599 _TableCode[i ++] = (IOpCode *)l._TableCode[i]->clone();
00600 }
00601 }
00602
00604 IOpCode *&operator [] (int i)
00605 {
00606 return _TableCode[i];
00607 }
00608
00610 void operator = (uint32 l)
00611 {
00612 _Ip = l;
00613 }
00614
00616 void operator += (uint32 l)
00617 {
00618 _Ip += l;
00619 }
00620
00622 operator uint32 ()
00623 {
00624 return _Ip;
00625 }
00626
00627 void init()
00628 {
00629 _Ip = 0;
00630 }
00631
00633 IOpCode &nextCode()
00634 {
00635 return *_TableCode[_Ip++];
00636 }
00637
00639
00640 virtual const NLAIAGENT::IObjectIA::CProcessResult &run(NLAIAGENT::IObjectIA &self);
00641 virtual const NLAIAGENT::IObjectIA::CProcessResult &run(CCodeContext &);
00642
00643 NLAIAGENT::TProcessStatement runOpCode(CCodeContext &context);
00644 void getDebugResult(std::string &str,CCodeContext &context) const;
00646
00648
00649 void save(NLMISC::IStream &f);
00650 void load(NLMISC::IStream &f);
00651 void getDebugString(std::string &) const;
00652 const NLAIC::CIdentType &getType() const;
00653 const NLAIC::IBasicType *clone() const
00654 {
00655 NLAIC::IBasicType *x = new CCodeBrancheRun(*this);
00656 return x;
00657 }
00658 const NLAIC::IBasicType *newInstance() const;
00659
00661
00663
00664 bool isEqual(const NLAIAGENT::IBasicObjectIA &a) const{ return true;}
00666
00668
00669 virtual const NLAIAGENT::IObjectIA::CProcessResult &run();
00671
00672 };
00673 }
00674 #include "nel/ai/script/opcode.h"
00675
00676 #endif
00677