A minimalistic programming language written in C89.
Nevar pievienot vairāk kā 25 tēmas Tēmai ir jāsākas ar burtu vai ciparu, tā var saturēt domu zīmes ('-') un var būt līdz 35 simboliem gara.

1086 rindas
28 KiB

pirms 5 mēnešiem
pirms 5 mēnešiem
pirms 6 mēnešiem
pirms 6 mēnešiem
pirms 6 mēnešiem
pirms 6 mēnešiem
pirms 6 mēnešiem
pirms 6 mēnešiem
pirms 6 mēnešiem
pirms 6 mēnešiem
pirms 6 mēnešiem
pirms 6 mēnešiem
pirms 6 mēnešiem
pirms 6 mēnešiem
pirms 5 mēnešiem
pirms 6 mēnešiem
pirms 6 mēnešiem
pirms 5 mēnešiem
pirms 6 mēnešiem
pirms 5 mēnešiem
pirms 6 mēnešiem
pirms 5 mēnešiem
pirms 6 mēnešiem
pirms 6 mēnešiem
pirms 5 mēnešiem
pirms 6 mēnešiem
pirms 5 mēnešiem
pirms 6 mēnešiem
pirms 5 mēnešiem
pirms 6 mēnešiem
pirms 5 mēnešiem
pirms 6 mēnešiem
pirms 6 mēnešiem
pirms 6 mēnešiem
pirms 5 mēnešiem
pirms 6 mēnešiem
pirms 5 mēnešiem
pirms 6 mēnešiem
pirms 5 mēnešiem
pirms 6 mēnešiem
pirms 6 mēnešiem
pirms 6 mēnešiem
pirms 6 mēnešiem
pirms 6 mēnešiem
pirms 6 mēnešiem
pirms 6 mēnešiem
pirms 6 mēnešiem
pirms 6 mēnešiem
pirms 6 mēnešiem
pirms 6 mēnešiem
pirms 6 mēnešiem
pirms 6 mēnešiem
pirms 6 mēnešiem
pirms 6 mēnešiem
pirms 6 mēnešiem
pirms 6 mēnešiem
pirms 6 mēnešiem
pirms 6 mēnešiem
pirms 5 mēnešiem
pirms 5 mēnešiem
pirms 5 mēnešiem
pirms 5 mēnešiem
pirms 6 mēnešiem
pirms 6 mēnešiem
pirms 5 mēnešiem
pirms 5 mēnešiem
pirms 6 mēnešiem
pirms 6 mēnešiem
pirms 6 mēnešiem
pirms 6 mēnešiem
pirms 6 mēnešiem
pirms 6 mēnešiem
pirms 6 mēnešiem
pirms 6 mēnešiem
pirms 6 mēnešiem
pirms 6 mēnešiem
pirms 6 mēnešiem
pirms 6 mēnešiem
pirms 6 mēnešiem
pirms 6 mēnešiem
pirms 6 mēnešiem
pirms 5 mēnešiem
pirms 6 mēnešiem
pirms 5 mēnešiem
pirms 6 mēnešiem
pirms 6 mēnešiem
pirms 6 mēnešiem
pirms 6 mēnešiem
pirms 5 mēnešiem
pirms 6 mēnešiem
pirms 6 mēnešiem
pirms 5 mēnešiem
pirms 6 mēnešiem
pirms 6 mēnešiem
pirms 5 mēnešiem
pirms 6 mēnešiem
pirms 5 mēnešiem
pirms 6 mēnešiem
pirms 5 mēnešiem
pirms 6 mēnešiem
pirms 5 mēnešiem
pirms 5 mēnešiem
pirms 6 mēnešiem
pirms 5 mēnešiem
pirms 6 mēnešiem
pirms 5 mēnešiem
pirms 6 mēnešiem
pirms 5 mēnešiem
pirms 6 mēnešiem
pirms 5 mēnešiem
pirms 6 mēnešiem
pirms 5 mēnešiem
pirms 6 mēnešiem
pirms 5 mēnešiem
pirms 6 mēnešiem
pirms 5 mēnešiem
pirms 6 mēnešiem
pirms 5 mēnešiem
pirms 6 mēnešiem
pirms 5 mēnešiem
pirms 6 mēnešiem
pirms 5 mēnešiem
pirms 6 mēnešiem
pirms 5 mēnešiem
pirms 6 mēnešiem
pirms 5 mēnešiem
pirms 6 mēnešiem
pirms 5 mēnešiem
pirms 6 mēnešiem
pirms 5 mēnešiem
pirms 6 mēnešiem
pirms 5 mēnešiem
pirms 6 mēnešiem
pirms 5 mēnešiem
pirms 6 mēnešiem
pirms 5 mēnešiem
pirms 6 mēnešiem
pirms 5 mēnešiem
pirms 6 mēnešiem
pirms 5 mēnešiem
pirms 6 mēnešiem
pirms 5 mēnešiem
pirms 6 mēnešiem
pirms 5 mēnešiem
pirms 6 mēnešiem
pirms 5 mēnešiem
pirms 6 mēnešiem
pirms 5 mēnešiem
pirms 6 mēnešiem
pirms 5 mēnešiem
pirms 6 mēnešiem
pirms 5 mēnešiem
pirms 6 mēnešiem
pirms 5 mēnešiem
pirms 6 mēnešiem
pirms 5 mēnešiem
pirms 6 mēnešiem
pirms 5 mēnešiem
pirms 6 mēnešiem
pirms 5 mēnešiem
pirms 6 mēnešiem
pirms 5 mēnešiem
pirms 6 mēnešiem
pirms 5 mēnešiem
pirms 6 mēnešiem
pirms 5 mēnešiem
pirms 6 mēnešiem
pirms 5 mēnešiem
pirms 6 mēnešiem
pirms 5 mēnešiem
pirms 6 mēnešiem
pirms 5 mēnešiem
pirms 6 mēnešiem
pirms 5 mēnešiem
pirms 6 mēnešiem
pirms 5 mēnešiem
pirms 6 mēnešiem
pirms 5 mēnešiem
pirms 6 mēnešiem
pirms 5 mēnešiem
pirms 6 mēnešiem
pirms 5 mēnešiem
pirms 6 mēnešiem
  1. #include "ink.h"
  2. #ifndef NOSTDLIB
  3. #include <stdio.h>
  4. #include <stdlib.h>
  5. #include <string.h>
  6. #include <ctype.h>
  7. #ifdef INSTRUMENTION
  8. #include <time.h>
  9. #endif
  10. #endif
  11. #define INK_RESERVED (-1)
  12. #define INK_FUNCTION_KW (-2)
  13. #define INK_DO_KW (-3)
  14. #define INK_END_KW (-4)
  15. #define INK_LABEL (-5)
  16. #define INK_RETURN (-6)
  17. #define _KEYWORD_INK_FUNCTION "fn"
  18. #define _KEYWORD_INK_DO "do"
  19. #define _KEYWORD_INK_END "end"
  20. #define _KEYWORD_INK_RETURN "return"
  21. struct label {
  22. int active;
  23. int dest;
  24. char* name;
  25. };
  26. #ifdef NOSTDLIB
  27. static size_t strlen(const char* c) {
  28. size_t j = 0;
  29. while(*(c++)) {
  30. j++;
  31. }
  32. return j;
  33. }
  34. static void* memcpy(void* _dest, const void* _src, size_t sz) {
  35. char* dest = _dest;
  36. const char* src = _src;
  37. while(sz--) {
  38. *(dest++) = *(src++);
  39. }
  40. return dest;
  41. }
  42. static int strcmp(const char* dest, const char* src) {
  43. while(*dest != 0 && *src != 0) {
  44. if(*(dest++) != *(src++)) {
  45. return 1;
  46. }
  47. }
  48. return 0;
  49. }
  50. static void* memmove(void* _dest, const void* _src, size_t sz) {
  51. char* dest = _dest;
  52. const char* src = _src;
  53. if (src < dest) {
  54. src += sz;
  55. dest += sz;
  56. while (sz-- > 0) {
  57. *--dest = *--src;
  58. }
  59. } else {
  60. while (sz-- > 0) {
  61. *dest++ = *src++;
  62. }
  63. }
  64. return dest;
  65. }
  66. static void* memset(void* _dest, int src, size_t sz) {
  67. char* dest = _dest;
  68. while(sz--) {
  69. *(dest++) = src++;
  70. }
  71. return dest;
  72. }
  73. static int isspace(int d) {
  74. return d == ' ' || d == '\t' || d == '\n';
  75. }
  76. static int isdigit(int d) {
  77. return '0' <= d && d <= '9';
  78. }
  79. static int atoi(const char* c) {
  80. int ret = 0;
  81. while(*c) {
  82. ret *= 10;
  83. ret += *c - '0';
  84. ++c;
  85. }
  86. return ret;
  87. }
  88. #endif
  89. int ink_add_native(struct context* ctx, const char* name, void(*value)(struct context*)) {
  90. if(ctx->native_words == NULL) {
  91. ctx->native_words = ctx->malloc(sizeof(struct native_fn) * 8);
  92. ctx->native_words_top = 0;
  93. ctx->native_words_capacity = 8;
  94. } else if(ctx->native_words_top == ctx->native_words_capacity) {
  95. int new_count = (ctx->native_words_capacity + ctx->native_words_capacity/2);
  96. void* renewed = ctx->realloc(ctx->native_words, sizeof(struct native_fn) * new_count);
  97. if(renewed == NULL) {
  98. return -3;
  99. } else {
  100. ctx->native_words = renewed;
  101. ctx->native_words_capacity = new_count;
  102. }
  103. }
  104. int len = strlen(name);
  105. char* copy = ctx->malloc(len+1);
  106. if(copy == NULL) {
  107. return -4;
  108. }
  109. memcpy(copy, name, len);
  110. copy[len] = 0;
  111. ctx->native_words[ctx->native_words_top].value = value;
  112. ctx->native_words[ctx->native_words_top].name = copy;
  113. ctx->native_words_top++;
  114. return 0;
  115. }
  116. static int ink_add_indigenous(struct context* ctx, const char* name, struct elem* m, size_t count) {
  117. if(ctx->words == NULL) {
  118. ctx->words = ctx->malloc(sizeof(struct fn) * 8);
  119. ctx->words_top = 0;
  120. ctx->words_capacity = 8;
  121. } else if(ctx->words_top == ctx->words_capacity) {
  122. int new_count = (ctx->words_capacity + ctx->words_capacity/2);
  123. void* renewed = ctx->realloc(ctx->words, sizeof(struct native_fn) * new_count);
  124. if(renewed == NULL) {
  125. return -1;
  126. } else {
  127. ctx->words = renewed;
  128. ctx->words_capacity = new_count;
  129. }
  130. }
  131. int i;
  132. for(i = 0; i < ctx->words_top; ++i) {
  133. if(strcmp(name, ctx->words[i].name) == 0) {
  134. ctx->free(ctx->words[i].things);
  135. ctx->words[i].things = ctx->malloc(sizeof(struct elem) * count);
  136. memcpy(ctx->words[i].things, m, sizeof(struct elem) * count);
  137. ctx->words[i].size = count;
  138. return i;
  139. }
  140. }
  141. int len = strlen(name);
  142. char* copy = ctx->malloc(len+1);
  143. if(copy == NULL) {
  144. return -2;
  145. }
  146. memcpy(copy, name, len);
  147. copy[len] = 0;
  148. ctx->words[ctx->words_top].things = ctx->malloc(sizeof(struct elem) * count);
  149. memcpy(ctx->words[ctx->words_top].things, m, sizeof(struct elem) * count);
  150. ctx->words[ctx->words_top].size = count;
  151. ctx->words[ctx->words_top].name = copy;
  152. return ctx->words_top++;
  153. }
  154. static int ink_add_lex_string(struct context* ctx, const char* name) {
  155. int i;
  156. if(ctx->lex_reserved_words == NULL) {
  157. ctx->lex_reserved_words = ctx->malloc(sizeof(char*) * 8);
  158. ctx->lex_reserved_words_top = 0;
  159. ctx->lex_reserved_words_capacity = 8;
  160. } else if(ctx->lex_reserved_words_top == ctx->lex_reserved_words_capacity) {
  161. int new_count = (ctx->lex_reserved_words_capacity + ctx->lex_reserved_words_capacity/2);
  162. void* renewed = ctx->realloc(ctx->lex_reserved_words, sizeof(struct native_fn) * new_count);
  163. if(renewed == NULL) {
  164. return -5;
  165. } else {
  166. ctx->lex_reserved_words = renewed;
  167. ctx->lex_reserved_words_capacity = new_count;
  168. }
  169. }
  170. for(i = 0; i < ctx->lex_reserved_words_top; i++) {
  171. if(strcmp(ctx->lex_reserved_words[i], name) == 0) {
  172. return i;
  173. }
  174. }
  175. int len = strlen(name);
  176. i = ctx->lex_reserved_words_top;
  177. ctx->lex_reserved_words[i] = ctx->malloc(len+1);
  178. memcpy(ctx->lex_reserved_words[i], name, len);
  179. ctx->lex_reserved_words[i][len] = 0;
  180. ctx->lex_reserved_words_top++;
  181. return i;
  182. }
  183. int ink_push(struct context* ctx, struct elem value) {
  184. if(ctx->routine_current >= ctx->routines_top) return -65;
  185. struct ink_routine* current = ctx->routines + ctx->routine_current;
  186. if(current->stack == NULL) {
  187. current->stack = ctx->malloc(sizeof(struct elem) * 8);
  188. current->top = 0;
  189. current->capacity = 8;
  190. } else if(current->top == current->capacity) {
  191. int new_count = (current->capacity + current->capacity/2);
  192. void* renewed = ctx->realloc(current->stack, sizeof(struct elem) * new_count);
  193. if(renewed == NULL) {
  194. return -18;
  195. } else {
  196. current->stack = renewed;
  197. current->capacity = new_count;
  198. }
  199. }
  200. current->stack[current->top] = value;
  201. current->top++;
  202. return 0;
  203. }
  204. int ink_push_fn(struct context* ctx, struct stack_frame value) {
  205. if(ctx->routine_current >= ctx->routines_top) return -55;
  206. struct ink_routine* current = ctx->routines + ctx->routine_current;
  207. if(current->panic) return -56;
  208. if(current->function_stack == NULL) {
  209. current->function_stack = ctx->malloc(sizeof(struct stack_frame) * 8);
  210. current->function_stack_top = 0;
  211. current->function_stack_capacity = 8;
  212. } else if(current->function_stack_top == current->function_stack_capacity) {
  213. int new_count = (current->function_stack_capacity + current->function_stack_capacity/2);
  214. void* renewed = ctx->realloc(current->function_stack, sizeof(struct stack_frame) * new_count);
  215. if(renewed == NULL) {
  216. return -9;
  217. } else {
  218. current->function_stack = renewed;
  219. current->function_stack_capacity = new_count;
  220. }
  221. }
  222. current->function_stack[current->function_stack_top] = value;
  223. current->function_stack_top++;
  224. return 0;
  225. }
  226. void ink_pop_fn(struct context* ctx) {
  227. if(ctx->routine_current >= ctx->routines_top) return;
  228. if(ctx->routines[ctx->routine_current].panic) return;
  229. if(ctx->routines[ctx->routine_current].function_stack == NULL) return;
  230. if(ctx->routines[ctx->routine_current].function_stack_top == 0) return;
  231. ctx->routines[ctx->routine_current].function_stack_top--;
  232. }
  233. void ink_pop(struct context* ctx) {
  234. if(ctx->routine_current >= ctx->routines_top) return;
  235. if(ctx->routines[ctx->routine_current].panic) return;
  236. if(ctx->routines[ctx->routine_current].stack == NULL) return;
  237. if(ctx->routines[ctx->routine_current].top == 0) return;
  238. ctx->routines[ctx->routine_current].top--;
  239. }
  240. struct context* ink_make_context(void*(*malloc)(size_t), void*(*realloc)(void*, size_t), void(*free)(void*), int(*putchar)(int)) {
  241. struct context* ctx = (struct context*)malloc(sizeof(struct context));
  242. ctx->malloc = malloc;
  243. ctx->realloc = realloc;
  244. ctx->free = free;
  245. ctx->putchar = putchar;
  246. ctx->panic = 0;
  247. ctx->routines = NULL;
  248. ctx->routines_capacity = 0;
  249. ctx->routines_top = 0;
  250. ctx->native_words = NULL;
  251. ctx->native_words_capacity = 0;
  252. ctx->native_words_top = 0;
  253. ctx->words = NULL;
  254. ctx->words_capacity = 0;
  255. ctx->words_top = 0;
  256. ctx->lex_reserved_words = NULL;
  257. ctx->lex_reserved_words_capacity = 0;
  258. ctx->lex_reserved_words_top = 0;
  259. ctx->steps = 0;
  260. return ctx;
  261. }
  262. /**
  263. * Allocates a string that contains the integer
  264. * @param _ context (used to allocate)
  265. * @param cpy the value
  266. * @return the allocated string, needs to be freed by ctx->free
  267. * @internal this function is slightly cursed
  268. */
  269. static char* ink_itoa(struct context* _, int cpy) {
  270. char* n = _->malloc(16);
  271. n[15] = 0;
  272. char* it = n+15;
  273. do {
  274. it--;
  275. *it = (cpy % 10) + '0';
  276. cpy = cpy / 10;
  277. } while(cpy);
  278. memmove(n, it, 16 - (it-n));
  279. return n;
  280. }
  281. #ifndef NOSTDLIB
  282. struct context* ink_make_default_context() {
  283. struct context* ctx = ink_make_context(malloc, realloc, free, putchar);
  284. ink_std_library(ctx);
  285. return ctx;
  286. }
  287. #endif
  288. static int ink_consume_one(int* end, struct context* pContext, char** buffer, char* r) {
  289. int i;
  290. if(*end == 0) {
  291. return 0;
  292. }
  293. r[*end] = 0;
  294. int done = 0;
  295. struct elem value;
  296. if (strcmp(r, _KEYWORD_INK_FUNCTION) == 0) {
  297. value.value = 0;
  298. value.type = INK_FUNCTION_KW;
  299. done = 1;
  300. }
  301. if (!done && strcmp(r, _KEYWORD_INK_DO) == 0) {
  302. value.value = 0;
  303. value.type = INK_DO_KW;
  304. done = 1;
  305. }
  306. if (!done && strcmp(r, _KEYWORD_INK_END) == 0) {
  307. value.value = 0;
  308. value.type = INK_END_KW;
  309. done = 1;
  310. }
  311. if (!done && strcmp(r, _KEYWORD_INK_RETURN) == 0) {
  312. value.value = 0;
  313. value.type = INK_RETURN;
  314. done = 1;
  315. }
  316. if(done) {
  317. int err;
  318. err = ink_push(pContext, value);
  319. if(err < 0) {
  320. return -19;
  321. }
  322. }
  323. if (!done) {
  324. for (i = 0; i < pContext->words_top; ++i) {
  325. if (strcmp(r, pContext->words[i].name) == 0) {
  326. value.value = i;
  327. value.type = INK_FUNCTION;
  328. int err;
  329. err = ink_push(pContext, value);
  330. if(err < 0) {
  331. return -20;
  332. }
  333. done = 1;
  334. break;
  335. }
  336. }
  337. }
  338. if (!done) {
  339. for (i = 0; i < pContext->native_words_top; ++i) {
  340. if (strcmp(r, pContext->native_words[i].name) == 0) {
  341. value.value = i;
  342. value.type = INK_NATIVE_FUNCTION;
  343. int err;
  344. err = ink_push(pContext, value);
  345. if(err < 0) {
  346. return -21;
  347. }
  348. done = 1;
  349. break;
  350. }
  351. }
  352. }
  353. if (!done) {
  354. for(i = (r[0] == '-'); i < *end; i++) {
  355. if(!isdigit(r[i])){
  356. goto not_an_int;
  357. }
  358. }
  359. value.value = atoi(r);
  360. value.type = INK_INTEGER;
  361. int err;
  362. err = ink_push(pContext, value);
  363. if(err < 0) {
  364. return -22;
  365. }
  366. done = 1;
  367. }
  368. not_an_int:
  369. if (!done) {
  370. i = ink_add_lex_string(pContext, r);
  371. if(i < 0) {
  372. pContext->panic = 1;
  373. return -7;
  374. }
  375. value.value = i;
  376. if(r[strlen(r) - 1] == ':') {
  377. value.type = INK_LABEL;
  378. } else {
  379. value.type = INK_RESERVED;
  380. }
  381. int err;
  382. err = ink_push(pContext, value);
  383. if(err < 0) {
  384. return -23;
  385. }
  386. }
  387. *end = 0;
  388. return 0;
  389. }
  390. static int ink_lex(struct context *pContext, char* buffer) {
  391. int i;
  392. char r[128];
  393. int end = 0;
  394. int err;
  395. while(*buffer != 0) {
  396. if(isspace(*buffer)) {
  397. err = ink_consume_one(&end, pContext, &buffer, r);
  398. if(err < 0) {
  399. pContext->panic = 1;
  400. return -8;
  401. }
  402. } else {
  403. r[end] = *buffer;
  404. ++end;
  405. }
  406. ++buffer;
  407. }
  408. err = ink_consume_one(&end, pContext, &buffer, r);
  409. if(err < 0) {
  410. pContext->panic = 1;
  411. return -9;
  412. }
  413. return 0;
  414. }
  415. static int lblcmp(const char* label, const char* other, size_t label_sz) {
  416. while (label_sz != 1) {
  417. if(*other == 0) return 1;
  418. if(*label != *other) return 1;
  419. ++label;
  420. ++other;
  421. label_sz--;
  422. }
  423. return 0;
  424. }
  425. int ink_make_routine(struct context* ctx) {
  426. if(ctx->routines == NULL) {
  427. ctx->routines = ctx->malloc(sizeof(struct ink_routine) * 8);
  428. ctx->routines_top = 0;
  429. ctx->routines_capacity = 8;
  430. struct ink_routine* it = ctx->routines;
  431. struct ink_routine* end = ctx->routines + 8;
  432. for(;it != end;++it) {
  433. it->stack = NULL;
  434. it->function_stack = NULL;
  435. it->panic = INK_ROUTINE_CAN_REUSE;
  436. }
  437. } else if(ctx->routines_top == ctx->routines_capacity) {
  438. int new_count = (ctx->routines_capacity + ctx->routines_capacity/2);
  439. void* renewed = ctx->realloc(ctx->routines, sizeof(struct stack_frame) * new_count);
  440. if(renewed == NULL) {
  441. return -99;
  442. } else {
  443. ctx->routines = renewed;
  444. struct ink_routine* it = ctx->routines + ctx->routines_capacity;
  445. struct ink_routine* end = ctx->routines + new_count;
  446. for(;it != end;++it) {
  447. it->panic = INK_ROUTINE_CAN_REUSE;
  448. }
  449. ctx->routines_capacity = new_count;
  450. }
  451. }
  452. struct ink_routine* it = ctx->routines;
  453. struct ink_routine* end = ctx->routines + ctx->routines_capacity;
  454. for(;it != end;++it) {
  455. if(it->panic == INK_ROUTINE_CAN_REUSE) {
  456. it->panic = 0;
  457. it->stack = NULL;
  458. it->top = 0;
  459. it->capacity = 0;
  460. it->function_stack = NULL;
  461. it->function_stack_top = 0;
  462. it->function_stack_capacity = 0;
  463. int idx = it - ctx->routines;
  464. if(idx >= ctx->routines_top) {
  465. ctx->routines_top = idx + 1;
  466. }
  467. return idx;
  468. }
  469. }
  470. }
  471. int ink_kill_routine(struct context* ctx, int routine){
  472. if(routine < 0 || routine >= ctx->routines_top) {
  473. return 0;
  474. }
  475. struct ink_routine* curr = ctx->routines + routine;
  476. if(curr->panic == INK_ROUTINE_CAN_REUSE) {
  477. return 0;
  478. }
  479. if(curr->stack != NULL) {
  480. ctx->free(curr->stack);
  481. curr->stack = NULL;
  482. }
  483. if(curr->function_stack != NULL) {
  484. ctx->free(curr->function_stack);
  485. curr->function_stack = NULL;
  486. }
  487. curr->panic = INK_ROUTINE_CAN_REUSE;
  488. return 1;
  489. }
  490. /**
  491. *
  492. * @param pContext
  493. * @param executable_buffer
  494. * @param executable_buffer_top
  495. * @internal Loop from hell
  496. */
  497. static int ink_parse(struct context* pContext, struct elem* executable_buffer, int* executable_buffer_top) {
  498. struct ink_routine* currentRoutine = pContext->routines + pContext->routine_current;
  499. int i;
  500. #define LABEL_BUFFER 128
  501. #define FUNCTION_BUFFER 256
  502. struct label labels[LABEL_BUFFER];
  503. struct elem function_buffer[FUNCTION_BUFFER];
  504. int function_buffer_top = 0;
  505. int function_name = -1;
  506. #define MODE_EXECUTABLE 0
  507. #define MODE_FUNCTION 1
  508. #define MODE_DO 2
  509. int mode = 0;
  510. memset(labels, 0, sizeof(struct label)*LABEL_BUFFER);
  511. for(i = 0; i < currentRoutine->top; ++i) {
  512. struct elem current;
  513. current = currentRoutine->stack[i];
  514. switch (mode) {
  515. case MODE_EXECUTABLE:
  516. switch(current.type) {
  517. case INK_FUNCTION_KW:
  518. mode = MODE_FUNCTION;
  519. function_name = -1;
  520. goto next_token;
  521. case INK_DO_KW:
  522. case INK_END_KW:
  523. return -26;
  524. default:
  525. executable_buffer[*executable_buffer_top] = current;
  526. *executable_buffer_top += 1;
  527. }
  528. break;
  529. case MODE_FUNCTION:
  530. if(current.type == INK_DO_KW) {
  531. if(function_name == -1) {
  532. return -27;
  533. } else {
  534. mode = MODE_DO;
  535. memset(labels, 0, sizeof(struct label)*128);
  536. goto next_token;
  537. }
  538. }
  539. if(function_name != -1) {
  540. return -28;
  541. }
  542. if(current.type != INK_RESERVED) {
  543. return -29;
  544. }
  545. function_name = current.value;
  546. break;
  547. case MODE_DO:
  548. if(current.type == INK_END_KW) {
  549. int j;
  550. for(j = 0; j < function_buffer_top; j++) {
  551. struct elem pt;
  552. pt = function_buffer[j];
  553. if(pt.type == INK_LABEL) {
  554. int k;
  555. for(k = 0; k < LABEL_BUFFER; k++) {
  556. if(labels[k].active) {
  557. if(strcmp(labels[k].name, pContext->lex_reserved_words[pt.value]) == 0) {
  558. labels[k].dest = j;
  559. return -30;
  560. break;
  561. }
  562. } else {
  563. labels[k].active = 1;
  564. labels[k].name = pContext->lex_reserved_words[pt.value];
  565. labels[k].dest = j;
  566. memcpy(function_buffer+j, function_buffer+j+1, sizeof(struct elem)*(function_buffer_top-j-1));
  567. function_buffer_top--;
  568. j--;
  569. break;
  570. }
  571. }
  572. }
  573. }
  574. for(j = 0; j < function_buffer_top; j++) {
  575. struct elem pt;
  576. pt = function_buffer[j];
  577. if(pt.type == INK_RESERVED) {
  578. const char* str = pContext->lex_reserved_words[pt.value];
  579. int k;
  580. for(k = 0; k < LABEL_BUFFER; k++) {
  581. if(labels[k].active) {
  582. const char* lbl = labels[k].name;
  583. int label_sz = strlen(lbl);
  584. if(lblcmp(labels[k].name, pContext->lex_reserved_words[pt.value], label_sz) == 0) {
  585. function_buffer[j].type = INK_INTEGER;
  586. function_buffer[j].value = labels[k].dest - j;
  587. break;
  588. }
  589. } else break;
  590. }
  591. }
  592. }
  593. int err;
  594. err = ink_add_indigenous(pContext, pContext->lex_reserved_words[function_name], function_buffer, function_buffer_top);
  595. if(err < 0) {
  596. pContext->panic = 1;
  597. return -33;
  598. }
  599. function_buffer_top = 0;
  600. mode = MODE_EXECUTABLE;
  601. goto next_token;
  602. }
  603. function_buffer[function_buffer_top] = current;
  604. function_buffer_top += 1;
  605. break;
  606. }
  607. next_token: i=i;
  608. }
  609. if(mode == MODE_FUNCTION || mode == MODE_DO) {
  610. return -32;
  611. }
  612. return 0;
  613. #undef MODE_EXECUTABLE
  614. #undef MODE_FUNCTION
  615. #undef MODE_DO
  616. #undef LABEL_BUFFER
  617. #undef FUNCTION_BUFFER
  618. }
  619. int ink_step(struct context *pContext) {
  620. struct ink_routine* currentRoutine = pContext->routines + pContext->routine_current;
  621. pContext->steps++;
  622. if(currentRoutine->function_stack_top == 0) return 0;
  623. if(pContext->panic) {
  624. return -1;
  625. }
  626. struct stack_frame frame;
  627. struct stack_frame* top;
  628. struct elem next;
  629. int t;
  630. top = &currentRoutine->function_stack[currentRoutine->function_stack_top-1];
  631. t = top->executing.type;
  632. switch(t) {
  633. case INK_NATIVE_FUNCTION:
  634. if(top->index != 0) {
  635. ink_pop_fn(pContext);
  636. } else {
  637. top->index++;
  638. if(pContext->native_words_top <= top->executing.value) {
  639. pContext->panic = 1;
  640. return -1;
  641. }
  642. pContext->native_words[top->executing.value].value(pContext);
  643. }
  644. break;
  645. case INK_FUNCTION:
  646. if(pContext->words_top <= top->executing.value) {
  647. pContext->panic = 1;
  648. return -1;
  649. }
  650. if(top->index >= pContext->words[top->executing.value].size) {
  651. ink_pop_fn(pContext);
  652. } else {
  653. next = pContext->words[top->executing.value].things[top->index];
  654. if(next.type == INK_RETURN) {
  655. ink_pop_fn(pContext);
  656. return 1;
  657. }
  658. frame.executing = next;
  659. frame.index = 0;
  660. t = ink_push_fn(pContext, frame);
  661. if(t < 0) {
  662. pContext->panic = 1;
  663. return -11;
  664. }
  665. top->index++;
  666. }
  667. break;
  668. default:
  669. t = ink_push(pContext, top->executing);
  670. if(t < 0) {
  671. pContext->panic = 1;
  672. return -25;
  673. }
  674. ink_pop_fn(pContext);
  675. break;
  676. }
  677. return 1;
  678. }
  679. void ink_compile(struct context *pContext, char* buffer) {
  680. int routine = ink_make_routine(pContext);
  681. int saved = pContext->routine_current;
  682. pContext->routine_current = routine;
  683. struct ink_routine* currentRoutine = pContext->routines + routine;
  684. currentRoutine->stack = NULL;
  685. currentRoutine->top = 0;
  686. currentRoutine->capacity = 0;
  687. int err;
  688. err = ink_lex(pContext, buffer);
  689. if(err < 0) {
  690. pContext->panic = 1;
  691. return;
  692. }
  693. int i = 0;
  694. struct elem executable_buffer[256];
  695. int executable_buffer_top = 0;
  696. err = ink_parse(pContext, executable_buffer, &executable_buffer_top);
  697. if(err < 0) {
  698. pContext->panic = 1;
  699. return;
  700. }
  701. struct stack_frame frame;
  702. char main_fn[32] = "__-MAIN-__";
  703. char* integer = ink_itoa(pContext, routine);
  704. size_t integer_size = strlen(integer);
  705. memcpy(main_fn+10, integer, integer_size);
  706. pContext->free(integer);
  707. main_fn[10+integer_size] = 0;
  708. frame.executing.value = ink_add_indigenous(pContext, main_fn, executable_buffer, executable_buffer_top);
  709. if(frame.executing.value < 0) {
  710. pContext->panic = 1;
  711. return;
  712. }
  713. frame.executing.type = INK_FUNCTION;
  714. frame.index = 0;
  715. err = ink_push_fn(pContext, frame);
  716. if(err < 0) {
  717. pContext->panic = 1;
  718. return;
  719. }
  720. pContext->routine_current = saved;
  721. return;
  722. }
  723. int ink_can_run(struct context* pContext) {
  724. int it = 0;
  725. for(;it < pContext->routines_top; ++it) {
  726. if(pContext->routines[it].panic == 0) {
  727. return 1;
  728. }
  729. }
  730. return 0;
  731. }
  732. int ink_step_everyone(struct context* pContext) {
  733. int out;
  734. pContext->routine_current = -1;
  735. for(;;) {
  736. do{
  737. ++(pContext->routine_current);
  738. } while(pContext->routine_current < pContext->routines_top && pContext->routines[pContext->routine_current].panic != 0);
  739. if(pContext->routine_current >= pContext->routines_top) break;
  740. if(pContext->routines[pContext->routine_current].panic == INK_ROUTINE_SUCCESS) {
  741. ink_kill_routine(pContext, pContext->routine_current);
  742. }
  743. out = ink_step(pContext);
  744. if(out == 0) {
  745. pContext->routines[pContext->routine_current].panic = INK_ROUTINE_SUCCESS;
  746. } else if(out < 0) {
  747. pContext->routines[pContext->routine_current].panic = out;
  748. }
  749. }
  750. return 0;
  751. }
  752. /**********************************************************************************************************************/
  753. static void print_stacktrace(struct context* _) {
  754. int i = 0;
  755. struct ink_routine* currentRoutine = _->routines + _->routine_current;
  756. for(; i < currentRoutine->function_stack_top; ++i) {
  757. struct elem thing;
  758. thing = currentRoutine->function_stack[i].executing;
  759. switch(thing.type) {
  760. case INK_NATIVE_FUNCTION: {
  761. char *n = _->native_words[thing.value].name;
  762. while (*n) {
  763. _->putchar(*n);
  764. ++n;
  765. }
  766. _->putchar(10);
  767. break;
  768. }
  769. case INK_FUNCTION:{
  770. char *n = _->native_words[thing.value].name;
  771. while (*n) {
  772. _->putchar(*n);
  773. ++n;
  774. }
  775. _->putchar(':');
  776. n = ink_itoa(_, currentRoutine->function_stack[i].index);
  777. while (*n) {
  778. _->putchar(*n);
  779. ++n;
  780. }
  781. _->free(n);
  782. _->putchar(10);
  783. break;
  784. }
  785. default:
  786. break;
  787. }
  788. }
  789. }
  790. static void add_int(struct context* ctx) {
  791. struct ink_routine* currentRoutine = ctx->routines + ctx->routine_current;
  792. if(currentRoutine->top < 2) {
  793. currentRoutine->panic = 1;
  794. return;
  795. }
  796. struct elem a;
  797. struct elem b;
  798. a = currentRoutine->stack[currentRoutine->top-1];
  799. b = currentRoutine->stack[currentRoutine->top-2];
  800. if(!(a.type == INK_INTEGER && b.type == INK_INTEGER)) {
  801. ctx->panic = 1;
  802. return;
  803. }
  804. ink_pop(ctx);
  805. currentRoutine->stack[currentRoutine->top-1].value = a.value + b.value;
  806. }
  807. static void sub_int(struct context* ctx) {
  808. struct ink_routine* currentRoutine = ctx->routines + ctx->routine_current;
  809. if(currentRoutine->top < 2) {
  810. currentRoutine->panic = 1;
  811. return;
  812. }
  813. struct elem a;
  814. struct elem b;
  815. a = currentRoutine->stack[currentRoutine->top-1];
  816. b = currentRoutine->stack[currentRoutine->top-2];
  817. if(!(a.type == INK_INTEGER && b.type == INK_INTEGER)) {
  818. currentRoutine->panic = 1;
  819. return;
  820. }
  821. ink_pop(ctx);
  822. currentRoutine->stack[currentRoutine->top-1].value = b.value - a.value;
  823. }
  824. static void mult_int(struct context* ctx) {
  825. struct ink_routine* currentRoutine = ctx->routines + ctx->routine_current;
  826. if(currentRoutine->top < 2) {
  827. currentRoutine->panic = 1;
  828. return;
  829. }
  830. struct elem a;
  831. struct elem b;
  832. a = currentRoutine->stack[currentRoutine->top-1];
  833. b = currentRoutine->stack[currentRoutine->top-2];
  834. if(!(a.type == INK_INTEGER && b.type == INK_INTEGER)) {
  835. currentRoutine->panic = 1;
  836. return;
  837. }
  838. ink_pop(ctx);
  839. currentRoutine->stack[currentRoutine->top-1].value = b.value * a.value;
  840. }
  841. static void div_int(struct context* ctx) {
  842. struct ink_routine* currentRoutine = ctx->routines + ctx->routine_current;
  843. if(currentRoutine->top < 2) {
  844. currentRoutine->panic = 1;
  845. return;
  846. }
  847. struct elem a;
  848. struct elem b;
  849. a = currentRoutine->stack[currentRoutine->top-1];
  850. b = currentRoutine->stack[currentRoutine->top-2];
  851. if(!(a.type == INK_INTEGER && b.type == INK_INTEGER)) {
  852. currentRoutine->panic = 1;
  853. return;
  854. }
  855. ink_pop(ctx);
  856. currentRoutine->stack[currentRoutine->top-1].value = b.value / a.value;
  857. }
  858. static void rem_int(struct context* ctx) {
  859. struct ink_routine* currentRoutine = ctx->routines + ctx->routine_current;
  860. if(currentRoutine->top < 2) {
  861. currentRoutine->panic = 1;
  862. return;
  863. }
  864. struct elem a;
  865. struct elem b;
  866. a = currentRoutine->stack[currentRoutine->top-1];
  867. b = currentRoutine->stack[currentRoutine->top-2];
  868. if(!(a.type == INK_INTEGER && b.type == INK_INTEGER)) {
  869. currentRoutine->panic = 1;
  870. return;
  871. }
  872. ink_pop(ctx);
  873. currentRoutine->stack[currentRoutine->top-1].value = b.value % a.value;
  874. }
  875. static void dupe_elem(struct context* ctx) {
  876. struct ink_routine* currentRoutine = ctx->routines + ctx->routine_current;
  877. if(currentRoutine->top < 1) {
  878. ctx->panic = 1;
  879. return;
  880. }
  881. struct elem a;
  882. a = currentRoutine->stack[currentRoutine->top-1];
  883. int err;
  884. err = ink_push(ctx, a);
  885. if(err < 0) ctx->panic;
  886. }
  887. static void drop_elem(struct context* ctx) {
  888. struct ink_routine* currentRoutine = ctx->routines + ctx->routine_current;
  889. if(currentRoutine->top < 1) {
  890. ctx->panic = 1;
  891. return;
  892. }
  893. ink_pop(ctx);
  894. }
  895. static void pluck_elem(struct context* ctx) {
  896. struct ink_routine* currentRoutine = ctx->routines + ctx->routine_current;
  897. if(currentRoutine->top < 1) {
  898. currentRoutine->panic = 1;
  899. return;
  900. }
  901. struct elem a;
  902. a = currentRoutine->stack[currentRoutine->top-1];
  903. if(a.type != INK_INTEGER) {
  904. ctx->panic = 1;
  905. return;
  906. }
  907. int position = currentRoutine->top - (a.value + 1);
  908. if(position >= currentRoutine->top || position < 0) {
  909. ctx->panic = 1;
  910. return;
  911. }
  912. ink_pop(ctx);
  913. int err;
  914. err = ink_push(ctx, currentRoutine->stack[position]);
  915. if(err < 0) ctx->panic;
  916. }
  917. static void swap_elem(struct context* ctx) {
  918. struct ink_routine* currentRoutine = ctx->routines + ctx->routine_current;
  919. if(currentRoutine->top < 2) {
  920. currentRoutine->panic = 1;
  921. return;
  922. }
  923. struct elem a;
  924. struct elem b;
  925. a = currentRoutine->stack[currentRoutine->top-1];
  926. b = currentRoutine->stack[currentRoutine->top-2];
  927. currentRoutine->stack[currentRoutine->top-2] = a;
  928. currentRoutine->stack[currentRoutine->top-1] = b;
  929. }
  930. static void return_if(struct context* ctx) {
  931. struct ink_routine* currentRoutine = ctx->routines + ctx->routine_current;
  932. if(currentRoutine->top < 1) {
  933. ctx->panic = 1;
  934. return;
  935. }
  936. struct elem a;
  937. a = currentRoutine->stack[currentRoutine->top-1];
  938. if(a.type != INK_INTEGER) {
  939. ctx->panic = 1;
  940. return;
  941. }
  942. if(a.value) {
  943. ink_pop_fn(ctx);
  944. ink_pop_fn(ctx);
  945. }
  946. ink_pop(ctx);
  947. return;
  948. }
  949. static void jump_if(struct context* ctx) {
  950. struct ink_routine* currentRoutine = ctx->routines + ctx->routine_current;
  951. if(currentRoutine->top < 1) {
  952. ctx->panic = 1;
  953. return;
  954. }
  955. struct elem a;
  956. a = currentRoutine->stack[currentRoutine->top-1];
  957. if(a.type != INK_INTEGER) {
  958. ctx->panic = 1;
  959. return;
  960. }
  961. ink_pop(ctx);
  962. if(a.value) {
  963. ink_pop_fn(ctx);
  964. a = currentRoutine->stack[currentRoutine->top-1];
  965. currentRoutine->function_stack[currentRoutine->function_stack_top - 1].index += a.value - 3;
  966. }
  967. ink_pop(ctx);
  968. return;
  969. }
  970. static void print_int(struct context* ctx) {
  971. struct ink_routine* currentRoutine = ctx->routines + ctx->routine_current;
  972. if(currentRoutine->top < 1 || currentRoutine->stack[currentRoutine->top-1].type != INK_INTEGER) {
  973. currentRoutine->panic = 1;
  974. return;
  975. }
  976. struct elem a;
  977. a = currentRoutine->stack[currentRoutine->top-1];
  978. ink_pop(ctx);
  979. char* n = ink_itoa(ctx, a.value);
  980. char* str = n;
  981. while (*str) {
  982. ctx->putchar(*str);
  983. ++str;
  984. }
  985. ctx->free(n);
  986. }
  987. static void print_as_utf8(struct context* ctx) {
  988. struct ink_routine* currentRoutine = ctx->routines + ctx->routine_current;
  989. if(currentRoutine->top < 1 || currentRoutine->stack[currentRoutine->top-1].type != INK_INTEGER) {
  990. ctx->panic = 1;
  991. return;
  992. }
  993. struct elem a;
  994. a = currentRoutine->stack[currentRoutine->top-1];
  995. if(a.value <= 0x7F) {
  996. ctx->putchar(a.value);
  997. } else if(a.value <= 0x7FF) {
  998. ctx->putchar(((a.value & 0xFC0) >> 6) | 192);
  999. ctx->putchar((a.value & 0x3F) | 128);
  1000. } else if(a.value <= 0xFFFF) {
  1001. ctx->putchar(((a.value & 0x3F000) >> 12) | 224);
  1002. ctx->putchar(((a.value & 0xFC0) >> 6) | 128);
  1003. ctx->putchar((a.value & 0x3F) | 128);
  1004. } else if(a.value <= 0x10FFFF) {
  1005. ctx->putchar(((a.value & 0x3C0000) >> 18) | 240);
  1006. ctx->putchar(((a.value & 0x3F000) >> 12) | 128);
  1007. ctx->putchar(((a.value & 0xFC0) >> 6) | 128);
  1008. ctx->putchar((a.value & 0x3F) | 128);
  1009. } else {
  1010. ctx->panic = 1;
  1011. return;
  1012. }
  1013. ink_pop(ctx);
  1014. }
  1015. int ink_std_library(struct context* ctx) {
  1016. int v;
  1017. v = 0;
  1018. v += ink_add_native(ctx, "trace", print_stacktrace);
  1019. v += ink_add_native(ctx, "print_int", print_int);
  1020. v += ink_add_native(ctx, "print_utf8", print_as_utf8);
  1021. v += ink_add_native(ctx, "+", add_int);
  1022. v += ink_add_native(ctx, "-", sub_int);
  1023. v += ink_add_native(ctx, "*", mult_int);
  1024. v += ink_add_native(ctx, "/", div_int);
  1025. v += ink_add_native(ctx, "%", rem_int);
  1026. v += ink_add_native(ctx, "swap", swap_elem);
  1027. v += ink_add_native(ctx, "dup", dupe_elem);
  1028. v += ink_add_native(ctx, "drop", drop_elem);
  1029. v += ink_add_native(ctx, "pluck", pluck_elem);
  1030. v += ink_add_native(ctx, "return_if", return_if);
  1031. v += ink_add_native(ctx, "jump_if", jump_if);
  1032. return v;
  1033. }