A minimalistic programming language written in C89.
Nelze vybrat více než 25 témat Téma musí začínat písmenem nebo číslem, může obsahovat pomlčky („-“) a může být dlouhé až 35 znaků.

2187 řádky
68 KiB

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