A minimalistic programming language written in C89.
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

251 regels
6.4 KiB

4 maanden geleden
4 maanden geleden
4 maanden geleden
4 maanden geleden
4 maanden geleden
4 maanden geleden
4 maanden geleden
4 maanden geleden
4 maanden geleden
4 maanden geleden
4 maanden geleden
4 maanden geleden
4 maanden geleden
4 maanden geleden
4 maanden geleden
4 maanden geleden
4 maanden geleden
4 maanden geleden
4 maanden geleden
4 maanden geleden
4 maanden geleden
4 maanden geleden
4 maanden geleden
4 maanden geleden
4 maanden geleden
4 maanden geleden
4 maanden geleden
4 maanden geleden
4 maanden geleden
4 maanden geleden
4 maanden geleden
4 maanden geleden
4 maanden geleden
4 maanden geleden
4 maanden geleden
4 maanden geleden
4 maanden geleden
4 maanden geleden
4 maanden geleden
4 maanden geleden
4 maanden geleden
4 maanden geleden
4 maanden geleden
4 maanden geleden
4 maanden geleden
4 maanden geleden
4 maanden geleden
4 maanden geleden
4 maanden geleden
4 maanden geleden
4 maanden geleden
4 maanden geleden
4 maanden geleden
4 maanden geleden
4 maanden geleden
4 maanden geleden
4 maanden geleden
4 maanden geleden
4 maanden geleden
4 maanden geleden
4 maanden geleden
4 maanden geleden
4 maanden geleden
4 maanden geleden
4 maanden geleden
4 maanden geleden
4 maanden geleden
4 maanden geleden
4 maanden geleden
4 maanden geleden
4 maanden geleden
4 maanden geleden
4 maanden geleden
4 maanden geleden
4 maanden geleden
4 maanden geleden
4 maanden geleden
4 maanden geleden
4 maanden geleden
4 maanden geleden
4 maanden geleden
4 maanden geleden
  1. #pragma once
  2. #include "stddef.h"
  3. /**
  4. * Represents the natively defined type of integers
  5. */
  6. #define INK_INTEGER 0
  7. /**
  8. * Represents the natively defined type of natively defined functions
  9. */
  10. #define INK_NATIVE_FUNCTION 1
  11. /**
  12. * Represents the natively defined type of functions defined from within ink
  13. */
  14. #define INK_FUNCTION 2
  15. /**
  16. * Represents the special coroutine state that means that it was disposed of and is ready for reuse
  17. */
  18. #define INK_ROUTINE_CAN_REUSE 32
  19. /**
  20. * Represents the special coroutine state that means that it was terminated without errors
  21. */
  22. #define INK_ROUTINE_SUCCESS 1
  23. #ifdef __cplusplus
  24. extern "C" {
  25. #endif
  26. /**
  27. * Represents arbitrary values within ink
  28. */
  29. struct elem {
  30. int type;
  31. int value;
  32. };
  33. /**
  34. * Represents a stack-frame within the execution context
  35. */
  36. struct stack_frame {
  37. struct elem executing;
  38. int index;
  39. };
  40. /**
  41. * Represents a function within ink, defined in ink, using the homoiconic representation of ink
  42. */
  43. struct fn {
  44. char *name;
  45. struct elem *things;
  46. int size;
  47. };
  48. struct context;
  49. /**
  50. * Represents natively defined words within ink
  51. */
  52. struct native_fn {
  53. char *name;
  54. void (*value)(struct context *);
  55. };
  56. /**
  57. * Represents the narrow execution context of a single thread of execution within ink.
  58. */
  59. struct ink_routine {
  60. int panic;
  61. struct elem *stack;
  62. int capacity;
  63. int top;
  64. struct stack_frame *function_stack;
  65. int function_stack_capacity;
  66. int function_stack_top;
  67. /**
  68. * This user data can be set to any value convenient for the user to track a state local to the routine that is executing
  69. */
  70. void *routine_userdata;
  71. };
  72. struct ink_collection_list {
  73. struct elem* elems;
  74. size_t size;
  75. };
  76. struct ink_type {
  77. const char* name;
  78. void* elements;
  79. void (*collect)(void*);
  80. struct ink_collection_list (*gc)(void*);
  81. };
  82. /**
  83. * Represents a complete execution context for the ink interpreter
  84. */
  85. struct context {
  86. int panic;
  87. void *(*malloc)(size_t);
  88. void *(*realloc)(void *, size_t);
  89. void (*free)(void *);
  90. int (*putchar)(int);
  91. struct ink_routine *routines;
  92. int routines_capacity;
  93. int routines_top;
  94. struct ink_type *types;
  95. int types_capacity;
  96. int types_top;
  97. /**
  98. * Contains the id of the routine that is currently being manipulated
  99. */
  100. int routine_current;
  101. struct native_fn *native_words;
  102. int native_words_capacity;
  103. int native_words_top;
  104. struct fn *words;
  105. int words_capacity;
  106. int words_top;
  107. char **lex_reserved_words;
  108. int lex_reserved_words_capacity;
  109. int lex_reserved_words_top;
  110. unsigned int steps;
  111. /**
  112. * Can be set to any data that is convenient to the user to track and use within natively defined functions
  113. */
  114. void *persistent_userdata;
  115. };
  116. /**
  117. * Creates a routine to execute within the context
  118. * @param ctx The context in which to create the routine
  119. * @warning Does not set the `routine_current` of the context to the newly created routine
  120. * @return either a negative error value or the id of the created routine
  121. */
  122. int ink_make_routine(struct context *ctx);
  123. /**
  124. * Cleans the targeted routine id data from the context
  125. * @param ctx The context to operate in
  126. * @param routine The id of the routine to destroy
  127. * @return 0 if nothing could or needed to be performed, 1 otherwise
  128. */
  129. int ink_kill_routine(struct context *ctx, int routine);
  130. /**
  131. * Declares and defines a native function within the context
  132. * @param ctx The context tpo operate in
  133. * @param name The name to give to the newly declared word
  134. * @param value A pointer to a valid word-function
  135. * @return a negative value in case of error, 0 otherwise
  136. */
  137. int ink_add_native(struct context *ctx, const char *name, void(*value)(struct context *));
  138. /**
  139. * Pushes a value on the current routine's value stack
  140. * @param ctx The context to manipulate
  141. * @param value The value to push
  142. * @return 0 on success, a negative value on failure
  143. */
  144. int ink_push(struct context *ctx, struct elem value);
  145. /**
  146. * Pushes a function on the execution stack of the current routine of the context
  147. * @param ctx The context to operate in
  148. * @param value the function that will be pushed. in the state one wants it to run from
  149. * @return 0 on success, a negative value on failure
  150. */
  151. int ink_push_fn(struct context *ctx, struct stack_frame value);
  152. /**
  153. * Create a context to execute routines
  154. * @param malloc the memory allocation function, with a signature similar to the standard malloc
  155. * @param realloc the memory allocation function, with a signature similar to the standard realloc
  156. * @param free the memory allocation function, with a signature similar to the standard free
  157. * @param putchar a function to print to the output character by character
  158. * @return a pointer to a context allocated within the malloc function itself.
  159. */
  160. struct context* ink_make_context(void *(*malloc)(size_t), void *(*realloc)(void *, size_t), void(*free)(void *), int(*putchar)(int));
  161. #ifndef NOSTDLIB
  162. /**
  163. * Creates a context that includes the standard library of ink, as well as uses the C standard library to operate
  164. * @return a pointer to a context allocated with malloc and with predefined functions added
  165. */
  166. struct context* ink_make_default_context();
  167. #endif
  168. /**
  169. * Steps the current routine by one execution step
  170. * @param pContext The context of the routine to advance
  171. * @return A negative value in case of error, 0 if execution is finished, a positive value if more steps are required to execute
  172. */
  173. int ink_step(struct context *pContext);
  174. /**
  175. * Examine the context to see if any routines can execute
  176. * @param pContext the context
  177. * @return 0 if no coroutines are available, 1 otherwise
  178. */
  179. int ink_can_run(struct context *pContext);
  180. /**
  181. * Step every routine that can be executed.
  182. * @param pContext The context, the `routine_current` value may be modified.
  183. * @return 0
  184. */
  185. int ink_step_everyone(struct context *pContext);
  186. /**
  187. * Compiles the code and starts a main routine to execute it
  188. * @param pContext The context to execute the code in
  189. * @param buffer The buffer that contains the source as a NULL terminated string
  190. */
  191. void ink_compile(struct context *pContext, char *buffer);
  192. /**
  193. * Includes the standard library in the specified context
  194. * @param ctx The context
  195. * @return 0
  196. */
  197. int ink_std_library(struct context *ctx);
  198. /**
  199. * Removes the top element of the function stack of the current routine of the specified context
  200. * @param ctx the context
  201. */
  202. void ink_pop_fn(struct context *ctx);
  203. /**
  204. * Removes the top element of the stack of the current routine of the specified context
  205. * @param ctx the context
  206. */
  207. void ink_pop(struct context *ctx);
  208. #ifdef __cplusplus
  209. };
  210. #endif