docs docs docs
This commit is contained in:
@@ -6,4 +6,6 @@
|
|||||||
|
|
||||||
the second sub-expr. "A.name != none" raises an error if the first one
|
the second sub-expr. "A.name != none" raises an error if the first one
|
||||||
"type(A) == type({})" isn't true, but doesn't need to be evaluated in
|
"type(A) == type({})" isn't true, but doesn't need to be evaluated in
|
||||||
that case.
|
that case.
|
||||||
|
|
||||||
|
- Implement the `count` method for static maps.
|
||||||
+1
-1
@@ -8,7 +8,7 @@ Here's an overview:
|
|||||||
`string`. `list` (array), `map` (associative array), `none` (null)
|
`string`. `list` (array), `map` (associative array), `none` (null)
|
||||||
3. No implicit casts.
|
3. No implicit casts.
|
||||||
2. Arithmetic operations only allowed on numbers.
|
2. Arithmetic operations only allowed on numbers.
|
||||||
3. Division between `ints` rounds down.
|
3. Division between `int`s rounds down.
|
||||||
4. Logical operators expect boolean operands.
|
4. Logical operators expect boolean operands.
|
||||||
5. Assignments are expressions that return the newly assigned value.
|
5. Assignments are expressions that return the newly assigned value.
|
||||||
6. No for loop (yet)
|
6. No for loop (yet)
|
||||||
|
|||||||
@@ -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 <string.h>
|
||||||
#include <assert.h>
|
#include <assert.h>
|
||||||
#include "o_staticmap.h"
|
#include "o_staticmap.h"
|
||||||
|
|||||||
+39
-13
@@ -12,19 +12,6 @@ typedef struct {
|
|||||||
Object *closure;
|
Object *closure;
|
||||||
} FunctionObject;
|
} 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)
|
static _Bool free_(Object *self, Error *error)
|
||||||
{
|
{
|
||||||
(void) error;
|
(void) error;
|
||||||
@@ -103,6 +90,45 @@ static Object *call(Object *self, Object **argv, unsigned int argc, Heap *heap,
|
|||||||
return result;
|
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)
|
Object *Object_FromNojaFunction(Runtime *runtime, Executable *exe, int index, int argc, Object *closure, Heap *heap, Error *error)
|
||||||
{
|
{
|
||||||
assert(runtime != NULL);
|
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 <assert.h>
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include "../utils/defs.h"
|
#include "../utils/defs.h"
|
||||||
@@ -11,15 +17,6 @@ typedef struct {
|
|||||||
int argc;
|
int argc;
|
||||||
} NativeFunctionObject;
|
} 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)
|
static Object *call(Object *self, Object **argv, unsigned int argc, Heap *heap, Error *error)
|
||||||
{
|
{
|
||||||
assert(self != NULL);
|
assert(self != NULL);
|
||||||
@@ -84,7 +81,10 @@ static Object *call(Object *self, Object **argv, unsigned int argc, Heap *heap,
|
|||||||
assert(func->callback != NULL);
|
assert(func->callback != NULL);
|
||||||
Object *result = func->callback(func->runtime, argv2, argc2, error);
|
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)
|
if(result == NULL && error->occurred == 0)
|
||||||
Error_Report(error, 1, "Native callback returned NULL but didn't report errors");
|
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;
|
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)
|
Object *Object_FromNativeFunction(Runtime *runtime, Object *(*callback)(Runtime*, Object**, unsigned int, Error*), int argc, Heap *heap, Error *error)
|
||||||
{
|
{
|
||||||
assert(callback != NULL);
|
assert(callback != NULL);
|
||||||
assert(heap != NULL);
|
|
||||||
assert(error != NULL);
|
|
||||||
|
|
||||||
NativeFunctionObject *func = (NativeFunctionObject*) Heap_Malloc(heap, &t_nfunc, error);
|
NativeFunctionObject *func = (NativeFunctionObject*) Heap_Malloc(heap, &t_nfunc, error);
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user