A minimalistic programming language written in C89.
選択できるのは25トピックまでです。 トピックは、先頭が英数字で、英数字とダッシュ('-')を使用した35文字以内のものにしてください。

1896 行
49 KiB

4ヶ月前
4ヶ月前
4ヶ月前
4ヶ月前
4ヶ月前
4ヶ月前
4ヶ月前
4ヶ月前
4ヶ月前
4ヶ月前
4ヶ月前
4ヶ月前
4ヶ月前
4ヶ月前
4ヶ月前
4ヶ月前
4ヶ月前
4ヶ月前
4ヶ月前
4ヶ月前
4ヶ月前
4ヶ月前
4ヶ月前
4ヶ月前
4ヶ月前
4ヶ月前
4ヶ月前
4ヶ月前
4ヶ月前
4ヶ月前
4ヶ月前
4ヶ月前
4ヶ月前
4ヶ月前
4ヶ月前
4ヶ月前
4ヶ月前
4ヶ月前
4ヶ月前
4ヶ月前
4ヶ月前
4ヶ月前
4ヶ月前
4ヶ月前
4ヶ月前
4ヶ月前
4ヶ月前
4ヶ月前
4ヶ月前
4ヶ月前
4ヶ月前
4ヶ月前
4ヶ月前
4ヶ月前
4ヶ月前
4ヶ月前
4ヶ月前
4ヶ月前
4ヶ月前
4ヶ月前
4ヶ月前
4ヶ月前
4ヶ月前
4ヶ月前
4ヶ月前
4ヶ月前
4ヶ月前
4ヶ月前
4ヶ月前
4ヶ月前
4ヶ月前
4ヶ月前
4ヶ月前
4ヶ月前
4ヶ月前
4ヶ月前
4ヶ月前
4ヶ月前
4ヶ月前
4ヶ月前
  1. #include "include/ink.h"
  2. #ifndef NOSTDLIB
  3. #include <stdio.h>
  4. #include <stdlib.h>
  5. #include <string.h>
  6. #include <ctype.h>
  7. #ifdef INSTRUMENTATION
  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. #define min(x, y) ((x) > (y) ? (y) : (x))
  22. #define max(x, y) ((x) < (y) ? (y) : (x))
  23. struct label {
  24. int active;
  25. int dest;
  26. char* name;
  27. };
  28. #ifdef NOSTDLIB
  29. static size_t strlen(const char* c) {
  30. size_t j;
  31. j = 0;
  32. while(*(c++)) {
  33. j++;
  34. }
  35. return j;
  36. }
  37. static void* memcpy(void* _dest, const void* _src, size_t sz) {
  38. char* dest;
  39. const char* src;
  40. dest = _dest;
  41. src = _src;
  42. while(sz--) {
  43. *(dest++) = *(src++);
  44. }
  45. return dest;
  46. }
  47. static int strcmp(const char* dest, const char* src) {
  48. while(*dest != 0 && *src != 0) {
  49. if(*(dest++) != *(src++)) {
  50. return 1;
  51. }
  52. }
  53. return 0;
  54. }
  55. static void* memmove(void* _dest, const void* _src, size_t sz) {
  56. char* dest;
  57. const char* src;
  58. dest = _dest;
  59. src = _src;
  60. if (src < dest) {
  61. src += sz;
  62. dest += sz;
  63. while (sz-- > 0) {
  64. *--dest = *--src;
  65. }
  66. } else {
  67. while (sz-- > 0) {
  68. *dest++ = *src++;
  69. }
  70. }
  71. return dest;
  72. }
  73. static void* memset(void* _dest, int src, size_t sz) {
  74. char* dest;
  75. dest = _dest;
  76. while(sz--) {
  77. *(dest++) = src++;
  78. }
  79. return dest;
  80. }
  81. static int isspace(int d) {
  82. return d == ' ' || d == '\t' || d == '\n';
  83. }
  84. static int isdigit(int d) {
  85. return '0' <= d && d <= '9';
  86. }
  87. static int atoi(const char* c) {
  88. int ret;
  89. ret = 0;
  90. while(*c) {
  91. ret *= 10;
  92. ret += *c - '0';
  93. ++c;
  94. }
  95. return ret;
  96. }
  97. #endif
  98. int ink_add_native(struct context* ctx, const char* name, void(*value)(struct context*)) {
  99. int len;
  100. char* copy;
  101. if(ctx->native_words == NULL) {
  102. ctx->native_words = ctx->inner_malloc(sizeof(struct native_fn) * 8);
  103. ctx->native_words_top = 0;
  104. ctx->native_words_capacity = 8;
  105. } else if(ctx->native_words_top == ctx->native_words_capacity) {
  106. int new_count;
  107. void* renewed;
  108. new_count = (ctx->native_words_capacity + ctx->native_words_capacity/2);
  109. renewed = ctx->inner_realloc(ctx->native_words, sizeof(struct native_fn) * new_count);
  110. if(renewed == NULL) {
  111. return -3;
  112. } else {
  113. ctx->native_words = renewed;
  114. ctx->native_words_capacity = new_count;
  115. }
  116. }
  117. len = strlen(name);
  118. copy = ctx->inner_malloc(len+1);
  119. if(copy == NULL) {
  120. return -4;
  121. }
  122. memcpy(copy, name, len);
  123. copy[len] = 0;
  124. ctx->native_words[ctx->native_words_top].value = value;
  125. ctx->native_words[ctx->native_words_top].name = copy;
  126. ctx->native_words_top++;
  127. return 0;
  128. }
  129. static int ink_add_indigenous(struct context* ctx, const char* name, struct elem* m, size_t count) {
  130. int len, i;
  131. char* copy;
  132. if(ctx->words == NULL) {
  133. ctx->words = ctx->malloc(sizeof(struct fn) * 8);
  134. ctx->words_top = 0;
  135. ctx->words_capacity = 8;
  136. } else if(ctx->words_top == ctx->words_capacity) {
  137. int new_count;
  138. void* renewed;
  139. new_count = (ctx->words_capacity + ctx->words_capacity/2);
  140. renewed = ctx->realloc(ctx->words, sizeof(struct fn) * new_count);
  141. if(renewed == NULL) {
  142. return -1;
  143. } else {
  144. ctx->words = renewed;
  145. ctx->words_capacity = new_count;
  146. }
  147. }
  148. for(i = 0; i < ctx->words_top; ++i) {
  149. if(strcmp(name, ctx->words[i].name) == 0) {
  150. ctx->free(ctx->words[i].things);
  151. ctx->words[i].things = ctx->malloc(sizeof(struct elem) * count);
  152. memcpy(ctx->words[i].things, m, sizeof(struct elem) * count);
  153. ctx->words[i].size = count;
  154. return i;
  155. }
  156. }
  157. len = strlen(name);
  158. copy = ctx->malloc(len+1);
  159. if(copy == NULL) {
  160. return -2;
  161. }
  162. memcpy(copy, name, len);
  163. copy[len] = 0;
  164. ctx->words[ctx->words_top].things = ctx->malloc(sizeof(struct elem) * count);
  165. memcpy(ctx->words[ctx->words_top].things, m, sizeof(struct elem) * count);
  166. ctx->words[ctx->words_top].size = count;
  167. ctx->words[ctx->words_top].name = copy;
  168. return ctx->words_top++;
  169. }
  170. /**
  171. *
  172. * @param ctx The context
  173. * @param name The name to add
  174. * @internal add a lexed string to the parser
  175. * @return the id of the string in the list
  176. */
  177. static int ink_add_lex_string(struct context* ctx, const char* name) {
  178. int i;
  179. int len;
  180. if(ctx->lex_reserved_words == NULL) {
  181. ctx->lex_reserved_words = ctx->inner_malloc(sizeof(char*) * 8);
  182. ctx->lex_reserved_words_top = 0;
  183. ctx->lex_reserved_words_capacity = 8;
  184. } else if(ctx->lex_reserved_words_top == ctx->lex_reserved_words_capacity) {
  185. int new_count;
  186. void* renewed;
  187. new_count = (ctx->lex_reserved_words_capacity + ctx->lex_reserved_words_capacity/2);
  188. renewed = ctx->inner_realloc(ctx->lex_reserved_words, sizeof(struct native_fn) * new_count);
  189. if(renewed == NULL) {
  190. return -5;
  191. } else {
  192. ctx->lex_reserved_words = renewed;
  193. ctx->lex_reserved_words_capacity = new_count;
  194. }
  195. }
  196. for(i = 0; i < ctx->lex_reserved_words_top; i++) {
  197. if(strcmp(ctx->lex_reserved_words[i], name) == 0) {
  198. return i;
  199. }
  200. }
  201. len = strlen(name);
  202. i = ctx->lex_reserved_words_top;
  203. ctx->lex_reserved_words[i] = ctx->malloc(len+1);
  204. memcpy(ctx->lex_reserved_words[i], name, len);
  205. ctx->lex_reserved_words[i][len] = 0;
  206. ctx->lex_reserved_words_top++;
  207. return i;
  208. }
  209. int ink_push(struct context* ctx, struct elem value) {
  210. struct ink_routine* current;
  211. if(ctx->routine_current >= ctx->routines_top) return -65;
  212. current = ctx->routines + ctx->routine_current;
  213. if(current->stack == NULL) {
  214. current->stack = ctx->malloc(sizeof(struct elem) * 8);
  215. current->top = 0;
  216. current->capacity = 8;
  217. } else if(current->top == current->capacity) {
  218. int new_count;
  219. void* renewed;
  220. new_count = (current->capacity + current->capacity/2);
  221. renewed = ctx->realloc(current->stack, sizeof(struct elem) * new_count);
  222. if(renewed == NULL) {
  223. return -18;
  224. } else {
  225. current->stack = renewed;
  226. current->capacity = new_count;
  227. }
  228. }
  229. current->stack[current->top] = value;
  230. current->top++;
  231. return 0;
  232. }
  233. int ink_push_fn(struct context* ctx, struct stack_frame value) {
  234. struct ink_routine* current;
  235. if(ctx->routine_current >= ctx->routines_top) return -55;
  236. current = ctx->routines + ctx->routine_current;
  237. if(current->panic) return -56;
  238. if(current->function_stack == NULL) {
  239. current->function_stack = ctx->malloc(sizeof(struct stack_frame) * 8);
  240. current->function_stack_top = 0;
  241. current->function_stack_capacity = 8;
  242. } else if(current->function_stack_top == current->function_stack_capacity) {
  243. int new_count;
  244. void* renewed;
  245. new_count = (current->function_stack_capacity + current->function_stack_capacity/2);
  246. renewed = ctx->realloc(current->function_stack, sizeof(struct stack_frame) * new_count);
  247. if(renewed == NULL) {
  248. return -9;
  249. } else {
  250. current->function_stack = renewed;
  251. current->function_stack_capacity = new_count;
  252. }
  253. }
  254. current->function_stack[current->function_stack_top] = value;
  255. current->function_stack_top++;
  256. return 0;
  257. }
  258. void ink_pop_fn(struct context* ctx) {
  259. if(ctx->routine_current >= ctx->routines_top) return;
  260. if(ctx->routines[ctx->routine_current].panic) return;
  261. if(ctx->routines[ctx->routine_current].function_stack == NULL) return;
  262. if(ctx->routines[ctx->routine_current].function_stack_top == 0) return;
  263. ctx->routines[ctx->routine_current].function_stack_top--;
  264. }
  265. void ink_pop(struct context* ctx) {
  266. if(ctx->routine_current >= ctx->routines_top) return;
  267. if(ctx->routines[ctx->routine_current].panic) return;
  268. if(ctx->routines[ctx->routine_current].stack == NULL) return;
  269. if(ctx->routines[ctx->routine_current].top == 0) return;
  270. ctx->routines[ctx->routine_current].top--;
  271. }
  272. struct context* ink_make_context(void*(*malloc)(size_t), void*(*realloc)(void*, size_t), void(*free)(void*), int(*putchar)(int)) {
  273. struct context* ctx;
  274. ctx = (struct context*)malloc(sizeof(struct context));
  275. ctx->malloc = malloc;
  276. ctx->realloc = realloc;
  277. ctx->free = free;
  278. ctx->inner_malloc = malloc;
  279. ctx->inner_realloc = realloc;
  280. ctx->inner_free = free;
  281. ctx->putchar = putchar;
  282. ctx->panic = 0;
  283. ctx->routines = NULL;
  284. ctx->routines_capacity = 0;
  285. ctx->routines_top = 0;
  286. ctx->types = NULL;
  287. ctx->types_capacity = 0;
  288. ctx->types_top = 0;
  289. ctx->native_words = NULL;
  290. ctx->native_words_capacity = 0;
  291. ctx->native_words_top = 0;
  292. ctx->words = NULL;
  293. ctx->words_capacity = 0;
  294. ctx->words_top = 0;
  295. ctx->lex_reserved_words = NULL;
  296. ctx->lex_reserved_words_capacity = 0;
  297. ctx->lex_reserved_words_top = 0;
  298. ctx->collections = 0;
  299. ctx->steps = 0;
  300. return ctx;
  301. }
  302. /**
  303. * Allocates a string that contains the integer
  304. * @param _ context (used to allocate)
  305. * @param cpy the value
  306. * @return the allocated string, needs to be freed by ctx->free
  307. * @internal this function is slightly cursed
  308. */
  309. static char* ink_itoa(struct context* _, int cpy) {
  310. char* n;
  311. char* it;
  312. n = _->malloc(16);
  313. n[15] = 0;
  314. it = n+15;
  315. do {
  316. it--;
  317. *it = (cpy % 10) + '0';
  318. cpy = cpy / 10;
  319. } while(cpy);
  320. memmove(n, it, 16 - (it-n));
  321. return n;
  322. }
  323. #ifndef NOSTDLIB
  324. struct context* ink_make_default_context(void) {
  325. struct context* ctx;
  326. ctx = ink_make_context(malloc, realloc, free, putchar);
  327. ink_std_library(ctx);
  328. return ctx;
  329. }
  330. #endif
  331. static int ink_consume_one(int* end, struct context* pContext, char** buffer, char* r) {
  332. int i;
  333. int done;
  334. struct elem value;
  335. int err;
  336. if(*end == 0) {
  337. return 0;
  338. }
  339. r[*end] = 0;
  340. done = 0;
  341. if (strcmp(r, _KEYWORD_INK_FUNCTION) == 0) {
  342. value.value = 0;
  343. value.type = INK_FUNCTION_KW;
  344. done = 1;
  345. }
  346. if (!done && strcmp(r, _KEYWORD_INK_DO) == 0) {
  347. value.value = 0;
  348. value.type = INK_DO_KW;
  349. done = 1;
  350. }
  351. if (!done && strcmp(r, _KEYWORD_INK_END) == 0) {
  352. value.value = 0;
  353. value.type = INK_END_KW;
  354. done = 1;
  355. }
  356. if (!done && strcmp(r, _KEYWORD_INK_RETURN) == 0) {
  357. value.value = 0;
  358. value.type = INK_RETURN;
  359. done = 1;
  360. }
  361. if(done) {
  362. err = ink_push(pContext, value);
  363. if(err < 0) {
  364. return -19;
  365. }
  366. }
  367. if (!done) {
  368. for (i = 0; i < pContext->words_top; ++i) {
  369. if (strcmp(r, pContext->words[i].name) == 0) {
  370. value.value = i;
  371. value.type = INK_FUNCTION;
  372. err = ink_push(pContext, value);
  373. if(err < 0) {
  374. return -20;
  375. }
  376. done = 1;
  377. break;
  378. }
  379. }
  380. }
  381. if (!done) {
  382. for (i = 0; i < pContext->native_words_top; ++i) {
  383. if (strcmp(r, pContext->native_words[i].name) == 0) {
  384. value.value = i;
  385. value.type = INK_NATIVE_FUNCTION;
  386. err = ink_push(pContext, value);
  387. if(err < 0) {
  388. return -21;
  389. }
  390. done = 1;
  391. break;
  392. }
  393. }
  394. }
  395. if (!done) {
  396. for(i = (r[0] == '-'); i < *end; i++) {
  397. if(!isdigit(r[i])){
  398. goto not_an_int;
  399. }
  400. }
  401. value.value = atoi(r);
  402. value.type = INK_INTEGER;
  403. err = ink_push(pContext, value);
  404. if(err < 0) {
  405. return -22;
  406. }
  407. done = 1;
  408. }
  409. not_an_int:
  410. if (!done) {
  411. i = ink_add_lex_string(pContext, r);
  412. if(i < 0) {
  413. pContext->panic = 1;
  414. return -7;
  415. }
  416. value.value = i;
  417. if(r[strlen(r) - 1] == ':') {
  418. value.type = INK_LABEL;
  419. } else {
  420. value.type = INK_RESERVED;
  421. }
  422. err = ink_push(pContext, value);
  423. if(err < 0) {
  424. return -23;
  425. }
  426. }
  427. *end = 0;
  428. return 0;
  429. }
  430. static int ink_lex(struct context *pContext, char* buffer) {
  431. /* Limits the token size to 127 chars */
  432. char r[128];
  433. int end;
  434. int err;
  435. end = 0;
  436. restart_after_comment:
  437. while(*buffer != 0) {
  438. if(isspace(*buffer)) {
  439. if(end == 1 && r[0] == '#') {
  440. while(*buffer != '\n' && *buffer != 0) {
  441. ++buffer;
  442. }
  443. end = 0;
  444. goto restart_after_comment;
  445. }
  446. err = ink_consume_one(&end, pContext, &buffer, r);
  447. if(err < 0) {
  448. pContext->panic = 1;
  449. return -8;
  450. }
  451. } else {
  452. r[end] = *buffer;
  453. ++end;
  454. }
  455. ++buffer;
  456. }
  457. err = ink_consume_one(&end, pContext, &buffer, r);
  458. if(err < 0) {
  459. pContext->panic = 1;
  460. return -9;
  461. }
  462. return 0;
  463. }
  464. static int lblcmp(const char* label, const char* other, size_t label_sz) {
  465. while (label_sz != 1) {
  466. if(*other == 0) return 1;
  467. if(*label != *other) return 1;
  468. ++label;
  469. ++other;
  470. label_sz--;
  471. }
  472. return 0;
  473. }
  474. int ink_make_routine(struct context* ctx) {
  475. struct ink_routine* it;
  476. struct ink_routine* end;
  477. /* Allocate space if needed */
  478. if(ctx->routines == NULL) {
  479. ctx->routines = ctx->inner_malloc(sizeof(struct ink_routine) * 8);
  480. ctx->routines_top = 0;
  481. ctx->routines_capacity = 8;
  482. it = ctx->routines;
  483. end = ctx->routines + 8;
  484. for(;it != end;++it) {
  485. it->stack = NULL;
  486. it->function_stack = NULL;
  487. it->panic = INK_ROUTINE_CAN_REUSE;
  488. }
  489. } else if(ctx->routines_top == ctx->routines_capacity) {
  490. int new_count;
  491. void* renewed;
  492. new_count = (ctx->routines_capacity + ctx->routines_capacity/2);
  493. renewed = ctx->inner_realloc(ctx->routines, sizeof(struct ink_routine) * new_count);
  494. if(renewed == NULL) {
  495. return -99;
  496. } else {
  497. ctx->routines = renewed;
  498. it = ctx->routines + ctx->routines_capacity;
  499. end = ctx->routines + new_count;
  500. for(;it != end;++it) {
  501. it->panic = INK_ROUTINE_CAN_REUSE;
  502. }
  503. ctx->routines_capacity = new_count;
  504. }
  505. }
  506. it = ctx->routines;
  507. end = ctx->routines + ctx->routines_capacity;
  508. /* Looks for a reusable routine space then uses it */
  509. for(;it != end;++it) {
  510. if(it->panic == INK_ROUTINE_CAN_REUSE) {
  511. int idx;
  512. it->panic = 0;
  513. it->stack = NULL;
  514. it->top = 0;
  515. it->capacity = 0;
  516. it->function_stack = NULL;
  517. it->function_stack_top = 0;
  518. it->function_stack_capacity = 0;
  519. idx = it - ctx->routines;
  520. if(idx >= ctx->routines_top) {
  521. ctx->routines_top = idx + 1;
  522. }
  523. return idx;
  524. }
  525. }
  526. return -758;
  527. }
  528. int ink_kill_routine(struct context* ctx, int routine){
  529. struct ink_routine* curr;
  530. if(routine < 0 || routine >= ctx->routines_top) {
  531. return 0;
  532. }
  533. curr = ctx->routines + routine;
  534. if(curr->panic == INK_ROUTINE_CAN_REUSE) {
  535. return 0;
  536. }
  537. if(curr->stack != NULL) {
  538. ctx->free(curr->stack);
  539. curr->stack = NULL;
  540. }
  541. if(curr->function_stack != NULL) {
  542. ctx->free(curr->function_stack);
  543. curr->function_stack = NULL;
  544. }
  545. curr->panic = INK_ROUTINE_CAN_REUSE;
  546. return 1;
  547. }
  548. /**
  549. *
  550. * @param pContext
  551. * @param executable_buffer
  552. * @param executable_buffer_top
  553. * @internal Loop from hell
  554. */
  555. static int ink_parse(struct context* pContext, struct elem* executable_buffer, int* executable_buffer_top) {
  556. struct ink_routine* currentRoutine;
  557. int i, function_buffer_top, function_name, mode;
  558. int err;
  559. #define LABEL_BUFFER 128
  560. #define FUNCTION_BUFFER 256
  561. struct label labels[LABEL_BUFFER];
  562. struct elem function_buffer[FUNCTION_BUFFER];
  563. /* TODO: add checks for overflows in these arrays */
  564. currentRoutine = pContext->routines + pContext->routine_current;
  565. function_buffer_top = 0;
  566. function_name = -1;
  567. #define MODE_EXECUTABLE 0
  568. #define MODE_FUNCTION 1
  569. #define MODE_DO 2
  570. mode = MODE_EXECUTABLE;
  571. memset(labels, 0, sizeof(struct label)*LABEL_BUFFER);
  572. /* Loop from hell, good luck, pro-tip: leave the parser alone */
  573. for(i = 0; i < currentRoutine->top; ++i) {
  574. struct elem current;
  575. current = currentRoutine->stack[i];
  576. switch (mode) {
  577. case MODE_EXECUTABLE:
  578. switch(current.type) {
  579. case INK_FUNCTION_KW:
  580. mode = MODE_FUNCTION;
  581. function_name = -1;
  582. goto next_token;
  583. case INK_DO_KW:
  584. case INK_END_KW:
  585. return -26;
  586. default:
  587. executable_buffer[*executable_buffer_top] = current;
  588. *executable_buffer_top += 1;
  589. }
  590. break;
  591. case MODE_FUNCTION:
  592. if(current.type == INK_DO_KW) {
  593. if(function_name == -1) {
  594. return -27;
  595. } else {
  596. mode = MODE_DO;
  597. memset(labels, 0, sizeof(struct label)*128);
  598. goto next_token;
  599. }
  600. }
  601. if(function_name != -1) {
  602. return -28;
  603. }
  604. if(current.type != INK_RESERVED) {
  605. return -29;
  606. }
  607. function_name = current.value;
  608. break;
  609. case MODE_DO:
  610. if(current.type == INK_END_KW) {
  611. int j;
  612. for(j = 0; j < function_buffer_top; j++) {
  613. struct elem pt;
  614. pt = function_buffer[j];
  615. if(pt.type == INK_LABEL) {
  616. int k;
  617. for(k = 0; k < LABEL_BUFFER; k++) {
  618. if(labels[k].active) {
  619. if(strcmp(labels[k].name, pContext->lex_reserved_words[pt.value]) == 0) {
  620. labels[k].dest = j;
  621. return -30;
  622. break;
  623. }
  624. } else {
  625. labels[k].active = 1;
  626. labels[k].name = pContext->lex_reserved_words[pt.value];
  627. labels[k].dest = j;
  628. memcpy(function_buffer+j, function_buffer+j+1, sizeof(struct elem)*(function_buffer_top-j-1));
  629. function_buffer_top--;
  630. j--;
  631. break;
  632. }
  633. }
  634. }
  635. }
  636. for(j = 0; j < function_buffer_top; j++) {
  637. struct elem pt;
  638. pt = function_buffer[j];
  639. if(pt.type == INK_RESERVED) {
  640. int k;
  641. for(k = 0; k < LABEL_BUFFER; k++) {
  642. if(labels[k].active) {
  643. int label_sz;
  644. const char* lbl;
  645. lbl = labels[k].name;
  646. label_sz = strlen(lbl);
  647. if(lblcmp(labels[k].name, pContext->lex_reserved_words[pt.value], label_sz) == 0) {
  648. function_buffer[j].type = INK_INTEGER;
  649. function_buffer[j].value = labels[k].dest - j;
  650. break;
  651. }
  652. } else break;
  653. }
  654. }
  655. }
  656. err = ink_add_indigenous(pContext, pContext->lex_reserved_words[function_name], function_buffer, function_buffer_top);
  657. if(err < 0) {
  658. pContext->panic = 1;
  659. return -33;
  660. }
  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. return -32;
  673. }
  674. return 0;
  675. #undef MODE_EXECUTABLE
  676. #undef MODE_FUNCTION
  677. #undef MODE_DO
  678. #undef LABEL_BUFFER
  679. #undef FUNCTION_BUFFER
  680. }
  681. int ink_step(struct context *pContext) {
  682. struct ink_routine* currentRoutine;
  683. struct stack_frame frame;
  684. struct stack_frame* top;
  685. struct elem next;
  686. int t;
  687. currentRoutine = pContext->routines + pContext->routine_current;
  688. pContext->steps++;
  689. if(currentRoutine->function_stack_top == 0) return 0;
  690. if(pContext->panic) {
  691. return -1;
  692. }
  693. top = &currentRoutine->function_stack[currentRoutine->function_stack_top-1];
  694. t = top->executing.type;
  695. switch(t) {
  696. case INK_NATIVE_FUNCTION:
  697. if(top->index != 0) {
  698. ink_pop_fn(pContext);
  699. } else {
  700. top->index++;
  701. if(pContext->native_words_top <= top->executing.value) {
  702. pContext->panic = 1;
  703. return -1;
  704. }
  705. pContext->native_words[top->executing.value].value(pContext);
  706. }
  707. break;
  708. case INK_FUNCTION:
  709. if(pContext->words_top <= top->executing.value) {
  710. pContext->panic = 1;
  711. return -1;
  712. }
  713. if(top->index >= pContext->words[top->executing.value].size) {
  714. ink_pop_fn(pContext);
  715. } else {
  716. next = pContext->words[top->executing.value].things[top->index];
  717. if(next.type == INK_RETURN) {
  718. ink_pop_fn(pContext);
  719. return 1;
  720. }
  721. frame.executing = next;
  722. frame.index = 0;
  723. t = ink_push_fn(pContext, frame);
  724. if(t < 0) {
  725. pContext->panic = 1;
  726. return -11;
  727. }
  728. top->index++;
  729. }
  730. break;
  731. default:
  732. t = ink_push(pContext, top->executing);
  733. if(t < 0) {
  734. pContext->panic = 1;
  735. return -25;
  736. }
  737. ink_pop_fn(pContext);
  738. break;
  739. }
  740. return 1;
  741. }
  742. void ink_compile(struct context *pContext, const char* buffer) {
  743. int routine, saved, executable_buffer_top;
  744. /* Main function has a size limit of 256 (need to know that for REPL */
  745. struct elem executable_buffer[256];
  746. struct ink_routine* currentRoutine;
  747. int err;
  748. struct stack_frame frame;
  749. char* integer;
  750. size_t integer_size;
  751. char main_fn[32] = "__-MAIN-__";
  752. routine = ink_make_routine(pContext);
  753. saved = pContext->routine_current;
  754. pContext->routine_current = routine;
  755. currentRoutine = pContext->routines + routine;
  756. currentRoutine->stack = NULL;
  757. currentRoutine->top = 0;
  758. currentRoutine->capacity = 0;
  759. err = ink_lex(pContext, buffer);
  760. if(err < 0) {
  761. pContext->panic = 1;
  762. return;
  763. }
  764. executable_buffer_top = 0;
  765. err = ink_parse(pContext, executable_buffer, &executable_buffer_top);
  766. if(err < 0) {
  767. pContext->panic = 1;
  768. return;
  769. }
  770. if(executable_buffer_top != 0) {
  771. integer = ink_itoa(pContext, routine);
  772. integer_size = strlen(integer);
  773. memcpy(main_fn + 10, integer, integer_size);
  774. pContext->free(integer);
  775. main_fn[10 + integer_size] = 0;
  776. frame.executing.value = ink_add_indigenous(pContext, main_fn, executable_buffer, executable_buffer_top);
  777. if (frame.executing.value < 0) {
  778. pContext->panic = 1;
  779. return;
  780. }
  781. frame.executing.type = INK_FUNCTION;
  782. frame.index = 0;
  783. err = ink_push_fn(pContext, frame);
  784. if (err < 0) {
  785. pContext->panic = 1;
  786. return;
  787. }
  788. } else {
  789. pContext->routines[pContext->routine_current].panic = INK_ROUTINE_SUCCESS;
  790. }
  791. pContext->routine_current = saved;
  792. return;
  793. }
  794. int ink_can_run(struct context* pContext) {
  795. int it;
  796. for(it = 0; it < pContext->routines_top; ++it) {
  797. if(pContext->routines[it].panic == 0) {
  798. return 1;
  799. }
  800. }
  801. return 0;
  802. }
  803. int ink_step_everyone(struct context* pContext) {
  804. int out;
  805. pContext->routine_current = -1;
  806. for(;;) {
  807. /* Increment to next runnable routine */
  808. do{
  809. ++(pContext->routine_current);
  810. } while(pContext->routine_current < pContext->routines_top && pContext->routines[pContext->routine_current].panic != 0);
  811. /* Exit condition */
  812. if(pContext->routine_current >= pContext->routines_top) break;
  813. /* Kill? */
  814. if(pContext->routines[pContext->routine_current].panic == INK_ROUTINE_SUCCESS) {
  815. ink_kill_routine(pContext, pContext->routine_current);
  816. }
  817. /* Step! */
  818. out = ink_step(pContext);
  819. if(out == 0) {
  820. pContext->routines[pContext->routine_current].panic = INK_ROUTINE_SUCCESS;
  821. } else if(out < 0) {
  822. pContext->routines[pContext->routine_current].panic = out;
  823. }
  824. }
  825. return 0;
  826. }
  827. int ink_new_type(
  828. struct context* ctx,
  829. const char* type_name,
  830. int size,
  831. void (*collect)(struct context*,void*),
  832. struct ink_collection_list (*gc)(struct context*,void*)
  833. ) {
  834. if(ctx->panic) return -128;
  835. /* Resize for push */
  836. if(ctx->types == NULL) {
  837. ctx->types = ctx->inner_malloc(sizeof(struct ink_type) * 8);
  838. ctx->types_top = 0;
  839. ctx->types_capacity = 8;
  840. } else if(ctx->types_top == ctx->types_capacity) {
  841. int new_count;
  842. void* renewed;
  843. new_count = (ctx->types_capacity + ctx->types_capacity/2);
  844. renewed = ctx->inner_realloc(ctx->types, sizeof(struct ink_type) * new_count);
  845. if(renewed == NULL) {
  846. return -129;
  847. } else {
  848. ctx->types = renewed;
  849. ctx->types_capacity = new_count;
  850. }
  851. }
  852. /* Push */
  853. ctx->types[ctx->types_top].name = type_name;
  854. ctx->types[ctx->types_top].element_size = size;
  855. ctx->types[ctx->types_top].elements = NULL;
  856. ctx->types[ctx->types_top].elements_top = 0;
  857. ctx->types[ctx->types_top].elements_capacity = 0;
  858. ctx->types[ctx->types_top].collect = collect;
  859. ctx->types[ctx->types_top].gc = gc;
  860. ctx->types_top++;
  861. /* Satisfying the minimal value requirement */
  862. return ctx->types_top - 1 + 16;
  863. }
  864. static struct element_slab* ink_get_value_link(struct context* ctx, struct elem ref) {
  865. int type_id;
  866. if(ref.type < 16) return NULL;
  867. type_id = ref.type - 16;
  868. if(type_id >= ctx->types_top) return NULL;
  869. if(ctx->types[type_id].element_size == 0) return NULL;
  870. if(ref.value < 0) return NULL;
  871. if(ref.value >= ctx->types[type_id].elements_top) return NULL;
  872. if(! ctx->types[type_id].elements[ref.value].in_use) return NULL;
  873. return ctx->types[type_id].elements + ref.value;
  874. }
  875. void* ink_get_value(struct context* ctx, struct elem ref) {
  876. struct element_slab* s;
  877. s = ink_get_value_link(ctx, ref);
  878. if(s == NULL) return NULL;
  879. return s->data;
  880. }
  881. struct elem ink_make_native(struct context* ctx, int type, void* ptr) {
  882. int type_id;
  883. struct elem ret;
  884. int g, i;
  885. if(type < 16) {
  886. ret.type = 0;
  887. ret.value = -130;
  888. return ret;
  889. }
  890. /* Apply invariant of the user defined types */
  891. type_id = type - 16;
  892. if(type_id >= ctx->types_top) {
  893. ret.type = 0;
  894. ret.value = -129;
  895. return ret;
  896. }
  897. if(ctx->panic) {
  898. ret.type = 0;
  899. ret.value = -135;
  900. return ret;
  901. }
  902. /* Resize for push of value in store */
  903. if(ctx->types[type_id].elements == NULL) {
  904. ctx->types[type_id].elements = ctx->inner_malloc(sizeof(struct element_slab) * 8);
  905. ctx->types[type_id].elements_top = 0;
  906. ctx->types[type_id].elements_capacity = 8;
  907. memset(ctx->types[type_id].elements + ctx->types[type_id].elements_top, 0, sizeof(struct element_slab)*(ctx->types[type_id].elements_capacity - ctx->types[type_id].elements_top));
  908. } else if(ctx->types[type_id].elements_top == ctx->types[type_id].elements_capacity) {
  909. int new_count;
  910. void* renewed;
  911. new_count = (ctx->types[type_id].elements_capacity + ctx->types[type_id].elements_capacity/2);
  912. renewed = ctx->inner_realloc(ctx->types[type_id].elements, sizeof(struct element_slab) * new_count);
  913. if(renewed == NULL) {
  914. ret.type = 0;
  915. ret.value = -129;
  916. return ret;
  917. } else {
  918. ctx->types[type_id].elements = renewed;
  919. ctx->types[type_id].elements_capacity = new_count;
  920. memset(ctx->types[type_id].elements + ctx->types[type_id].elements_top, 0, sizeof(struct element_slab)*(ctx->types[type_id].elements_capacity - ctx->types[type_id].elements_top));
  921. }
  922. }
  923. /* Push value in store */
  924. g = ctx->types[type_id].elements_capacity;
  925. for(i = 0; i < g; ++i) {
  926. if(! ctx->types[type_id].elements[i].in_use) {
  927. ctx->types[type_id].elements[i].in_use = 1;
  928. ctx->types[type_id].elements[i].uses = 1;
  929. if(ctx->types[type_id].element_size < 0) {
  930. ctx->types[type_id].elements[i].data = ptr;
  931. } else {
  932. void* new_ptr = ctx->malloc(ctx->types[type_id].element_size);
  933. if(new_ptr == NULL) {
  934. ret.type = 0;
  935. ret.value = -139;
  936. return ret;
  937. }
  938. memcpy(new_ptr, ptr, ctx->types[type_id].element_size);
  939. ctx->types[type_id].elements[i].data = new_ptr;
  940. }
  941. ctx->types[type_id].elements_top = max(ctx->types[type_id].elements_top, i+1);
  942. ret.type = type;
  943. ret.value = i;
  944. return ret;
  945. }
  946. }
  947. ret.type = 0;
  948. ret.value = -140;
  949. return ret;
  950. }
  951. void ink_gc(struct context* ctx) {
  952. int i, j, k;
  953. int marked;
  954. struct element_slab* v;
  955. for(i = 0; i < ctx->types_top; ++i) {
  956. for(j = 0; j < ctx->types[i].elements_top; ++j) {
  957. ctx->types[i].elements[j].uses = 0;
  958. }
  959. }
  960. /* Start by marking the roots of the routines, Clear the routines if possible */
  961. for(i = 0; i < ctx->routines_top; ++i) {
  962. if(ctx->routines[i].panic == INK_ROUTINE_SUCCESS) {
  963. ctx->free(ctx->routines[i].stack);
  964. ctx->free(ctx->routines[i].function_stack);
  965. ctx->routines[i].panic = INK_ROUTINE_CAN_REUSE;
  966. }
  967. if(ctx->routines[i].panic == INK_ROUTINE_CAN_REUSE) {
  968. continue;
  969. }
  970. for(j = 0; j < ctx->routines[i].top; ++j) {
  971. v = ink_get_value_link(ctx, ctx->routines[i].stack[j]);
  972. if(v != NULL) ++v->uses;
  973. }
  974. }
  975. /* TODO: Mark objects contained within function code */
  976. /* Mark the rest of the data */
  977. do {
  978. marked = 0;
  979. for (i = 0; i < ctx->types_top; ++i) {
  980. for (j = 0; j < ctx->types[i].elements_top; ++j) {
  981. /* Only mark from things that are active and detected as in use */
  982. if (ctx->types[i].elements[j].in_use && ctx->types[i].elements[j].uses) {
  983. struct ink_collection_list c;
  984. c = ctx->types[i].gc(ctx, ctx->types[i].elements[j].data);
  985. for (k = 0; k < c.count; ++k) {
  986. v = ink_get_value_link(ctx, c.elements[k]);
  987. /* Never mark twice to avoid infinite loops with e.g. arrays that contain themselves */
  988. if (v != NULL && !v->uses) {
  989. ++v->uses;
  990. marked = 1;
  991. }
  992. }
  993. if (c.elements != NULL) ctx->inner_free(c.elements);
  994. }
  995. }
  996. }
  997. } while(marked);
  998. /* Sweep phase: explore any allocated data and sweep the unused away */
  999. for(i = 0; i < ctx->types_top; ++i) {
  1000. for(j = 0; j < ctx->types[i].elements_top; ++j) {
  1001. if(ctx->types[i].elements[j].uses == 0 && ctx->types[i].elements[j].in_use) {
  1002. ctx->collections++;
  1003. ctx->types[i].collect(ctx, ctx->types[i].elements[j].data);
  1004. if(ctx->types[i].element_size > 0) {
  1005. ctx->free(ctx->types[i].elements[j].data);
  1006. }
  1007. ctx->types[i].elements[j].data = NULL;
  1008. ctx->types[i].elements[j].uses = 0;
  1009. ctx->types[i].elements[j].in_use = 0;
  1010. }
  1011. }
  1012. }
  1013. }
  1014. /**********************************************************************************************************************/
  1015. static void print_stacktrace(struct context* _) {
  1016. int i;
  1017. struct ink_routine* currentRoutine;
  1018. currentRoutine = _->routines + _->routine_current;
  1019. for(i = 0; i < currentRoutine->function_stack_top; ++i) {
  1020. struct elem thing;
  1021. char *n;
  1022. thing = currentRoutine->function_stack[i].executing;
  1023. switch(thing.type) {
  1024. case INK_NATIVE_FUNCTION: {
  1025. n = _->native_words[thing.value].name;
  1026. while (*n) {
  1027. _->putchar(*n);
  1028. ++n;
  1029. }
  1030. _->putchar(10);
  1031. break;
  1032. }
  1033. case INK_FUNCTION:{
  1034. n = _->words[thing.value].name;
  1035. while (*n) {
  1036. _->putchar(*n);
  1037. ++n;
  1038. }
  1039. _->putchar(':');
  1040. n = ink_itoa(_, currentRoutine->function_stack[i].index);
  1041. while (*n) {
  1042. _->putchar(*n);
  1043. ++n;
  1044. }
  1045. _->putchar(10);
  1046. break;
  1047. }
  1048. default:
  1049. break;
  1050. }
  1051. }
  1052. }
  1053. static void add_int(struct context* ctx) {
  1054. struct ink_routine* currentRoutine;
  1055. struct elem a;
  1056. struct elem b;
  1057. currentRoutine = ctx->routines + ctx->routine_current;
  1058. if(currentRoutine->top < 2) {
  1059. currentRoutine->panic = -1;
  1060. return;
  1061. }
  1062. a = currentRoutine->stack[currentRoutine->top-1];
  1063. b = currentRoutine->stack[currentRoutine->top-2];
  1064. if(!(a.type == INK_INTEGER && b.type == INK_INTEGER)) {
  1065. ctx->panic = 1;
  1066. return;
  1067. }
  1068. ink_pop(ctx);
  1069. currentRoutine->stack[currentRoutine->top-1].value = a.value + b.value;
  1070. }
  1071. static void sub_int(struct context* ctx) {
  1072. struct ink_routine* currentRoutine;
  1073. struct elem a;
  1074. struct elem b;
  1075. currentRoutine = ctx->routines + ctx->routine_current;
  1076. if(currentRoutine->top < 2) {
  1077. currentRoutine->panic = -1;
  1078. return;
  1079. }
  1080. a = currentRoutine->stack[currentRoutine->top-1];
  1081. b = currentRoutine->stack[currentRoutine->top-2];
  1082. if(!(a.type == INK_INTEGER && b.type == INK_INTEGER)) {
  1083. currentRoutine->panic = -1;
  1084. return;
  1085. }
  1086. ink_pop(ctx);
  1087. currentRoutine->stack[currentRoutine->top-1].value = b.value - a.value;
  1088. }
  1089. static void mult_int(struct context* ctx) {
  1090. struct ink_routine* currentRoutine;
  1091. struct elem a;
  1092. struct elem b;
  1093. currentRoutine = ctx->routines + ctx->routine_current;
  1094. if(currentRoutine->top < 2) {
  1095. currentRoutine->panic = -1;
  1096. return;
  1097. }
  1098. a = currentRoutine->stack[currentRoutine->top-1];
  1099. b = currentRoutine->stack[currentRoutine->top-2];
  1100. if(!(a.type == INK_INTEGER && b.type == INK_INTEGER)) {
  1101. currentRoutine->panic = -1;
  1102. return;
  1103. }
  1104. ink_pop(ctx);
  1105. currentRoutine->stack[currentRoutine->top-1].value = b.value * a.value;
  1106. }
  1107. static void div_int(struct context* ctx) {
  1108. struct ink_routine* currentRoutine;
  1109. struct elem a;
  1110. struct elem b;
  1111. currentRoutine = ctx->routines + ctx->routine_current;
  1112. if(currentRoutine->top < 2) {
  1113. currentRoutine->panic = -1;
  1114. return;
  1115. }
  1116. a = currentRoutine->stack[currentRoutine->top-1];
  1117. b = currentRoutine->stack[currentRoutine->top-2];
  1118. if(!(a.type == INK_INTEGER && b.type == INK_INTEGER)) {
  1119. currentRoutine->panic = -1;
  1120. return;
  1121. }
  1122. ink_pop(ctx);
  1123. currentRoutine->stack[currentRoutine->top-1].value = b.value / a.value;
  1124. }
  1125. static void is_equal(struct context* ctx) {
  1126. struct ink_routine* currentRoutine;
  1127. struct elem a;
  1128. struct elem b;
  1129. struct elem ret;
  1130. currentRoutine = ctx->routines + ctx->routine_current;
  1131. if(currentRoutine->top < 2) {
  1132. currentRoutine->panic = -1;
  1133. return;
  1134. }
  1135. a = currentRoutine->stack[currentRoutine->top-1];
  1136. b = currentRoutine->stack[currentRoutine->top-2];
  1137. ink_pop(ctx);
  1138. ink_pop(ctx);
  1139. ret.type = INK_INTEGER;
  1140. ret.value = a.value == b.value && a.type == b.type;
  1141. ink_push(ctx, ret);
  1142. }
  1143. static void is_different(struct context* ctx) {
  1144. struct ink_routine* currentRoutine;
  1145. struct elem a;
  1146. struct elem b;
  1147. struct elem ret;
  1148. currentRoutine = ctx->routines + ctx->routine_current;
  1149. if(currentRoutine->top < 2) {
  1150. currentRoutine->panic = -1;
  1151. return;
  1152. }
  1153. a = currentRoutine->stack[currentRoutine->top-1];
  1154. b = currentRoutine->stack[currentRoutine->top-2];
  1155. ink_pop(ctx);
  1156. ink_pop(ctx);
  1157. ret.type = INK_INTEGER;
  1158. ret.value = !(a.value == b.value && a.type == b.type);
  1159. ink_push(ctx, ret);
  1160. }
  1161. #ifndef NOEXTRAARITHMETIC
  1162. static void rem_int(struct context* ctx) {
  1163. struct ink_routine* currentRoutine;
  1164. struct elem a;
  1165. struct elem b;
  1166. currentRoutine = ctx->routines + ctx->routine_current;
  1167. if(currentRoutine->top < 2) {
  1168. currentRoutine->panic = -1;
  1169. return;
  1170. }
  1171. a = currentRoutine->stack[currentRoutine->top-1];
  1172. b = currentRoutine->stack[currentRoutine->top-2];
  1173. if(!(a.type == INK_INTEGER && b.type == INK_INTEGER)) {
  1174. currentRoutine->panic = -1;
  1175. return;
  1176. }
  1177. ink_pop(ctx);
  1178. currentRoutine->stack[currentRoutine->top-1].value = b.value % a.value;
  1179. }
  1180. static void gt_int(struct context* ctx) {
  1181. struct ink_routine* currentRoutine;
  1182. struct elem a;
  1183. struct elem b;
  1184. currentRoutine = ctx->routines + ctx->routine_current;
  1185. if(currentRoutine->top < 2) {
  1186. currentRoutine->panic = -1;
  1187. return;
  1188. }
  1189. a = currentRoutine->stack[currentRoutine->top-1];
  1190. b = currentRoutine->stack[currentRoutine->top-2];
  1191. if(!(a.type == INK_INTEGER && b.type == INK_INTEGER)) {
  1192. currentRoutine->panic = -1;
  1193. return;
  1194. }
  1195. ink_pop(ctx);
  1196. currentRoutine->stack[currentRoutine->top-1].value = b.value > a.value;
  1197. }
  1198. static void gte_int(struct context* ctx) {
  1199. struct ink_routine* currentRoutine;
  1200. struct elem a;
  1201. struct elem b;
  1202. currentRoutine = ctx->routines + ctx->routine_current;
  1203. if(currentRoutine->top < 2) {
  1204. currentRoutine->panic = -1;
  1205. return;
  1206. }
  1207. a = currentRoutine->stack[currentRoutine->top-1];
  1208. b = currentRoutine->stack[currentRoutine->top-2];
  1209. if(!(a.type == INK_INTEGER && b.type == INK_INTEGER)) {
  1210. currentRoutine->panic = -1;
  1211. return;
  1212. }
  1213. ink_pop(ctx);
  1214. currentRoutine->stack[currentRoutine->top-1].value = b.value >= a.value;
  1215. }
  1216. static void lte_int(struct context* ctx) {
  1217. struct ink_routine* currentRoutine;
  1218. struct elem a;
  1219. struct elem b;
  1220. currentRoutine = ctx->routines + ctx->routine_current;
  1221. if(currentRoutine->top < 2) {
  1222. currentRoutine->panic = -1;
  1223. return;
  1224. }
  1225. a = currentRoutine->stack[currentRoutine->top-1];
  1226. b = currentRoutine->stack[currentRoutine->top-2];
  1227. if(!(a.type == INK_INTEGER && b.type == INK_INTEGER)) {
  1228. currentRoutine->panic = -1;
  1229. return;
  1230. }
  1231. ink_pop(ctx);
  1232. currentRoutine->stack[currentRoutine->top-1].value = b.value <= a.value;
  1233. }
  1234. #endif // NOEXTRAARITHMETIC
  1235. static void lt_int(struct context* ctx) {
  1236. struct ink_routine* currentRoutine;
  1237. struct elem a;
  1238. struct elem b;
  1239. currentRoutine = ctx->routines + ctx->routine_current;
  1240. if(currentRoutine->top < 2) {
  1241. currentRoutine->panic = -1;
  1242. return;
  1243. }
  1244. a = currentRoutine->stack[currentRoutine->top-1];
  1245. b = currentRoutine->stack[currentRoutine->top-2];
  1246. if(!(a.type == INK_INTEGER && b.type == INK_INTEGER)) {
  1247. currentRoutine->panic = -1;
  1248. return;
  1249. }
  1250. ink_pop(ctx);
  1251. currentRoutine->stack[currentRoutine->top-1].value = b.value < a.value;
  1252. }
  1253. static void dupe_elem(struct context* ctx) {
  1254. struct ink_routine* currentRoutine;
  1255. struct elem a;
  1256. int err;
  1257. currentRoutine = ctx->routines + ctx->routine_current;
  1258. if(currentRoutine->top < 1) {
  1259. ctx->panic = 1;
  1260. return;
  1261. }
  1262. a = currentRoutine->stack[currentRoutine->top-1];
  1263. err = ink_push(ctx, a);
  1264. if(err < 0) ctx->panic = 1;
  1265. }
  1266. static void drop_elem(struct context* ctx) {
  1267. struct ink_routine* currentRoutine;
  1268. currentRoutine = ctx->routines + ctx->routine_current;
  1269. if(currentRoutine->top < 1) {
  1270. ctx->panic = 1;
  1271. return;
  1272. }
  1273. ink_pop(ctx);
  1274. }
  1275. static void pluck_elem(struct context* ctx) {
  1276. struct ink_routine* currentRoutine;
  1277. struct elem a;
  1278. int position, err;
  1279. currentRoutine = ctx->routines + ctx->routine_current;
  1280. if(currentRoutine->top < 1) {
  1281. currentRoutine->panic = -1;
  1282. return;
  1283. }
  1284. a = currentRoutine->stack[currentRoutine->top-1];
  1285. if(a.type != INK_INTEGER) {
  1286. ctx->panic = 1;
  1287. return;
  1288. }
  1289. position = currentRoutine->top - (a.value + 1);
  1290. if(position >= currentRoutine->top || position < 0) {
  1291. ctx->panic = 1;
  1292. return;
  1293. }
  1294. ink_pop(ctx);
  1295. err = ink_push(ctx, currentRoutine->stack[position]);
  1296. if(err < 0) ctx->panic = 1;
  1297. }
  1298. static void swap_elem(struct context* ctx) {
  1299. struct ink_routine* currentRoutine;
  1300. struct elem a;
  1301. struct elem b;
  1302. currentRoutine = ctx->routines + ctx->routine_current;
  1303. if(currentRoutine->top < 2) {
  1304. currentRoutine->panic = -1;
  1305. return;
  1306. }
  1307. a = currentRoutine->stack[currentRoutine->top-1];
  1308. b = currentRoutine->stack[currentRoutine->top-2];
  1309. currentRoutine->stack[currentRoutine->top-2] = a;
  1310. currentRoutine->stack[currentRoutine->top-1] = b;
  1311. }
  1312. static void return_if(struct context* ctx) {
  1313. struct ink_routine* currentRoutine;
  1314. struct elem a;
  1315. currentRoutine = ctx->routines + ctx->routine_current;
  1316. if(currentRoutine->top < 1) {
  1317. ctx->panic = -1;
  1318. return;
  1319. }
  1320. a = currentRoutine->stack[currentRoutine->top-1];
  1321. if(a.type != INK_INTEGER) {
  1322. ctx->panic = 1;
  1323. return;
  1324. }
  1325. if(a.value) {
  1326. ink_pop_fn(ctx);
  1327. ink_pop_fn(ctx);
  1328. }
  1329. ink_pop(ctx);
  1330. return;
  1331. }
  1332. static void jump_if(struct context* ctx) {
  1333. struct ink_routine* currentRoutine;
  1334. struct elem label;
  1335. struct elem condition;
  1336. currentRoutine = ctx->routines + ctx->routine_current;
  1337. if(currentRoutine->top < 2) {
  1338. ctx->panic = -1;
  1339. return;
  1340. }
  1341. label = currentRoutine->stack[currentRoutine->top-1];
  1342. condition = currentRoutine->stack[currentRoutine->top-2];
  1343. if(label.type != INK_INTEGER || condition.type != INK_INTEGER) {
  1344. ctx->panic = -1;
  1345. return;
  1346. }
  1347. ink_pop(ctx);
  1348. ink_pop(ctx);
  1349. ink_pop_fn(ctx);
  1350. if(condition.value) {
  1351. currentRoutine->function_stack[currentRoutine->function_stack_top - 1].index += label.value - 2;
  1352. }
  1353. return;
  1354. }
  1355. static void print_int(struct context* ctx) {
  1356. struct ink_routine* currentRoutine;
  1357. struct elem a;
  1358. char* n;
  1359. char* str;
  1360. currentRoutine = ctx->routines + ctx->routine_current;
  1361. if(currentRoutine->top < 1 || currentRoutine->stack[currentRoutine->top-1].type != INK_INTEGER) {
  1362. currentRoutine->panic = -1;
  1363. return;
  1364. }
  1365. a = currentRoutine->stack[currentRoutine->top-1];
  1366. ink_pop(ctx);
  1367. n = ink_itoa(ctx, a.value);
  1368. str = n;
  1369. while (*str) {
  1370. ctx->putchar(*str);
  1371. ++str;
  1372. }
  1373. ctx->free(n);
  1374. }
  1375. static void print_as_utf8(struct context* ctx) {
  1376. struct ink_routine* currentRoutine;
  1377. struct elem a;
  1378. currentRoutine = ctx->routines + ctx->routine_current;
  1379. if(currentRoutine->top < 1 || currentRoutine->stack[currentRoutine->top-1].type != INK_INTEGER) {
  1380. ctx->panic = -1;
  1381. return;
  1382. }
  1383. a = currentRoutine->stack[currentRoutine->top-1];
  1384. if(a.value <= 0x7F) {
  1385. ctx->putchar(a.value);
  1386. } else if(a.value <= 0x7FF) {
  1387. ctx->putchar(((a.value & 0xFC0) >> 6) | 192);
  1388. ctx->putchar((a.value & 0x3F) | 128);
  1389. } else if(a.value <= 0xFFFF) {
  1390. ctx->putchar(((a.value & 0x3F000) >> 12) | 224);
  1391. ctx->putchar(((a.value & 0xFC0) >> 6) | 128);
  1392. ctx->putchar((a.value & 0x3F) | 128);
  1393. } else if(a.value <= 0x10FFFF) {
  1394. ctx->putchar(((a.value & 0x3C0000) >> 18) | 240);
  1395. ctx->putchar(((a.value & 0x3F000) >> 12) | 128);
  1396. ctx->putchar(((a.value & 0xFC0) >> 6) | 128);
  1397. ctx->putchar((a.value & 0x3F) | 128);
  1398. } else {
  1399. ctx->panic = -1;
  1400. return;
  1401. }
  1402. ink_pop(ctx);
  1403. }
  1404. static int get_type_by_name(struct context* ctx, const char* name) {
  1405. int i;
  1406. for(i = 0; i < ctx->types_top; ++i) {
  1407. if(strcmp(ctx->types[i].name, name) == 0) {
  1408. return i + 16;
  1409. }
  1410. }
  1411. return -1;
  1412. }
  1413. static void run_gc(struct context* ctx) {
  1414. ink_gc(ctx);
  1415. }
  1416. static void clear_stack(struct context* ctx) {
  1417. struct ink_routine* currentRoutine;
  1418. currentRoutine = ctx->routines + ctx->routine_current;
  1419. while (currentRoutine->top >= 1) {
  1420. ink_pop(ctx);
  1421. }
  1422. return;
  1423. }
  1424. static void collect_noop(struct context* _1, void* _2) {}
  1425. static struct ink_collection_list gc_noop(struct context* _1, void* _2) {
  1426. struct ink_collection_list c;
  1427. c.elements = NULL;
  1428. c.count = 0;
  1429. return c;
  1430. }
  1431. #ifndef NOARRAYLIB
  1432. struct ink_array {
  1433. int top;
  1434. int capacity;
  1435. struct elem* elements;
  1436. };
  1437. static void collect_array(struct context* ctx, void* array) {
  1438. struct ink_array* ary;
  1439. ary = array;
  1440. if(ary->elements != NULL) ctx->free(ary->elements);
  1441. }
  1442. static struct ink_collection_list gc_array(struct context* ctx, void* array) {
  1443. struct ink_array* ary;
  1444. struct ink_collection_list c;
  1445. ary = array;
  1446. c.elements = ctx->inner_malloc(sizeof(struct elem)*ary->top);
  1447. c.count = ary->top;
  1448. memcpy(c.elements, ary->elements, sizeof(struct elem)*ary->top);
  1449. return c;
  1450. }
  1451. static void new_array(struct context* ctx) {
  1452. int tid;
  1453. struct elem e;
  1454. struct ink_array ary;
  1455. tid = get_type_by_name(ctx, "array");
  1456. ary.elements = NULL;
  1457. ary.top = 0;
  1458. ary.capacity = 0;
  1459. e = ink_make_native(ctx, tid, &ary);
  1460. ink_push(ctx, e);
  1461. }
  1462. static void push_array_stack_delim(struct context* ctx) {
  1463. int tid;
  1464. struct elem e;
  1465. tid = get_type_by_name(ctx, "array_marker");
  1466. e.type = tid;
  1467. e.value = 0;
  1468. ink_push(ctx, e);
  1469. }
  1470. static void array_push(struct context* ctx, struct ink_routine* currentRoutine, struct ink_array* ary, struct elem value) {
  1471. if(ary->elements == NULL) {
  1472. ary->elements = ctx->malloc(sizeof(struct elem) * 8);
  1473. ary->top = 0;
  1474. ary->capacity = 8;
  1475. } else if(ary->top == ary->capacity) {
  1476. int new_count;
  1477. void* renewed;
  1478. new_count = (ary->capacity + ary->capacity/2);
  1479. renewed = ctx->realloc(ary->elements, sizeof(struct elem) * new_count);
  1480. if(renewed == NULL) {
  1481. currentRoutine->panic = -1;
  1482. return;
  1483. } else {
  1484. ary->elements = renewed;
  1485. ary->capacity = new_count;
  1486. }
  1487. }
  1488. ary->elements[ary->top] = value;
  1489. ary->top++;
  1490. }
  1491. static void push_array(struct context* ctx) {
  1492. int tid;
  1493. struct elem a;
  1494. struct ink_routine* currentRoutine;
  1495. struct ink_array* ary;
  1496. tid = get_type_by_name(ctx, "array");
  1497. currentRoutine = ctx->routines + ctx->routine_current;
  1498. if(currentRoutine->top < 2 || currentRoutine->stack[currentRoutine->top-1].type != tid) {
  1499. currentRoutine->panic = -1;
  1500. return;
  1501. }
  1502. a = currentRoutine->stack[currentRoutine->top-1];
  1503. ary= ink_get_value(ctx, a);
  1504. if(ary == NULL) {
  1505. currentRoutine->panic = -1;
  1506. return;
  1507. }
  1508. ink_pop(ctx);
  1509. array_push(ctx, currentRoutine, ary, currentRoutine->stack[currentRoutine->top-1]);
  1510. ink_pop(ctx);
  1511. }
  1512. static void push_delimited_array(struct context* ctx) {
  1513. int tid, idx, counter, i;
  1514. struct elem a;
  1515. struct ink_routine* currentRoutine;
  1516. struct ink_array* ary;
  1517. tid = get_type_by_name(ctx, "array_marker");
  1518. currentRoutine = ctx->routines + ctx->routine_current;
  1519. if(currentRoutine->top < 1) {
  1520. currentRoutine->panic = -1;
  1521. return;
  1522. }
  1523. new_array(ctx);
  1524. a = currentRoutine->stack[currentRoutine->top-1];
  1525. ink_pop(ctx);
  1526. ary= ink_get_value(ctx, a);
  1527. for(idx = 1; idx <= currentRoutine->top; ++idx) {
  1528. struct elem maybe_delim;
  1529. if(currentRoutine->stack[currentRoutine->top-idx].type == tid) {
  1530. break;
  1531. }
  1532. }
  1533. /* Save for cleanup */
  1534. counter = idx;
  1535. /* Don't copy the delimiter */
  1536. idx -= 1;
  1537. ary->elements = malloc(sizeof(struct elem) * idx);
  1538. if(ary->elements == NULL) {
  1539. currentRoutine->panic = -541;
  1540. return;
  1541. }
  1542. ary->capacity = idx;
  1543. ary->top = 0;
  1544. /* Copy the data */
  1545. for(i = currentRoutine->top - idx; i < currentRoutine->top; ++i) {
  1546. ary->elements[ary->top] = currentRoutine->stack[i];
  1547. ++(ary->top);
  1548. }
  1549. /* Cleanup */
  1550. while(counter--) {
  1551. ink_pop(ctx);
  1552. }
  1553. /* Pop the marker too */
  1554. ink_pop(ctx);
  1555. /* Put value in place */
  1556. ink_push(ctx, a);
  1557. }
  1558. static void index_array(struct context* ctx) {
  1559. int tid;
  1560. struct ink_routine *currentRoutine;
  1561. struct elem a;
  1562. struct ink_array *ary;
  1563. struct elem idx;
  1564. tid = get_type_by_name(ctx, "array");
  1565. currentRoutine = ctx->routines + ctx->routine_current;
  1566. if (currentRoutine->top < 2 || currentRoutine->stack[currentRoutine->top - 1].type != tid || currentRoutine->stack[currentRoutine->top - 2].type != INK_INTEGER) {
  1567. currentRoutine->panic = -1;
  1568. return;
  1569. }
  1570. a = currentRoutine->stack[currentRoutine->top - 1];
  1571. ary = ink_get_value(ctx, a);
  1572. if (ary == NULL) {
  1573. currentRoutine->panic = -1;
  1574. return;
  1575. }
  1576. ink_pop(ctx);
  1577. idx = currentRoutine->stack[currentRoutine->top - 1];
  1578. ink_pop(ctx);
  1579. if(ary->top <= idx.value) {
  1580. currentRoutine->panic = -1;
  1581. return;
  1582. }
  1583. ink_push(ctx, ary->elements[idx.value]);
  1584. }
  1585. static void set_array(struct context* ctx) {
  1586. int tid;
  1587. struct ink_routine *currentRoutine;
  1588. struct elem a;
  1589. struct ink_array *ary;
  1590. struct elem idx;
  1591. struct elem value;
  1592. tid = get_type_by_name(ctx, "array");
  1593. currentRoutine = ctx->routines + ctx->routine_current;
  1594. if (currentRoutine->top < 3 || currentRoutine->stack[currentRoutine->top - 1].type != tid || currentRoutine->stack[currentRoutine->top - 2].type != INK_INTEGER) {
  1595. currentRoutine->panic = -1;
  1596. return;
  1597. }
  1598. a = currentRoutine->stack[currentRoutine->top - 1];
  1599. ary = ink_get_value(ctx, a);
  1600. if (ary == NULL) {
  1601. currentRoutine->panic = -1;
  1602. return;
  1603. }
  1604. idx = currentRoutine->stack[currentRoutine->top - 2];
  1605. value = currentRoutine->stack[currentRoutine->top - 3];
  1606. if(ary->top <= idx.value) {
  1607. currentRoutine->panic = -1;
  1608. return;
  1609. }
  1610. ink_pop(ctx);
  1611. ink_pop(ctx);
  1612. ink_pop(ctx);
  1613. ary->elements[idx.value] = value;
  1614. }
  1615. static void get_size_array(struct context* ctx) {
  1616. int tid;
  1617. struct ink_routine *currentRoutine;
  1618. struct elem a;
  1619. struct ink_array *ary;
  1620. struct elem sz;
  1621. tid = get_type_by_name(ctx, "array");
  1622. currentRoutine = ctx->routines + ctx->routine_current;
  1623. if (currentRoutine->top < 1 || currentRoutine->stack[currentRoutine->top - 1].type != tid) {
  1624. currentRoutine->panic = -1;
  1625. return;
  1626. }
  1627. a = currentRoutine->stack[currentRoutine->top - 1];
  1628. ary = ink_get_value(ctx, a);
  1629. if (ary == NULL) {
  1630. currentRoutine->panic = -1;
  1631. return;
  1632. }
  1633. ink_pop(ctx);
  1634. sz.type = INK_INTEGER;
  1635. sz.value = ary->top;
  1636. ink_push(ctx, sz);
  1637. }
  1638. static void is_array(struct context* ctx) {
  1639. int tid;
  1640. struct ink_routine *currentRoutine;
  1641. struct elem a;
  1642. tid = get_type_by_name(ctx, "array");
  1643. currentRoutine = ctx->routines + ctx->routine_current;
  1644. if (currentRoutine->top < 1) {
  1645. currentRoutine->panic = -1;
  1646. return;
  1647. }
  1648. a.type = INK_INTEGER;
  1649. a.value = currentRoutine->stack[currentRoutine->top - 1].type == tid;
  1650. ink_pop(ctx);
  1651. ink_push(ctx, a);
  1652. }
  1653. static void is_int(struct context* ctx) {
  1654. int tid;
  1655. struct ink_routine *currentRoutine;
  1656. struct elem a;
  1657. currentRoutine = ctx->routines + ctx->routine_current;
  1658. if (currentRoutine->top < 1) {
  1659. currentRoutine->panic = -1;
  1660. return;
  1661. }
  1662. a.type = INK_INTEGER;
  1663. a.value = currentRoutine->stack[currentRoutine->top - 1].type == INK_INTEGER;
  1664. ink_pop(ctx);
  1665. ink_push(ctx, a);
  1666. }
  1667. static void print_array_of_codepoints(struct context* ctx) {
  1668. int tid, i;
  1669. struct ink_routine *currentRoutine;
  1670. struct elem a;
  1671. struct ink_array *ary;
  1672. struct elem idx;
  1673. tid = get_type_by_name(ctx, "array");
  1674. currentRoutine = ctx->routines + ctx->routine_current;
  1675. if (currentRoutine->top < 1 || currentRoutine->stack[currentRoutine->top - 1].type != tid) {
  1676. currentRoutine->panic = -1;
  1677. return;
  1678. }
  1679. a = currentRoutine->stack[currentRoutine->top - 1];
  1680. ary = ink_get_value(ctx, a);
  1681. for(i = 0; i < ary->top; ++i) {
  1682. if(ary->elements[i].type != INK_INTEGER) {
  1683. currentRoutine->panic = -1;
  1684. return;
  1685. }
  1686. }
  1687. ink_pop(ctx);
  1688. for(i = 0; i < ary->top; ++i) {
  1689. ink_push(ctx, ary->elements[i]);
  1690. print_as_utf8(ctx);
  1691. }
  1692. }
  1693. static void arrayify_stack(struct context* ctx) {
  1694. struct ink_routine* currentRoutine;
  1695. struct elem array_ref;
  1696. struct ink_array* ary;
  1697. int idx;
  1698. currentRoutine = ctx->routines + ctx->routine_current;
  1699. new_array(ctx);
  1700. if(currentRoutine->panic < 0) return;
  1701. array_ref = currentRoutine->stack[currentRoutine->top - 1];
  1702. ary = ink_get_value(ctx, array_ref);
  1703. if(ary == NULL) {
  1704. currentRoutine->panic = -717;
  1705. return;
  1706. }
  1707. ink_pop(ctx);
  1708. for(idx = 0; idx < currentRoutine->top; ++idx) {
  1709. array_push(ctx, currentRoutine, ary, currentRoutine->stack[idx]);
  1710. }
  1711. while (currentRoutine->top > 0) {
  1712. ink_pop(ctx);
  1713. }
  1714. ink_push(ctx, array_ref);
  1715. return;
  1716. }
  1717. #endif // NOARRAYLIB
  1718. int ink_std_library(struct context* ctx) {
  1719. int v;
  1720. v = 0;
  1721. v += ink_add_native(ctx, "sys.trace", print_stacktrace);
  1722. v += ink_add_native(ctx, "sys.gc", run_gc);
  1723. v += ink_add_native(ctx, "print_int", print_int);
  1724. v += ink_add_native(ctx, "print_utf8", print_as_utf8);
  1725. v += ink_add_native(ctx, "+", add_int);
  1726. v += ink_add_native(ctx, "-", sub_int);
  1727. v += ink_add_native(ctx, "*", mult_int);
  1728. v += ink_add_native(ctx, "/", div_int);
  1729. v += ink_add_native(ctx, "==", is_equal);
  1730. v += ink_add_native(ctx, "!=", is_different);
  1731. v += ink_add_native(ctx, "<", lt_int);
  1732. v += ink_add_native(ctx, "swap", swap_elem);
  1733. v += ink_add_native(ctx, "dup", dupe_elem);
  1734. v += ink_add_native(ctx, "drop", drop_elem);
  1735. v += ink_add_native(ctx, "stack.clear", clear_stack);
  1736. v += ink_add_native(ctx, "pluck", pluck_elem);
  1737. v += ink_add_native(ctx, "return_if", return_if);
  1738. v += ink_add_native(ctx, "jump_if", jump_if);
  1739. v += ink_add_native(ctx, "is.int", is_int);
  1740. #ifndef NOEXTRAARITHMETIC
  1741. v += ink_add_native(ctx, ">", gt_int);
  1742. v += ink_add_native(ctx, ">=", gte_int);
  1743. v += ink_add_native(ctx, "=<", lte_int);
  1744. v += ink_add_native(ctx, "%", rem_int);
  1745. #endif // NOEXTRAARITHMETIC
  1746. #ifndef NOARRAYLIB
  1747. ink_new_type(ctx, "array", sizeof(struct ink_array), collect_array, gc_array);
  1748. ink_new_type(ctx, "array_marker", 0, collect_noop, gc_noop);
  1749. v += ink_add_native(ctx, "[", push_array_stack_delim);
  1750. v += ink_add_native(ctx, "]", push_delimited_array);
  1751. v += ink_add_native(ctx, "array.new", new_array);
  1752. v += ink_add_native(ctx, "array.push", push_array);
  1753. v += ink_add_native(ctx, "array.index", index_array);
  1754. v += ink_add_native(ctx, "array.set", set_array);
  1755. v += ink_add_native(ctx, "array.size", get_size_array);
  1756. v += ink_add_native(ctx, "array.print_utf8", print_array_of_codepoints);
  1757. v += ink_add_native(ctx, "is.array", is_array);
  1758. v += ink_add_native(ctx, "stack.to_array", arrayify_stack);
  1759. #endif // NOARRAYLIB
  1760. return v;
  1761. }