docs docs docs
This commit is contained in:
@@ -0,0 +1 @@
|
||||
Here are implemented the language's builtin variables. Each file define it's values and exposes them through a `StaticMapSlot` array. These values can then be accessed from within the language by wrapping these arrays in static map objects (check src/o_staticmap.c to know more).
|
||||
@@ -1,3 +1,30 @@
|
||||
/*
|
||||
*
|
||||
* -- WHAT IS THIS FILE? --------------------------------------------
|
||||
* This file implements the "static map" object. The static map
|
||||
* object behaves like a read-only "map". (Note that "implementing
|
||||
* an object" means a very specific thing in this interpreter. If
|
||||
* you didn't know, check the src/objects folder.)
|
||||
* ------------------------------------------------------------------
|
||||
*
|
||||
* -- THE STATIC MAP OBJECT -----------------------------------------
|
||||
* The statis map is a read-only collection of objects. You can see
|
||||
* it as an interface for static arrays. You can define an array of
|
||||
* `StaticMapSlot`s and then wrap it in this object. When the map is
|
||||
* accessed, a lookup is performed into the array. Something to note
|
||||
* is that the array is converted to noja objects lazily when they
|
||||
* are accessed, which makes the start-up times lower than a general
|
||||
* purpose map.
|
||||
* ------------------------------------------------------------------
|
||||
*
|
||||
* NOTES:
|
||||
* - This object, unlike the others implemented in src/objects,
|
||||
* depends on the Runtime objects. This is because it needs
|
||||
* to be able to create `NativeFuncObject`s.
|
||||
*
|
||||
* - Only strings can be keys. There is no intrinsic reason why
|
||||
* it should be like that, it's just simpler.
|
||||
*/
|
||||
#include <string.h>
|
||||
#include <assert.h>
|
||||
#include "o_staticmap.h"
|
||||
|
||||
+39
-13
@@ -12,19 +12,6 @@ typedef struct {
|
||||
Object *closure;
|
||||
} FunctionObject;
|
||||
|
||||
static Object *call(Object *self, Object **argv, unsigned int argc, Heap *heap, Error *error);
|
||||
static void walk(Object *self, void (*callback)(Object **referer, void *userp), void *userp);
|
||||
static _Bool free_(Object *self, Error *error);
|
||||
|
||||
static TypeObject t_func = {
|
||||
.base = (Object) { .type = &t_type, .flags = Object_STATIC },
|
||||
.name = "function",
|
||||
.size = sizeof (FunctionObject),
|
||||
.call = call,
|
||||
.walk = walk,
|
||||
.free = free_,
|
||||
};
|
||||
|
||||
static _Bool free_(Object *self, Error *error)
|
||||
{
|
||||
(void) error;
|
||||
@@ -103,6 +90,45 @@ static Object *call(Object *self, Object **argv, unsigned int argc, Heap *heap,
|
||||
return result;
|
||||
}
|
||||
|
||||
static TypeObject t_func = {
|
||||
.base = (Object) { .type = &t_type, .flags = Object_STATIC },
|
||||
.name = "function",
|
||||
.size = sizeof (FunctionObject),
|
||||
.call = call,
|
||||
.walk = walk,
|
||||
.free = free_,
|
||||
};
|
||||
|
||||
/* Symbol: Object_FromNojaFunction
|
||||
*
|
||||
* Creates an object from a noja executable structure.
|
||||
*
|
||||
* Args:
|
||||
* - runtime: The reference to an instanciated Runtime.
|
||||
*
|
||||
* - exe: A noja executable.
|
||||
*
|
||||
* - index: The index of the first bytecode instruction
|
||||
* of the noja function within the executable.
|
||||
*
|
||||
* - argc: The number of arguments the function expects.
|
||||
* It must be positive (unlike [Object_FromNativeFunction],
|
||||
* where -1 means variadic).
|
||||
*
|
||||
* - closure: An object containing variables that will be
|
||||
* accessible from the noja function other than
|
||||
* the ones that will be defined inside it.
|
||||
*
|
||||
* - heap: The heap that will be used to allocate the object.
|
||||
* It can't be NULL.
|
||||
*
|
||||
* - error: Output parameter where error information is stored.
|
||||
* It can't be NULL.
|
||||
*
|
||||
* Returns:
|
||||
* The newly created object. If an error occurred, NULL is returned
|
||||
* and information about the error is stored in the [error] argument.
|
||||
*/
|
||||
Object *Object_FromNojaFunction(Runtime *runtime, Executable *exe, int index, int argc, Object *closure, Heap *heap, Error *error)
|
||||
{
|
||||
assert(runtime != NULL);
|
||||
|
||||
+41
-12
@@ -1,3 +1,9 @@
|
||||
/*
|
||||
* WHAT IS THIS FILE?
|
||||
* This file implements an object that makes it possible
|
||||
* to call native functions from within noja code.
|
||||
*
|
||||
*/
|
||||
#include <assert.h>
|
||||
#include <stdlib.h>
|
||||
#include "../utils/defs.h"
|
||||
@@ -11,15 +17,6 @@ typedef struct {
|
||||
int argc;
|
||||
} NativeFunctionObject;
|
||||
|
||||
static Object *call(Object *self, Object **argv, unsigned int argc, Heap *heap, Error *error);
|
||||
|
||||
static TypeObject t_nfunc = {
|
||||
.base = (Object) { .type = &t_type, .flags = Object_STATIC },
|
||||
.name = "native function",
|
||||
.size = sizeof (NativeFunctionObject),
|
||||
.call = call,
|
||||
};
|
||||
|
||||
static Object *call(Object *self, Object **argv, unsigned int argc, Heap *heap, Error *error)
|
||||
{
|
||||
assert(self != NULL);
|
||||
@@ -84,7 +81,10 @@ static Object *call(Object *self, Object **argv, unsigned int argc, Heap *heap,
|
||||
assert(func->callback != NULL);
|
||||
Object *result = func->callback(func->runtime, argv2, argc2, error);
|
||||
|
||||
// NOTE: Every object reference is invalidated from here.
|
||||
// NOTE: Since the callback may have executed some bytecode, a GC
|
||||
// cycle may have been triggered, therefore we must assume
|
||||
// every object reference that was locally saved is invalidated
|
||||
// from here (the returned object is good tho).
|
||||
|
||||
if(result == NULL && error->occurred == 0)
|
||||
Error_Report(error, 1, "Native callback returned NULL but didn't report errors");
|
||||
@@ -95,11 +95,40 @@ static Object *call(Object *self, Object **argv, unsigned int argc, Heap *heap,
|
||||
return result;
|
||||
}
|
||||
|
||||
static TypeObject t_nfunc = {
|
||||
.base = (Object) { .type = &t_type, .flags = Object_STATIC },
|
||||
.name = "native function",
|
||||
.size = sizeof (NativeFunctionObject),
|
||||
.call = call,
|
||||
};
|
||||
|
||||
/* Symbol: Object_FromNativeFunction
|
||||
*
|
||||
* Creates an object from a function pointer.
|
||||
*
|
||||
* Args:
|
||||
* - runtime: The reference to an instanciated Runtime. This must be
|
||||
* provided so that the callback can also access it.
|
||||
*
|
||||
* - callback: The native function to be executed when this object
|
||||
* is called.
|
||||
*
|
||||
* - argc: The number of arguments the function expects. If -1 is
|
||||
* provided, then the function is considered to be variadic.
|
||||
*
|
||||
* - heap: The heap that will be used to allocate the object.
|
||||
* It can't be NULL.
|
||||
*
|
||||
* - error: Output parameter where error information is stored.
|
||||
* It can't be NULL.
|
||||
*
|
||||
* Returns:
|
||||
* The newly created object. If an error occurred, NULL is returned
|
||||
* and information about the error is stored in the [error] argument.
|
||||
*/
|
||||
Object *Object_FromNativeFunction(Runtime *runtime, Object *(*callback)(Runtime*, Object**, unsigned int, Error*), int argc, Heap *heap, Error *error)
|
||||
{
|
||||
assert(callback != NULL);
|
||||
assert(heap != NULL);
|
||||
assert(error != NULL);
|
||||
|
||||
NativeFunctionObject *func = (NativeFunctionObject*) Heap_Malloc(heap, &t_nfunc, error);
|
||||
|
||||
|
||||
Reference in New Issue
Block a user