ugl_arrays.c 4.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247
  1. #include "ugl.h"
  2. #include "ugl_bc.h"
  3. #include <string.h>
  4. #include <stdio.h>
  5. /* arrays & variables */
  6. #define UGL_MAX_BYTECODE_LEN (63*1024)
  7. uint8_t ugl_bytecode_array[UGL_MAX_BYTECODE_LEN];
  8. uint16_t ugl_bytecode_len;
  9. #define UGL_MAX_LABEL_CNT 128
  10. char ugl_label_name[UGL_MAX_LABEL_CNT][UGL_MAX_IDENTIFIER_LEN+1];
  11. uint16_t ugl_label_bytecode_pos[UGL_MAX_LABEL_CNT]; /* position in the bytecode array */
  12. int ugl_label_cnt;
  13. /* procedures */
  14. void ugl_AddBytecode(uint8_t x)
  15. {
  16. ugl_bytecode_array[ugl_bytecode_len] = x;
  17. ugl_bytecode_len++;
  18. }
  19. void ugl_InitBytecode(void)
  20. {
  21. ugl_bytecode_len = 0;
  22. ugl_AddBytecode(BC_CMD_RETURN_FROM_PROCEDURE);
  23. }
  24. /*
  25. extern uint8_t ugl_bytecode_array[];
  26. void ugl_ExecBytecode(void)
  27. {
  28. bc_t bc;
  29. bc_exec(&bc, ugl_bytecode_array, 0);
  30. }
  31. */
  32. void ugl_CheckForAllLabelsDefined(void)
  33. {
  34. int i;
  35. for( i = 0; i < ugl_label_cnt; i++ )
  36. {
  37. if ( ugl_label_bytecode_pos[ugl_label_cnt] == 0x0ffff )
  38. {
  39. ugl_err("undefined label '%s'", ugl_label_name[i] );
  40. }
  41. }
  42. }
  43. void ugl_ResolveSymbols(void)
  44. {
  45. uint8_t *code = ugl_bytecode_array;
  46. uint8_t *dest = ugl_bytecode_array+ugl_bytecode_len;
  47. uint16_t val;
  48. uint8_t cmd;
  49. ugl_CheckForAllLabelsDefined();
  50. ugl_glog("Resolve start=%p, end=%p", code, dest);
  51. ugl_glog("Resolve bytecode len=%d", ugl_bytecode_len);
  52. while( code < dest )
  53. {
  54. cmd = *code;
  55. ugl_glog("Resolve pos=%p, cmd=%02x", code, cmd);
  56. code++;
  57. val = cmd;
  58. val &=0x0f0; /* put upper four bit as upper 4bit of the 12bit value into val */
  59. val <<= 4;
  60. switch(cmd&15)
  61. {
  62. case BC_CMD_LOAD_12BIT:
  63. code++;
  64. break;
  65. case BC_CMD_CALL_BUILDIN:
  66. code++;
  67. break;
  68. case BC_CMD_CALL_BUILDIN_POP_STACK:
  69. code++;
  70. break;
  71. case BC_CMD_BRANCH:
  72. val |= *code;
  73. code++;
  74. ugl_glog("Resolve BRANCH '%s' (idx=%d)", ugl_label_name[val], val);
  75. val = ugl_GetLabelBytecodePos(val);
  76. val = (val - (uint16_t)(code - ugl_bytecode_array));
  77. ugl_glog("Resolve BRANCH delta=0x%03x", val);
  78. *(code-2) &= 0x0f;
  79. *(code-2) |= (val >> 4) & 0x0f0;
  80. *(code-1) = val & 255;
  81. break;
  82. case BC_CMD_POP_ARG_STACK:
  83. break;
  84. case BC_CMD_PUSH_ARG_STACK:
  85. break;
  86. case BC_CMD_CALL_PROCEDURE:
  87. val = code[0];
  88. val <<= 8;
  89. val |= code[1];
  90. ugl_glog("Resolve CALL Procedre '%s' pos=%u", ugl_label_name[val], ugl_GetLabelBytecodePos(val));
  91. val = ugl_GetLabelBytecodePos(val);
  92. *code = val>>8;
  93. code++;
  94. *code = val&255;
  95. code++;
  96. break;
  97. default: /* assume 0x0f, extended command */
  98. switch( cmd )
  99. {
  100. case BC_CMD_LOAD_0:
  101. break;
  102. case BC_CMD_LOAD_1:
  103. break;
  104. case BC_CMD_LOAD_16BIT:
  105. code++;
  106. code++;
  107. break;
  108. case BC_CMD_RETURN_FROM_PROCEDURE:
  109. break;
  110. case BC_CMD_JUMP_NOT_ZERO:
  111. case BC_CMD_JUMP_ZERO:
  112. val = code[0];
  113. val <<= 8;
  114. val |= code[1];
  115. ugl_glog("Resolve JUMP '%s'", ugl_label_name[val]);
  116. val = ugl_GetLabelBytecodePos(val);
  117. *code = val>>8;
  118. code++;
  119. *code = val&255;
  120. code++;
  121. break;
  122. #ifdef NOT_USED
  123. case BC_CMD_CALL_PROCEDURE:
  124. val = code[0];
  125. val <<= 8;
  126. val |= code[1];
  127. ugl_glog("Resolve CALL Procedre '%s' pos=%u", ugl_label_name[val], ugl_GetLabelBytecodePos(val));
  128. val = ugl_GetLabelBytecodePos(val);
  129. *code = val>>8;
  130. code++;
  131. *code = val&255;
  132. code++;
  133. break;
  134. #endif
  135. /*
  136. case BC_CMD_POP_ARG_STACK:
  137. break;
  138. */
  139. default:
  140. ugl_err("Resolve: Unexpected command");
  141. break;
  142. }
  143. break;
  144. } /* switch() */
  145. } /* while */
  146. }
  147. static int ugl_FindLabel(const char *name)
  148. {
  149. int i;
  150. for( i = 0; i < ugl_label_cnt; i++ )
  151. {
  152. if (strcmp(name, ugl_label_name[i] ) == 0 )
  153. return i;
  154. }
  155. return -1;
  156. }
  157. static int ugl_AddLabel(const char *name)
  158. {
  159. strcpy(ugl_label_name[ugl_label_cnt], name);
  160. ugl_label_bytecode_pos[ugl_label_cnt] = 0x0ffff;
  161. ugl_label_cnt++;
  162. if ( ugl_label_cnt >= UGL_MAX_LABEL_CNT )
  163. ugl_err("max number of labels reached, label=%s", name);
  164. return ugl_label_cnt-1;
  165. }
  166. int ugl_GetLabel(const char *name)
  167. {
  168. int idx;
  169. idx = ugl_FindLabel(name);
  170. if ( idx >= 0 )
  171. return idx;
  172. return ugl_AddLabel(name);
  173. }
  174. void ugl_SetLabelBytecodePos(const char *name, uint16_t bytecode_pos)
  175. {
  176. int idx;
  177. idx = ugl_GetLabel(name);
  178. if ( ugl_label_bytecode_pos[idx] != 0x0ffff )
  179. ugl_err("double definition of label '%s'", name);
  180. ugl_label_bytecode_pos[idx] = bytecode_pos;
  181. }
  182. uint16_t ugl_GetLabelBytecodePos(int idx)
  183. {
  184. if ( ugl_label_bytecode_pos[idx] == 0x0ffff )
  185. ugl_err("undefined label '%s'", ugl_label_name[idx]);
  186. return ugl_label_bytecode_pos[idx];
  187. }
  188. void ugl_WriteBytecodeCArray(FILE *fp, const char *name)
  189. {
  190. uint16_t i;
  191. fprintf(fp, "unsigned char %s[] =\n \"", name);
  192. i = 0;
  193. while ( i < ugl_bytecode_len )
  194. {
  195. fprintf(fp, "\\x%02x", ugl_bytecode_array[i]);
  196. if ( i+1 == ugl_bytecode_len )
  197. {
  198. break;
  199. }
  200. if ( (i & 0x0f) == 0x0f )
  201. {
  202. fprintf(fp, "\"\n \"");
  203. }
  204. i++;
  205. }
  206. fprintf(fp, "\";\n\n");
  207. }