language

some fools attempt at an interpreted language
Log | Files | Refs | README

bc.c (5762B)


      1 #include <stdlib.h>
      2 #include <stdio.h>
      3 
      4 #include "bc.h"
      5 
      6 #include "fh.h"
      7 #include "var.h"
      8 #include "helper.h"
      9 #include "is.h"
     10 #include "ins_def.h"
     11 
     12 /* Handles allocation for new `bc_cont` instances
     13  */
     14 void bc_cont_new(bc_cont* new)
     15 {
     16 	//new = (bc_cont*)malloc(sizeof(bc_cont));
     17 	M_ASSERT(new);
     18 
     19 	new->args[0] = NULL;
     20 	new->args[1] = NULL;
     21 	new->args[2] = NULL;
     22 
     23 	new->varg[0] = NULL;
     24 	new->varg[1] = NULL;
     25 	new->varg[2] = NULL;
     26 
     27 	new->sarg[0] = 0;
     28 	new->sarg[1] = 0;
     29 	new->sarg[2] = 0;
     30 }
     31 
     32 void bc_cont_del(bc_cont* ins)
     33 {
     34 	if (ins != NULL)
     35 	{
     36 		if (ins->args[0] != NULL) free(ins->args[0]);
     37 		if (ins->args[1] != NULL) free(ins->args[1]);
     38 		if (ins->args[2] != NULL) free(ins->args[2]);
     39 
     40 		if (ins->varg[0] != NULL) var_del(ins->varg[0]);
     41 		if (ins->varg[1] != NULL) var_del(ins->varg[1]);
     42 		if (ins->varg[2] != NULL) var_del(ins->varg[2]);
     43 	}
     44 }
     45 
     46 /* Given a file object, and an instance of `bc_cont` with proper metadata, this
     47  * function will read arguements into bc_cont.
     48  *
     49  * 'bc_cont' proper metadata is generated by
     50  */
     51 void get_opcode_adata(FILE* f, bc_cont* ins)
     52 {
     53 	int num_args,
     54 	    arg_types[3];
     55 
     56 	// `is.h`-> unencode
     57 	unencode(ins->mdata, &num_args, arg_types);
     58 
     59 	int x;
     60 	for (x = 0; x < num_args; x++)
     61 	{
     62 		// A_BYTE -> byte-length arguement
     63 		if (arg_types[x] == A_BYTE)
     64 		{
     65 			ins->args[x] = get_byte_arg(f, &ins->sarg[x]);
     66 		} else
     67 		// A_NAME -> name-length arguement
     68 		if (arg_types[x] == A_NAME)
     69 		{
     70 			ins->args[x] = get_name_arg(f, &ins->sarg[x]);
     71 		} else
     72 		// A_ADDR -> address-length arguement
     73 		if (arg_types[x] == A_ADDR)
     74 		{
     75 			ins->args[x] = get_addr_arg(f, &ins->sarg[x]);
     76 		} else
     77 		// A_DYNC -> dynamic-length arguement
     78 		if (arg_types[x] == A_DYNC)
     79 		{
     80 			ins->args[x] = get_dync_arg(f, &ins->sarg[x]);
     81 		}
     82 	}
     83 }
     84 byte_t* get_byte_arg(FILE* f, int* size)
     85 {
     86 	*size = 1;
     87 	return read_bytes(f, 1);
     88 }
     89 byte_t* get_name_arg(FILE* f, int* size)
     90 {
     91 	*size = NAMELEN;
     92 	return read_bytes(f, NAMELEN);
     93 }
     94 byte_t* get_addr_arg(FILE* f, int* size)
     95 {
     96 	*size = ADDRLEN;
     97 	return read_bytes(f, ADDRLEN);
     98 }
     99 byte_t* get_dync_arg(FILE* f, int* size)
    100 {
    101 	int n = 0;
    102 
    103 	byte_t byte = read_byte(f);
    104 
    105 	// This bit gets the length in bytes it needs to read into a buffer
    106 	// NOTE:
    107 	//      There are certain 'holes' where, a certain number, ex.
    108 	//        0xFF00, 0xFF0001, 0xFFFF00, etc
    109 	//      will yeild improper values due to the while loop below encountering
    110 	//      a null octet prematurely.
    111 	//      Numbers that work are the following:
    112 	//        0xFF01, 0xFF0101, 0xFFFF01
    113 	//      Whenever a seralizer is using dynamic arguements the seralizer must
    114 	//      implement a method that asserts if a number is such that each octet
    115 	//      does not equal 0. For a given bitwidth, the set of numbers is
    116 	//      described roughly:
    117 	//        { <valid octets> | !(0 in <octets>) }
    118 	//      if the length of the body of a set of bytes is a member of
    119 	//      <valid octets>, it can work with this function.
    120 	while (byte != 0)
    121 	{
    122 		n = (n << 8 | byte);
    123 		byte = read_byte(f);
    124 	}
    125 
    126 	*size = n;
    127 
    128 	return read_bytes(f, n);
    129 }
    130 
    131 /* Given an instruction, convert raw arguement data into typed data
    132  *  bc_cont* - bytecode container
    133  */
    134 void process_args(bc_cont* ins)
    135 {
    136 	int num_args,
    137 	    arg_types[3];
    138 
    139 	// `is.h`-> unencode
    140 	unencode(ins->adata, &num_args, arg_types);
    141 
    142 	int x;
    143 	for (x = 0; x < num_args; x++)
    144 	{
    145 		if (arg_types[x] == BTOI)
    146 		{
    147 			ins->varg[x] = raw_to_int(ins->sarg[x], 0, ins->args[x], 0);
    148 		} else
    149 		if (arg_types[x] == BTOT)
    150 		{
    151 			ins->varg[x] = byte_to_type(ins->args[x][0], 0);
    152 		} else
    153 		if (arg_types[x] == DTOL)
    154 		{
    155 			ins->varg[x] = raw_to_plist(ins->sarg[x], ins->args[x], 0);
    156 		} else
    157 		if (arg_types[x] == DTOV)
    158 		{
    159 			ins->varg[x] = raw_to_var(ins->sarg[x], ins->args[x], 0);
    160 		}
    161 	}
    162 }
    163 
    164 /* Reads program into bc_cont instances
    165  *  FILE*    - File descriptor
    166  *  bc_addr* - pointer to size variable
    167  */
    168 bc_cont* bc_read(FILE* f, bc_addr* len)
    169 {
    170 	N_ASSERT(f, "bc_read\n");
    171 
    172 	long fsize = read_size(f);
    173 
    174 	bc_addr addr = 0;
    175 	bc_cont* ptr;
    176 	byte_t byte;
    177 
    178 	bc_cont* heap = (bc_cont*)malloc(sizeof(bc_cont)*fsize);
    179 	N_ASSERT(heap, "bc_read\n");
    180 
    181 	/* Loop through file byte-by-byte */
    182 	while (ftell(f) < fsize)
    183 	{
    184 		ptr = &heap[addr];
    185 		// Creates a new bc_cont instance
    186 		bc_cont_new(ptr);
    187 		// Gets the opcode
    188 		byte = read_byte(f);
    189 		// Gets opcode metadata
    190 		get_opcode_mdata(byte, ptr);
    191 		// Gets opcode arguement metadata
    192 		get_opcode_adata(f, ptr);
    193 		// Process raw arguements
    194 		process_args(ptr);
    195 
    196 		// Set the real address of instruction
    197 		heap[addr].real_addr = addr;
    198 
    199 		// Increment address
    200 		addr++;
    201 	}
    202 
    203 	*len = addr;
    204 	return heap;
    205 }
    206 
    207 /* Reads program into bc_t instance
    208  *  char* - filename
    209  */
    210 bc_t* bc_init(char* fname)
    211 {
    212 	N_ASSERT(fname, "bc_init\n");
    213 
    214 	FILE* f;
    215 
    216 	bc_t* program;
    217 	
    218 	f = fopen(fname, "rb");
    219 
    220 	program = (bc_t*)malloc(sizeof(bc_t));
    221 	N_ASSERT(program, "bc_read\n");
    222 
    223 	// Read bytecode into array of bc_cont*
    224 	program->heap = bc_read(f, &program->size);
    225 
    226 	fclose(f);
    227 
    228 	return program;
    229 }
    230 
    231 /* Deletes instance of bc_t*
    232  */
    233 void bc_del(bc_t* program)
    234 {
    235 	N_ASSERT(program, "bc_del\n");
    236 
    237 	int i;
    238 	for (i=0; i < program->size; i++)
    239 	{
    240 		bc_cont_del(&program->heap[i]);
    241 	}
    242 
    243 	free(program->heap);
    244 
    245 	free(program);
    246 }
    247 
    248 /* Thing for pretty printing
    249  */
    250 void bc_print_op(bc_cont* op)
    251 {
    252 	int num_args,
    253 	    arg_types[3];
    254 
    255 	unencode(op->mdata, &num_args, arg_types);
    256 
    257 	printf("%s [%x] - ", INS_DESC[op->op], op->op);
    258 	for (int i = 0; i < num_args && num_args != 0; i++)
    259 	{
    260 		if (arg_types[i] == A_BYTE)
    261 		{
    262 			printf("I:<%02x>, ", op->args[i][0]);
    263 		} else
    264 		if (arg_types[i] == A_NAME)
    265 		{
    266 			printf("N:<%02x%02x>, ", op->args[i][0], op->args[i][1]);
    267 		} else
    268 		if (arg_types[i] == A_DYNC)
    269 		{
    270 			printf("DYN[%02x]: ", op->sarg[i]);
    271 			for (int x = 0; x < op->sarg[i]; x++)
    272 				printf("%02x ", op->args[i][x]);
    273 		}
    274 	}
    275 }
    276