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.

787 lignes
19 KiB

il y a 6 mois
il y a 6 mois
il y a 6 mois
il y a 6 mois
il y a 6 mois
il y a 6 mois
il y a 6 mois
il y a 6 mois
il y a 6 mois
il y a 6 mois
il y a 6 mois
il y a 6 mois
il y a 6 mois
il y a 6 mois
il y a 6 mois
il y a 6 mois
il y a 6 mois
il y a 6 mois
il y a 6 mois
il y a 6 mois
il y a 6 mois
il y a 6 mois
il y a 6 mois
il y a 6 mois
il y a 6 mois
il y a 6 mois
il y a 6 mois
il y a 6 mois
il y a 6 mois
il y a 6 mois
il y a 6 mois
  1. #ifndef NOSTDLIB
  2. #include <stdio.h>
  3. #include <stdlib.h>
  4. #include <string.h>
  5. #include <ctype.h>
  6. #endif
  7. #include "ink.h"
  8. #define INK_RESERVED (-1)
  9. #define INK_FUNCTION_KW (-2)
  10. #define INK_DO_KW (-3)
  11. #define INK_END_KW (-4)
  12. #define INK_LABEL (-5)
  13. #define INK_RETURN (-6)
  14. #define _KEYWORD_INK_FUNCTION "fn"
  15. #define _KEYWORD_INK_DO "do"
  16. #define _KEYWORD_INK_END "end"
  17. #define _KEYWORD_INK_RETURN "return"
  18. struct label {
  19. int active;
  20. int dest;
  21. char* name;
  22. };
  23. #ifdef NOSTDLIB
  24. static size_t strlen(const char* c) {
  25. size_t j = 0;
  26. while(*(c++)) {
  27. j++;
  28. }
  29. return j;
  30. }
  31. static void* memcpy(void* _dest, const void* _src, size_t sz) {
  32. char* dest = _dest;
  33. const char* src = _src;
  34. while(sz--) {
  35. *(dest++) = *(src++);
  36. }
  37. return dest;
  38. }
  39. static int strcmp(const char* dest, const char* src) {
  40. while(*dest != 0 && *src != 0) {
  41. if(*(dest++) != *(src++)) {
  42. return 1;
  43. }
  44. }
  45. return 0;
  46. }
  47. static void* memmove(void* _dest, const void* _src, size_t sz) {
  48. char* dest = _dest;
  49. const char* src = _src;
  50. if (src < dest) {
  51. src += sz;
  52. dest += sz;
  53. while (sz-- > 0) {
  54. *--dest = *--src;
  55. }
  56. } else {
  57. while (sz-- > 0) {
  58. *dest++ = *src++;
  59. }
  60. }
  61. return dest;
  62. }
  63. static void* memset(void* _dest, int src, size_t sz) {
  64. char* dest = _dest;
  65. while(sz--) {
  66. *(dest++) = src++;
  67. }
  68. return dest;
  69. }
  70. static int isspace(int d) {
  71. return d == ' ' || d == '\t' || d == '\n';
  72. }
  73. static int isdigit(int d) {
  74. return '0' <= d && d <= '9';
  75. }
  76. static int atoi(const char* c) {
  77. int ret = 0;
  78. while(*c) {
  79. ret *= 10;
  80. ret += *c - '0';
  81. ++c;
  82. }
  83. return ret;
  84. }
  85. #endif
  86. void ink_add_native(struct context* ctx, const char* name, void(*value)(struct context*)) {
  87. if(ctx->native_words == NULL) {
  88. ctx->native_words = ctx->malloc(sizeof(struct native_fn) * 8);
  89. ctx->native_words_top = 0;
  90. ctx->native_words_capacity = 8;
  91. } else if(ctx->native_words_top == ctx->native_words_capacity) {
  92. int new_count = (ctx->native_words_capacity + ctx->native_words_capacity/2);
  93. void* renewed = ctx->realloc(ctx->native_words, sizeof(struct native_fn) * new_count);
  94. if(renewed == NULL) {
  95. // TODO: error
  96. } else {
  97. ctx->native_words = renewed;
  98. ctx->native_words_capacity = new_count;
  99. }
  100. }
  101. int len = strlen(name);
  102. char* copy = ctx->malloc(len+1);
  103. if(copy == NULL) {
  104. // TODO: error
  105. }
  106. memcpy(copy, name, len);
  107. copy[len] = 0;
  108. ctx->native_words[ctx->native_words_top].value = value;
  109. ctx->native_words[ctx->native_words_top].name = copy;
  110. ctx->native_words_top++;
  111. }
  112. static int ink_add_indigenous(struct context* ctx, const char* name, struct elem* m, size_t count) {
  113. if(ctx->words == NULL) {
  114. ctx->words = ctx->malloc(sizeof(struct fn) * 8);
  115. ctx->words_top = 0;
  116. ctx->words_capacity = 8;
  117. } else if(ctx->words_top == ctx->words_capacity) {
  118. int new_count = (ctx->words_capacity + ctx->words_capacity/2);
  119. void* renewed = ctx->realloc(ctx->words, sizeof(struct native_fn) * new_count);
  120. if(renewed == NULL) {
  121. // TODO: error
  122. } else {
  123. ctx->words = renewed;
  124. ctx->words_capacity = new_count;
  125. }
  126. }
  127. int i;
  128. for(i = 0; i < ctx->words_top; ++i) {
  129. if(strcmp(name, ctx->words[i].name) == 0) {
  130. ctx->free(ctx->words[i].things);
  131. ctx->words[i].things = ctx->malloc(sizeof(struct elem) * count);
  132. memcpy(ctx->words[i].things, m, sizeof(struct elem) * count);
  133. ctx->words[i].size = count;
  134. return i;
  135. }
  136. }
  137. int len = strlen(name);
  138. char* copy = ctx->malloc(len+1);
  139. if(copy == NULL) {
  140. // TODO: error
  141. }
  142. memcpy(copy, name, len);
  143. copy[len] = 0;
  144. ctx->words[ctx->words_top].things = ctx->malloc(sizeof(struct elem) * count);
  145. memcpy(ctx->words[ctx->words_top].things, m, sizeof(struct elem) * count);
  146. ctx->words[ctx->words_top].size = count;
  147. ctx->words[ctx->words_top].name = copy;
  148. return ctx->words_top++;
  149. }
  150. static int ink_add_lex_string(struct context* ctx, const char* name) {
  151. int i;
  152. if(ctx->lex_reserved_words == NULL) {
  153. ctx->lex_reserved_words = ctx->malloc(sizeof(char*) * 8);
  154. ctx->lex_reserved_words_top = 0;
  155. ctx->lex_reserved_words_capacity = 8;
  156. } else if(ctx->lex_reserved_words_top == ctx->lex_reserved_words_capacity) {
  157. int new_count = (ctx->lex_reserved_words_capacity + ctx->lex_reserved_words_capacity/2);
  158. void* renewed = ctx->realloc(ctx->lex_reserved_words, sizeof(struct native_fn) * new_count);
  159. if(renewed == NULL) {
  160. // TODO: error
  161. } else {
  162. ctx->lex_reserved_words = renewed;
  163. ctx->lex_reserved_words_capacity = new_count;
  164. }
  165. }
  166. for(i = 0; i < ctx->lex_reserved_words_top; i++) {
  167. if(strcmp(ctx->lex_reserved_words[i], name) == 0) {
  168. return i;
  169. }
  170. }
  171. int len = strlen(name);
  172. i = ctx->lex_reserved_words_top;
  173. ctx->lex_reserved_words[i] = ctx->malloc(len+1);
  174. memcpy(ctx->lex_reserved_words[i], name, len);
  175. ctx->lex_reserved_words[i][len] = 0;
  176. ctx->lex_reserved_words_top++;
  177. return i;
  178. }
  179. void ink_push(struct context* ctx, struct elem value) {
  180. if(ctx->stack == NULL) {
  181. ctx->stack = ctx->malloc(sizeof(struct elem) * 8);
  182. ctx->top = 0;
  183. ctx->capacity = 8;
  184. } else if(ctx->top == ctx->capacity) {
  185. int new_count = (ctx->capacity + ctx->capacity/2);
  186. void* renewed = ctx->realloc(ctx->stack, sizeof(struct elem) * new_count);
  187. if(renewed == NULL) {
  188. // TODO: error
  189. } else {
  190. ctx->stack = renewed;
  191. ctx->capacity = new_count;
  192. }
  193. }
  194. ctx->stack[ctx->top] = value;
  195. ctx->top++;
  196. }
  197. void ink_push_fn(struct context* ctx, struct stack_frame value) {
  198. if(ctx->function_stack == NULL) {
  199. ctx->function_stack = ctx->malloc(sizeof(struct stack_frame) * 8);
  200. ctx->function_stack_top = 0;
  201. ctx->function_stack_capacity = 8;
  202. } else if(ctx->function_stack_top == ctx->function_stack_capacity) {
  203. int new_count = (ctx->function_stack_capacity + ctx->function_stack_capacity/2);
  204. void* renewed = ctx->realloc(ctx->function_stack, sizeof(struct stack_frame) * new_count);
  205. if(renewed == NULL) {
  206. // TODO: error
  207. } else {
  208. ctx->function_stack = renewed;
  209. ctx->function_stack_capacity = new_count;
  210. }
  211. }
  212. ctx->function_stack[ctx->function_stack_top] = value;
  213. ctx->function_stack_top++;
  214. }
  215. static void ink_pop_fn(struct context* ctx) {
  216. if(ctx->function_stack == NULL) return;
  217. if(ctx->function_stack_top == 0) return;
  218. ctx->function_stack_top--;
  219. }
  220. static void ink_pop(struct context* ctx) {
  221. if(ctx->stack == NULL) return;
  222. if(ctx->top == 0) return;
  223. ctx->top--;
  224. }
  225. struct context* ink_make_context(void*(*malloc)(size_t), void*(*realloc)(void*, size_t), void(*free)(void*), int(*putchar)(int)) {
  226. struct context* ctx = (struct context*)malloc(sizeof(struct context));
  227. ctx->malloc = malloc;
  228. ctx->realloc = realloc;
  229. ctx->free = free;
  230. ctx->putchar = putchar;
  231. ctx->panic = 0;
  232. ctx->stack = NULL;
  233. ctx->capacity = 0;
  234. ctx->top = 0;
  235. ctx->function_stack = NULL;
  236. ctx->function_stack_capacity = 0;
  237. ctx->function_stack_top = 0;
  238. ctx->native_words = NULL;
  239. ctx->native_words_capacity = 0;
  240. ctx->native_words_top = 0;
  241. ctx->words = NULL;
  242. ctx->words_capacity = 0;
  243. ctx->words_top = 0;
  244. ctx->lex_reserved_words = NULL;
  245. ctx->lex_reserved_words_capacity = 0;
  246. ctx->lex_reserved_words_top = 0;
  247. return ctx;
  248. }
  249. /**
  250. * Allocates a string that contains the integer
  251. * @param _ context (used to allocate)
  252. * @param cpy the value
  253. * @return the allocated string, needs to be freed by ctx->free
  254. */
  255. static char* ink_itoa(struct context* _, int cpy) {
  256. char* n = _->malloc(16);
  257. n[15] = 0;
  258. char* it = n+15;
  259. do {
  260. it--;
  261. *it = (cpy % 10) + '0';
  262. cpy = cpy / 10;
  263. } while(cpy);
  264. memmove(n, it, 16 - (it-n));
  265. return n;
  266. }
  267. static void print_stacktrace(struct context* _) {
  268. int i = 0;
  269. for(; i < _->function_stack_top; ++i) {
  270. struct elem thing = _->function_stack[i].executing;
  271. switch(thing.type) {
  272. case INK_NATIVE_FUNCTION: {
  273. char *n = _->native_words[thing.value].name;
  274. while (*n) {
  275. _->putchar(*n);
  276. ++n;
  277. }
  278. _->putchar(10);
  279. break;
  280. }
  281. case INK_FUNCTION:{
  282. char *n = _->native_words[thing.value].name;
  283. while (*n) {
  284. _->putchar(*n);
  285. ++n;
  286. }
  287. _->putchar(':');
  288. n = ink_itoa(_, _->function_stack[i].index);
  289. while (*n) {
  290. _->putchar(*n);
  291. ++n;
  292. }
  293. _->free(n);
  294. _->putchar(10);
  295. break;
  296. }
  297. default:
  298. break;
  299. }
  300. }
  301. }
  302. static void add_int(struct context* ctx) {
  303. if(ctx->top < 2) {
  304. ctx->panic = 1;
  305. return;
  306. }
  307. struct elem a = ctx->stack[ctx->top-1];
  308. struct elem b = ctx->stack[ctx->top-2];
  309. if(!(a.type == INK_INTEGER && b.type == INK_INTEGER)) {
  310. ctx->panic = 1;
  311. return;
  312. }
  313. ink_pop(ctx);
  314. ctx->stack[ctx->top-1].value = a.value + b.value;
  315. }
  316. static void dupe_elem(struct context* ctx) {
  317. if(ctx->top < 1) {
  318. ctx->panic = 1;
  319. return;
  320. }
  321. struct elem a = ctx->stack[ctx->top-1];
  322. ink_push(ctx, a);
  323. }
  324. static void drop_elem(struct context* ctx) {
  325. if(ctx->top < 1) {
  326. ctx->panic = 1;
  327. return;
  328. }
  329. ink_pop(ctx);
  330. }
  331. static void pluck_elem(struct context* ctx) {
  332. if(ctx->top < 1) {
  333. ctx->panic = 1;
  334. return;
  335. }
  336. struct elem a = ctx->stack[ctx->top-1];
  337. if(a.type != INK_INTEGER) {
  338. ctx->panic = 1;
  339. return;
  340. }
  341. int position = ctx->top - (a.value + 1);
  342. if(position >= ctx->top || position < 0) {
  343. ctx->panic = 1;
  344. return;
  345. }
  346. ink_pop(ctx);
  347. ink_push(ctx, ctx->stack[position]);
  348. }
  349. static void swap_elem(struct context* ctx) {
  350. if(ctx->top < 2) {
  351. ctx->panic = 1;
  352. return;
  353. }
  354. struct elem a = ctx->stack[ctx->top-1];
  355. struct elem b = ctx->stack[ctx->top-2];
  356. ctx->stack[ctx->top-2] = a;
  357. ctx->stack[ctx->top-1] = b;
  358. }
  359. static void return_if(struct context* ctx) {
  360. if(ctx->top < 1) {
  361. ctx->panic = 1;
  362. return;
  363. }
  364. struct elem a = ctx->stack[ctx->top-1];
  365. if(a.type != INK_INTEGER) {
  366. ctx->panic = 1;
  367. return;
  368. }
  369. if(a.value) {
  370. ink_pop_fn(ctx);
  371. ink_pop_fn(ctx);
  372. }
  373. ink_pop(ctx);
  374. return;
  375. }
  376. static void jump_if(struct context* ctx) {
  377. if(ctx->top < 1) {
  378. ctx->panic = 1;
  379. return;
  380. }
  381. struct elem a = ctx->stack[ctx->top-1];
  382. if(a.type != INK_INTEGER) {
  383. ctx->panic = 1;
  384. return;
  385. }
  386. ink_pop(ctx);
  387. if(a.value) {
  388. ink_pop_fn(ctx);
  389. a = ctx->stack[ctx->top-1];
  390. ctx->function_stack[ctx->function_stack_top - 1].index += a.value - 3;
  391. ink_pop(ctx);
  392. //printf("\t*%d\n", ctx->function_stack[ctx->function_stack_top - 1].index);
  393. }
  394. return;
  395. }
  396. static void print_int(struct context* ctx) {
  397. if(ctx->top < 1 || ctx->stack[ctx->top-1].type != INK_INTEGER) {
  398. ctx->panic = 1;
  399. return;
  400. }
  401. struct elem a = ctx->stack[ctx->top-1];
  402. ink_pop(ctx);
  403. char* n = ink_itoa(ctx, a.value);
  404. char* str = n;
  405. while (*str) {
  406. ctx->putchar(*str);
  407. ++str;
  408. }
  409. ctx->free(n);
  410. }
  411. static void print_as_utf8(struct context* ctx) {
  412. if(ctx->top < 1 || ctx->stack[ctx->top-1].type != INK_INTEGER) {
  413. ctx->panic = 1;
  414. return;
  415. }
  416. struct elem a = ctx->stack[ctx->top-1];
  417. if(a.value <= 0x7F) {
  418. ctx->putchar(a.value);
  419. } else if(a.value <= 0x7FF) {
  420. ctx->putchar(((a.value & 0xFC0) >> 6) | 192);
  421. ctx->putchar((a.value & 0x3F) | 128);
  422. } else if(a.value <= 0xFFFF) {
  423. ctx->putchar(((a.value & 0x3F000) >> 12) | 224);
  424. ctx->putchar(((a.value & 0xFC0) >> 6) | 128);
  425. ctx->putchar((a.value & 0x3F) | 128);
  426. } else if(a.value <= 0x10FFFF) {
  427. ctx->putchar(((a.value & 0x3C0000) >> 18) | 240);
  428. ctx->putchar(((a.value & 0x3F000) >> 12) | 128);
  429. ctx->putchar(((a.value & 0xFC0) >> 6) | 128);
  430. ctx->putchar((a.value & 0x3F) | 128);
  431. } else {
  432. ctx->panic = 1;
  433. return;
  434. }
  435. ink_pop(ctx);
  436. }
  437. #ifndef NOSTDLIB
  438. struct context* ink_make_default_context() {
  439. struct context* ctx = ink_make_context(malloc, realloc, free, putchar);
  440. ink_add_native(ctx, "trace", print_stacktrace);
  441. ink_add_native(ctx, "print_int", print_int);
  442. ink_add_native(ctx, "print_utf8", print_as_utf8);
  443. ink_add_native(ctx, "+", add_int);
  444. ink_add_native(ctx, "swap", swap_elem);
  445. ink_add_native(ctx, "dup", dupe_elem);
  446. ink_add_native(ctx, "drop", drop_elem);
  447. ink_add_native(ctx, "pluck", pluck_elem);
  448. ink_add_native(ctx, "return_if", return_if);
  449. ink_add_native(ctx, "jump_if", jump_if);
  450. return ctx;
  451. }
  452. #endif
  453. static void ink_consume_one(int* end, struct context* pContext, char** buffer, char* r) {
  454. int i;
  455. if(*end == 0) {
  456. return;
  457. }
  458. r[*end] = 0;
  459. int done = 0;
  460. if (strcmp(r, _KEYWORD_INK_FUNCTION) == 0) {
  461. struct elem value;
  462. value.value = 0;
  463. value.type = INK_FUNCTION_KW;
  464. ink_push(pContext, value);
  465. done = 1;
  466. }
  467. if (!done && strcmp(r, _KEYWORD_INK_DO) == 0) {
  468. struct elem value;
  469. value.value = 0;
  470. value.type = INK_DO_KW;
  471. ink_push(pContext, value);
  472. done = 1;
  473. }
  474. if (!done && strcmp(r, _KEYWORD_INK_END) == 0) {
  475. struct elem value;
  476. value.value = 0;
  477. value.type = INK_END_KW;
  478. ink_push(pContext, value);
  479. done = 1;
  480. }
  481. if (!done && strcmp(r, _KEYWORD_INK_RETURN) == 0) {
  482. struct elem value;
  483. value.value = 0;
  484. value.type = INK_RETURN;
  485. ink_push(pContext, value);
  486. done = 1;
  487. }
  488. if (!done) {
  489. for (i = 0; i < pContext->words_top; ++i) {
  490. if (strcmp(r, pContext->words[i].name) == 0) {
  491. struct elem value;
  492. value.value = i;
  493. value.type = INK_FUNCTION;
  494. ink_push(pContext, value);
  495. done = 1;
  496. break;
  497. }
  498. }
  499. }
  500. if (!done) {
  501. for (i = 0; i < pContext->native_words_top; ++i) {
  502. if (strcmp(r, pContext->native_words[i].name) == 0) {
  503. struct elem value;
  504. value.value = i;
  505. value.type = INK_NATIVE_FUNCTION;
  506. ink_push(pContext, value);
  507. done = 1;
  508. break;
  509. }
  510. }
  511. }
  512. if (!done) {
  513. for(i = (r[0] == '-'); i < *end; i++) {
  514. if(!isdigit(r[i])){
  515. goto not_an_int;
  516. }
  517. }
  518. struct elem value;
  519. value.value = atoi(r);
  520. value.type = INK_INTEGER;
  521. ink_push(pContext, value);
  522. done = 1;
  523. }
  524. not_an_int: if (!done) {
  525. i = ink_add_lex_string(pContext, r);
  526. struct elem value;
  527. value.value = i;
  528. if(r[strlen(r) - 1] == ':') {
  529. value.type = INK_LABEL;
  530. } else {
  531. value.type = INK_RESERVED;
  532. }
  533. ink_push(pContext, value);
  534. }
  535. *end = 0;
  536. }
  537. static void ink_lex(struct context *pContext, char* buffer) {
  538. int i;
  539. char r[128];
  540. int end = 0;
  541. while(*buffer != 0) {
  542. if(isspace(*buffer)) {
  543. ink_consume_one(&end, pContext, &buffer, r);
  544. } else {
  545. r[end] = *buffer;
  546. ++end;
  547. }
  548. ++buffer;
  549. }
  550. ink_consume_one(&end, pContext, &buffer, r);
  551. }
  552. static int lblcmp(const char* label, const char* other, size_t label_sz) {
  553. while (label_sz != 1) {
  554. if(*other == 0) return 1;
  555. if(*label != *other) return 1;
  556. ++label;
  557. ++other;
  558. label_sz--;
  559. }
  560. return 0;
  561. }
  562. /**
  563. *
  564. * @param pContext
  565. * @param executable_buffer
  566. * @param executable_buffer_top
  567. * @internal Loop from hell
  568. */
  569. static void ink_parse(struct context* pContext, struct elem* executable_buffer, int* executable_buffer_top) {
  570. int i;
  571. #define LABEL_BUFFER 128
  572. #define FUNCTION_BUFFER 256
  573. struct label labels[LABEL_BUFFER];
  574. struct elem function_buffer[FUNCTION_BUFFER];
  575. int function_buffer_top = 0;
  576. int function_name = -1;
  577. #define MODE_EXECUTABLE 0
  578. #define MODE_FUNCTION 1
  579. #define MODE_DO 2
  580. int mode = 0;
  581. memset(labels, 0, sizeof(struct label)*LABEL_BUFFER);
  582. for(i = 0; i < pContext->top; ++i) {
  583. struct elem current = pContext->stack[i];
  584. switch (mode) {
  585. case MODE_EXECUTABLE:
  586. switch(current.type) {
  587. case INK_FUNCTION_KW:
  588. mode = MODE_FUNCTION;
  589. goto next_token;
  590. case INK_DO_KW:
  591. case INK_END_KW:
  592. // TODO: error
  593. default:
  594. executable_buffer[*executable_buffer_top] = current;
  595. *executable_buffer_top += 1;
  596. }
  597. break;
  598. case MODE_FUNCTION:
  599. if(current.type == INK_DO_KW) {
  600. if(function_name == -1) {
  601. // TODO: error (function name was not supplied)
  602. } else {
  603. mode = MODE_DO;
  604. memset(labels, 0, sizeof(struct label)*128);
  605. goto next_token;
  606. }
  607. }
  608. if(function_name != -1) {
  609. // TODO: error (function name supplied already)
  610. }
  611. if(current.type != INK_RESERVED) {
  612. // TODO: error
  613. }
  614. function_name = current.value;
  615. break;
  616. case MODE_DO:
  617. if(current.type == INK_END_KW) {
  618. int j;
  619. for(j = 0; j < function_buffer_top; j++) {
  620. struct elem pt = function_buffer[j];
  621. if(pt.type == INK_LABEL) {
  622. int k;
  623. for(k = 0; k < LABEL_BUFFER; k++) {
  624. if(labels[k].active) {
  625. if(strcmp(labels[k].name, pContext->lex_reserved_words[pt.value]) == 0) {
  626. labels[k].dest = j;
  627. // TODO: error
  628. break;
  629. }
  630. } else {
  631. labels[k].active = 1;
  632. labels[k].name = pContext->lex_reserved_words[pt.value];
  633. labels[k].dest = j;
  634. memcpy(function_buffer+j, function_buffer+j+1, sizeof(struct elem)*(function_buffer_top-j-1));
  635. function_buffer_top--;
  636. j--;
  637. break;
  638. }
  639. }
  640. }
  641. }
  642. for(j = 0; j < function_buffer_top; j++) {
  643. struct elem pt = function_buffer[j];
  644. if(pt.type == INK_RESERVED) {
  645. const char* str = pContext->lex_reserved_words[pt.value];
  646. int k;
  647. for(k = 0; k < LABEL_BUFFER; k++) {
  648. if(labels[k].active) {
  649. const char* lbl = labels[k].name;
  650. int label_sz = strlen(lbl);
  651. if(lblcmp(labels[k].name, pContext->lex_reserved_words[pt.value], label_sz) == 0) {
  652. function_buffer[j].type = INK_INTEGER;
  653. function_buffer[j].value = labels[k].dest - j;
  654. break;
  655. }
  656. } else break;
  657. }
  658. }
  659. }
  660. ink_add_indigenous(pContext, pContext->lex_reserved_words[function_name], function_buffer, function_buffer_top);
  661. function_buffer_top = 0;
  662. mode = MODE_EXECUTABLE;
  663. goto next_token;
  664. }
  665. function_buffer[function_buffer_top] = current;
  666. function_buffer_top += 1;
  667. break;
  668. }
  669. next_token: i=i;
  670. }
  671. if(mode == MODE_FUNCTION || mode == MODE_DO) {
  672. // error, missing an end
  673. }
  674. #undef MODE_EXECUTABLE
  675. #undef MODE_FUNCTION
  676. #undef MODE_DO
  677. #undef LABEL_BUFFER
  678. #undef FUNCTION_BUFFER
  679. }
  680. int ink_step(struct context *pContext) {
  681. if(pContext->function_stack_top == 0) return 0;
  682. if(pContext->panic) {
  683. return -1;
  684. }
  685. struct stack_frame* top = &pContext->function_stack[pContext->function_stack_top-1];
  686. switch(top->executing.type) {
  687. case INK_NATIVE_FUNCTION:
  688. if(top->index != 0) {
  689. ink_pop_fn(pContext);
  690. } else {
  691. top->index++;
  692. if(pContext->native_words_top <= top->executing.value) {
  693. pContext->panic = 1;
  694. return -1;
  695. }
  696. pContext->native_words[top->executing.value].value(pContext);
  697. }
  698. break;
  699. case INK_FUNCTION:
  700. if(pContext->words_top <= top->executing.value) {
  701. pContext->panic = 1;
  702. return -1;
  703. }
  704. if(top->index >= pContext->words[top->executing.value].size) {
  705. ink_pop_fn(pContext);
  706. } else {
  707. struct elem next = pContext->words[top->executing.value].things[top->index];
  708. if(next.type == INK_RETURN) {
  709. ink_pop_fn(pContext);
  710. return 1;
  711. }
  712. struct stack_frame frame;
  713. frame.executing = next;
  714. frame.index = 0;
  715. ink_push_fn(pContext, frame);
  716. top->index++;
  717. }
  718. break;
  719. default:
  720. ink_push(pContext, top->executing);
  721. ink_pop_fn(pContext);
  722. break;
  723. }
  724. return 1;
  725. }
  726. void ink_run(struct context *pContext, char* buffer) {
  727. pContext->free(pContext->stack);
  728. pContext->stack = NULL;
  729. pContext->top = 0;
  730. pContext->capacity = 0;
  731. ink_lex(pContext, buffer);
  732. int i = 0;
  733. struct elem executable_buffer[256];
  734. int executable_buffer_top = 0;
  735. ink_parse(pContext, executable_buffer, &executable_buffer_top);
  736. struct stack_frame frame;
  737. frame.executing.value = ink_add_indigenous(pContext, "__-MAIN-__", executable_buffer, executable_buffer_top);
  738. frame.executing.type = INK_FUNCTION;
  739. frame.index = 0;
  740. ink_push_fn(pContext, frame);
  741. int out;
  742. do {
  743. out = ink_step(pContext);
  744. } while(out > 0);
  745. }