A minimalistic programming language written in C89.
Vous ne pouvez pas sélectionner plus de 25 sujets Les noms de sujets doivent commencer par une lettre ou un nombre, peuvent contenir des tirets ('-') et peuvent comporter jusqu'à 35 caractères.

252 lignes
6.4 KiB

#pragma once
#include "stddef.h"
/**
* Represents the natively defined type of integers
*/
#define INK_INTEGER 0
/**
* Represents the natively defined type of natively defined functions
*/
#define INK_NATIVE_FUNCTION 1
/**
* Represents the natively defined type of functions defined from within ink
*/
#define INK_FUNCTION 2
/**
* Represents the special coroutine state that means that it was disposed of and is ready for reuse
*/
#define INK_ROUTINE_CAN_REUSE 32
/**
* Represents the special coroutine state that means that it was terminated without errors
*/
#define INK_ROUTINE_SUCCESS 1
#ifdef __cplusplus
extern "C" {
#endif
/**
* Represents arbitrary values within ink
*/
struct elem {
int type;
int value;
};
/**
* Represents a stack-frame within the execution context
*/
struct stack_frame {
struct elem executing;
int index;
};
/**
* Represents a function within ink, defined in ink, using the homoiconic representation of ink
*/
struct fn {
char *name;
struct elem *things;
int size;
};
struct context;
/**
* Represents natively defined words within ink
*/
struct native_fn {
char *name;
void (*value)(struct context *);
};
/**
* Represents the narrow execution context of a single thread of execution within ink.
*/
struct ink_routine {
int panic;
struct elem *stack;
int capacity;
int top;
struct stack_frame *function_stack;
int function_stack_capacity;
int function_stack_top;
/**
* This user data can be set to any value convenient for the user to track a state local to the routine that is executing
*/
void *routine_userdata;
};
struct ink_collection_list {
struct elem* elems;
size_t size;
};
struct ink_type {
const char* name;
void* elements;
void (*collect)(void*);
struct ink_collection_list (*gc)(void*);
};
/**
* Represents a complete execution context for the ink interpreter
*/
struct context {
int panic;
void *(*malloc)(size_t);
void *(*realloc)(void *, size_t);
void (*free)(void *);
int (*putchar)(int);
struct ink_routine *routines;
int routines_capacity;
int routines_top;
struct ink_type *types;
int types_capacity;
int types_top;
/**
* Contains the id of the routine that is currently being manipulated
*/
int routine_current;
struct native_fn *native_words;
int native_words_capacity;
int native_words_top;
struct fn *words;
int words_capacity;
int words_top;
char **lex_reserved_words;
int lex_reserved_words_capacity;
int lex_reserved_words_top;
unsigned int steps;
/**
* Can be set to any data that is convenient to the user to track and use within natively defined functions
*/
void *persistent_userdata;
};
/**
* Creates a routine to execute within the context
* @param ctx The context in which to create the routine
* @warning Does not set the `routine_current` of the context to the newly created routine
* @return either a negative error value or the id of the created routine
*/
int ink_make_routine(struct context *ctx);
/**
* Cleans the targeted routine id data from the context
* @param ctx The context to operate in
* @param routine The id of the routine to destroy
* @return 0 if nothing could or needed to be performed, 1 otherwise
*/
int ink_kill_routine(struct context *ctx, int routine);
/**
* Declares and defines a native function within the context
* @param ctx The context tpo operate in
* @param name The name to give to the newly declared word
* @param value A pointer to a valid word-function
* @return a negative value in case of error, 0 otherwise
*/
int ink_add_native(struct context *ctx, const char *name, void(*value)(struct context *));
/**
* Pushes a value on the current routine's value stack
* @param ctx The context to manipulate
* @param value The value to push
* @return 0 on success, a negative value on failure
*/
int ink_push(struct context *ctx, struct elem value);
/**
* Pushes a function on the execution stack of the current routine of the context
* @param ctx The context to operate in
* @param value the function that will be pushed. in the state one wants it to run from
* @return 0 on success, a negative value on failure
*/
int ink_push_fn(struct context *ctx, struct stack_frame value);
/**
* Create a context to execute routines
* @param malloc the memory allocation function, with a signature similar to the standard malloc
* @param realloc the memory allocation function, with a signature similar to the standard realloc
* @param free the memory allocation function, with a signature similar to the standard free
* @param putchar a function to print to the output character by character
* @return a pointer to a context allocated within the malloc function itself.
*/
struct context* ink_make_context(void *(*malloc)(size_t), void *(*realloc)(void *, size_t), void(*free)(void *), int(*putchar)(int));
#ifndef NOSTDLIB
/**
* Creates a context that includes the standard library of ink, as well as uses the C standard library to operate
* @return a pointer to a context allocated with malloc and with predefined functions added
*/
struct context* ink_make_default_context();
#endif
/**
* Steps the current routine by one execution step
* @param pContext The context of the routine to advance
* @return A negative value in case of error, 0 if execution is finished, a positive value if more steps are required to execute
*/
int ink_step(struct context *pContext);
/**
* Examine the context to see if any routines can execute
* @param pContext the context
* @return 0 if no coroutines are available, 1 otherwise
*/
int ink_can_run(struct context *pContext);
/**
* Step every routine that can be executed.
* @param pContext The context, the `routine_current` value may be modified.
* @return 0
*/
int ink_step_everyone(struct context *pContext);
/**
* Compiles the code and starts a main routine to execute it
* @param pContext The context to execute the code in
* @param buffer The buffer that contains the source as a NULL terminated string
*/
void ink_compile(struct context *pContext, char *buffer);
/**
* Includes the standard library in the specified context
* @param ctx The context
* @return 0
*/
int ink_std_library(struct context *ctx);
/**
* Removes the top element of the function stack of the current routine of the specified context
* @param ctx the context
*/
void ink_pop_fn(struct context *ctx);
/**
* Removes the top element of the stack of the current routine of the specified context
* @param ctx the context
*/
void ink_pop(struct context *ctx);
#ifdef __cplusplus
};
#endif