diff --git a/Makefile b/Makefile index 8218f5b..2ed97e2 100644 --- a/Makefile +++ b/Makefile @@ -1,18 +1,22 @@ - -SQUIRREL=. -MAKE=make - -sq32: - cd squirrel; $(MAKE) - cd sqstdlib; $(MAKE) - cd sq; $(MAKE) - -sqprof: - cd squirrel; $(MAKE) sqprof - cd sqstdlib; $(MAKE) sqprof - cd sq; $(MAKE) sqprof - -sq64: - cd squirrel; $(MAKE) sq64 - cd sqstdlib; $(MAKE) sq64 - cd sq; $(MAKE) sq64 + +SQUIRREL=. +MAKE=make + +sq32: folders + cd squirrel; $(MAKE) + cd sqstdlib; $(MAKE) + cd sq; $(MAKE) + +sqprof: folders + cd squirrel; $(MAKE) sqprof + cd sqstdlib; $(MAKE) sqprof + cd sq; $(MAKE) sqprof + +sq64: folders + cd squirrel; $(MAKE) sq64 + cd sqstdlib; $(MAKE) sq64 + cd sq; $(MAKE) sq64 + +folders: + mkdir -p lib + mkdir -p bin diff --git a/samples/regex.nut b/samples/regex.nut new file mode 100644 index 0000000..fcd8e59 --- /dev/null +++ b/samples/regex.nut @@ -0,0 +1,10 @@ +local ex = regexp("[a-zA-Z]+"); +local string = "123 Test; strlen(str);"; +local res = ex.search(string); +print(string.slice(res.begin,res.end)); //prints "Test" +print("\n"); +ex = regexp(@"\m()"); +string = "123 Test; doSomething(str, getTemp(), (a+(b/c)));"; +res = ex.search(string); +print(string.slice(res.begin,res.end)); //prints "(...)" +print("\n"); diff --git a/sqstdlib/sqstdrex.cpp b/sqstdlib/sqstdrex.cpp index 2f91792..143516a 100644 --- a/sqstdlib/sqstdrex.cpp +++ b/sqstdlib/sqstdrex.cpp @@ -13,7 +13,7 @@ static const SQChar *g_nnames[] = _SC("NONE"),_SC("OP_GREEDY"), _SC("OP_OR"), _SC("OP_EXPR"),_SC("OP_NOCAPEXPR"),_SC("OP_DOT"), _SC("OP_CLASS"), _SC("OP_CCLASS"),_SC("OP_NCLASS"),_SC("OP_RANGE"),_SC("OP_CHAR"), - _SC("OP_EOL"),_SC("OP_BOL"),_SC("OP_WB") + _SC("OP_EOL"),_SC("OP_BOL"),_SC("OP_WB"),_C("OP_MB") }; #endif @@ -31,6 +31,7 @@ static const SQChar *g_nnames[] = #define OP_EOL (MAX_CHAR+11) #define OP_BOL (MAX_CHAR+12) #define OP_WB (MAX_CHAR+13) +#define OP_MB (MAX_CHAR+14) //match balanced #define SQREX_SYMBOL_ANY_CHAR ('.') #define SQREX_SYMBOL_GREEDY_ONE_OR_MORE ('+') @@ -139,7 +140,20 @@ static SQInteger sqstd_rex_charnode(SQRex *exp,SQBool isclass) t = *exp->_p; exp->_p++; return sqstd_rex_charclass(exp,t); } - case 'b': + case 'm': + { + SQChar cb, ce; //cb = character begin match ce = character end match + cb = *++exp->_p; //skip 'm' + ce = *++exp->_p; + exp->_p++; //points to the next char to be parsed + if ((!cb) || (!ce)) sqstd_rex_error(exp,_SC("balanced chars expected")); + if ( cb == ce ) sqstd_rex_error(exp,_SC("open/close char can't be the same")); + SQInteger node = sqstd_rex_newnode(exp,OP_MB); + exp->_nodes[node].left = cb; + exp->_nodes[node].right = ce; + return node; + } + case 'b': case 'B': if(!isclass) { SQInteger node = sqstd_rex_newnode(exp,OP_WB); @@ -199,8 +213,6 @@ static SQInteger sqstd_rex_class(SQRex *exp) if(first!=-1){ SQInteger c = first; exp->_nodes[chain].next = c; - chain = c; - first = -1; } /* hack? */ exp->_nodes[ret].left = exp->_nodes[ret].next; @@ -506,6 +518,23 @@ static const SQChar *sqstd_rex_matchnode(SQRex* exp,SQRexNode *node,const SQChar return str; } return NULL; + case OP_MB: + { + int cb = node->left; //char that opens a balanced expression + if(*str != cb) return NULL; // string doesnt start with open char + int ce = node->right; //char that closes a balanced expression + int cont = 1; + const SQChar *strEol = exp->_eol; + while (++str < strEol) { + if (*str == ce) { + if (--cont == 0) { + return ++str; + } + } + else if (*str == cb) cont++; + } + } + return NULL; // string ends out of balance default: /* char */ if(*str != node->type) return NULL; str++; diff --git a/sqstdlib/sqstdstring.cpp b/sqstdlib/sqstdstring.cpp index 4e3160f..5b43bc9 100644 --- a/sqstdlib/sqstdstring.cpp +++ b/sqstdlib/sqstdstring.cpp @@ -71,7 +71,7 @@ SQRESULT sqstd_format(HSQUIRRELVM v,SQInteger nformatstringidx,SQInteger *outlen SQChar fmt[MAX_FORMAT_LEN]; sq_getstring(v,nformatstringidx,&format); SQInteger format_size = sq_getsize(v,nformatstringidx); - SQInteger allocated = (sq_getsize(v,nformatstringidx)+2)*sizeof(SQChar); + SQInteger allocated = (format_size+2)*sizeof(SQChar); dest = sq_getscratchpad(v,allocated); SQInteger n = 0,i = 0, nparam = nformatstringidx+1, w = 0; //while(format[n] != '\0') diff --git a/squirrel/sqapi.cpp b/squirrel/sqapi.cpp index 93c86b0..413b04c 100644 --- a/squirrel/sqapi.cpp +++ b/squirrel/sqapi.cpp @@ -34,7 +34,8 @@ static bool sq_aux_gettypedarg(HSQUIRRELVM v,SQInteger idx,SQObjectType type,SQO SQInteger sq_aux_invalidtype(HSQUIRRELVM v,SQObjectType type) { - scsprintf(_ss(v)->GetScratchPad(100), 100 *sizeof(SQChar), _SC("unexpected type %s"), IdType2Name(type)); + SQUnsignedInteger buf_size = 100 *sizeof(SQChar); + scsprintf(_ss(v)->GetScratchPad(buf_size), buf_size, _SC("unexpected type %s"), IdType2Name(type)); return sq_throwerror(v, _ss(v)->GetScratchPad(-1)); } @@ -454,6 +455,7 @@ SQRESULT sq_bindenv(HSQUIRRELVM v,SQInteger idx) return sq_throwerror(v,_SC("the target is not a closure")); SQObjectPtr &env = stack_get(v,-1); if(!sq_istable(env) && + !sq_isarray(env) && !sq_isclass(env) && !sq_isinstance(env)) return sq_throwerror(v,_SC("invalid environment")); @@ -891,29 +893,30 @@ SQRESULT sq_set(HSQUIRRELVM v,SQInteger idx) SQRESULT sq_rawset(HSQUIRRELVM v,SQInteger idx) { SQObjectPtr &self = stack_get(v, idx); - if(type(v->GetUp(-2)) == OT_NULL) { + SQObjectPtr &key = v->GetUp(-2); + if(type(key) == OT_NULL) { v->Pop(2); return sq_throwerror(v, _SC("null key")); } switch(type(self)) { case OT_TABLE: - _table(self)->NewSlot(v->GetUp(-2), v->GetUp(-1)); + _table(self)->NewSlot(key, v->GetUp(-1)); v->Pop(2); return SQ_OK; break; case OT_CLASS: - _class(self)->NewSlot(_ss(v), v->GetUp(-2), v->GetUp(-1),false); + _class(self)->NewSlot(_ss(v), key, v->GetUp(-1),false); v->Pop(2); return SQ_OK; break; case OT_INSTANCE: - if(_instance(self)->Set(v->GetUp(-2), v->GetUp(-1))) { + if(_instance(self)->Set(key, v->GetUp(-1))) { v->Pop(2); return SQ_OK; } break; case OT_ARRAY: - if(v->Set(self, v->GetUp(-2), v->GetUp(-1),false)) { + if(v->Set(self, key, v->GetUp(-1),false)) { v->Pop(2); return SQ_OK; } @@ -929,8 +932,9 @@ SQRESULT sq_newmember(HSQUIRRELVM v,SQInteger idx,SQBool bstatic) { SQObjectPtr &self = stack_get(v, idx); if(type(self) != OT_CLASS) return sq_throwerror(v, _SC("new member only works with classes")); - if(type(v->GetUp(-3)) == OT_NULL) return sq_throwerror(v, _SC("null key")); - if(!v->NewSlotA(self,v->GetUp(-3),v->GetUp(-2),v->GetUp(-1),bstatic?true:false,false)) + SQObjectPtr &key = v->GetUp(-3); + if(type(key) == OT_NULL) return sq_throwerror(v, _SC("null key")); + if(!v->NewSlotA(self,key,v->GetUp(-2),v->GetUp(-1),bstatic?true:false,false)) return SQ_ERROR; return SQ_OK; } @@ -939,8 +943,9 @@ SQRESULT sq_rawnewmember(HSQUIRRELVM v,SQInteger idx,SQBool bstatic) { SQObjectPtr &self = stack_get(v, idx); if(type(self) != OT_CLASS) return sq_throwerror(v, _SC("new member only works with classes")); - if(type(v->GetUp(-3)) == OT_NULL) return sq_throwerror(v, _SC("null key")); - if(!v->NewSlotA(self,v->GetUp(-3),v->GetUp(-2),v->GetUp(-1),bstatic?true:false,true)) + SQObjectPtr &key = v->GetUp(-3); + if(type(key) == OT_NULL) return sq_throwerror(v, _SC("null key")); + if(!v->NewSlotA(self,key,v->GetUp(-2),v->GetUp(-1),bstatic?true:false,true)) return SQ_ERROR; return SQ_OK; } @@ -1010,7 +1015,8 @@ SQRESULT sq_getdelegate(HSQUIRRELVM v,SQInteger idx) SQRESULT sq_get(HSQUIRRELVM v,SQInteger idx) { SQObjectPtr &self=stack_get(v,idx); - if(v->Get(self,v->GetUp(-1),v->GetUp(-1),0,DONT_FALL_BACK)) + SQObjectPtr &obj = v->GetUp(-1); + if(v->Get(self,obj,obj,false,DONT_FALL_BACK)) return SQ_OK; v->Pop(); return SQ_ERROR; @@ -1019,23 +1025,23 @@ SQRESULT sq_get(HSQUIRRELVM v,SQInteger idx) SQRESULT sq_rawget(HSQUIRRELVM v,SQInteger idx) { SQObjectPtr &self=stack_get(v,idx); + SQObjectPtr &obj = v->GetUp(-1); switch(type(self)) { case OT_TABLE: - if(_table(self)->Get(v->GetUp(-1),v->GetUp(-1))) + if(_table(self)->Get(obj,obj)) return SQ_OK; break; case OT_CLASS: - if(_class(self)->Get(v->GetUp(-1),v->GetUp(-1))) + if(_class(self)->Get(obj,obj)) return SQ_OK; break; case OT_INSTANCE: - if(_instance(self)->Get(v->GetUp(-1),v->GetUp(-1))) + if(_instance(self)->Get(obj,obj)) return SQ_OK; break; case OT_ARRAY:{ - SQObjectPtr& key = v->GetUp(-1); - if(sq_isnumeric(key)){ - if(_array(self)->Get(tointeger(key),v->GetUp(-1))) { + if(sq_isnumeric(obj)){ + if(_array(self)->Get(tointeger(obj),obj)) { return SQ_OK; } } @@ -1048,7 +1054,7 @@ SQRESULT sq_rawget(HSQUIRRELVM v,SQInteger idx) default: v->Pop(); return sq_throwerror(v,_SC("rawget works only on array/table/instance and class")); - } + } v->Pop(); return sq_throwerror(v,_SC("the index doesn't exist")); } @@ -1131,9 +1137,10 @@ SQRESULT sq_reservestack(HSQUIRRELVM v,SQInteger nsize) SQRESULT sq_resume(HSQUIRRELVM v,SQBool retval,SQBool raiseerror) { - if(type(v->GetUp(-1))==OT_GENERATOR){ + SQObjectPtr &obj = v->GetUp(-1); + if(type(obj)==OT_GENERATOR){ v->PushNull(); //retval - if(!v->Execute(v->GetUp(-2),0,v->_top,v->GetUp(-1),raiseerror,SQVM::ET_RESUME_GENERATOR)) + if(!v->Execute(v->GetUp(-2),0,v->_top,obj,raiseerror,SQVM::ET_RESUME_GENERATOR)) {v->Raise_Error(v->_lasterror); return SQ_ERROR;} if(!retval) v->Pop();