Skip to content

Commit 12a7bb8

Browse files
committed
Dynamic access to Umka API (#333)
1 parent e55d43f commit 12a7bb8

File tree

8 files changed

+106
-3
lines changed

8 files changed

+106
-3
lines changed

doc/api.md

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -292,3 +292,33 @@ UMKA_API int umkaGetDynArrayLen(const void *array);
292292

293293
Returns the length of the dynamic `array` (treated as a pointer to `UmkaDynArray(T)`).
294294

295+
## Accessing Umka API dynamically
296+
297+
Using the Umka API functions generally requires linking against the Umka interpreter library. This dependency is undesirable when implementing UMIs. In such cases, the same Umka API functions can be accessed dynamically, through the Umka interpreter instance passed to UMI functions.
298+
299+
### Types
300+
301+
```
302+
typedef struct
303+
{
304+
// Function pointers
305+
} UmkaAPI;
306+
```
307+
308+
A set of pointers to all Umka API functions. For any function `umkaXXXX()`, there is a corresponding field `umkaXXXX` in `UmkaAPI`.
309+
310+
### Functions
311+
312+
```
313+
static inline UmkaAPI *umkaGetAPI(void *umka);
314+
315+
```
316+
Returns Umka API function pointers. Here, `umka` is the interpreter instance handle previously initialized by calling `umkaInit()`.
317+
318+
Example:
319+
320+
```
321+
UmkaAPI *api = umkaGetAPI(umka);
322+
char *s = api->umkaMakeStr(umka, "Hello");
323+
324+
```

playground/umka.js

Lines changed: 1 addition & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

src/umka_api.h

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -87,6 +87,33 @@ typedef struct
8787
typedef void (*UmkaWarningCallback)(UmkaError *warning);
8888

8989

90+
typedef struct
91+
{
92+
void *(*umkaAlloc) (void);
93+
bool (*umkaInit) (void *umka, const char *fileName, const char *sourceString, int stackSize, const char *locale, int argc, char **argv, bool fileSystemEnabled, bool implLibsEnabled, UmkaWarningCallback warningCallback);
94+
bool (*umkaCompile) (void *umka);
95+
bool (*umkaRun) (void *umka);
96+
bool (*umkaCall) (void *umka, int entryOffset, int numParamSlots, UmkaStackSlot *params, UmkaStackSlot *result);
97+
void (*umkaFree) (void *umka);
98+
void (*umkaGetError) (void *umka, UmkaError *err);
99+
char *(*umkaAsm) (void *umka);
100+
bool (*umkaAddModule) (void *umka, const char *fileName, const char *sourceString);
101+
bool (*umkaAddFunc) (void *umka, const char *name, UmkaExternFunc func);
102+
int (*umkaGetFunc) (void *umka, const char *moduleName, const char *funcName);
103+
bool (*umkaGetCallStack) (void *umka, int depth, int nameSize, int *offset, char *fileName, char *fnName, int *line);
104+
void (*umkaSetHook) (void *umka, UmkaHookEvent event, UmkaHookFunc hook);
105+
void *(*umkaAllocData) (void *umka, int size, UmkaExternFunc onFree);
106+
void (*umkaIncRef) (void *umka, void *ptr);
107+
void (*umkaDecRef) (void *umka, void *ptr);
108+
void *(*umkaGetMapItem) (void *umka, UmkaMap *map, UmkaStackSlot key);
109+
char *(*umkaMakeStr) (void *umka, const char *str);
110+
int (*umkaGetStrLen) (const char *str);
111+
void (*umkaMakeDynArray) (void *umka, void *array, void *type, int len);
112+
int (*umkaGetDynArrayLen) (const void *array);
113+
const char *(*umkaGetVersion) (void);
114+
} UmkaAPI;
115+
116+
90117
UMKA_API void *umkaAlloc (void);
91118
UMKA_API bool umkaInit (void *umka, const char *fileName, const char *sourceString, int stackSize, const char *locale, int argc, char **argv, bool fileSystemEnabled, bool implLibsEnabled, UmkaWarningCallback warningCallback);
92119
UMKA_API bool umkaCompile (void *umka);
@@ -110,6 +137,11 @@ UMKA_API void umkaMakeDynArray (void *umka, void *array, void *type, int le
110137
UMKA_API int umkaGetDynArrayLen (const void *array);
111138
UMKA_API const char *umkaGetVersion (void);
112139

140+
static inline UmkaAPI *umkaGetAPI (void *umka)
141+
{
142+
return (UmkaAPI *)umka;
143+
}
144+
113145

114146
#if defined(__cplusplus)
115147
}

src/umka_compiler.c

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,33 @@
1313
void parseProgram(Compiler *comp);
1414

1515

16+
static void compilerSetAPI(Compiler *comp)
17+
{
18+
comp->api.umkaAlloc = umkaAlloc;
19+
comp->api.umkaInit = umkaInit;
20+
comp->api.umkaCompile = umkaCompile;
21+
comp->api.umkaRun = umkaRun;
22+
comp->api.umkaCall = umkaCall;
23+
comp->api.umkaFree = umkaFree;
24+
comp->api.umkaGetError = umkaGetError;
25+
comp->api.umkaAsm = umkaAsm;
26+
comp->api.umkaAddModule = umkaAddModule;
27+
comp->api.umkaAddFunc = umkaAddFunc;
28+
comp->api.umkaGetFunc = umkaGetFunc;
29+
comp->api.umkaGetCallStack = umkaGetCallStack;
30+
comp->api.umkaSetHook = umkaSetHook;
31+
comp->api.umkaAllocData = umkaAllocData;
32+
comp->api.umkaIncRef = umkaIncRef;
33+
comp->api.umkaDecRef = umkaDecRef;
34+
comp->api.umkaGetMapItem = umkaGetMapItem;
35+
comp->api.umkaMakeStr = umkaMakeStr;
36+
comp->api.umkaGetStrLen = umkaGetStrLen;
37+
comp->api.umkaMakeDynArray = umkaMakeDynArray;
38+
comp->api.umkaGetDynArrayLen = umkaGetDynArrayLen;
39+
comp->api.umkaGetVersion = umkaGetVersion;
40+
}
41+
42+
1643
static void compilerDeclareBuiltinTypes(Compiler *comp)
1744
{
1845
comp->voidType = typeAdd(&comp->types, &comp->blocks, TYPE_VOID);
@@ -152,6 +179,8 @@ static void compilerDeclareExternalFuncs(Compiler *comp, bool fileSystemEnabled)
152179

153180
void compilerInit(Compiler *comp, const char *fileName, const char *sourceString, int stackSize, const char *locale, int argc, char **argv, bool fileSystemEnabled, bool implLibsEnabled)
154181
{
182+
compilerSetAPI(comp);
183+
155184
storageInit (&comp->storage);
156185
moduleInit (&comp->modules, implLibsEnabled, &comp->error);
157186
blocksInit (&comp->blocks, &comp->error);

src/umka_compiler.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,10 +9,13 @@
99
#include "umka_ident.h"
1010
#include "umka_const.h"
1111
#include "umka_runtime.h"
12+
#include "umka_api.h"
1213

1314

1415
typedef struct
1516
{
17+
UmkaAPI api; // Must be the first field
18+
1619
Storage storage;
1720
Modules modules;
1821
Blocks blocks;

tests/extlib.um

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
import "lib/lib.um"
22

33
fn test*() {
4-
printf("%f %f\n", lib.add(3, 5), lib.sub(3, 5))
4+
printf("%f %f %s\n", lib.add(3, 5), lib.sub(3, 5), lib.hello())
55
}
66

77
fn main() {

tests/lib/lib.c

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,4 +14,12 @@ void sub(UmkaStackSlot *params, UmkaStackSlot *result)
1414
double a = params[1].realVal;
1515
double b = params[0].realVal;
1616
result->realVal = a - b;
17+
}
18+
19+
20+
void hello(UmkaStackSlot *params, UmkaStackSlot *result)
21+
{
22+
void *umka = result->ptrVal;
23+
UmkaAPI *api = umkaGetAPI(umka);
24+
result->ptrVal = api->umkaMakeStr(umka, "Hello");
1725
}

tests/lib/lib.um

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,2 +1,3 @@
11
fn add*(a, b: real): real
2-
fn sub*(a, b: real): real
2+
fn sub*(a, b: real): real
3+
fn hello*(): str

0 commit comments

Comments
 (0)