Low Level Functions¶
In this chapter we will learn about the low level functions provided by Ring
* callgarbagecollector()| callgc()
* variablepointer() | varptr()
* space()
* nullpointer() | nullptr()
* object2pointer() | obj2ptr()
* pointer2object() | ptr2obj()
* ispointer() | isptr()
* pointercompare() | ptrcmp()
* setpointer() | setptr()
* getpointer() | getptr()
* pointer2string() | ptr2str()
* memorycopy() | memcpy()
* ringvm_cfunctionslist()
* ringvm_functionslist()
* ringvm_classeslist()
* ringvm_packageslist()
* ringvm_memorylist()
* ringvm_calllist()
* ringvm_fileslist()
* ringvm_settrace()
* ringvm_tracedata()
* ringvm_traceevent()
* ringvm_tracefunc()
* ringvm_scopescount()
* ringvm_evalinscope()
* ringvm_passerror()
* ringvm_hideerrorMsg()
* ringvm_callfunc()
* ringvm_see()
* ringvm_give()
* ringvm_info()
callgc() function¶
Syntax:
callgc() # Short name
callgarbagecollector() # Long name
Use this function to force calling the garbage collector during function execution when you use a loop that create temp. variables that you don’t free using the assignment operation.
It’s very rare to need this function but it’s useful when you create something like event-loop for your game engine and start creating lists on the fly when you call functions.
Example
While True
# process events
# call functions using temp. lists like myfunc(["temp list"])
# call the garbage collector
callgc()
End
Tip
In Ring the garbage collector works automatically in the end of function execution or when you use the assignment statement.
varptr() function¶
Use the varptr() function when you need to pass a pointer to a C/C++ function.
Syntax:
varptr(cVariableName,cPointerType) ---> Low Level Object (C Pointer)
variablepointer(cVariableName,cPointerType) ---> Low Level Object (C Pointer)
example:
r = 10
z = 20
see r + nl
see varptr("r","int")
see varptr("z","int")
Output:
10
00E3C740
int
2
00E3BEC0
int
2
Note
the low level object is a list contains three items (The Pointer, The Type, The Status)
space() function¶
Use the space function to allocate a specific number of bytes in Memory.
Syntax:
Space(nBytesCount) ---> String
Example:
mystring = space(200)
See "String Size : " + len(mystring) + nl
See "String : " + mystring + nl
See "String Pointer : "
See varptr("mystring",:char)
Output:
String Size : 200
String :
String Pointer : 00FF8FE8
char
2
Note
You may need the space() and VarPtr() functions to pass buffers to C functions.
Tip
To free the memory allocated using the space() function, use the Assignment operator
mystring = space(1000) # Allocate memory (1000 bytes)
mystring = NULL # Free memory stored in mystring
Note
We don’t need to free the memory if it’s a local variable that will be deleted after the function execution.
nullpointer() function¶
Syntax:
nullptr() # Short name
nullpointer() # Long name
You may need to pass the NULL pointer to a C function that may expect a pointer as parameter and accept NULL pointers for optional parameters.
Example:
The next example uses the SDL_BlitSurface() function from the LibSDL Library through RingSDL The function accept SDL_Rect pointers in the second and the last parameter. Also the function accept NULL pointers, so we can pass them using the NULLPointer() Function.
SDL_BlitSurface(text, nullpointer(), surface, nullpointer())
Note
The previous code doesn’t work alone, you need to learn how to use RingSDL first.
Tip
We can pass NULL as parameter instead of using the NULLPointer() function
SDL_BlitSurface(text, NULL, surface, NULL)
object2pointer() function¶
Use this function to get a C pointer for Ring lists and objects
Syntax:
obj2ptr(List|Object) --> Low Level Object ( C Pointer ) # Short name
object2pointer(List|Object) --> Low Level Object ( C Pointer ) # Long name
Note
You have to be sure that the Pointer still valid (Doesn’t point to deallocated memory)
pointer2object() function¶
Use this function to get the Ring list and/or object from the low level object (C Pointer)
Syntax:
ptr2obj(Low Level Object) ---> List|Object # Short name
pointer2object(Low Level Object) ---> List|Object # Long name
Note
You have to be sure that the Pointer still valid (Doesn’t point to deallocated memory)
Example:
# Create the list
mylist = 1:5
# Create pointer to the list
x = object2pointer(mylist)
see x
see nl
# Add items to the list
mylist + "welcome"
# print the list items
y = pointer2object(x)
see y
Output:
0069A5D8
OBJECTPOINTER
0
1
2
3
4
5
welcome
Note
In Ring the assignment operator copy lists and objects by value, to copy by reference Just use the object2pointer() and pointer2object() functions.
Tip
The object2pointer() and pointer2object() are used in the stdlib - Tree Class implementation to create a reference for the parent node (object) in the child node (another object).
The functions Object2Pointer() and Pointer2Object() are low level functions
We have to be careful when using them to avoid memory problems
If we created a Pointer to a (Local Variable)
This local variable will be deleted from the memory after the end of the function/method execution
This means that the pointer created with Object2Pointer() will becomes a dangling pointer
i.e. A pointer that points to the memory location of the deallocated memory
Using this invalid pointer could lead to (CRASH or Memory Corruption).
If you will use pointers (Using Object2Pointer() or Pointer2Object) then never use pointers that point to the memory that are deallocated.
In simple words, Keep the memory (Don’t delete it if you still need it)
i.e. instead of using (Local Variables) that will be deleted, You can use Class Attributes or Global Variables.
ispointer() function¶
Check if the parameter is a pointer (C Object) or not.
Syntax:
IsPtr(vPara) ---> True|False # Short name
IsPointer(vPara) ---> True|False # Long name
Example :
fp = fopen(filename(),"r")
? type(fp)
? ispointer(fp)
Output :
file
1
ptrcmp() function¶
We can compare between two pointers (C Objects) using the ptrcmp() function.
Syntax:
ptrcmp(oObject1,oObject2) ---> value = 1 if oObject1 = oObject2
value = 0 if oObject1 != oObject2
pointercompare(oObject1,oObject2) ---> value = 1 if oObject1 = oObject2
value = 0 if oObject1 != oObject2
Example:
fp = fopen("ptrcmp.ring","r")
fp2 = fp
fp3 = fopen("ptrcmp.ring","r")
see ptrcmp(fp,fp2) + nl
see ptrcmp(fp,fp3) + nl
fclose(fp)
fclose(fp3)
Output:
1
0
setpointer() function¶
Set the pointer address to another address
Syntax:
setptr(pointer,nNewAddress) # Short name
setpointer(pointer,nNewAddress) # Long name
Note
Using setPointer() and getPointer() functions we can change the Memory Address
getpointer() function¶
Get the pointer address
Syntax:
getptr(pointer) ---> nAddress # Short name
getpointer(pointer) ---> nAddress # Long name
Example:
? "Sample about using setPointer() and getPointer() functions"
? copy("=",50)
pointer = NULLPOINTER()
? pointer
? "Type: " + type(pointer)
? "Address: " + Upper(hex(getpointer(pointer)))
? copy("=",50)
name = "ring"
pointer = varptr(:name,:char)
? pointer
? "Type: " + type(pointer)
? "Address: " + Upper(hex(getpointer(pointer)))
? copy("=",50)
setpointer(pointer, getpointer(pointer) + 1 )
? "After Update"
? "Address: " + Upper(hex(getpointer(pointer)))
? copy("=",50)
Output:
==================================================
00000000
NULLPOINTER
0
Type: NULLPOINTER
Address: 0
==================================================
026E2BA8
char
0
Type: char
Address: 26E2BA8
==================================================
After Update
Address: 26E2BA9
==================================================
pointer2string() function¶
Convert a pointer to a string of binary data
If you want to convert the string to a pointer again use VarPtr() function
Syntax:
ptr2str(pointer,nStart,nCount) ---> cString # Short name
pointer2string(pointer,nStart,nCount) ---> cString # Long name
Note
pointer2String() return another copy of the data
Note
if nStart is Zero, this means starting from the first character
Example:
name = "ring"
pointer = varptr(:name,:char)
? pointer
? "Type: " + type(pointer)
? "Address: " + Upper(hex(getpointer(pointer)))
? "Get 4 bytes starting from the pointer address"
mystring = Pointer2String(pointer,0,4)
? mystring
? "Get 2 bytes starting from the pointer address + 1"
mystring2 = Pointer2String(pointer,1,2)
? mystring2
Output:
01E03380
char
0
Type: char
Address: 1E03380
Get 4 bytes starting from the pointer address
ring
Get 2 bytes starting from the pointer address + 1
in
memcpy() function¶
Syntax:
memcpy(pDestinationPointer,cSourceString,nSize) # Short name
memorycopy(pDestinationPointer,cSourceString,nSize) # Long name
Example:
str = space(9)
pointer = varptr(:str,"char")
memcpy(pointer,"one",3)
? str
setPointer(pointer,getPointer(pointer)+3)
memcpy(pointer,"one",3)
? str
setPointer(pointer,getPointer(pointer)+3)
memcpy(pointer,"one",3)
? str
Output:
one
oneone
oneoneone
ringvm_cfunctionslist() function¶
The Function return a list of functions written in C.
Syntax:
RingVM_CFunctionsList() ---> List
Example:
See RingVM_CFunctionsList()
ringvm_functionslist() function¶
The Function return a list of functions written in Ring.
Each List Member is a list contains the next items
Function Name
Program Counter (PC) - Function Position in Byte Code.
Source Code File Name
Private Flag (For Private Methods in Classes)
Syntax:
RingVM_FunctionsList() ---> List
Example:
test()
func test
see ringvm_functionslist()
Output:
test
8
B:/ring/tests/scripts/functionslist.ring
0
ringvm_classeslist() function¶
The Function return a list of Classes.
Each List Member is a list contains the next items
Class Name
Program Counter (PC) - Class Position in Byte Code.
Parent Class Name
Methods List
Flag (Is parent class information collected)
Pointer to the package (or NULL if no package is used)
Syntax:
RingVM_ClassesList() ---> List
Example:
see ringvm_classeslist()
class class1
func f1
class class2 from class1
class class3 from class1
Output:
class1
9
f1
13
B:/ring/tests/scripts/classeslist.ring
0
0
00000000
class2
16
class1
0
00000000
class3
20
class1
0
00000000
ringvm_packageslist() function¶
The Function return a list of Packages.
Each List Member is a list contains the next items
Package Name
Classes List
Syntax:
RingVM_PackagesList() ---> List
Example:
see ringvm_packageslist()
package package1
class class1
package package2
class class1
package package3
class class1
Output:
package1
class1
11
0
00FEF838
package2
class1
17
0
00FEF978
package3
class1
23
0
00FEFF68
ringvm_memorylist() function¶
The Function return a list of Memory Scopes and Variables.
Each List Member is a list contains variables in a different scope.
Each Item in the scope list is a list contains the next items
Variable Name
Variable Type
Variable Value
Pointer Type (List/Item) if the value is a list
Private Flag (if the variable is an attribute in a Class)
Syntax:
RingVM_MemoryList() ---> List
Example:
x = 10
test()
func test
y = 20
see ringvm_memorylist()
Output:
true
2
1
0
0
false
2
0
0
0
nl
1
0
0
null
1
0
0
ring_gettemp_var
4
00000000
0
0
ccatcherror
1
NULL
0
0
ring_settemp_var
4
00000000
0
0
ring_tempflag_var
2
0
0
0
stdin
3
50512DB8
file
0
0
0
stdout
3
50512DD8
file
0
0
0
stderr
3
50512DF8
file
0
0
0
this
4
00000000
0
0
sysargv
3
B:\ring\bin/ring
B:/ring/tests/scripts/memorylist.ring
0
0
x
2
10
0
0
y
2
20
0
0
ringvm_calllist() function¶
The Function return a list of the functions call list.
Each List Member is a list contains the next items
Function Type
Function Name
Program Counter (PC)
Stack Pointer (SP)
Temp. Memory List
Method or Function Flag
Caller PC
FuncExec Flag
ListStart Flag
Nested Lists Pointer
State List
Syntax:
RingVM_CallList() ---> List
Example:
hello()
func hello
test()
func test
mylist = ringvm_calllist()
for t in mylist see t[2] + nl next
Output:
function hello() in file B:/ring/tests/scripts/calllist.ring
called from line 1
function test() in file B:/ring/tests/scripts/calllist.ring
called from line 3
ringvm_calllist
ringvm_fileslist() function¶
Function return a list of the Ring Files.
Syntax:
RingVM_FilesList() ---> List
Example:
load "stdlib.ring"
see ringvm_fileslist()
Output:
B:/ring/tests/scripts/fileslist.ring
B:\ring\bin\stdlib.ring
eval
stdlib.ring
stdlib.rh
stdclasses.ring
stdfunctions.ring
stdbase.ring
stdstring.ring
stdlist.ring
stdstack.ring
stdqueue.ring
stdmath.ring
stddatetime.ring
stdfile.ring
stdsystem.ring
stddebug.ring
stddatatype.ring
stdconversion.ring
stdodbc.ring
stdmysql.ring
stdsecurity.ring
stdinternet.ring
stdhashtable.ring
stdtree.ring
ringvm_settrace()¶
The function ringvm_settrace() determine the Trace function name
The trace function is a Ring function that will be called for each event
Syntax:
RingVM_SetTrace(cCode)
ringvm_tracedata()¶
Inside the function that we will use for tracing events
We can use the ringvm_tracedata() function to get the event data.
The event data is a list contains the next items
The Source Code Line Number
The Source File Name
The Function/Method Name
Method or Function (Bool : True=Method, False=Function/File)
Syntax:
RingVM_TraceData() ---> aDataList
ringvm_traceevent()¶
Inside the function that we will use for tracing events
We can use ringvm_traceevent() to know the event type
New Line
Before Function
After Function
Runtime Error
Before C Function
After C Function
Syntax:
RingVM_TraceEvent() ---> nTraceEvent
ringvm_tracefunc()¶
The function return the name of the function that we are using for tracing events.
Syntax:
RingVM_TraceEvent() ---> cCode
ringvm_scopescount()¶
We can use the RingVM_ScopesCount() function to know the number of scopes used in the application.
In the start of the program, We have the (global scope only)
When we call a function, A new scope is created.
When the function execution is done, the function scope is deleted.
Syntax:
RingVM_ScopesCount() ---> nScopes
ringvm_evalinscope()¶
The function ringvm_evalinscope() is similar to the eval() function
Unlike eval() which execute the code in the current scope
Using RingVM_EvalInScope() we can execute the code in a specific scope.
Syntax:
RingVM_EvalInScope(nScope,cCode)
ringvm_passerror()¶
When we have runtime error, After printing the Error message, Ring will end the execution of the program.
Using ringvm_passerror() we can avoid that, and continue the execution of our program.
Syntax:
RingVM_PassError()
ringvm_hideerrormsg()¶
We can disable/enable displaying the runtime error messages using the RingVM_HideErrorMsg() function.
Syntax:
RingVM_HideErrorMsg(lStatus)
ringvm_callfunc()¶
We can call a function from a string without using eval() using the ringvm_callfunc()
Syntax:
RingVM_CallFunc(cFuncName)
Example - Using the Trace Functions¶
The next example use the Trace Functions to trace the program Events!
In practical, We will use the Trace Library instead of these low level functions!
load "tracelib.ring"
ringvm_settrace("mytrace()")
see "Hello, world!" + nl
see "Welcome" + nl
see "How are you?" +nl
mytest()
new myclass { mymethod() }
func mytest
see "Message from mytest" + nl
func mytrace
see "====== The Trace function is Active ======" + nl +
"Trace Function Name : " + ringvm_TraceFunc() + nl +
"Trace Event : "
switch ringvm_TraceEvent()
on TRACEEVENT_NEWLINE see "New Line"
on TRACEEVENT_NEWFUNC see "New Function"
on TRACEEVENT_RETURN see "Return"
on TRACEEVENT_ERROR see "Error"
on TRACEEVENT_BEFORECFUNC see "Before C Function"
on TRACEEVENT_AFTERCFUNC see "After C Function"
off
see nl +
"Line Number : " + ringvm_tracedata()[TRACEDATA_LINENUMBER] + nl +
"File Name : " + ringvm_tracedata()[TRACEDATA_FILENAME] + nl +
"Function Name : " + ringvm_tracedata()[TRACEDATA_FUNCNAME] + nl +
"Method or Function : "
if ringvm_tracedata()[TRACEDATA_METHODORFUNC] =
TRACEDATA_METHODORFUNC_METHOD
see "Method"
else
if ringvm_tracedata()[TRACEDATA_FUNCNAME] = NULL
see "Command"
else
see "Function"
ok
ok
see nl + Copy("=",42) + nl
class myclass
func mymethod
see "Message from mymethod" + nl
Output:
====== The Trace function is Active ======
Trace Function Name : mytrace()
Trace Event : After C Function
Line Number : 3
File Name : test1.ring
Function Name : ringvm_settrace
Method or Function : Function
==========================================
====== The Trace function is Active ======
Trace Function Name : mytrace()
Trace Event : New Line
Line Number : 5
File Name : test1.ring
Function Name :
Method or Function : Command
==========================================
Hello, world!
====== The Trace function is Active ======
Trace Function Name : mytrace()
Trace Event : New Line
Line Number : 6
File Name : test1.ring
Function Name :
Method or Function : Command
==========================================
Welcome
====== The Trace function is Active ======
Trace Function Name : mytrace()
Trace Event : New Line
Line Number : 7
File Name : test1.ring
Function Name :
Method or Function : Command
==========================================
How are you?
====== The Trace function is Active ======
Trace Function Name : mytrace()
Trace Event : New Line
Line Number : 8
File Name : test1.ring
Function Name :
Method or Function : Command
==========================================
====== The Trace function is Active ======
Trace Function Name : mytrace()
Trace Event : New Function
Line Number : 8
File Name : test1.ring
Function Name : mytest
Method or Function : Function
==========================================
====== The Trace function is Active ======
Trace Function Name : mytrace()
Trace Event : New Line
Line Number : 12
File Name : test1.ring
Function Name : mytest
Method or Function : Function
==========================================
Message from mytest
====== The Trace function is Active ======
Trace Function Name : mytrace()
Trace Event : New Line
Line Number : 14
File Name : test1.ring
Function Name : mytest
Method or Function : Function
==========================================
====== The Trace function is Active ======
Trace Function Name : mytrace()
Trace Event : Return
Line Number : 8
File Name : test1.ring
Function Name :
Method or Function : Command
==========================================
====== The Trace function is Active ======
Trace Function Name : mytrace()
Trace Event : New Line
Line Number : 9
File Name : test1.ring
Function Name :
Method or Function : Command
==========================================
====== The Trace function is Active ======
Trace Function Name : mytrace()
Trace Event : New Line
Line Number : 43
File Name : test1.ring
Function Name :
Method or Function : Command
==========================================
====== The Trace function is Active ======
Trace Function Name : mytrace()
Trace Event : Before C Function
Line Number : 9
File Name : test1.ring
Function Name : ismethod
Method or Function : Function
==========================================
====== The Trace function is Active ======
Trace Function Name : mytrace()
Trace Event : After C Function
Line Number : 9
File Name : test1.ring
Function Name : ismethod
Method or Function : Function
==========================================
====== The Trace function is Active ======
Trace Function Name : mytrace()
Trace Event : New Function
Line Number : 9
File Name : test1.ring
Function Name : mymethod
Method or Function : Method
==========================================
====== The Trace function is Active ======
Trace Function Name : mytrace()
Trace Event : New Line
Line Number : 44
File Name : test1.ring
Function Name : mymethod
Method or Function : Method
==========================================
Message from mymethod
====== The Trace function is Active ======
Trace Function Name : mytrace()
Trace Event : Return
Line Number : 9
File Name : test1.ring
Function Name :
Method or Function : Command
==========================================
====== The Trace function is Active ======
Trace Function Name : mytrace()
Trace Event : Before C Function
Line Number : 9
File Name : test1.ring
Function Name : ismethod
Method or Function : Function
==========================================
====== The Trace function is Active ======
Trace Function Name : mytrace()
Trace Event : After C Function
Line Number : 9
File Name : test1.ring
Function Name : ismethod
Method or Function : Function
==========================================
====== The Trace function is Active ======
Trace Function Name : mytrace()
Trace Event : Before C Function
Line Number : 9
File Name : test1.ring
Function Name : ismethod
Method or Function : Function
==========================================
====== The Trace function is Active ======
Trace Function Name : mytrace()
Trace Event : After C Function
Line Number : 9
File Name : test1.ring
Function Name : ismethod
Method or Function : Function
==========================================
====== The Trace function is Active ======
Trace Function Name : mytrace()
Trace Event : New Line
Line Number : 11
File Name : test1.ring
Function Name :
Method or Function : Command
==========================================
Example - The Trace Library¶
The next example uses the Trace functions provided by the Ring language to create the Trace library.
Using the Trace library we have nice Tracing tools and Interaction debugger too.
# Trace Events
TRACEEVENT_NEWLINE = 1
TRACEEVENT_NEWFUNC = 2
TRACEEVENT_RETURN = 3
TRACEEVENT_ERROR = 4
TRACEEVENT_BEFORECFUNC = 5
TRACEEVENT_AFTERCFUNC = 6
# Trace Data
TRACEDATA_LINENUMBER = 1
TRACEDATA_FILENAME = 2
TRACEDATA_FUNCNAME = 3
TRACEDATA_METHODORFUNC = 4
# Method of Function
TRACEDATA_METHODORFUNC_METHOD = TRUE
TRACEDATA_METHODORFUNC_NOTMETHOD = FALSE
TRACE_BREAKPOINTS = TRUE
TRACE_TEMPLIST = []
func Trace cType
switch trim(lower(cType))
on :AllEvents
ringvm_settrace("TraceLib_AllEvents()")
on :Functions
ringvm_settrace("TraceLib_Functions()")
on :PassError
ringvm_settrace("TraceLib_PassError()")
on :Debugger
ringvm_settrace("TraceLib_Debugger()")
on :LineByLine
ringvm_settrace("TraceLib_LineByLine()")
off
func TraceLib_AllEvents
if right(ringvm_tracedata()[TRACEDATA_FILENAME],13) = "tracelib.ring"
return
ok
see "====== The Trace function is Active ======" + nl +
"Trace Function Name : " + ringvm_TraceFunc() + nl +
"Trace Event : "
switch ringvm_TraceEvent()
on TRACEEVENT_NEWLINE see "New Line"
on TRACEEVENT_NEWFUNC see "New Function"
on TRACEEVENT_RETURN see "Return"
on TRACEEVENT_ERROR see "Error"
on TRACEEVENT_BEFORECFUNC see "Before C Function"
on TRACEEVENT_AFTERCFUNC see "After C Function"
off
see nl +
"Line Number : " + ringvm_tracedata()[TRACEDATA_LINENUMBER] + nl +
"File Name : " + ringvm_tracedata()[TRACEDATA_FILENAME] + nl +
"Function Name : " + ringvm_tracedata()[TRACEDATA_FUNCNAME] + nl +
"Method or Function : "
if ringvm_tracedata()[TRACEDATA_METHODORFUNC] =
TRACEDATA_METHODORFUNC_METHOD
see "Method"
else
if ringvm_tracedata()[TRACEDATA_FUNCNAME] = NULL
see "Command"
else
see "Function"
ok
ok
see nl + Copy("=",42) + nl
func TraceLib_Functions
if right(ringvm_tracedata()[TRACEDATA_FILENAME],13) = "tracelib.ring"
return
ok
switch ringvm_TraceEvent()
on TRACEEVENT_NEWFUNC
see "Open Func : " +
ringvm_TraceData()[TRACEDATA_FUNCNAME] + nl
on TRACEEVENT_RETURN
see "Return to Func : " +
ringvm_TraceData()[TRACEDATA_FUNCNAME] + nl
off
func TraceLib_PassError
if right(ringvm_tracedata()[TRACEDATA_FILENAME],13) = "tracelib.ring"
return
ok
switch ringvm_TraceEvent()
on TRACEEVENT_ERROR
see nl
see "TraceLib : After Error !" + nl
ringvm_passerror()
off
func TraceLib_Debugger
if right(ringvm_tracedata()[TRACEDATA_FILENAME],13) = "tracelib.ring"
return
ok
switch ringvm_TraceEvent()
on TRACEEVENT_ERROR
_BreakPoint()
off
func TraceLib_LineByLine
if right(ringvm_tracedata()[TRACEDATA_FILENAME],13) = "tracelib.ring" or
ringvm_TraceEvent() != TRACEEVENT_NEWLINE
return
ok
aList = ringvm_tracedata()
see "Before Line : " + aList[TRACEDATA_LINENUMBER] + nl
_BreakPoint()
func BreakPoint
if not TRACE_BREAKPOINTS
return
ok
_BreakPoint()
func _BreakPoint
see nl+nl+Copy("=",60) + nl +
Copy(" ",20)+"Interactive Debugger" + nl +
Copy("=",60) + nl +
"Command (Exit) : End Program" + nl +
"Command (Cont) : Continue Execution" + nl +
"Command (Locals) : Print local variables names" + nl +
"Command (LocalsData) : Print local variables data" + nl +
"Command (Globals) : Print global variables names" + nl +
"We can execute Ring code" + nl +
Copy("=",60) + nl
while true
see nl + "code:> "
give cCode
cmd = trim(lower(cCode))
if cmd = "exit" or cmd = "bye"
shutdown()
ok
nScope = ringvm_scopescount()-2
switch cmd
on "locals"
ringvm_EvalInScope(nScope,"see locals() callgc()")
loop
on "localsdata"
PrintLocalsData(nScope)
loop
on "globals"
ringvm_EvalInScope(nScope,"see globals() callgc()")
loop
on "cont"
ringvm_passerror()
exit
off
Try
ringvm_EvalInScope(nScope,cCode)
catch
see cCatchError
done
end
func NoBreakPoints
TRACE_BREAKPOINTS = FALSE
func PrintLocalsData nScope
if nScope = 1 # Global
ringvm_Evalinscope(nScope,'TRACE_TEMPLIST = globals()')
else
ringvm_Evalinscope(nScope,'TRACE_TEMPLIST = locals() callgc()')
ok
see nl
aTempList = TRACE_TEMPLIST
TRACE_TEMPLIST = []
nSpaces = 5
for TRACE_ITEM in aTempList
if len(TRACE_ITEM) + 5 > nSpaces
nSpaces = len(TRACE_ITEM) + 5
ok
next
for TRACE_ITEM in aTempList
see "Variable : " + TRACE_ITEM
cVarName = TRACE_ITEM
see copy(" ",nSpaces-len(cVarName)) + " Type : "
ringvm_Evalinscope(nScope,"see type(" + TRACE_ITEM +")")
ringvm_Evalinscope(nScope,"see Copy(' ',fabs(15-len(type(" +
TRACE_ITEM +"))))")
see " Value : "
ringvm_Evalinscope(nScope,"see " + TRACE_ITEM)
see nl
next
ringvm_see() function¶
Using the ringvm_see() function we can redefine the behavior of the See command
Also we can use ring_see() to have the original behavior
Example:
see "Hello world" + nl
see 123 + nl
see ["one","two","three"]
see new point {x=10 y=20 z=30}
func ringvm_see t
ring_see("We want to print: ")
ring_See(t)
class point x y z
Output:
We want to print: Hello world
We want to print: 123
We want to print: one
two
three
We want to print: x: 10.000000
y: 20.000000
z: 30.000000
ringvm_give() function¶
Using the ringvm_give() function we can redefine the behavior of the Give command
Example:
see "Name: " give name
see "Hello " + name
func ringvm_give
see "Mahmoud" + nl
return "Mahmoud"
Output:
Name: Mahmoud
Hello Mahmoud
ringvm_info() function¶
The ringvm_info() is an internal function that return a list of information about the Ring VM structure.
It’s used only by the Ring Team in advanced tests to check the VM status.
Syntax:
ringvm_info() ---> List of information about the VM structure