SINGLE_ARG_FUNC(cos) SINGLE_ARG_FUNC(asin) SINGLE_ARG_FUNC(acos) SINGLE_ARG_FUNC(log) SINGLE_ARG_FUNC(log10) SINGLE_ARG_FUNC(tan) SINGLE_ARG_FUNC(atan) TWO_ARGS_FUNC(atan2) TWO_ARGS_FUNC(pow) SINGLE_ARG_FUNC(floor) SINGLE_ARG_FUNC(ceil) SINGLE_ARG_FUNC(exp) #define _DECL_FUNC(name,nparams,tycheck) {_SC(#name),math_##name,nparams,tycheck} static SQRegFunction mathlib_funcs[] = { _DECL_FUNC(sqrt,2,_SC(".n")), _DECL_FUNC(sin,2,_SC(".n")), _DECL_FUNC(cos,2,_SC(".n")), _DECL_FUNC(asin,2,_SC(".n")), _DECL_FUNC(acos,2,_SC(".n")), _DECL_FUNC(log,2,_SC(".n")), _DECL_FUNC(log10,2,_SC(".n")), _DECL_FUNC(tan,2,_SC(".n")), _DECL_FUNC(atan,2,_SC(".n")), _DECL_FUNC(atan2,3,_SC(".nn")), _DECL_FUNC(pow,3,_SC(".nn")), _DECL_FUNC(floor,2,_SC(".n")), _DECL_FUNC(ceil,2,_SC(".n")), _DECL_FUNC(exp,2,_SC(".n")), _DECL_FUNC(srand,2,_SC(".n")), _DECL_FUNC(rand,1,NULL),
SQInteger SQLexer::Lex() { _lasttokenline = _currentline; while(CUR_CHAR != SQUIRREL_EOB) { switch(CUR_CHAR){ case _SC('\t'): case _SC('\r'): case _SC(' '): NEXT(); continue; case _SC('\n'): _currentline++; _prevtoken=_curtoken; _curtoken=_SC('\n'); NEXT(); _currentcolumn=1; continue; case _SC('#'): LexLineComment(); continue; case _SC('/'): NEXT(); switch(CUR_CHAR){ case _SC('*'): NEXT(); LexBlockComment(); continue; case _SC('/'): LexLineComment(); continue; case _SC('='): NEXT(); RETURN_TOKEN(TK_DIVEQ); continue; case _SC('>'): NEXT(); RETURN_TOKEN(TK_ATTR_CLOSE); continue; default: RETURN_TOKEN('/'); } case _SC('='): NEXT(); if (CUR_CHAR != _SC('=')){ RETURN_TOKEN('=') } else { NEXT(); RETURN_TOKEN(TK_EQ); } case _SC('<'): NEXT(); switch(CUR_CHAR) { case _SC('='): NEXT(); if(CUR_CHAR == _SC('>')) { NEXT(); RETURN_TOKEN(TK_3WAYSCMP); } RETURN_TOKEN(TK_LE) break; case _SC('-'): NEXT(); RETURN_TOKEN(TK_NEWSLOT); break; case _SC('<'): NEXT(); RETURN_TOKEN(TK_SHIFTL); break; case _SC('/'): NEXT(); RETURN_TOKEN(TK_ATTR_OPEN); break; } RETURN_TOKEN('<'); case _SC('>'): NEXT(); if (CUR_CHAR == _SC('=')){ NEXT(); RETURN_TOKEN(TK_GE);} else if(CUR_CHAR == _SC('>')){ NEXT(); if(CUR_CHAR == _SC('>')){ NEXT(); RETURN_TOKEN(TK_USHIFTR); } RETURN_TOKEN(TK_SHIFTR); } else { RETURN_TOKEN('>') } case _SC('!'): NEXT(); if (CUR_CHAR != _SC('=')){ RETURN_TOKEN('!')} else { NEXT(); RETURN_TOKEN(TK_NE); } case _SC('@'): { SQInteger stype; NEXT(); if(CUR_CHAR != _SC('"')) { RETURN_TOKEN('@'); } if((stype=ReadString('"',true))!=-1) { RETURN_TOKEN(stype); } Error(_SC("error parsing the string")); } case _SC('"'): case _SC('\''): { SQInteger stype; if((stype=ReadString(CUR_CHAR,false))!=-1){ RETURN_TOKEN(stype); } Error(_SC("error parsing the string")); } case _SC('{'): case _SC('}'): case _SC('('): case _SC(')'): case _SC('['): case _SC(']'): case _SC(';'): case _SC(','): case _SC('?'): case _SC('^'): case _SC('~'): {SQInteger ret = CUR_CHAR; NEXT(); RETURN_TOKEN(ret); } case _SC('.'): NEXT(); if (CUR_CHAR != _SC('.')){ RETURN_TOKEN('.') } NEXT(); if (CUR_CHAR != _SC('.')){ Error(_SC("invalid token '..'")); } NEXT(); RETURN_TOKEN(TK_VARPARAMS); case _SC('&'): NEXT(); if (CUR_CHAR != _SC('&')){ RETURN_TOKEN('&') } else { NEXT(); RETURN_TOKEN(TK_AND); } case _SC('|'): NEXT(); if (CUR_CHAR != _SC('|')){ RETURN_TOKEN('|') } else { NEXT(); RETURN_TOKEN(TK_OR); } case _SC(':'): NEXT(); if (CUR_CHAR != _SC(':')){ RETURN_TOKEN(':') } else { NEXT(); RETURN_TOKEN(TK_DOUBLE_COLON); } case _SC('*'): NEXT(); if (CUR_CHAR == _SC('=')){ NEXT(); RETURN_TOKEN(TK_MULEQ);} else RETURN_TOKEN('*'); case _SC('%'): NEXT(); if (CUR_CHAR == _SC('=')){ NEXT(); RETURN_TOKEN(TK_MODEQ);} else RETURN_TOKEN('%'); case _SC('-'): NEXT(); if (CUR_CHAR == _SC('=')){ NEXT(); RETURN_TOKEN(TK_MINUSEQ);} else if (CUR_CHAR == _SC('-')){ NEXT(); RETURN_TOKEN(TK_MINUSMINUS);} else RETURN_TOKEN('-'); case _SC('+'): NEXT(); if (CUR_CHAR == _SC('=')){ NEXT(); RETURN_TOKEN(TK_PLUSEQ);} else if (CUR_CHAR == _SC('+')){ NEXT(); RETURN_TOKEN(TK_PLUSPLUS);} else RETURN_TOKEN('+'); case SQUIRREL_EOB: return 0; default:{ if (scisdigit(CUR_CHAR)) { SQInteger ret = ReadNumber(); RETURN_TOKEN(ret); } else if (scisalpha(CUR_CHAR) || CUR_CHAR == _SC('_')) { SQInteger t = ReadID(); RETURN_TOKEN(t); } else { SQInteger c = CUR_CHAR; if (sciscntrl((int)c)) Error(_SC("unexpected character(control)")); NEXT(); RETURN_TOKEN(c); } RETURN_TOKEN(0); } } } return 0; }
SQInteger scisodigit(SQInteger c) { return c >= _SC('0') && c <= _SC('7'); }
SQInteger ScriptList::Valuate(HSQUIRRELVM vm) { this->modifications++; /* The first parameter is the instance of ScriptList. */ int nparam = sq_gettop(vm) - 1; if (nparam < 1) { return sq_throwerror(vm, _SC("You need to give a least a Valuator as parameter to ScriptList::Valuate")); } /* Make sure the valuator function is really a function, and not any * other type. It's parameter 2 for us, but for the user it's the * first parameter they give. */ SQObjectType valuator_type = sq_gettype(vm, 2); if (valuator_type != OT_CLOSURE && valuator_type != OT_NATIVECLOSURE) { return sq_throwerror(vm, _SC("parameter 1 has an invalid type (expected function)")); } /* Don't allow docommand from a Valuator, as we can't resume in * mid C++-code. */ bool backup_allow = ScriptObject::GetAllowDoCommand(); ScriptObject::SetAllowDoCommand(false); /* Push the function to call */ sq_push(vm, 2); for (ScriptListMap::iterator iter = this->items.begin(); iter != this->items.end(); iter++) { /* Check for changing of items. */ int previous_modification_count = this->modifications; /* Push the root table as instance object, this is what squirrel does for meta-functions. */ sq_pushroottable(vm); /* Push all arguments for the valuator function. */ sq_pushinteger(vm, (*iter).first); for (int i = 0; i < nparam - 1; i++) { sq_push(vm, i + 3); } /* Call the function. Squirrel pops all parameters and pushes the return value. */ if (SQ_FAILED(sq_call(vm, nparam + 1, SQTrue, SQTrue))) { ScriptObject::SetAllowDoCommand(backup_allow); return SQ_ERROR; } /* Retreive the return value */ SQInteger value; switch (sq_gettype(vm, -1)) { case OT_INTEGER: { sq_getinteger(vm, -1, &value); break; } case OT_BOOL: { SQBool v; sq_getbool(vm, -1, &v); value = v ? 1 : 0; break; } default: { /* See below for explanation. The extra pop is the return value. */ sq_pop(vm, nparam + 4); ScriptObject::SetAllowDoCommand(backup_allow); return sq_throwerror(vm, _SC("return value of valuator is not valid (not integer/bool)")); } } /* Was something changed? */ if (previous_modification_count != this->modifications) { /* See below for explanation. The extra pop is the return value. */ sq_pop(vm, nparam + 4); ScriptObject::SetAllowDoCommand(backup_allow); return sq_throwerror(vm, _SC("modifying valuated list outside of valuator function")); } this->SetValue((*iter).first, value); /* Pop the return value. */ sq_poptop(vm); Squirrel::DecreaseOps(vm, 5); } /* Pop from the squirrel stack: * 1. The root stable (as instance object). * 2. The valuator function. * 3. The parameters given to this function. * 4. The ScriptList instance object. */ sq_pop(vm, nparam + 3); ScriptObject::SetAllowDoCommand(backup_allow); return 0; }
_set_integer_slot(v, _SC("sec"), date->tm_sec); _set_integer_slot(v, _SC("min"), date->tm_min); _set_integer_slot(v, _SC("hour"), date->tm_hour); _set_integer_slot(v, _SC("day"), date->tm_mday); _set_integer_slot(v, _SC("month"), date->tm_mon); _set_integer_slot(v, _SC("year"), date->tm_year+1900); _set_integer_slot(v, _SC("wday"), date->tm_wday); _set_integer_slot(v, _SC("yday"), date->tm_yday); return 1; } #define _DECL_FUNC(name,nparams,pmask) {_SC(#name),_system_##name,nparams,pmask} static const SQRegFunction systemlib_funcs[]={ _DECL_FUNC(getenv,2,_SC(".s")), _DECL_FUNC(system,2,_SC(".s")), _DECL_FUNC(clock,0,NULL), _DECL_FUNC(time,1,NULL), _DECL_FUNC(date,-1,_SC(".nn")), _DECL_FUNC(remove,2,_SC(".s")), _DECL_FUNC(rename,3,_SC(".ss")), {NULL,(SQFUNCTION)0,0,NULL} }; #undef _DECL_FUNC SQInteger sqstd_register_systemlib(HSQUIRRELVM v) { SQInteger i=0; while(systemlib_funcs[i].name!=0) {
#include <ctype.h> #include <stdlib.h> #include <stdio.h> #include <string.h> #include <zlib.h> #include <unzip.h> #include "squirrel.h" #include "sqstdblobimpl.h" SQ_OPT_STRING_STRLEN(); #define LZ_BUFFER_SIZE 8192 #define LZ_MAX_ZIP_NAME_SIZE 256 #define ZIP_DOS_DIR_ATTRIBUTE_BITFLAG 0x10 static const SQChar sq_minizip_unzip_TAG[] = _SC("sq_minizip_unzip_tag"); #define GET_minizip_unzip_INSTANCE_VAR_AT(idx, Var) \ SQ_GET_INSTANCE_VAR(v, idx, unzFile, Var, sq_minizip_unzip_TAG);\ if(!Var) return sq_throwerror(v, _SC("miniz_ziparchive already destroyed")); #define GET_minizip_unzip_INSTANCE() GET_minizip_unzip_INSTANCE_VAR_AT(1, self) static SQRESULT sq_minizip_unzip_releasehook(SQUserPointer p, SQInteger size, HSQUIRRELVM v) { unzFile self = ((unzFile)p); if(self) { unzClose(self); } return 0; } static SQRESULT sq_minizip_unzip_constructor(HSQUIRRELVM v)
static SQInteger _regexp__typeof(HSQUIRRELVM v) { sq_pushstring(v,_SC("regexp"),-1); return 1; }
void SQVM::Raise_CompareError(const SQObject &o1, const SQObject &o2) { SQObjectPtr oval1 = PrintObjVal(o1), oval2 = PrintObjVal(o2); Raise_Error(_SC("comparsion between '%.50s' and '%.50s'"), _stringval(oval1), _stringval(oval2)); }
if (SUCCEED!=mkdir(s, 0777)) { sprintf(err, "mkdir failed: %d:%s", errno, strerror(errno)); return ps_throwerror(v,err); } } return 1; } return 0; } #define _DECL_FUNC(name,nparams,pmask) {_SC(#name),_exutil_##name,nparams,pmask} static PSRegFunction exutillib_funcs[]={ _DECL_FUNC(getline,1,_SC(".s")), _DECL_FUNC(getcwd,1,_SC(".s")), _DECL_FUNC(getosname,1,_SC(".s")), _DECL_FUNC(userlog,2,_SC(".s")), _DECL_FUNC(mkdir,2,_SC(".s")), _DECL_FUNC(chmod,3,_SC(".ss")), {0,0} }; #undef _DECL_FUNC PSInteger psstd_register_exutillib(HPSCRIPTVM v) { PSInteger i=0; while(exutillib_funcs[i].name!=0) { ps_pushstring(v,exutillib_funcs[i].name,-1);
static SQRESULT sq_libclang_parseTranslationUnit(HSQUIRRELVM v){ SQ_FUNC_VARS(v); GET_libclang_INSTANCE(); if(sq_gettype(v, 2) != OT_CLOSURE) return sq_throwerror(v, _SC("invalid fisrt parameter expected closure")); SQ_GET_STRING(v, 3, fname); release_visitor_cb(self); sq_getstackobj(v, 2, &self->visitor_cb); sq_addref(v, &self->visitor_cb); const char *cl_argsDefault[] = {"-I."}; const char **cl_args = cl_argsDefault; int cl_argNum = 1; int rc = 0; const int cl_arg_start = 4; bool has_extra_params = _top_ >= cl_arg_start; if(has_extra_params) { //create cl_args with extra parameters cl_argNum = _top_ - (cl_arg_start -1); cl_args = (const char **)sq_malloc(sizeof(char*) * cl_argNum); for(int i=cl_arg_start; i <= _top_; ++i) { const SQChar *p; if(sq_gettype(v, i) == OT_STRING) { rc = sq_getstring(v, i, &p); } else { rc = sq_throwerror(v, _SC("not a string parameter at %d"), i); goto cleanup; } cl_args[i-cl_arg_start] = p; } } CXTranslationUnit TU; CXCursor rootCursor; TU = dlclang_parseTranslationUnit(self->index, fname, cl_args, cl_argNum, 0, 0, CXTranslationUnit_Incomplete); if (TU == NULL) { rc = sq_throwerror(v, _SC("clang_parseTranslationUnit for %s failed\n"), fname); goto cleanup; } rootCursor = dlclang_getTranslationUnitCursor(TU); dlclang_visitChildren(rootCursor, cursorVisitor, self); dlclang_disposeTranslationUnit(TU); cleanup: if(has_extra_params) { sq_free(cl_args, sizeof(char*) * cl_argNum); } return rc; }
void SQVM::Raise_IdxError(SQObject &o) { SQObjectPtr oval = PrintObjVal(o); Raise_Error(_SC("the index '%.50s' does not exist"), _stringval(oval)); }
static SQRESULT get_libclang_instance(HSQUIRRELVM v, SQInteger idx, MyLibClang **self){ SQRESULT _rc_; if((_rc_ = sq_getinstanceup(v,idx,(SQUserPointer*)self,(void*)LibClang_TAG)) < 0) return _rc_; if(!*self) return sq_throwerror(v, _SC("libclang is closed")); return _rc_; }
dlclang_getPresumedLocation = (clang_getPresumedLocation_t) dynamicLib.dlsym("clang_getPresumedLocation"); if(!dlclang_getPresumedLocation) return false; dlclang_getCursorLinkage = (clang_getCursorLinkage_t) dynamicLib.dlsym("clang_getCursorLinkage"); if(!dlclang_getCursorLinkage) return false; dlclang_getResultType = (clang_getResultType_t) dynamicLib.dlsym("clang_getResultType"); if(!dlclang_getResultType) return false; // generated-code:end return true; } return false; } //////////////////////////////////////////////////////////////////////////////// static const SQChar *LibClang_TAG = _SC("LibClang"); struct MyLibClang { CXIndex index; int depth; const char *file_name; char *function_name; unsigned int prev_line, prev_column; unsigned int line, column; HSQUIRRELVM v; HSQOBJECT visitor_cb; HSQOBJECT visitor_udata; }; static SQRESULT get_libclang_instance(HSQUIRRELVM v, SQInteger idx, MyLibClang **self){ SQRESULT _rc_;
a = SQArray::Create(_ss(v),tointeger(size)); } v->Push(a); return 1; } static SQInteger base_type(HSQUIRRELVM v) { SQObjectPtr &o = stack_get(v,2); v->Push(SQString::Create(_ss(v),GetTypeName(o),-1)); return 1; } static SQRegFunction base_funcs[]={ //generic {_SC("seterrorhandler"),base_seterrorhandler,2, NULL}, {_SC("setdebughook"),base_setdebughook,2, NULL}, {_SC("enabledebuginfo"),base_enabledebuginfo,2, NULL}, {_SC("getstackinfos"),base_getstackinfos,2, _SC(".n")}, {_SC("getroottable"),base_getroottable,1, NULL}, {_SC("setroottable"),base_setroottable,2, NULL}, {_SC("getconsttable"),base_getconsttable,1, NULL}, {_SC("setconsttable"),base_setconsttable,2, NULL}, {_SC("assert"),base_assert,2, NULL}, {_SC("print"),base_print,2, NULL}, {_SC("compilestring"),base_compilestring,-2, _SC(".ss")}, {_SC("newthread"),base_newthread,2, _SC(".c")}, {_SC("suspend"),base_suspend,-1, NULL}, {_SC("array"),base_array,-2, _SC(".n")}, {_SC("type"),base_type,2, NULL}, {_SC("dummy"),base_dummy,0,NULL},
//<<FIXME>> this func is a mess int getargs(HPSCRIPTVM v,int argc, char* argv[],PSInteger *retval) { int i; int compiles_only = 0; #ifdef PSUNICODE static PSChar temp[500]; #endif char * output = NULL; *retval = 0; if(argc>1) { int arg=1,exitloop=0; while(arg < argc && !exitloop) { if(argv[arg][0]=='-') { switch(argv[arg][1]) { case 'd': //DEBUG(debug infos) ps_enabledebuginfo(v,1); break; case 'c': compiles_only = 1; break; case 'o': if(arg < argc) { arg++; output = argv[arg]; } break; case 'v': PrintVersionInfos(); return _DONE; case 'h': PrintVersionInfos(); PrintUsage(); return _DONE; default: PrintVersionInfos(); scprintf(_SC("unknown prameter '-%c'\n"),argv[arg][1]); PrintUsage(); *retval = -1; return _ERROR; } }else break; arg++; } // src file if(arg<argc) { const PSChar *filename=NULL; #ifdef PSUNICODE mbstowcs(temp,argv[arg],strlen(argv[arg])); filename=temp; #else filename=argv[arg]; #endif arg++; //ps_pushstring(v,_SC("ARGS"),-1); //ps_newarray(v,0); //ps_createslot(v,-3); //ps_pop(v,1); if(compiles_only) { if(PS_SUCCEEDED(psstd_loadfile(v,filename,PSTrue))){ const PSChar *outfile = _SC("out.cnut"); if(output) { #ifdef PSUNICODE int len = (int)(strlen(output)+1); mbstowcs(ps_getscratchpad(v,len*sizeof(PSChar)),output,len); outfile = ps_getscratchpad(v,-1); #else outfile = output; #endif } if(PS_SUCCEEDED(psstd_writeclosuretofile(v,outfile))) return _DONE; } } else { //if(PS_SUCCEEDED(psstd_dofile(v,filename,PSFalse,PSTrue))) { //return _DONE; //} if(PS_SUCCEEDED(psstd_loadfile(v,filename,PSTrue))) { int callargs = 1; ps_pushroottable(v); for(i=arg;i<argc;i++) { const PSChar *a; #ifdef PSUNICODE int alen=(int)strlen(argv[i]); a=ps_getscratchpad(v,(int)(alen*sizeof(PSChar))); mbstowcs(ps_getscratchpad(v,-1),argv[i],alen); ps_getscratchpad(v,-1)[alen] = _SC('\0'); #else a=argv[i]; #endif ps_pushstring(v,a,-1); callargs++; //ps_arrayappend(v,-2); } if(PS_SUCCEEDED(ps_call(v,callargs,PSTrue,PSTrue))) { PSObjectType type = ps_gettype(v,-1); if(type == OT_INTEGER) { *retval = type; ps_getinteger(v,-1,retval); } return _DONE; } else{ return _ERROR; } } } //if this point is reached an error occured { const PSChar *err; ps_getlasterror(v); if(PS_SUCCEEDED(ps_getstring(v,-1,&err))) { scprintf(_SC("Error [%s]\n"),err); *retval = -2; return _ERROR; } } } } return _INTERACTIVE; }
SQInteger sq_aux_invalidtype(HSQUIRRELVM v,SQObjectType type) { scsprintf(_ss(v)->GetScratchPad(100), _SC("unexpected type %s"), IdType2Name(type)); return sq_throwerror(v, _ss(v)->GetScratchPad(-1)); }
SQInteger CSquirrel::PrintErrorFunction(SQVM * pVM) { if(sq_gettop(pVM) >= 1) { const SQChar * szError = NULL; sq_getstring(pVM, 2, &szError); ErrorInfo info; info.strError = szError; SQStackInfos si; SQInteger level = 1; // 1 is to skip this function that is level 0 const SQChar *name = 0; SQInteger seq = 0; while(SQ_SUCCEEDED(sq_stackinfos(pVM, level, &si))) { const SQChar * fn = _SC("unknown"); const SQChar * src = _SC("unknown"); if(si.funcname) fn = si.funcname; if(si.source) src = si.source; info.callstack.push_back(ErrorCallstackPair(fn, ErrorSourcePair(src, si.line))); level++; } for(level = 0; level < 10; level++) { seq = 0; while((name = sq_getlocal(pVM, level, seq))) { seq++; CSquirrelArgument arg; arg.pushFromStack(pVM, -1); info.locals.push_back(ErrorLocalPair(name, arg)); sq_pop(pVM, 1); } } CSquirrel * pScript = CScriptingManager::GetInstance()->Get(pVM); if(pScript) { CSquirrelArguments arguments; CSquirrelArguments tempArray; CSquirrelArguments callstackTable; CSquirrelArguments localsTable; arguments.push(info.strError); for(ErrorCallstackList::iterator iter = info.callstack.begin(); iter != info.callstack.end(); iter++) { String strFunction = iter->first; String strSource = iter->second.first; int iLine = iter->second.second; callstackTable.push(strFunction); tempArray.reset(); tempArray.push(strSource); tempArray.push(iLine); callstackTable.push(tempArray, true); } arguments.push(callstackTable, false); for(ErrorLocalsList::iterator iter = info.locals.begin(); iter != info.locals.end(); iter++) { String strName = iter->first; CSquirrelArgument arg = iter->second; localsTable.push(strName); localsTable.push(arg); } arguments.push(localsTable, false); if(CEvents::GetInstance()->Call("scriptError", &arguments, pScript).GetInteger() == 1) { CLogFile::Printf("<Error (%s)>", info.strError.Get()); CLogFile::Printf("<Callstack>"); for(ErrorCallstackList::iterator iter = info.callstack.begin(); iter != info.callstack.end(); iter++) { String strFunction = iter->first; String strSource = iter->second.first; int iLine = iter->second.second; CLogFile::Printf("<%s (%s, %d)>", strFunction.Get(), strSource.Get(), iLine); } CLogFile::Printf("</Callstack>"); CLogFile::Printf("<Locals>"); for(ErrorLocalsList::iterator iter = info.locals.begin(); iter != info.locals.end(); iter++) { String strName = iter->first; CSquirrelArgument arg = iter->second; CLogFile::Printf("<%s (%s)>", strName.Get(), arg.GetTypeString().Get()); } CLogFile::Printf("</Locals>"); CLogFile::Printf("</Error>"); } } } return 0; }
/* see copyright notice in squirrel.h */ #include "sqpcheader.h" #ifndef NO_COMPILER #include "sqcompiler.h" #include "sqstring.h" #include "sqfuncproto.h" #include "sqtable.h" #include "sqopcodes.h" #include "sqfuncstate.h" #ifdef _DEBUG_DUMP SQInstructionDesc g_InstrDesc[]={ {_SC("_OP_LINE")}, {_SC("_OP_LOAD")}, {_SC("_OP_LOADINT")}, {_SC("_OP_LOADFLOAT")}, {_SC("_OP_DLOAD")}, {_SC("_OP_TAILCALL")}, {_SC("_OP_CALL")}, {_SC("_OP_PREPCALL")}, {_SC("_OP_PREPCALLK")}, {_SC("_OP_GETK")}, {_SC("_OP_MOVE")}, {_SC("_OP_NEWSLOT")}, {_SC("_OP_DELETE")}, {_SC("_OP_SET")}, {_SC("_OP_GET")}, {_SC("_OP_EQ")}, {_SC("_OP_NE")},
SQRex *rex = sqstd_rex_compile(pattern,&error); if(!rex) return sq_throwerror(v,error); sq_setinstanceup(v,1,rex); sq_setreleasehook(v,1,_rexobj_releasehook); return 0; } static SQInteger _regexp__typeof(HSQUIRRELVM v) { sq_pushstring(v,_SC("regexp"),-1); return 1; } #define _DECL_REX_FUNC(name,nparams,pmask) {_SC(#name),_regexp_##name,nparams,pmask} static SQRegFunction rexobj_funcs[]={ _DECL_REX_FUNC(constructor,2,_SC(".s")), _DECL_REX_FUNC(search,-2,_SC("xsn")), _DECL_REX_FUNC(match,2,_SC("xs")), _DECL_REX_FUNC(capture,-2,_SC("xsn")), _DECL_REX_FUNC(subexpcount,1,_SC("x")), _DECL_REX_FUNC(_typeof,1,_SC("x")), {0,0} }; #define _DECL_FUNC(name,nparams,pmask) {_SC(#name),_string_##name,nparams,pmask} static SQRegFunction stringlib_funcs[]={ _DECL_FUNC(format,-2,_SC(".s")), _DECL_FUNC(strip,2,_SC(".s")), _DECL_FUNC(lstrip,2,_SC(".s")), _DECL_FUNC(rstrip,2,_SC(".s")), _DECL_FUNC(split,3,_SC(".ss")),
void SQFuncState::Dump(SQFunctionProto *func) { SQUnsignedInteger n=0,i; SQInteger si; scprintf(_SC("SQInstruction sizeof %d\n"),sizeof(SQInstruction)); scprintf(_SC("SQObject sizeof %d\n"),sizeof(SQObject)); scprintf(_SC("--------------------------------------------------------------------\n")); scprintf(_SC("*****FUNCTION [%s]\n"),type(func->_name)==OT_STRING?_stringval(func->_name):_SC("unknown")); scprintf(_SC("-----LITERALS\n")); SQObjectPtr refidx,key,val; SQInteger idx; SQObjectPtrVec templiterals; templiterals.resize(_nliterals); while((idx=_table(_literals)->Next(false,refidx,key,val))!=-1) { refidx=idx; templiterals[_integer(val)]=key; } for(i=0;i<templiterals.size();i++){ scprintf(_SC("[%d] "),n); DumpLiteral(templiterals[i]); scprintf(_SC("\n")); n++; } scprintf(_SC("-----PARAMS\n")); if(_varparams) scprintf(_SC("<<VARPARAMS>>\n")); n=0; for(i=0;i<_parameters.size();i++){ scprintf(_SC("[%d] "),n); DumpLiteral(_parameters[i]); scprintf(_SC("\n")); n++; } scprintf(_SC("-----LOCALS\n")); for(si=0;si<func->_nlocalvarinfos;si++){ SQLocalVarInfo lvi=func->_localvarinfos[si]; scprintf(_SC("[%d] %s \t%d %d\n"),lvi._pos,_stringval(lvi._name),lvi._start_op,lvi._end_op); n++; } scprintf(_SC("-----LINE INFO\n")); for(i=0;i<_lineinfos.size();i++){ SQLineInfo li=_lineinfos[i]; scprintf(_SC("op [%d] line [%d] \n"),li._op,li._line); n++; } scprintf(_SC("-----dump\n")); n=0; for(i=0;i<_instructions.size();i++){ SQInstruction &inst=_instructions[i]; if(inst.op==_OP_LOAD || inst.op==_OP_DLOAD || inst.op==_OP_PREPCALLK || inst.op==_OP_GETK ){ SQInteger lidx = inst._arg1; scprintf(_SC("[%03d] %15s %d "),n,g_InstrDesc[inst.op].name,inst._arg0); if(lidx >= 0xFFFFFFFF) scprintf(_SC("null")); else { SQInteger refidx; SQObjectPtr val,key,refo; while(((refidx=_table(_literals)->Next(false,refo,key,val))!= -1) && (_integer(val) != lidx)) { refo = refidx; } DumpLiteral(key); } if(inst.op != _OP_DLOAD) { scprintf(_SC(" %d %d \n"),inst._arg2,inst._arg3); } else { scprintf(_SC(" %d "),inst._arg2); lidx = inst._arg3; if(lidx >= 0xFFFFFFFF) scprintf(_SC("null")); else { SQInteger refidx; SQObjectPtr val,key,refo; while(((refidx=_table(_literals)->Next(false,refo,key,val))!= -1) && (_integer(val) != lidx)) { refo = refidx; } DumpLiteral(key); scprintf(_SC("\n")); } } } else if(inst.op==_OP_LOADFLOAT) { scprintf(_SC("[%03d] %15s %d %f %d %d\n"),n,g_InstrDesc[inst.op].name,inst._arg0,*((SQFloat*)&inst._arg1),inst._arg2,inst._arg3); } /* else if(inst.op==_OP_ARITH){ scprintf(_SC("[%03d] %15s %d %d %d %c\n"),n,g_InstrDesc[inst.op].name,inst._arg0,inst._arg1,inst._arg2,inst._arg3); }*/ else { scprintf(_SC("[%03d] %15s %d %d %d %d\n"),n,g_InstrDesc[inst.op].name,inst._arg0,inst._arg1,inst._arg2,inst._arg3); } n++; } scprintf(_SC("-----\n")); scprintf(_SC("stack size[%d]\n"),func->_stacksize); scprintf(_SC("--------------------------------------------------------------------\n\n")); }
SQRESULT sqstd_format(HSQUIRRELVM v,SQInteger nformatstringidx,SQInteger *outlen,SQChar **output) { const SQChar *format; SQChar *dest; SQChar fmt[MAX_FORMAT_LEN]; sq_getstring(v,nformatstringidx,&format); SQInteger allocated = (sq_getsize(v,nformatstringidx)+2)*sizeof(SQChar); dest = sq_getscratchpad(v,allocated); SQInteger n = 0,i = 0, nparam = nformatstringidx+1, w = 0; while(format[n] != '\0') { if(format[n] != '%') { assert(i < allocated); dest[i++] = format[n]; n++; } else if(format[n+1] == '%') { //handles %% dest[i++] = '%'; n += 2; } else { n++; if( nparam > sq_gettop(v) ) return sq_throwerror(v,_SC("not enough parameters for the given format string")); n = validate_format(v,fmt,format,n,w); if(n < 0) return -1; SQInteger addlen = 0; SQInteger valtype = 0; const SQChar *ts; SQInteger ti; SQFloat tf; switch(format[n]) { case 's': if(SQ_FAILED(sq_getstring(v,nparam,&ts))) return sq_throwerror(v,_SC("string expected for the specified format")); addlen = (sq_getsize(v,nparam)*sizeof(SQChar))+((w+1)*sizeof(SQChar)); valtype = 's'; break; case 'i': case 'd': case 'c':case 'o': case 'u': case 'x': case 'X': if(SQ_FAILED(sq_getinteger(v,nparam,&ti))) return sq_throwerror(v,_SC("integer expected for the specified format")); addlen = (ADDITIONAL_FORMAT_SPACE)+((w+1)*sizeof(SQChar)); valtype = 'i'; break; case 'f': case 'g': case 'G': case 'e': case 'E': if(SQ_FAILED(sq_getfloat(v,nparam,&tf))) return sq_throwerror(v,_SC("float expected for the specified format")); addlen = (ADDITIONAL_FORMAT_SPACE)+((w+1)*sizeof(SQChar)); valtype = 'f'; break; default: return sq_throwerror(v,_SC("invalid format")); } n++; allocated += addlen + sizeof(SQChar); dest = sq_getscratchpad(v,allocated); switch(valtype) { case 's': i += scsprintf(&dest[i],fmt,ts); break; case 'i': i += scsprintf(&dest[i],fmt,ti); break; case 'f': i += scsprintf(&dest[i],fmt,tf); break; }; nparam ++; } } *outlen = i; dest[i] = '\0'; *output = dest; return SQ_OK; }
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE // SOFTWARE. #include "sqxtd_vm.hpp" #include "sqxtd_array.h" #include "sqxtd_string.h" #include "sqxtd_utils.h" //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // MARK: - Private forwards and constants //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// static const SQChar * const kKeyComponentsJoinedByString = _SC("componentsJoinedByString"); namespace sqxtd { namespace native { namespace array { static SQRESULT components_joined_by_string(HSQUIRRELVM vm); }}} //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // MARK: - Public //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// void sqxtd_register_array(HSQUIRRELVM vm) { sqxtd::vm{vm}.const_table(_SC("SQXTD_ARRAY_EXTENSION_VERSION")) = _SC(SQXTD_VERSION); sqxtd::set_default_delegate_native(vm, OT_ARRAY, kKeyComponentsJoinedByString, &sqxtd::native::array::components_joined_by_string); }
void SQSharedState::Init() { _scratchpad=NULL; _scratchpadsize=0; #ifndef NO_GARBAGE_COLLECTOR _gc_chain=NULL; #endif _stringtable = (SQStringTable*)SQ_MALLOC(sizeof(SQStringTable)); new (_stringtable) SQStringTable(this); sq_new(_metamethods,SQObjectPtrVec); sq_new(_systemstrings,SQObjectPtrVec); sq_new(_types,SQObjectPtrVec); _metamethodsmap = SQTable::Create(this,MT_LAST-1); //adding type strings to avoid memory trashing //types names newsysstring(_SC("null")); newsysstring(_SC("table")); newsysstring(_SC("array")); newsysstring(_SC("closure")); newsysstring(_SC("string")); newsysstring(_SC("userdata")); newsysstring(_SC("integer")); newsysstring(_SC("float")); newsysstring(_SC("userpointer")); newsysstring(_SC("function")); newsysstring(_SC("generator")); newsysstring(_SC("thread")); newsysstring(_SC("class")); newsysstring(_SC("instance")); newsysstring(_SC("bool")); //meta methods newmetamethod(MM_ADD); newmetamethod(MM_SUB); newmetamethod(MM_MUL); newmetamethod(MM_DIV); newmetamethod(MM_UNM); newmetamethod(MM_MODULO); newmetamethod(MM_SET); newmetamethod(MM_GET); newmetamethod(MM_TYPEOF); newmetamethod(MM_NEXTI); newmetamethod(MM_CMP); newmetamethod(MM_CALL); newmetamethod(MM_CLONED); newmetamethod(MM_NEWSLOT); newmetamethod(MM_DELSLOT); newmetamethod(MM_TOSTRING); newmetamethod(MM_NEWMEMBER); newmetamethod(MM_INHERITED); _constructoridx = SQString::Create(this,_SC("constructor")); _registry = SQTable::Create(this,0); _consts = SQTable::Create(this,0); _table_default_delegate = CreateDefaultDelegate(this,_table_default_delegate_funcz); _array_default_delegate = CreateDefaultDelegate(this,_array_default_delegate_funcz); _string_default_delegate = CreateDefaultDelegate(this,_string_default_delegate_funcz); _number_default_delegate = CreateDefaultDelegate(this,_number_default_delegate_funcz); _closure_default_delegate = CreateDefaultDelegate(this,_closure_default_delegate_funcz); _generator_default_delegate = CreateDefaultDelegate(this,_generator_default_delegate_funcz); _thread_default_delegate = CreateDefaultDelegate(this,_thread_default_delegate_funcz); _class_default_delegate = CreateDefaultDelegate(this,_class_default_delegate_funcz); _instance_default_delegate = CreateDefaultDelegate(this,_instance_default_delegate_funcz); _weakref_default_delegate = CreateDefaultDelegate(this,_weakref_default_delegate_funcz); }
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // MARK: - Public //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// void sqxtd_register_array(HSQUIRRELVM vm) { sqxtd::vm{vm}.const_table(_SC("SQXTD_ARRAY_EXTENSION_VERSION")) = _SC(SQXTD_VERSION); sqxtd::set_default_delegate_native(vm, OT_ARRAY, kKeyComponentsJoinedByString, &sqxtd::native::array::components_joined_by_string); }
void SQLexer::LexLineComment() { do { NEXT(); } while (CUR_CHAR != _SC('\n') && (!IS_EOB())); }
void Interactive(HPSCRIPTVM v) { #define MAXINPUT 1024 PSChar buffer[MAXINPUT]; PSInteger blocks =0; PSInteger string=0; PSInteger retval=0; PSInteger done=0; PrintVersionInfos(); ps_pushroottable(v); ps_pushstring(v,_SC("quit"),-1); ps_pushuserpointer(v,&done); ps_newclosure(v,quit,1); ps_setparamscheck(v,1,NULL); ps_newslot(v,-3,PSFalse); ps_pop(v,1); while (!done) { PSInteger i = 0; scprintf(_SC("\nps>")); for(;;) { int c; if(done)return; c = getchar(); if (c == _SC('\n')) { if (i>0 && buffer[i-1] == _SC('\\')) { buffer[i-1] = _SC('\n'); } else if(blocks==0)break; buffer[i++] = _SC('\n'); } else if (c==_SC('}')) {blocks--; buffer[i++] = (PSChar)c;} else if(c==_SC('{') && !string){ blocks++; buffer[i++] = (PSChar)c; } else if(c==_SC('"') || c==_SC('\'')){ string=!string; buffer[i++] = (PSChar)c; } else if (i >= MAXINPUT-1) { scfprintf(stderr, _SC("ps : input line too long\n")); break; } else{ buffer[i++] = (PSChar)c; } } buffer[i] = _SC('\0'); if(buffer[0]==_SC('=')){ scsprintf(ps_getscratchpad(v,MAXINPUT),(size_t)MAXINPUT,_SC("return (%s)"),&buffer[1]); memcpy(buffer,ps_getscratchpad(v,-1),(scstrlen(ps_getscratchpad(v,-1))+1)*sizeof(PSChar)); retval=1; } i=scstrlen(buffer); if(i>0){ PSInteger oldtop=ps_gettop(v); if(PS_SUCCEEDED(ps_compilebuffer(v,buffer,i,_SC("interactive console"),PSTrue))){ ps_pushroottable(v); if(PS_SUCCEEDED(ps_call(v,1,retval,PSTrue)) && retval){ scprintf(_SC("\n")); ps_pushroottable(v); ps_pushstring(v,_SC("print"),-1); ps_get(v,-2); ps_pushroottable(v); ps_push(v,-4); ps_call(v,2,PSFalse,PSTrue); retval=0; scprintf(_SC("\n")); } } ps_settop(v,oldtop); } } }
SQInteger SQLexer::ReadString(SQInteger ndelim,bool verbatim) { INIT_TEMP_STRING(); NEXT(); if(IS_EOB()) return -1; for(;;) { while(CUR_CHAR != ndelim) { switch(CUR_CHAR) { case SQUIRREL_EOB: Error(_SC("unfinished string")); return -1; case _SC('\n'): if(!verbatim) Error(_SC("newline in a constant")); APPEND_CHAR(CUR_CHAR); NEXT(); _currentline++; break; case _SC('\\'): if(verbatim) { APPEND_CHAR('\\'); NEXT(); } else { NEXT(); switch(CUR_CHAR) { case _SC('x'): NEXT(); { if(!isxdigit(CUR_CHAR)) Error(_SC("hexadecimal number expected")); const SQInteger maxdigits = 4; SQChar temp[maxdigits+1]; SQInteger n = 0; while(isxdigit(CUR_CHAR) && n < maxdigits) { temp[n] = CUR_CHAR; n++; NEXT(); } temp[n] = 0; SQChar *sTemp; APPEND_CHAR((SQChar)scstrtoul(temp,&sTemp,16)); } break; case _SC('t'): APPEND_CHAR(_SC('\t')); NEXT(); break; case _SC('a'): APPEND_CHAR(_SC('\a')); NEXT(); break; case _SC('b'): APPEND_CHAR(_SC('\b')); NEXT(); break; case _SC('n'): APPEND_CHAR(_SC('\n')); NEXT(); break; case _SC('r'): APPEND_CHAR(_SC('\r')); NEXT(); break; case _SC('v'): APPEND_CHAR(_SC('\v')); NEXT(); break; case _SC('f'): APPEND_CHAR(_SC('\f')); NEXT(); break; case _SC('0'): APPEND_CHAR(_SC('\0')); NEXT(); break; case _SC('\\'): APPEND_CHAR(_SC('\\')); NEXT(); break; case _SC('"'): APPEND_CHAR(_SC('"')); NEXT(); break; case _SC('\''): APPEND_CHAR(_SC('\'')); NEXT(); break; default: Error(_SC("unrecognised escaper char")); break; } } break; default: APPEND_CHAR(CUR_CHAR); NEXT(); } } NEXT(); if(verbatim && CUR_CHAR == '"') { //double quotation APPEND_CHAR(CUR_CHAR); NEXT(); } else { break; } } TERMINATE_BUFFER(); SQInteger len = _longstr.size()-1; if(ndelim == _SC('\'')) { if(len == 0) Error(_SC("empty constant")); if(len > 1) Error(_SC("constant too long")); _nvalue = _longstr[0]; return TK_INTEGER; } _svalue = &_longstr[0]; return TK_STRING_LITERAL; }
void PrintVersionInfos() { scfprintf(stdout,_SC("%s %s (%d bits)\n"),PSCRIPT_VERSION,PSCRIPT_COPYRIGHT,((int)(sizeof(PSInteger)*8))); }
SQInteger SQLexer::ReadNumber() { #define TINT 1 #define TFLOAT 2 #define THEX 3 #define TSCIENTIFIC 4 #define TOCTAL 5 SQInteger type = TINT, firstchar = CUR_CHAR; SQChar *sTemp; INIT_TEMP_STRING(); NEXT(); if(firstchar == _SC('0') && (toupper(CUR_CHAR) == _SC('X') || scisodigit(CUR_CHAR)) ) { if(scisodigit(CUR_CHAR)) { type = TOCTAL; while(scisodigit(CUR_CHAR)) { APPEND_CHAR(CUR_CHAR); NEXT(); } if(scisdigit(CUR_CHAR)) Error(_SC("invalid octal number")); } else { NEXT(); type = THEX; while(isxdigit(CUR_CHAR)) { APPEND_CHAR(CUR_CHAR); NEXT(); } if(_longstr.size() > MAX_HEX_DIGITS) Error(_SC("too many digits for an Hex number")); } } else { APPEND_CHAR((int)firstchar); while (CUR_CHAR == _SC('.') || scisdigit(CUR_CHAR) || isexponent(CUR_CHAR)) { if(CUR_CHAR == _SC('.') || isexponent(CUR_CHAR)) type = TFLOAT; if(isexponent(CUR_CHAR)) { if(type != TFLOAT) Error(_SC("invalid numeric format")); type = TSCIENTIFIC; APPEND_CHAR(CUR_CHAR); NEXT(); if(CUR_CHAR == '+' || CUR_CHAR == '-'){ APPEND_CHAR(CUR_CHAR); NEXT(); } if(!scisdigit(CUR_CHAR)) Error(_SC("exponent expected")); } APPEND_CHAR(CUR_CHAR); NEXT(); } } TERMINATE_BUFFER(); switch(type) { case TSCIENTIFIC: case TFLOAT: _fvalue = (SQFloat)scstrtod(&_longstr[0],&sTemp); return TK_FLOAT; case TINT: LexInteger(&_longstr[0],(SQUnsignedInteger *)&_nvalue); return TK_INTEGER; case THEX: LexHexadecimal(&_longstr[0],(SQUnsignedInteger *)&_nvalue); return TK_INTEGER; case TOCTAL: LexOctal(&_longstr[0],(SQUnsignedInteger *)&_nvalue); return TK_INTEGER; } return 0; }
SQInteger _stream__cloned(HSQUIRRELVM v) { return sq_throwerror(v,_SC("this object cannot be cloned")); }