The Ring Programming Language Version 1.4.1 Book - Part 21 of 31
The Ring Programming Language Version 1.4.1 Book - Part 21 of 31
EndLine
===================================================
Command:
ring test.ring -rules -norun
Output:
===================================================
Grammar Rules Used by The Parser
===================================================
Line 1
Rule : Statement --> 'Func' Identifier [ParaList]
Line 2
Rule : Factor --> Literal
Rule : Range --> Factor
Rule : Term --> Range
Rule : Arithmetic --> Term
Rule : Factor --> Identifier [ {Mixer} | Assignment | PlusPlus | MinusMinus]
Rule : Range --> Factor
Rule : Term --> Range
Rule : Arithmetic --> Term
Rule : Arithmetic --> Arithmetic + Arithmetic
Rule : BitShift --> Arithmetic
Rule : BitAnd --> BitShift
Rule : BitOrXOR --> BitAnd
Rule : Compare --> BitOrXOR
Rule : EqualOrNot --> Compare
Rule : LogicNot -> EqualOrNot
Rule : Expr --> LogicNot
Rule : Statement --> 'See' Expr
Line 3
Rule : Factor --> Number
Rule : Range --> Factor
Rule : Term --> Range
Rule : Arithmetic --> Term
Rule : BitShift --> Arithmetic
Rule : BitAnd --> BitShift
Rule : BitOrXOR --> BitAnd
Rule : Compare --> BitOrXOR
Rule : EqualOrNot --> Compare
Rule : LogicNot -> EqualOrNot
Rule : Expr --> LogicNot
Rule : Factor --> Number
Rule : Range --> Factor
Rule : Term --> Range
Rule : Arithmetic --> Term
Rule : BitShift --> Arithmetic
Line 4
Rule : Factor --> Identifier [ {Mixer} | Assignment | PlusPlus | MinusMinus]
Rule : Range --> Factor
Rule : Term --> Range
Rule : Arithmetic --> Term
Rule : Factor --> Identifier [ {Mixer} | Assignment | PlusPlus | MinusMinus]
Rule : Range --> Factor
Rule : Term --> Range
Rule : Arithmetic --> Term
Rule : Arithmetic --> Arithmetic + Arithmetic
Rule : BitShift --> Arithmetic
Rule : BitAnd --> BitShift
Rule : BitOrXOR --> BitAnd
Rule : Compare --> BitOrXOR
Rule : EqualOrNot --> Compare
Rule : LogicNot -> EqualOrNot
Rule : Expr --> LogicNot
Rule : Statement --> 'See' Expr
Line 5
Rule : Next --> 'Next'
Line 6
Rule : Mixer -> '(' [Expr { ',' Expr} ] ')'
Line 8
Rule : Factor --> Identifier [ {Mixer} | Assignment | PlusPlus | MinusMinus]
Rule : Range --> Factor
Rule : Term --> Range
Rule : Arithmetic --> Term
Rule : BitShift --> Arithmetic
Rule : BitAnd --> BitShift
Rule : BitOrXOR --> BitAnd
Rule : Compare --> BitOrXOR
Rule : EqualOrNot --> Compare
Rule : LogicNot -> EqualOrNot
Rule : Expr --> LogicNot
Rule : Statement --> Expr
Rule : Statement --> 'Func' Identifier [ParaList]
Line 9
Rule : Factor --> Literal
Rule : Range --> Factor
Rule : Term --> Range
Rule : Arithmetic --> Term
Rule : Factor --> Identifier [ {Mixer} | Assignment | PlusPlus | MinusMinus]
Rule : Range --> Factor
Rule : Term --> Range
Rule : Arithmetic --> Term
Rule : Arithmetic --> Arithmetic + Arithmetic
Line 10
Rule : Factor --> New Identifier {'.' Identifier }
Rule : Mixer --> '{' {Statement} BraceEnd
Rule : Factor --> Number
Rule : Range --> Factor
Rule : Term --> Range
Rule : Arithmetic --> Term
Rule : BitShift --> Arithmetic
Rule : BitAnd --> BitShift
Rule : BitOrXOR --> BitAnd
Rule : Compare --> BitOrXOR
Rule : EqualOrNot --> Compare
Rule : LogicNot -> EqualOrNot
Rule : Expr --> LogicNot
Rule : Assignment -> '=' Expr
Rule : Factor --> Identifier [ {Mixer} | Assignment | PlusPlus | MinusMinus]
Rule : Range --> Factor
Rule : Term --> Range
Rule : Arithmetic --> Term
Rule : BitShift --> Arithmetic
Rule : BitAnd --> BitShift
Rule : BitOrXOR --> BitAnd
Rule : Compare --> BitOrXOR
Rule : EqualOrNot --> Compare
Rule : LogicNot -> EqualOrNot
Rule : Expr --> LogicNot
Rule : Statement --> Expr
Rule : Factor --> Number
Rule : Range --> Factor
Rule : Term --> Range
Rule : Arithmetic --> Term
Rule : BitShift --> Arithmetic
Rule : BitAnd --> BitShift
Rule : BitOrXOR --> BitAnd
Rule : Compare --> BitOrXOR
Rule : EqualOrNot --> Compare
Rule : LogicNot -> EqualOrNot
Rule : Expr --> LogicNot
Rule : Assignment -> '=' Expr
Rule : Factor --> Identifier [ {Mixer} | Assignment | PlusPlus | MinusMinus]
Rule : Range --> Factor
Rule : Term --> Range
Rule : Arithmetic --> Term
Rule : BitShift --> Arithmetic
Rule : BitAnd --> BitShift
Rule : BitOrXOR --> BitAnd
Rule : Compare --> BitOrXOR
Rule : EqualOrNot --> Compare
Rule : LogicNot -> EqualOrNot
Line 11
Rule : Factor --> Identifier [ {Mixer} | Assignment | PlusPlus | MinusMinus]
Rule : Range --> Factor
Rule : Term --> Range
Rule : Arithmetic --> Term
Rule : BitShift --> Arithmetic
Rule : BitAnd --> BitShift
Line 13
Rule : Statement --> 'Class' Identifier
Rule : Factor --> Identifier [ {Mixer} | Assignment | PlusPlus | MinusMinus]
Rule : Range --> Factor
Rule : Term --> Range
Rule : Arithmetic --> Term
Rule : BitShift --> Arithmetic
Rule : BitAnd --> BitShift
Rule : BitOrXOR --> BitAnd
Rule : Compare --> BitOrXOR
Rule : EqualOrNot --> Compare
Rule : LogicNot -> EqualOrNot
Rule : Expr --> LogicNot
Rule : Statement --> Expr
Rule : Factor --> Identifier [ {Mixer} | Assignment | PlusPlus | MinusMinus]
Rule : Range --> Factor
Rule : Term --> Range
Rule : Arithmetic --> Term
Rule : BitShift --> Arithmetic
Rule : BitAnd --> BitShift
Rule : BitOrXOR --> BitAnd
Rule : Compare --> BitOrXOR
Rule : EqualOrNot --> Compare
Rule : LogicNot -> EqualOrNot
Rule : Expr --> LogicNot
Rule : Statement --> Expr
Rule : Factor --> Identifier [ {Mixer} | Assignment | PlusPlus | MinusMinus]
Rule : Range --> Factor
Rule : Term --> Range
Rule : Arithmetic --> Term
Rule : BitShift --> Arithmetic
Rule : BitAnd --> BitShift
Rule : BitOrXOR --> BitAnd
Rule : Compare --> BitOrXOR
Rule : EqualOrNot --> Compare
Rule : LogicNot -> EqualOrNot
Rule : Expr --> LogicNot
Rule : Statement --> Expr
===================================================
Command:
ring test.ring -ic -norun
Output:
===================================================
Byte Code - Before Execution by the VM
===================================================
PC OPCode Data
1 ReturnNull
2 Func main
3 NewLine 2
4 FuncExE
5 PushC Hello World
6 LoadA nl 0
7 PushV
8 SUM 0
9 Print
10 NewLine 3
11 ExitMark 29 28
12 LoadAFirst x
13 PushN 1.000000
14 BeforeEqual 0
15 Assignment
16 PushN 1.000000
17 StepNumber
18 JumpVarLENum x 10.000000 29
19 NewLine 4
20 FuncExE
21 LoadA x 0
22 PushV
23 LoadA nl 0
24 PushV
25 SUM 0
26 Print
27 NewLine 5
28 IncJump x 18
29 POPExitMark
30 POPStep
31 NewLine 6
32 LoadFunc test
33 Call 0
34 NoOperation
35 NewLine 8
36 PushV
37 FreeStack
38 ReturnNull
39 Func test
40 NewLine 9
41 FuncExE
42 PushC welcome
43 LoadA nl 0
44 PushV
45 SUM 0
46 Print
47 NewLine 10
48 LoadA o1 0
49 AssignmentPointer
50 New point
51 SetScope
52 PushV
53 BraceStart
54 LoadA x 0 58
55 AssignmentPointer
56 PushN 10.000000
57 BeforeEqual 0
58 Assignment 0 0
59 FreeStack
60 LoadA y 0 64
61 AssignmentPointer
62 PushN 20.000000
63 BeforeEqual 0
64 Assignment 0 0
65 FreeStack
66 LoadA z 0 70
67 AssignmentPointer
68 PushN 30.000000
69 BeforeEqual 0
70 Assignment 0 0
71 FreeStack
72 LoadFunc ismethod
73 LoadA self 0
74 PushV
75 PushC braceend
76 Call
77 NoOperation
78 PushV
79 JumpZ 85
80 LoadFunc braceend
81 Call
82 NoOperation
83 PushV
84 FreeStack
85 BraceEnd
86 FreeStack
87 NewLine 11
88 FuncExE
89 LoadA o1 0
90 PushV
91 Print
92 NewLine 13
93 ReturnNull
94 Class point 006E8BC0
95 NewLabel
96 LoadA x 0
97 PushV
98 FreeStack
99 LoadA y 0
100 PushV
101 FreeStack
102 LoadA z 0
103 PushV
104 FreeStack
105 ReturnNull
===================================================
Command:
ring test.ring -icfinal
Output:
Hello World
1
2
3
4
5
6
7
8
9
10
welcome
x: 10.000000
y: 20.000000
z: 30.000000
===================================================
Byte Code - After Execution by the VM
===================================================
PC OPCode Data
1 ReturnNull
2 Func main
3 NewLine 2
4 FuncExE
5 PushC Hello World
6 PushP 007D3670 0
7 PushV
8 SUM 0
9 Print
10 NewLine 3
11 ExitMark 29 28
12 LoadAFirst x
13 PushN 1.000000
14 BeforeEqual 0
15 Assignment
16 PushN 1.000000
17 StepNumber
18 JumpVarLPLENum x 10.000000 29
19 NewLine 4
20 FuncExE
21 PushPLocal x 0
22 PushV
23 PushP 007D3670 0
24 PushV
25 SUM 0
26 Print
27 NewLine 5
28 IncLPJump x 18
29 POPExitMark
30 POPStep
31 NewLine 6
32 LoadFuncP test
33 Call 0
34 NoOperation
35 NewLine 8
36 PushV
37 FreeStack
38 ReturnNull
39 Func test
40 NewLine 9
41 FuncExE
42 PushC welcome
43 PushP 007D3670 0
44 PushV
45 SUM 0
46 Print
47 NewLine 10
48 PushPLocal o1 0
49 AssignmentPointer
50 New point
51 SetScope
52 PushV
53 BraceStart
54 LoadA x 0 58
55 AssignmentPointer
56 PushN 10.000000
57 BeforeEqual 0
58 SetProperty 0 106
59 FreeStack
60 LoadA y 0 64
61 AssignmentPointer
62 PushN 20.000000
63 BeforeEqual 0
64 SetProperty 0 141
65 FreeStack
66 LoadA z 0 70
67 AssignmentPointer
68 PushN 30.000000
69 BeforeEqual 0
70 SetProperty 0 176
71 FreeStack
72 LoadFunc ismethod
73 LoadA self 0
74 PushV
75 PushC braceend
76 Call
77 NoOperation
78 PushV
79 JumpZ 85
80 LoadFunc braceend
81 Call
82 NoOperation
83 PushV
84 FreeStack
85 BraceEnd
86 FreeStack
87 NewLine 11
88 FuncExE
89 PushPLocal o1 0
90 PushV
91 Print
92 NewLine 13
93 ReturnNull
94 Class point 007D8470
95 NewLabel
96 LoadA x 0
97 PushV
98 FreeStack
99 LoadA y 0
100 PushV
101 FreeStack
102 LoadA z 0
103 PushV
104 FreeStack
105 ReturnNull
106 LoadFunc ismethod
107 LoadA ring_gettemp_var 0
108 PushV
109 PushC setx
110 Call 0
111 NoOperation
112 PushV
113 JumpZ 132
114 NewLine 2
115 LoadA ring_gettemp_var 0
116 LoadMethod setx
117 LoadA ring_settemp_var 0
118 PushV
119 Call 0 1
120 AfterCallMethod
121 PushV
122 FreeStack
123 NewLine 3
124 LoadA ring_tempflag_var 0 128
125 AssignmentPointer
126 PushN 0.000000
127 BeforeEqual 0
128 Assignment 0 0
129 FreeStack
130 NewLine 4
131 Jump 140
132 NewLine 5
133 PushP 007D37D8 0 137
134 AssignmentPointer
135 PushN 1.000000
136 BeforeEqual 0
137 Assignment 0 0
138 FreeStack
139 NewLine 6
140 Return
141 LoadFunc ismethod
142 LoadA ring_gettemp_var 0
143 PushV
202 NewLine 5
203 PushP 007D37D8 0 207
204 AssignmentPointer
205 PushN 1.000000
206 BeforeEqual 0
207 Assignment 0 0
208 FreeStack
209 NewLine 6
210 Return
===================================================
Command:
ring test.ring -cgi
60.6 No Run
Command:
ring test.ring -norun
Command:
ring test.ring -ins
Output:
===================================================
Operation : ReturnNull
PC : 1
Line Number : 1 , File test.ring
SP (After) : 0 - FuncSP : 0
LineNumber 1
===================================================
.....
.....
.....
Tip: Output removed from the previous example because its very large!
60.8 Performance
Command:
Output:
===================================================
Date : 2015/09/15 Time : 15:56:17
Clock : 0
===================================================
Hello World
1
2
3
4
5
6
7
8
9
10
welcome
x: 10.000000
y: 20.000000
z: 30.000000
===================================================
Date : 2015/09/15 Time : 15:56:17
Clock : 0
===================================================
You can generate object file (.ringo) from your source code file (.ring) using -go option
Tip: You will get one object file to use for distributing/running your application which may contains one or many
ring source files that you can keep or distribute based on the application (commercial or open source).
Command:
ring test.ring -go
SIXTYONE
In this chapter we will learn about the low level functions provided by Ring
callgc()
varptr()
space()
nullpointer()
object2pointer()
pointer2object()
ptrcmp()
ringvm_cfunctionslist()
ringvm_functionslist()
ringvm_classeslist()
ringvm_packageslist()
ringvm_memorylist()
ringvm_calllist()
ringvm_fileslist()
Use this function to force calling the garbage collector during function execution when you use a loop that create temp.
variables that you dont free using the assignment operation.
Its very rare to need this function but its 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"])
591
Ring Documentation, Release 1.4.1
Tip: In Ring the garbage collector works automatically in the end of function execution or when you use the assign-
ment statement.
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)
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)
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.
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 doesnt work alone, you need to learn how to use RingSDL first.
Use this function to get a C pointer for Ring lists and objects
Syntax:
object2pointer(List|Object) --> Low Level Object ( C Pointer )
Use this function to get the Ring list and/or object from the low level object (C Pointer)
Syntax:
pointer2object(Low Level Object) ---> List|Object
Example:
# Create the list
mylist = 1:5
see nl
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 ob-
ject2pointer() 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).
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
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
Example:
See RingVM_CFunctionsList()
Example:
test()
func test
see ringvm_functionslist()
Output:
test
8
B:/ring/tests/scripts/functionslist.ring
0
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
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
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
Example:
hello()
func hello
test()
func test
mylist = ringvm_calllist()
for t in mylist see t[2] + nl next
Output:
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
SIXTYTWO
INTRODUCTION
In this chapter we will learn about embedding Ring in Ring programs and applications.
From Ring 1.0 we already have functions for embedding Ring in the C language. Also we can execute Ring code
inside Ring programs using the eval() function. In this release we provide functions for embedding Ring in Ring
programs without sharing the state.
Advantages:
1. Quick integration for Ring programs and applications together without conflicts.
2. Execute and run Ring code in safe environments that we can trace.
Example:
pState = ring_state_init()
ring_state_runcode(pState,"See 'Hello, World!'+nl")
ring_state_runcode(pState,"x = 10")
pState2 = ring_state_init()
ring_state_runcode(pState2,"See 'Hello, World!'+nl")
ring_state_runcode(pState2,"x = 20")
ring_state_runcode(pState,"see x +nl")
ring_state_runcode(pState2,"see x +nl")
v1 = ring_state_findvar(pState,"x")
v2 = ring_state_findvar(pState2,"x")
see v1[3] + nl
see V2[3] + nl
ring_state_delete(pState)
ring_state_delete(pState2)
Output:
Hello, World!
Hello, World!
10
20
10
20
601
Ring Documentation, Release 1.4.1
SIXTYTHREE
We can extend the Ring Virtual Machine (RingVM) by adding new functions written in the C programming language
or C++. The RingVM comes with many functions written in C that we can call like any Ring function.
We can extend the language by writing new functions then rebuilding the RingVM again, or we can create shared
library (DLL/So) file to extend the RingVM without the need to rebuild it.
The Ring language source code comes with two files to add new modules to the RingVM, ring_ext.h and ring_ext.c
63.1 ring_ext.h
The file ring_ext.h contains constants that we can change to include/exclude modules during the build process.
#ifndef ringext_h
#define ringext_h
/* Constants */
#define RING_VM_LISTFUNCS 1
#define RING_VM_REFMETA 1
#define RING_VM_MATH 1
#define RING_VM_FILE 1
#define RING_VM_OS 1
#define RING_VM_MYSQL 1
#define RING_VM_ODBC 1
#define RING_VM_OPENSSL 1
#define RING_VM_CURL 1
#define RING_VM_DLL 1
#endif
63.2 ring_ext.c
The file ring_ext.c check constants defined in ring_ext.h before calling the start-up function in each module.
Each module contains a function that register the module functions in the RingVM.
#include "ring.h"
603
Ring Documentation, Release 1.4.1
/* List Functions */
#if RING_VM_LISTFUNCS
ring_vm_listfuncs_loadfunctions(pRingState);
#endif
/* Math */
#if RING_VM_MATH
ring_vm_math_loadfunctions(pRingState);
#endif
/* File */
#if RING_VM_FILE
ring_vm_file_loadfunctions(pRingState);
#endif
/* OS */
#if RING_VM_OS
ring_vm_os_loadfunctions(pRingState);
#endif
/* MySQL */
#if RING_VM_MYSQL
ring_vm_mysql_loadfunctions(pRingState);
#endif
/* ODBC */
#if RING_VM_ODBC
ring_vm_odbc_loadfunctions(pRingState);
#endif
/* OPENSSL */
#if RING_VM_OPENSSL
ring_vm_openssl_loadfunctions(pRingState);
#endif
/* CURL */
#if RING_VM_CURL
ring_vm_curl_loadfunctions(pRingState);
#endif
/* DLL */
#if RING_VM_DLL
ring_vm_dll_loadfunctions(pRingState);
#endif
}
Each module starts by include the ring header file (ring.h). This files contains the Ring API that we can use to extend
the RingVM.
Each module comes with a function to register the module functions in the RingVM The registration is done by using
ring_vm_funcregister() function.
The ring_vm_funcregister() function takes two parameters, the first is the function name that will be used by Ring
programs to call the function. The second parameter is the function pointer in the C program.
for example, the ring_vmmath.c module contains the next code to register the module functions
#include "ring.h"
ring_vm_funcregister("tan",ring_vm_math_tan);
ring_vm_funcregister("asin",ring_vm_math_asin);
ring_vm_funcregister("acos",ring_vm_math_acos);
ring_vm_funcregister("atan",ring_vm_math_atan);
ring_vm_funcregister("atan2",ring_vm_math_atan2);
ring_vm_funcregister("sinh",ring_vm_math_sinh);
ring_vm_funcregister("cosh",ring_vm_math_cosh);
ring_vm_funcregister("tanh",ring_vm_math_tanh);
ring_vm_funcregister("exp",ring_vm_math_exp);
ring_vm_funcregister("log",ring_vm_math_log);
ring_vm_funcregister("log10",ring_vm_math_log10);
ring_vm_funcregister("ceil",ring_vm_math_ceil);
ring_vm_funcregister("floor",ring_vm_math_floor);
ring_vm_funcregister("fabs",ring_vm_math_fabs);
ring_vm_funcregister("pow",ring_vm_math_pow);
ring_vm_funcregister("sqrt",ring_vm_math_sqrt);
ring_vm_funcregister("unsigned",ring_vm_math_unsigned);
ring_vm_funcregister("decimals",ring_vm_math_decimals);
ring_vm_funcregister("murmur3hash",ring_vm_math_murmur3hash);
}
Tip: Remember that the function ring_vm_math_loadfunctions() will be called by the ring_vm_extension() function
(in the ring_ext.c file).
Example:
if ( RING_API_PARACOUNT == 1 ) {
/* code */
}
Note: the behaviour of this function can be changed by the Ring code using Try/Catch/Done statements, so in your C
code, use Return after this function.
Syntax:
RING_API_ERROR(const char *cErrorMsg);
The Ring API comes with some of predefined error messages that we can use
#define RING_API_MISS1PARA "Bad parameters count, the function expect one parameter"
#define RING_API_MISS2PARA "Bad parameters count, the function expect two parameters"
#define RING_API_MISS3PARA "Bad parameters count, the function expect three parameters"
#define RING_API_MISS4PARA "Bad parameters count, the function expect four parameters"
#define RING_API_BADPARATYPE "Bad parameter type!"
#define RING_API_BADPARACOUNT "Bad parameters count!"
#define RING_API_BADPARARANGE "Bad parameters value, error in range!"
#define RING_API_NOTPOINTER "Error in parameter, not pointer!"
#define RING_API_NULLPOINTER "Error in parameter, NULL pointer!"
#define RING_API_EMPTYLIST "Bad parameter, empty list!"
We can return values from our function using the next functions.
RING_API_RETNUMBER(double nValue);
RING_API_RETSTRING(const char *cString);
RING_API_RETSTRING2(const char *cString,int nStringSize);
RING_API_RETLIST(List *pList);
RING_API_RETCPOINTER(void *pValue,const char *cPointerType);
When we define new function to be used for RingVM extension, we use the next prototype
void my_function_name( void *pPointer );
The next code represents the sin() function implementation using the Ring API and the sin() C function.
void ring_vm_math_sin ( void *pPointer )
{
if ( RING_API_PARACOUNT != 1 ) {
RING_API_ERROR(RING_API_MISS1PARA);
return ;
}
if ( RING_API_ISNUMBER(1) ) {
RING_API_RETNUMBER(sin(RING_API_GETNUMBER(1)));
} else {
RING_API_ERROR(RING_API_BADPARATYPE);
}
}
The next code represents the fopen() function implementation using the Ring API and the fopen() C Function.
The function takes two parameters, the first parameter is the file name as string. The second parameter is the mode as
string.
In the file ring_vmfile.h we have some constants to use as the pointer type like
#define RING_VM_POINTER_FILE "file"
#define RING_VM_POINTER_FILEPOS "filepos"