Back to home page

Enduro/X

 
 

    


0001 /*

0002     see copyright notice in pscript.h

0003 */
0004 #include "pspcheader.h"
0005 #include <stdarg.h>
0006 #include "psvm.h"
0007 #include "psfuncproto.h"
0008 #include "psclosure.h"
0009 #include "psstring.h"
0010 
0011 PSRESULT ps_getfunctioninfo(HPSCRIPTVM v,PSInteger level,PSFunctionInfo *fi)
0012 {
0013     PSInteger cssize = v->_callsstacksize;
0014     if (cssize > level) {
0015         PSVM::CallInfo &ci = v->_callsstack[cssize-level-1];
0016         if(ps_isclosure(ci._closure)) {
0017             PSClosure *c = _closure(ci._closure);
0018             PSFunctionProto *proto = c->_function;
0019             fi->funcid = proto;
0020             fi->name = type(proto->_name) == OT_STRING?_stringval(proto->_name):_SC("unknown");
0021             fi->source = type(proto->_sourcename) == OT_STRING?_stringval(proto->_sourcename):_SC("unknown");
0022             fi->line = proto->_lineinfos[0]._line;
0023             return PS_OK;
0024         }
0025     }
0026     return ps_throwerror(v,_SC("the object is not a closure"));
0027 }
0028 
0029 PSRESULT ps_stackinfos(HPSCRIPTVM v, PSInteger level, PSStackInfos *si)
0030 {
0031     PSInteger cssize = v->_callsstacksize;
0032     if (cssize > level) {
0033         memset(si, 0, sizeof(PSStackInfos));
0034         PSVM::CallInfo &ci = v->_callsstack[cssize-level-1];
0035         switch (type(ci._closure)) {
0036         case OT_CLOSURE:{
0037             PSFunctionProto *func = _closure(ci._closure)->_function;
0038             if (type(func->_name) == OT_STRING)
0039                 si->funcname = _stringval(func->_name);
0040             if (type(func->_sourcename) == OT_STRING)
0041                 si->source = _stringval(func->_sourcename);
0042             si->line = func->GetLine(ci._ip);
0043                         }
0044             break;
0045         case OT_NATIVECLOSURE:
0046             si->source = _SC("NATIVE");
0047             si->funcname = _SC("unknown");
0048             if(type(_nativeclosure(ci._closure)->_name) == OT_STRING)
0049                 si->funcname = _stringval(_nativeclosure(ci._closure)->_name);
0050             si->line = -1;
0051             break;
0052         default: break; //shutup compiler

0053         }
0054         return PS_OK;
0055     }
0056     return PS_ERROR;
0057 }
0058 
0059 void PSVM::Raise_Error(const PSChar *s, ...)
0060 {
0061     va_list vl;
0062     va_start(vl, s);
0063     PSInteger buffersize = (PSInteger)scstrlen(s)+(NUMBER_MAX_CHAR*2);
0064     scvsprintf(_sp(ps_rsl(buffersize)),buffersize, s, vl);
0065     va_end(vl);
0066     _lasterror = PSString::Create(_ss(this),_spval,-1);
0067 }
0068 
0069 void PSVM::Raise_Error(const PSObjectPtr &desc)
0070 {
0071     _lasterror = desc;
0072 }
0073 
0074 PSString *PSVM::PrintObjVal(const PSObjectPtr &o)
0075 {
0076     switch(type(o)) {
0077     case OT_STRING: return _string(o);
0078     case OT_INTEGER:
0079         scsprintf(_sp(ps_rsl(NUMBER_MAX_CHAR+1)),ps_rsl(NUMBER_MAX_CHAR), _PRINT_INT_FMT, _integer(o));
0080         return PSString::Create(_ss(this), _spval);
0081         break;
0082     case OT_FLOAT:
0083         scsprintf(_sp(ps_rsl(NUMBER_MAX_CHAR+1)), ps_rsl(NUMBER_MAX_CHAR), _SC("%.14g"), _float(o));
0084         return PSString::Create(_ss(this), _spval);
0085         break;
0086     default:
0087         return PSString::Create(_ss(this), GetTypeName(o));
0088     }
0089 }
0090 
0091 void PSVM::Raise_IdxError(const PSObjectPtr &o)
0092 {
0093     PSObjectPtr oval = PrintObjVal(o);
0094     Raise_Error(_SC("the index '%.50s' does not exist"), _stringval(oval));
0095 }
0096 
0097 void PSVM::Raise_CompareError(const PSObject &o1, const PSObject &o2)
0098 {
0099     PSObjectPtr oval1 = PrintObjVal(o1), oval2 = PrintObjVal(o2);
0100     Raise_Error(_SC("comparison between '%.50s' and '%.50s'"), _stringval(oval1), _stringval(oval2));
0101 }
0102 
0103 
0104 void PSVM::Raise_ParamTypeError(PSInteger nparam,PSInteger typemask,PSInteger type)
0105 {
0106     PSObjectPtr exptypes = PSString::Create(_ss(this), _SC(""), -1);
0107     PSInteger found = 0;
0108     for(PSInteger i=0; i<16; i++)
0109     {
0110         PSInteger mask = 0x00000001 << i;
0111         if(typemask & (mask)) {
0112             if(found>0) StringCat(exptypes,PSString::Create(_ss(this), _SC("|"), -1), exptypes);
0113             found ++;
0114             StringCat(exptypes,PSString::Create(_ss(this), IdType2Name((PSObjectType)mask), -1), exptypes);
0115         }
0116     }
0117     Raise_Error(_SC("parameter %d has an invalid type '%s' ; expected: '%s'"), nparam, IdType2Name((PSObjectType)type), _stringval(exptypes));
0118 }