| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247 |
- #include "ugl.h"
- #include "ugl_bc.h"
- #include <string.h>
- #include <stdio.h>
- /* arrays & variables */
- #define UGL_MAX_BYTECODE_LEN (63*1024)
- uint8_t ugl_bytecode_array[UGL_MAX_BYTECODE_LEN];
- uint16_t ugl_bytecode_len;
- #define UGL_MAX_LABEL_CNT 128
- char ugl_label_name[UGL_MAX_LABEL_CNT][UGL_MAX_IDENTIFIER_LEN+1];
- uint16_t ugl_label_bytecode_pos[UGL_MAX_LABEL_CNT]; /* position in the bytecode array */
- int ugl_label_cnt;
- /* procedures */
- void ugl_AddBytecode(uint8_t x)
- {
- ugl_bytecode_array[ugl_bytecode_len] = x;
- ugl_bytecode_len++;
- }
- void ugl_InitBytecode(void)
- {
- ugl_bytecode_len = 0;
- ugl_AddBytecode(BC_CMD_RETURN_FROM_PROCEDURE);
- }
- /*
- extern uint8_t ugl_bytecode_array[];
- void ugl_ExecBytecode(void)
- {
- bc_t bc;
- bc_exec(&bc, ugl_bytecode_array, 0);
- }
- */
- void ugl_CheckForAllLabelsDefined(void)
- {
- int i;
- for( i = 0; i < ugl_label_cnt; i++ )
- {
- if ( ugl_label_bytecode_pos[ugl_label_cnt] == 0x0ffff )
- {
- ugl_err("undefined label '%s'", ugl_label_name[i] );
- }
- }
- }
- void ugl_ResolveSymbols(void)
- {
- uint8_t *code = ugl_bytecode_array;
- uint8_t *dest = ugl_bytecode_array+ugl_bytecode_len;
- uint16_t val;
- uint8_t cmd;
-
- ugl_CheckForAllLabelsDefined();
-
- ugl_glog("Resolve start=%p, end=%p", code, dest);
- ugl_glog("Resolve bytecode len=%d", ugl_bytecode_len);
- while( code < dest )
- {
- cmd = *code;
- ugl_glog("Resolve pos=%p, cmd=%02x", code, cmd);
- code++;
- val = cmd;
- val &=0x0f0; /* put upper four bit as upper 4bit of the 12bit value into val */
- val <<= 4;
- switch(cmd&15)
- {
- case BC_CMD_LOAD_12BIT:
- code++;
- break;
- case BC_CMD_CALL_BUILDIN:
- code++;
- break;
- case BC_CMD_CALL_BUILDIN_POP_STACK:
- code++;
- break;
- case BC_CMD_BRANCH:
- val |= *code;
- code++;
- ugl_glog("Resolve BRANCH '%s' (idx=%d)", ugl_label_name[val], val);
- val = ugl_GetLabelBytecodePos(val);
- val = (val - (uint16_t)(code - ugl_bytecode_array));
- ugl_glog("Resolve BRANCH delta=0x%03x", val);
- *(code-2) &= 0x0f;
- *(code-2) |= (val >> 4) & 0x0f0;
- *(code-1) = val & 255;
- break;
- case BC_CMD_POP_ARG_STACK:
- break;
- case BC_CMD_PUSH_ARG_STACK:
- break;
- case BC_CMD_CALL_PROCEDURE:
- val = code[0];
- val <<= 8;
- val |= code[1];
-
- ugl_glog("Resolve CALL Procedre '%s' pos=%u", ugl_label_name[val], ugl_GetLabelBytecodePos(val));
- val = ugl_GetLabelBytecodePos(val);
- *code = val>>8;
- code++;
- *code = val&255;
- code++;
- break;
-
- default: /* assume 0x0f, extended command */
- switch( cmd )
- {
- case BC_CMD_LOAD_0:
- break;
- case BC_CMD_LOAD_1:
- break;
- case BC_CMD_LOAD_16BIT:
- code++;
- code++;
- break;
- case BC_CMD_RETURN_FROM_PROCEDURE:
- break;
- case BC_CMD_JUMP_NOT_ZERO:
- case BC_CMD_JUMP_ZERO:
- val = code[0];
- val <<= 8;
- val |= code[1];
-
-
- ugl_glog("Resolve JUMP '%s'", ugl_label_name[val]);
- val = ugl_GetLabelBytecodePos(val);
-
- *code = val>>8;
- code++;
- *code = val&255;
- code++;
-
- break;
- #ifdef NOT_USED
- case BC_CMD_CALL_PROCEDURE:
- val = code[0];
- val <<= 8;
- val |= code[1];
-
- ugl_glog("Resolve CALL Procedre '%s' pos=%u", ugl_label_name[val], ugl_GetLabelBytecodePos(val));
- val = ugl_GetLabelBytecodePos(val);
- *code = val>>8;
- code++;
- *code = val&255;
- code++;
-
- break;
- #endif
- /*
- case BC_CMD_POP_ARG_STACK:
- break;
- */
- default:
- ugl_err("Resolve: Unexpected command");
- break;
- }
- break;
- } /* switch() */
- } /* while */
- }
-
- static int ugl_FindLabel(const char *name)
- {
- int i;
- for( i = 0; i < ugl_label_cnt; i++ )
- {
- if (strcmp(name, ugl_label_name[i] ) == 0 )
- return i;
- }
- return -1;
- }
- static int ugl_AddLabel(const char *name)
- {
- strcpy(ugl_label_name[ugl_label_cnt], name);
- ugl_label_bytecode_pos[ugl_label_cnt] = 0x0ffff;
- ugl_label_cnt++;
- if ( ugl_label_cnt >= UGL_MAX_LABEL_CNT )
- ugl_err("max number of labels reached, label=%s", name);
- return ugl_label_cnt-1;
- }
- int ugl_GetLabel(const char *name)
- {
- int idx;
- idx = ugl_FindLabel(name);
- if ( idx >= 0 )
- return idx;
- return ugl_AddLabel(name);
- }
- void ugl_SetLabelBytecodePos(const char *name, uint16_t bytecode_pos)
- {
- int idx;
- idx = ugl_GetLabel(name);
- if ( ugl_label_bytecode_pos[idx] != 0x0ffff )
- ugl_err("double definition of label '%s'", name);
- ugl_label_bytecode_pos[idx] = bytecode_pos;
- }
- uint16_t ugl_GetLabelBytecodePos(int idx)
- {
- if ( ugl_label_bytecode_pos[idx] == 0x0ffff )
- ugl_err("undefined label '%s'", ugl_label_name[idx]);
- return ugl_label_bytecode_pos[idx];
- }
- void ugl_WriteBytecodeCArray(FILE *fp, const char *name)
- {
- uint16_t i;
- fprintf(fp, "unsigned char %s[] =\n \"", name);
- i = 0;
- while ( i < ugl_bytecode_len )
- {
- fprintf(fp, "\\x%02x", ugl_bytecode_array[i]);
- if ( i+1 == ugl_bytecode_len )
- {
- break;
- }
- if ( (i & 0x0f) == 0x0f )
- {
- fprintf(fp, "\"\n \"");
- }
- i++;
- }
- fprintf(fp, "\";\n\n");
- }
|