7 VXInteger
vox_printfunc_callback(VXState
* v
, VXInteger start
, VXPrintFunc vpf
)
16 for(i
=start
; i
<=top
; i
++)
19 VXObject
& ob
= v
->StackGet(i
);
20 #if defined(VX_PRINT_REPR)
21 VXOType tp
= ob
.Type();
22 if(tp
!= VX_OT_STRING
&& !ob
.IsNumeric())
24 const std::string
& s
= VXRepr(v
, ob
).str();
26 data_len
= s
.length();
31 res
.String()->Get(&data_str
, &data_len
);
35 res
.String
->Get(&data_str
, &data_len
);
37 if(VX_FAILED(vpf(v
, false, data_str
, data_len
)))
39 goto _printfunc_failed
;
42 if(VX_FAILED(vpf(v
, true, data_str
, data_len
)))
44 goto _printfunc_failed
;
50 return v
->ThrowError("Internal error: call to printfunc failed");
54 VXInteger
_println_callback(VXState
* v
, bool isend
, const char* str
, VXInteger len
)
56 if(v
->Shared()->_printfunc
)
60 v
->Shared()->_printfunc(v
, "\n");
64 v
->Shared()->_printfunc(v
, "%s", str
);
71 VXInteger
_print_callback(VXState
* v
, bool isend
, const char* str
, VXInteger len
)
73 if(_ss(v
)->_printfunc
)
77 _ss(v
)->_printfunc(v
, "%s", str
);
84 VXInteger
system_repr(VXState
* v
)
87 VXRepr
ser(v
, v
->StackGet(2));
88 status
= ser
.status();
91 const std::string
& data
= ser
.str();
92 v
->Push(v
->NewString(data
.c_str(), data
.length()));
98 VXInteger
system_dummy(VXState
*)
103 VXInteger
system_gc_collect(VXState
* v
)
105 v
->Push(v
->CollectGarbage());
109 VXInteger
system_gc_resurrect(VXState
* v
)
111 v
->ResurrectUnreachable();
115 VXInteger
system_gc_release(VXState
* v
)
117 VXObject
& ob
= v
->StackGet(2);
122 VXInteger
system_getroottable(VXState
* v
)
124 v
->Push(v
->_roottable
);
128 VXInteger
system_getconsttable(VXState
* v
)
130 v
->Push(v
->Shared()->_consts
);
134 VXInteger
system_setroottable(VXState
* v
)
136 VXObject oldroot
= v
->_roottable
;
137 VXObject newroot
= v
->StackGet(2);
138 if(newroot
.Type() == VX_OT_TABLE
|| newroot
.Type() == VX_OT_NULL
)
140 v
->_roottable
= newroot
;
144 return v
->ThrowError("wrong type (expected 'table' or 'null')");
147 VXInteger
system_setconsttable(VXState
* v
)
149 VXObject oldtable
= v
->Shared()->_consts
;
150 VXObject newtable
= v
->StackGet(2);
151 if(newtable
.Type() == VX_OT_TABLE
)
153 v
->Shared()->_consts
= newtable
;
160 VXInteger
system_seterrorhandler(VXState
* v
)
162 v
->SetErrorHandler(v
->StackGet(2));
166 VXInteger
system_setdebughook(VXState
* v
)
168 v
->SetDebugHook(v
->StackGet(2));
172 VXInteger
system_enabledebuginfo(VXState
* v
)
176 v
->EnableDebugInfo(val
);
181 VXInteger
system_getstackinfos(VXState
* v
)
184 v
->GetInteger(-1, &level
);
185 return __getcallstackinfos(v
,level
);
188 VXInteger
system_assert(VXState
* v
)
191 if(VXState::IsFalse(v
->StackGet(2)))
193 if(VX_FAILED(v
->GetString(3, &message
, NULL
)))
195 return v
->ThrowError("assertion failed");
199 return v
->ThrowError("assertion failed: %s", message
);
207 VXInteger
system_print(VXState
* v
)
209 return vox_printfunc_callback(v
, 2, _print_callback
);
212 VXInteger
system_println(VXState
* v
)
214 return vox_printfunc_callback(v
, 2, _println_callback
);
218 VXInteger
system_compilestring(VXState
* v
)
223 v
->GetString(2, &src
, &size
);
224 if(VX_FAILED(v
->GetString(3, &name
, NULL
)))
226 name
= "unnamedbuffer";
228 if(VX_SUCCEEDED(v
->CompileBuffer(src
,size
,name
,false)))
235 VXInteger
system_newthread(VXState
* v
)
237 VXObject
&func
= v
->StackGet(2);
238 VXInteger stksize
= (func
.Closure()->_function
->_stacksize
<< 1) +2;
239 VXState
* newv
= v
->NewThread(v
, (stksize
< MIN_STACK_OVERHEAD
+ 2)?
240 MIN_STACK_OVERHEAD
+ 2 : stksize
);
241 VXState::MoveIndex(newv
, v
, -2);
245 VXInteger
system_suspend(VXState
* v
)
250 VXInteger
system_type(VXState
* v
)
252 VXObject
&o
= v
->StackGet(2);
253 v
->PushString(o
.TypeString());
257 VXInteger
system_callee(VXState
* v
)
259 if(v
->_callsstacksize
> 1)
261 v
->Push(v
->_callsstack
[v
->_callsstacksize
- 2]._closure
);
264 return v
->ThrowError("no closure in the calls stack");
267 VXInteger
system_loadfile(VXState
* v
)
269 const char *filename
;
270 bool printerror
= false;
271 v
->GetString(2, &filename
, NULL
);
272 if(VX_FAILED(v
->GetBool(3, &printerror
)))
276 if(VX_SUCCEEDED(v
->LoadFile(filename
,printerror
)))
280 return v
->ThrowError("loadfile('%s'): %s", filename
, v
->LastError());
285 VXInteger
system_writeclosuretofile(VXState
* v
)
287 const char *filename
;
288 v
->GetString(2, &filename
, NULL
);
289 if(VX_SUCCEEDED(v
->WriteClosureToFile(filename
)))
296 VXInteger
system_dofile(VXState
* v
)
298 const char *filename
;
300 v
->GetString(2, &filename
, NULL
);
301 if(VX_FAILED(v
->GetBool(3, &printerror
)))
303 /* by default, do not print the yielded error */
306 v
->Push(v
->GetRootTable());
307 if(VX_SUCCEEDED(v
->DoFile(filename
, true, printerror
)))
311 return v
->ThrowError("dofile('%s'): %s", filename
, v
->LastError());
316 VXInteger
system_dostring(VXState
* v
)
320 const char* buffername
;
322 v
->GetString(2, &source
);
323 if(VX_FAILED(v
->GetBool(3, &printerror
)))
325 /* by default, do not print the yielded error */
328 if(VX_FAILED(v
->GetString(4, &buffername
, NULL
)))
332 v
->Push(v
->GetRootTable());
336 buffername
, true, printerror
);
337 if(VX_SUCCEEDED(ret
))
341 /* only throw custom errormessage if buffername is not NULL.
342 reason: if system.errorhandler() is called from vox,
343 the buffername is not reachable, so we'll just act as if
344 it got called natively */
345 if(buffername
!= NULL
)
347 return v
->ThrowError("dostring(%s): %s", buffername
, v
->LastError());
352 VXInteger
system_platform_group(VXState
* v
)
354 v
->Push(v
->NewString(VOX_PLATFORM_GROUP_NAME
));
358 VXInteger
system_platform(VXState
* v
)
360 v
->Push(v
->NewString(VOX_PLATFORM_NAME
));
364 VXInteger
system_atexit(VXState
* v
)
366 VXObject
& o
= v
->StackGet(2);
370 VXInteger
system_errorhandler(VXState
* v
)
372 v
->CallErrorHandler(v
->StackGet(2));
388 VXInteger
xrange_releasehook(VXUserPointer p
, VXInteger size
)
390 XRange
* self
= (XRange
*)p
;
396 VXInteger
xrange_ctor(VXState
* v
)
402 XRange
* self
= new XRange
;
403 self
->values
= v
->NewArray();
404 if(VX_FAILED(v
->GetInteger(2, &pstart
)))
406 return v
->Raise_ParamTypeError(2, VX_OT_INTEGER
, v
->StackGet(2).Type());
408 if(VX_FAILED(v
->GetInteger(3, &pstop
)))
413 if(VX_FAILED(v
->GetInteger(4, &pstep
)))
417 self
->start
= pstart
;
421 for(i
=pstart
; (pstop
>-1)?(i
<pstop
):(i
!=pstop
); i
+=pstep
)
423 self
->values
->Append(VXObject(i
));
425 v
->SetInstanceUp(1, (VXUserPointer
*)&self
);
426 v
->SetReleaseHook(1, xrange_releasehook
);
430 VXInteger
xrange_values(VXState
* v
)
433 v
->GetInstanceUp(1, (VXUserPointer
*)&self
, 0);
434 v
->Push(self
->values
);
438 VXInteger
xrange_get(VXState
* v
)
443 v
->GetInstanceUp(1, (VXUserPointer
*)&self
, 0);
444 idx
= v
->StackGet(2);
445 if(!self
->values
->Get(idx
.Integer(), val
))
449 return v
->ThrowError("xrange::__get__: bad index");
453 return v
->ThrowError();
461 VXInteger
xrange_nexti(VXState
* v
)
464 v
->GetInstanceUp(1, (VXUserPointer
*)&self
, 0);
465 if(self
->count
!= self
->values
->Size())
467 v
->Push(self
->count
++);
473 VXInteger
xrange_tostring(VXState
* v
)
476 v
->GetInstanceUp(1, (VXUserPointer
*)&self
, 0);
477 std::stringstream str
;
478 str
<< "<xrange at " << ((void*)self
) << " ";
480 << "start:" << self
->start
481 << ", stop:" << self
->stop
482 << ", step:" << self
->step
484 v
->PushString(str
.str().c_str(), str
.str().length());
488 VXInteger
xrange_typeof(VXState
* v
)
491 v
->GetInstanceUp(1, (VXUserPointer
*)&self
, 0);
492 v
->PushString("xrange");
496 VXRegFunction xrange_funcs
[]=
498 {"constructor", xrange_ctor
, -1, NULL
},
499 {"values", xrange_values
, -1, ".x"},
500 {"__get__", xrange_get
, -1, NULL
},
501 {"__nexti__", xrange_nexti
, -1, NULL
},
502 {"__tostring__", xrange_tostring
, -1, NULL
},
503 {"__typeof__", xrange_typeof
, -1, NULL
},
507 VXRegFunction system_funcs
[]=
509 {"platform", system_platform
, 1, NULL
},
510 {"platform_group", system_platform_group
, 1, NULL
},
511 {"seterrorhandler", system_seterrorhandler
, 2, NULL
},
512 {"debughook", system_setdebughook
, 2, NULL
},
513 {"enabledebug", system_enabledebuginfo
, 2, NULL
},
514 {"stackinfos", system_getstackinfos
, 2, ".n"},
515 {"getroot", system_getroottable
, 1, NULL
},
516 {"setroot", system_setroottable
, 2, NULL
},
517 {"getconsttable", system_getconsttable
, 1, NULL
},
518 {"setconsttable", system_setconsttable
, 2, NULL
},
519 {"compilestring", system_compilestring
, -2, ".ss"},
520 {"newthread", system_newthread
, 2, ".c"},
521 {"suspend", system_suspend
, -1, NULL
},
522 {"type", system_type
, 2, NULL
},
523 {"callee", system_callee
, 0, NULL
},
524 {"dummy", system_dummy
, 0, NULL
},
525 {"loadfile", system_loadfile
, -2, ".sb"},
526 {"loadstring", system_compilestring
, -2, ".ss"},
527 {"dofile", system_dofile
, -2, ".sb"},
528 {"dostring", system_dostring
, -2, ".sbs"},
529 {"writeclosuretofile", system_writeclosuretofile
, 3, ".sc"},
530 {"atexit", system_atexit
, 2, ".c"},
531 //{"repr", system_repr, 2, NULL},
532 {"errorhandler", system_errorhandler
, 2, NULL
},
533 {"gc_collect", system_gc_collect
, 0, NULL
},
534 {"gc_resurrect", system_gc_resurrect
, 0, NULL
},
535 {"gc_release", system_gc_release
, 2, "."},
537 /** NOTE: these declarations are going to be deprecated in some
538 future release. remember to remove them at some point...
539 Main reason(s) for removal are usually:
540 + overly verbose function name (writeclosuretofile is way too long)
541 + ambigious/idiotic function name (gc_collect vs gccollect)
543 {"getstackinfos", system_getstackinfos
, 2, ".n"},
544 {"setdebughook", system_setdebughook
, 2, NULL
},
545 {"enabledebuginfo", system_enabledebuginfo
, 2, NULL
},
546 {"seterrorhandler", system_seterrorhandler
, 2, NULL
},
547 {"getroottable", system_getroottable
, 1, NULL
},
548 {"setroottable", system_setroottable
, 2, NULL
},
549 {"getconsttable", system_getconsttable
, 1, NULL
},
550 {"setconsttable", system_setconsttable
, 2, NULL
},
554 VXRegFunction system_globalfuncs
[] =
556 {"assert", system_assert
, -2, ".bs"},
557 {"print", system_print
, -1, NULL
},
558 {"println", system_println
, -1, NULL
},
563 VXInteger
voxstd_register_system(VXState
* v
)
565 VXTableObj
* systb
= v
->NewTable();
566 systb
->NewSlot(v
->NewString("argv"), v
->GetSysArgv());
567 v
->RegisterLib("system", system_funcs
, true, systb
);
568 v
->RegisterLib(NULL
, system_globalfuncs
, true);
569 v
->GetRootTable()->NewSlot(v
->NewString("xrange"), v
->RegClass(xrange_funcs
));