00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00032 #ifndef _UCOMMON_SCRIPT_H_
00033 #define _UCOMMON_SCRIPT_H_
00034
00035 #ifndef _UCOMMON_CONFIG_H_
00036 #include <ucommon/platform.h>
00037 #endif
00038
00039 #ifndef _UCOMMON_UCOMMON_H_
00040 #include <ucommon/ucommon.h>
00041 #endif
00042
00043 NAMESPACE_UCOMMON
00044
00050 class __EXPORT script : public CountedObject, private memalloc
00051 {
00052 public:
00053 class interp;
00054 class header;
00055 class checks;
00056
00060 typedef bool (script::interp::*method_t)(void);
00061
00068 typedef struct line {
00069 struct line *next;
00070 union {
00071 const char *cmd;
00072 header *sub;
00073 };
00074 char **argv;
00075 unsigned short loop, argc;
00076 unsigned lnum, mask;
00077 method_t method;
00078 } line_t;
00079
00083 typedef const char *(*check_t)(script *img, script::header *scr, script::line_t *line);
00084
00090 typedef struct keyword
00091 {
00092 public:
00093 const char *name;
00094 method_t method;
00095 check_t check;
00096 struct keyword *next;
00097 } keyword_t;
00098
00106 class __EXPORT strict : public LinkedObject
00107 {
00108 public:
00109 const char *id;
00110
00111 public:
00112 static bool find(script *img, header *scr, const char *id);
00113 static void createVar(script *img, header *scr, const char *id);
00114 static void createSym(script *img, header *scr, const char *id);
00115 static void createAny(script *img, header *scr, const char *id);
00116 static void createGlobal(script *img, const char *id);
00117
00118 void put(FILE *fp, const char *header);
00119 };
00120
00128 class __EXPORT symbol : public LinkedObject
00129 {
00130 public:
00131 const char *name;
00132 char *data;
00133 unsigned size;
00134 header *scope;
00135 };
00136
00142 class __EXPORT event : public LinkedObject
00143 {
00144 public:
00145 line_t *first;
00146 const char *name;
00147 };
00148
00152 typedef event event_t;
00153
00162 class __EXPORT header : public LinkedObject
00163 {
00164 public:
00165 LinkedObject *scoped;
00166 LinkedObject *events;
00167 LinkedObject *methods;
00168 line_t *first;
00169 const char *name;
00170 unsigned resmask;
00176 inline void link(header *scr)
00177 {next = scr;};
00178 };
00179
00187 class __EXPORT checks
00188 {
00189 public:
00190 static bool isValue(const char *text);
00191 static bool isText(const char *text);
00192
00193 static const char *chkPush(script *img, header *scr, line_t *line);
00194 static const char *chkApply(script *img, header *scr, line_t *line);
00195 static const char *chkIgnore(script *img, header *scr, line_t *line);
00196 static const char *chkNop(script *img, header *scr, line_t *line);
00197 static const char *chkExit(script *img, header *scr, line_t *line);
00198 static const char *chkVar(script *img, header *scr, line_t *line);
00199 static const char *chkConst(script *img, header *scr, line_t *line);
00200 static const char *chkSet(script *img, header *scr, line_t *line);
00201 static const char *chkClear(script *img, header *scr, line_t *line);
00202 static const char *chkError(script *img, header *scr, line_t *line);
00203 static const char *chkPack(script *img, header *scr, line_t *line);
00204 static const char *chkExpand(script *img, header *scr, line_t *line);
00205 static const char *chkGosub(script *img, header *src, line_t *line);
00206 static const char *chkGoto(script *img, header *scr, line_t *line);
00207 static const char *chkDo(script *img, header *scr, line_t *line);
00208 static const char *chkUntil(script *img, header *scr, line_t *line);
00209 static const char *chkWhile(script *ing, header *scr, line_t *line);
00210 static const char *chkConditional(script *img, header *scr, line_t *line);
00211 static const char *chkContinue(script *img, header *scr, line_t *line);
00212 static const char *chkBreak(script *img, header *scr, line_t *line);
00213 static const char *chkLoop(script *img, header *scr, line_t *line);
00214 static const char *chkPrevious(script *img, header *scr, line_t *line);
00215 static const char *chkIndex(script *img, header *scr, line_t *line);
00216 static const char *chkForeach(script *img, header *scr, line_t *line);
00217 static const char *chkCase(script *img, header *scr, line_t *line);
00218 static const char *chkEndcase(script *img, header *scr, line_t *line);
00219 static const char *chkOtherwise(script *img, header *scr, line_t *line);
00220 static const char *chkIf(script *img, header *scr, line_t *line);
00221 static const char *chkElif(script *img, header *scr, line_t *line);
00222 static const char *chkElse(script *img, header *scr, line_t *line);
00223 static const char *chkEndif(script *img, header *scr, line_t *line);
00224 static const char *chkDefine(script *img, header *scr, line_t *line);
00225 static const char *chkInvoke(script *img, header *scr, line_t *line);
00226 static const char *chkWhen(script *img, header *scr, line_t *line);
00227 static const char *chkStrict(script *img, header *scr, line_t *line);
00228 static const char *chkExpr(script *img, header *scr, line_t *line);
00229 static const char *chkRef(script *ing, header *scr, line_t *line);
00230 };
00231
00236 typedef struct {
00237 header *scr;
00238 header *scope;
00239 event_t *event;
00240 line_t *line;
00241 unsigned short index;
00242 unsigned short base;
00243 unsigned short resmask;
00244 } stack_t;
00245
00256 class __EXPORT interp : protected memalloc
00257 {
00258 public:
00259 typedef char num_t[16];
00260
00261 interp();
00262 virtual ~interp();
00263
00269 bool step(void);
00270
00279 bool attach(script *image, const char *entry = NULL);
00280
00284 void detach(void);
00285
00291 void initialize(void);
00292
00297 bool error(const char *text);
00298
00303 unsigned getResource(void);
00304
00305 protected:
00306 symbol *find(const char *id);
00307 void skip(void);
00308 void push(void);
00309 bool trylabel(const char *id);
00310 bool tryexit(void);
00311 void pullScope(void);
00312 void pullBase(void);
00313 void pullLoop(void);
00314 bool pop(void);
00315 void setStack(header *scr, event *ev = NULL);
00316
00324 virtual bool match(const char *pattern, const char *name);
00325
00333 virtual bool isInherited(const char *name);
00334
00342 bool scriptEvent(const char *name);
00343
00349 event *scriptMethod(const char *name);
00350
00351 stack_t *stack;
00352 pointer<script> image;
00353 LinkedObject **syms;
00354 unsigned frame;
00355
00356 char *getTemp(void);
00357 bool setConst(const char *id, const char *value);
00358 symbol *createSymbol(const char *id);
00359 symbol *getVar(const char *id, const char *value = NULL);
00360 const char *getValue(void);
00361 const char *getContent(void);
00362 const char *getContent(const char *text);
00363 const char *getKeyword(const char *id);
00364 method_t getLooping(void);
00365 bool isConditional(unsigned index);
00366 void setRef(header *scope, const char *id, char *data, unsigned size);
00367 void getParams(header *scope, line_t *line);
00368 void startScript(header *scr);
00369
00370 virtual unsigned getTypesize(const char *type_id);
00371 virtual const char *getTypeinit(const char *type_id);
00372 virtual const char *getFormat(symbol *sym, const char *id, char *temp);
00373 virtual bool getCondition(const char *test, const char *value);
00374 const char *getIndex(void);
00375
00376 private:
00377 bool getExpression(unsigned index);
00378
00379 char *errmsg;
00380 char *temps[3];
00381 unsigned tempindex;
00382 };
00383
00390 class __EXPORT error : public OrderedObject
00391 {
00392 private:
00393 friend class script;
00394 error(script *img, unsigned line, const char *str);
00395
00396 public:
00397 char *errmsg;
00398 unsigned errline;
00399 };
00400
00408 class __EXPORT methods : public interp
00409 {
00410 public:
00411 bool scrPush(void);
00412 bool scrApply(void);
00413 bool scrExpr(void);
00414 bool scrVar(void);
00415 bool scrSet(void);
00416 bool scrAdd(void);
00417 bool scrClear(void);
00418 bool scrConst(void);
00419 bool scrPause(void);
00420 bool scrNop(void);
00421 bool scrPack(void);
00422 bool scrExpand(void);
00423 bool scrExit(void);
00424 bool scrReturn(void);
00425 bool scrError(void);
00426 bool scrRestart(void);
00427 bool scrGosub(void);
00428 bool scrGoto(void);
00429 bool scrDo(void);
00430 bool scrLoop(void);
00431 bool scrUntil(void);
00432 bool scrWhile(void);
00433 bool scrBreak(void);
00434 bool scrContinue(void);
00435 bool scrForeach(void);
00436 bool scrPrevious(void);
00437 bool scrRepeat(void);
00438 bool scrIndex(void);
00439 bool scrCase(void);
00440 bool scrEndcase(void);
00441 bool scrOtherwise(void);
00442 bool scrIf(void);
00443 bool scrElif(void);
00444 bool scrElse(void);
00445 bool scrEndif(void);
00446 bool scrDefine(void);
00447 bool scrInvoke(void);
00448 bool scrWhen(void);
00449 bool scrRef(void);
00450 };
00451
00452 ~script();
00453
00454 static unsigned stepping;
00455 static unsigned indexing;
00456 static size_t paging;
00457 static unsigned sizing;
00458 static unsigned stacking;
00459 static unsigned decimals;
00470 static script *append(script *merge, const char *filename, script *config = NULL);
00471
00480 static script *compile(const char *filename, script *config = NULL);
00481
00482
00483
00493 static script *merge(const char *filename, script *root = NULL);
00494
00500 static void assign(keyword_t *list);
00501
00509 static keyword_t *find(const char *id);
00510
00514 static void init(void);
00515
00516 static unsigned offset(const char *list, unsigned index);
00517 static void copy(const char *list, char *item, unsigned size);
00518 static unsigned count(const char *list);
00519 static const char *get(const char *list, unsigned offset);
00520 static char *get(char *list, unsigned offset);
00521 static header *find(script *img, const char *id);
00522 static bool isEvent(header *scr, const char *id);
00523
00524 header *first;
00525 LinkedObject **scripts;
00526
00527 bool push(line_t *line);
00528 method_t pull(void);
00529 method_t looping(void);
00530
00531 inline unsigned getErrors(void)
00532 {return errors;};
00533
00534 inline LinkedObject *getListing(void)
00535 {return errlist.begin();};
00536
00537 inline const char *getFilename(void)
00538 {return filename;};
00539
00540 inline bool isStrict(void)
00541 {return global != NULL;};
00542
00543 inline unsigned getLines(void)
00544 {return lines;};
00545
00546 private:
00547 friend class strict;
00548 friend class checks;
00549 friend class error;
00550 friend class interp;
00551 friend class methods;
00552
00553 script();
00554
00555 void errlog(unsigned line, const char *fmt, ...);
00556
00557 unsigned errors;
00558 unsigned loop;
00559 unsigned lines;
00560 bool thencheck;
00561 line_t **stack;
00562 LinkedObject *global;
00563 OrderedIndex errlist;
00564 pointer<script> shared;
00565 const char *filename;
00566 LinkedObject *headers;
00567 };
00568
00569 END_NAMESPACE
00570
00571 #endif