You can integrate the V1 interpreter language with a simple C/C++ API into own applications.
Therefore download the newest development package from v1-script.net with precompiled v1.dll for Windows or libv1.so for Linux (libc >= 2.2 required) and VC++, GCC examples.
Here are 16 examples how to work with the C API. Take a look at v1.h to see all API functions.
Example 1: Hello World
#include <stdio.h> #include "v1.h" int main (int argc, char **argv) { v1Startup (); V1Context ctx = v1CreateContext (); // Evaluate V1 code const char* code = "print ('Hello World');"; v1Eval (ctx, code, strlen (code)); v1DeleteContext (ctx); v1Shutdown (); return 0; }
Example 2: Calculate a value
#include <stdio.h> #include "v1.h" int main (int argc, char **argv) { v1Startup (); V1Context ctx = v1CreateContext (); V1Data ret = v1CreateData (); // Evaluate V1 code and return a calculated value const char* code = "10+22*8;"; v1Eval (ctx, code, strlen (code), ret); printf ("Return: %g\r\n", v1Number(ret)); v1DeleteData (ret); v1DeleteContext (ctx); v1Shutdown (); return 0; }
Example 3: Execute a V1 script file
#include <stdio.h> #include "v1.h" int main (int argc, char **argv) { v1Startup (); // Execute a V1 filename v1Execute (ctx, "example.v1", argc, argv); v1Shutdown (); return 0; }
Example 4: Fetch a parser error
#include <stdio.h> #include "v1.h" int main (int argc, char **argv) { v1Startup (); V1Context ctx = v1CreateContext (); // Evaluate V1 code with parser error const char* code = "print X ('Hello World');"; int retCode = v1Eval (ctx, code, strlen (code)); if (v1Aborted (ctx)) printf ("Aborted with: %s\r\n", (const char*) v1LastError (ctx)); v1DeleteContext (ctx); v1Shutdown (); return 0; }
Example 5: Exit with exit code
#include <stdio.h> #include "v1.h" int main (int argc, char **argv) { v1Startup (); V1Context ctx = v1CreateContext (); // Exit with exit code const char* code = "exit(99);"; exitCode = v1Eval (ctx, code, strlen (code)); if (v1Exited (ctx)) printf ("Exit Code: %i\r\n", (int) exitCode); v1DeleteContext (ctx); v1Shutdown (); return 0; }
Example 6: Set own error function
#include <stdio.h> #include "v1.h" int myErrorFunc (const char* filename, int line, const char* text) { printf ("%s\r\n", text); return 0; } int main (int argc, char **argv) { v1Startup (); // Set own error function, otherwise errors will be printed to stdout/stderr v1SetErrorFunction (myErrorFunc); v1Shutdown (); return 0; }
Example 7: Working with own functions
#include <stdio.h> #include "v1.h" int myFunction (V1ArgList args, V1Data ret, V1Context ctx) { // Check if first parameter is set and at least a string value (also number, bool, null possible) if (v1Argument1NoString (args)) return V1_RET_PARAM1|V1_RET_NUM_REQUIRED; // Parameter 2 is required and must be an array if (v1ArgumentCount(args)<2 || v1Argument2Type (args)<V1_DATATYPE_ARRAY) return V1_RET_PARAM2|V1_RET_ARRAY_REQUIRED; // Parameter 3 is optional and must be a number value (also number, bool, null possible) if (v1ArgumentCount(args)>2 && v1Argument3Type (args)>V1_DATATYPE_STR) return V1_RET_PARAM3|V1_RET_NUM_REQUIRED; // Get the arguments printf ("myFunction() is called with %i arguments.\r\n", v1ArgumentCount(args)); V1Data arg1 = v1Argument(args,0); printf ("First argument: %s\r\n", v1String (arg1)); printf ("Second argument:\r\n"); V1Data arg2 = v1Argument(args,1); V1Data value; const char* key; v1ArrayIterate (arg2); while (value=v1ArrayNext (arg2, &key)) { printf ("%s => %s\r\n", (const char*) key, (const char*) v1String (value)); } if (v1ArgumentCount(args)>2) { V1Data arg3 = v1Argument(args,2); printf ("Third argument: %g\r\n", v1Number (arg3)); } /* // Raise a warning v1WarnInterprete (ctx, "Raise a warning"); */ /* // Abort, you can check if interpreter is aborted by v1IsAborted (ctx) v1AbortInterprete (ctx, "Now abort"); return V1_RET_ABORT; */ // Set return value as string v1SetString (ret, "My return value"); return 0; } int main (int argc, char **argv) { v1Startup (); V1Context ctx = v1CreateContext (); // Register own function and call it v1RegisterFunction (ctx, "myFunction", myFunction); const char* code = "print (myFunction ('Param 1', ['Param 2'=>'Value']));"; v1Eval (ctx, code, strlen (code)); v1DeleteContext (ctx); v1Shutdown (); return 0; }
Example 8: Set constants
#include <stdio.h> #include "v1.h" int main (int argc, char **argv) { v1Startup (); V1Context ctx = v1CreateContext (); // Set simple constants v1SetConstant (ctx, "MY_CONSTANT", 0, "MY STRING"); // String "MY STRING" v1SetConstant (ctx, "MY_CONSTANT2", 99, NULL); // Number 99 const char* code = "print (MY_CONSTANT);"\ "print (MY_CONSTANT2);"; v1Eval (ctx, code, strlen (code)); v1DeleteContext (ctx); v1Shutdown (); return 0; }
Example 9: Read and change a global variable written by V1
#include <stdio.h> #include "v1.h" int main (int argc, char **argv) { v1Startup (); V1Context ctx = v1CreateContext (); // Read a global variable written by V1 const char* code = "a = time ();"; v1Eval (ctx, code, strlen (code)); V1Data a = v1Symbol (ctx, "a", V1_SYMBOLS_GLOBAL); // 0 = constants, 1 = global vars if (a) { printf ("a = %.13g\r\n", (double) v1Number (a)); // Change the variable v1SetNumber (a, 99); code = "print('a is now ', a);"; v1Eval (ctx, code, strlen (code)); } v1DeleteContext (ctx); v1Shutdown (); return 0; }
Example 10: Manipulate a global array written by V1
#include <stdio.h> #include "v1.h" int main (int argc, char **argv) { v1Startup (); V1Context ctx = v1CreateContext (); // Manipulate a global array written by V1 const char* code = "b = array ('key1'=>'Value 1', 'key2'=>99, 'key3'=>true); print_r (b);"; v1Eval (ctx, code, strlen (code)); V1Data b = v1Symbol (ctx, "b", V1_SYMBOLS_GLOBAL); // 0 = constants, 1 = global vars if (b) { // Unset key2 v1UnsetArrayKey (b, "key2"); printf ("b has now %u elements\r\n", v1ArraySize (b)); // Iterate the array V1Data value; const char* key; v1ArrayIterate (b); while (value=v1ArrayNext (b, &key)) { printf ("%s => %s\r\n", (const char*) key, (const char*) v1String (value)); } // Set a value in array safe: // Note! v1ArrayPut...() will insert/replace the complete array key/value pair // To change only the value of a key, first get the value with v1ArrayValue(). // So the references to this value will be not destroyed! V1Data v = v1ArrayValue (b, "key1"); if (v) { v1SetNumber (v, 100); } code = "print ('key1 was changed by application.'); print_r (b);"; v1Eval (ctx, code, strlen (code)); } v1DeleteContext (ctx); v1Shutdown (); return 0; }
Example 11: Call a V1 user function
#include <stdio.h> #include "v1.h" int main (int argc, char **argv) { v1Startup (); V1Context ctx = v1CreateContext (); // Define a V1 user function code = "function myUserFunc (arg1,arg2) { print ('myUserFunc() called from application with arg1=', arg1, ' and arg2=', arg2); return 'OK'; }"; v1Eval (ctx, code, strlen (code)); // Call the V1 function with arguments V1ArgList argList = v1CreateArgList (); V1Data ret = v1CreateData (); V1Data arg1 = v1CreateData (); v1SetString (arg1, "Value for Argument 1"); V1Data arg2 = v1CreateData (); v1SetNumber (arg2, 99); v1SetArgument (argList, 0, arg1); v1SetArgument (argList, 1, arg2); if (!v1CallUserFunction (ctx, "myUserFunc", argList, ret)) { printf ("Return value: %s\r\n", (const char*) v1String (ret)); } else { printf ("%s\r\n", (const char*) v1LastError (ctx)); } v1DeleteData (arg1); // v1DeleteData() must be called for a corresponding v1CreateData() v1DeleteData (arg2); v1DeleteData (ret); v1DeleteArgList (argList); // v1DeleteArgList() must be called for a corresponding v1CreateArgList() v1DeleteContext (ctx); v1Shutdown (); return 0; }
Example 12: Read a V1 file handle
#include <stdio.h> #include "v1.h" int main (int argc, char **argv) { v1Startup (); V1Context ctx = v1CreateContext (); // Create a file handle with V1 and work with it code = "fh = fopen ('testfile.txt', 'w+');"; v1Eval (ctx, code, strlen (code)); V1Data fh = v1Symbol (ctx, "fh", V1_SYMBOLS_GLOBAL); // 0 = constants, 1 = global vars if (fh && v1HandleType (fh)==V1_HANDLETYPE_FILE) { // Cast to FILE* HANDLE FILE* pFile = (FILE*) v1Handle (fh); if (pFile) { // Write const char* buf = "Written by application"; unsigned int size = strlen (buf); if (fwrite (buf, sizeof(char), size, pFile) < size) { printf ("Problems to write file.\r\n"); } } } v1DeleteContext (ctx); v1Shutdown (); return 0; }
Example 13: Create a file and assign the file handle to a V1 variable
#include <stdio.h> #include "v1.h" int main (int argc, char **argv) { v1Startup (); V1Context ctx = v1CreateContext (); // Create a WIN32 file and assign file handle to V1 variable (on Linux you can assign a FILE* pointer) wchar_t wFilename[MAX_PATH+1]; DWORD size = MultiByteToWideChar(CP_UTF8, 0, "testfile2.txt", -1, wFilename, MAX_PATH); wFilename[size]=0; HANDLE hFile; if (INVALID_HANDLE_VALUE == (hFile = CreateFileW (wFilename, GENERIC_READ|GENERIC_WRITE, FILE_SHARE_READ|FILE_SHARE_WRITE, NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL|FILE_FLAG_RANDOM_ACCESS, NULL))) { printf ("Cannot create file."); } else { V1Data symbol = v1CreateSymbol (ctx, "fh2", V1_SYMBOLS_CONSTANT); // 0=constants, 1=global vars, 2=first running function ... v1SetHandle (ctx, symbol, V1_HANDLETYPE_FILE, (V1Handle) hFile); // only V1_HANDLETYPE_FILE, V1_HANDLETYPE_SOCKET allowed code = "fwrite (fh2, 'Written by V1'); fclose (fh2);"; v1Eval (ctx, code, strlen (code)); // Note! File handles will be closed also automatically in v1DeleteContext() } v1DeleteContext (ctx); v1Shutdown (); return 0; }
Example 14: Iterate all variables of current symbol table
#include <stdio.h> #include "v1.h" int main (int argc, char **argv) { v1Startup (); V1Context ctx = v1CreateContext (); // Set some variables code = "a=1;b=2;c=['key'=>'value'];"; v1Eval (ctx, code, strlen (code)); // Iterate all variables of current symbol table V1Data value; const char* name; v1SymbolIterate (ctx, v1CurrentSymbolTable (ctx)); printf ("Max. %u symbol tables available, current symbol table is %u.\r\n", (unsigned int) v1SymbolTableCount (ctx), (unsigned int) v1CurrentSymbolTable (ctx)); while (value=v1SymbolNext (ctx, v1CurrentSymbolTable (ctx), &name)) { printf ("%s => Type %i (string=\"%s\")\r\n", (const char*) name, (int) v1Type (value), (const char*) v1String (value)); } v1DeleteContext (ctx); v1Shutdown (); return 0; }
Example 15: Remove a function
#include <stdio.h> #include "v1.h" int main (int argc, char **argv) { v1Startup (); V1Context ctx = v1CreateContext (); // Remove a function code = "function userFunc (x) { return sqrt(x); }; print (userFunc(16));"; v1Eval (ctx, code, strlen (code)); if (v1FunctionRegistered (ctx, "userFunc")) { v1RemoveFunction (ctx, "userFunc"); // Redefinition will cause no error, because function was removed v1Eval (ctx, code, strlen (code)); } v1DeleteContext (ctx); v1Shutdown (); return 0; }
Example 16: Create a constant array
#include <stdio.h> #include "v1.h" int main (int argc, char **argv) { v1Startup (); V1Context ctx = v1CreateContext (); // Create a constant array V1Data symbol = v1CreateSymbol (ctx, "mySymbol", V1_SYMBOLS_CONSTANT); // 0=constants, 1=global vars, 2=first running function ... v1PutArrayString (symbol, "key1", "Value 1"); v1PutArrayString (symbol, "key2", "Value 2"); v1PutArrayBool (symbol, "key3", true); V1Data subArray = v1PutArrayArray (symbol, "subArray"); v1PutArrayString (subArray, "key1", "Value 1"); v1PutArrayString (subArray, "key2", "Value 2"); v1PutArrayBool (subArray, "key3", true); V1Data subArray2 = v1PutArrayArray (symbol, "subArray2"); // Push will create a vector (keys are set automatically 0,1,2 ...) v1PushArrayString (subArray2, "Value 1"); v1PushArrayNumber (subArray2, 42.12); v1PushArrayBool (subArray2, true); code = "print_r (mySymbol);"; v1Eval (ctx, code, strlen (code)); // Try to overwrite constant array will cause error code = "mySymbol['key1']['key3']=42;"; v1Eval (ctx, code, strlen (code)); printf ("%s\r\n", (const char*) v1LastError (ctx)); v1DeleteContext (ctx); v1Shutdown (); return 0; }