docs docs docs

This commit is contained in:
cozis
2022-03-12 20:48:43 +01:00
parent c1b442f843
commit 15d1d5bbe5
6 changed files with 112 additions and 27 deletions
+3 -1
View File
@@ -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
View File
@@ -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)
+1
View File
@@ -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).
+27
View File
@@ -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
View File
@@ -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
View File
@@ -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);