language

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

pc.c (3508B)


      1 #include <stdlib.h>
      2 #include <stdio.h>
      3 
      4 #include "pc.h"
      5 
      6 #include "is.h"
      7 #include "fh.h"
      8 #include "bc.h"
      9 #include "helper.h"
     10 
     11 /* Initalizes program counter, returns pc_t* instance
     12  * char* - filename of file containing bytecode
     13  */
     14 pc_t* pc_new(char* fname)
     15 {
     16 	N_ASSERT(fname, "pc_new\n");
     17 
     18 	pc_t* pc = (pc_t*)malloc(sizeof(pc_t));
     19 	M_ASSERT(pc);
     20 	// Make a new address stack and set its inital address to 0
     21 	pc->stk = pc_addr_stk_new(0);
     22 	// Make sure the inital address is 0
     23 	pc_branch(pc, 0);
     24 	// Read the program specified
     25 	pc->bc = bc_init(fname);
     26 	// Update the program counter.
     27 	pc_update(pc);
     28 
     29 	N_ASSERT(pc->line, "Error in creating new program counter\n");
     30 
     31 	return pc;
     32 }
     33 
     34 /* Creates a new address stack.
     35  *  ns_addr - inital address
     36  */
     37 pc_addr_stk* pc_addr_stk_new(ns_addr address)
     38 {
     39 	pc_addr_stk* new = (pc_addr_stk*)malloc(sizeof(pc_addr_stk));
     40 	M_ASSERT(new);
     41 
     42 	new->addresses = (pc_addr*)malloc(sizeof(pc_addr)*PC_RETURN_DEPTH);
     43 	M_ASSERT(new->addresses);
     44 
     45 	new->ptr = 0;
     46 	new->size = PC_RETURN_DEPTH;
     47 	new->addresses[new->ptr] = address;
     48 
     49 	return new;
     50 }
     51 
     52 /* Frees memory assosiated with pc_t* instance
     53  */
     54 void pc_del(pc_t* pc)
     55 {
     56 	N_ASSERT(pc, "pc_del\n");
     57 	N_ASSERT(pc->stk, "pc_del\n");
     58 	N_ASSERT(pc->bc, "pc_del\n");
     59 
     60 	// Free the address stack
     61 	pc_addr_stk_del(pc->stk);
     62 	// Free the program
     63 	bc_del(pc->bc);
     64 
     65 	free(pc);
     66 }
     67 
     68 /* Frees memory assosiated with pc_addr_stk* instance
     69  */
     70 void pc_addr_stk_del(pc_addr_stk* stk)
     71 {
     72 	N_ASSERT(stk, "pc_addr_stk_del\n");
     73 	N_ASSERT(stk->addresses, "pc_addr_stk_del\n");
     74 
     75 	free(stk->addresses);
     76 	free(stk);
     77 }
     78 
     79 /* Updates current insturction
     80  *
     81  * When called, pc_t->line will reflect pc_t->bc[pc_t->address]
     82  */
     83 void pc_update(pc_t* pc)
     84 {
     85 	N_ASSERT(pc, "pc_update\n");
     86 	ASSERT((pc->address < (pc->bc->size + 1)), "Address out of range\n");
     87 	// Update the pointer
     88 	pc->line = &pc->bc->heap[pc->address];
     89 }
     90 
     91 /* Increment program counter by +-addr
     92  *  pc_t*   - Program counter instance
     93  *  pc_addr - Address to increment by
     94  */
     95 void pc_inc(pc_t* pc, pc_addr addr)
     96 {
     97 	N_ASSERT(pc, "pc_inc\n");
     98 	// Increment pc->address by addr
     99 	pc->address = pc->address + addr;
    100 }
    101 
    102 /* Branch to specified address.
    103  *  pc_t*   - Program counter instance
    104  *  pc_addr - Address to branch to
    105  */
    106 void pc_branch(pc_t* pc, pc_addr address)
    107 {
    108 	N_ASSERT(pc, "pc_branch\n");
    109 	// Is there space in the address stack?
    110 	ASSERT(((pc->stk->ptr + 1) < pc->stk->size), "Address Stack Overflow\n");
    111 
    112 	// Push the current address on to the stack
    113 	pc->stk->addresses[pc->stk->ptr] = pc->address;
    114 
    115 	// Increment the stack pointer
    116 	pc->stk->ptr = pc->stk->ptr + 1;
    117 
    118 	// Set the current address to the branching address
    119 	pc->address = address;
    120 }
    121 
    122 /* Return from previous branch.
    123  *  pc_t* - Program counter instance
    124  */
    125 void pc_return(pc_t* pc)
    126 {
    127 	N_ASSERT(pc, "pc_return\n");
    128 	// Is the stack pointer in range?
    129 	ASSERT(((pc->stk->ptr - 1) > 0), "Address Stack Underflow\n");
    130 
    131 	// Decrement the stack pointer
    132 	pc->stk->ptr = pc->stk->ptr - 1;
    133 
    134 	// Pop the stack to pc->address
    135 	pc->address = pc->stk->addresses[pc->stk->ptr];
    136 }
    137 
    138 /* Simply goto that address
    139  *  pc_t    - Program counter instance
    140  *  pc_addr - Address to branch to
    141  */
    142 void pc_goto(pc_t* pc, pc_addr addr)
    143 {
    144 	N_ASSERT(pc, "pc_goto\n");
    145 	// Do I really need to comment?
    146 	pc->address = addr;
    147 }
    148 
    149 /* For now, a simple function that tests if the address is in range
    150  */
    151 int pc_safe(pc_t* pc)
    152 {
    153 	// If the address is in range return true, if out of range return false
    154 	int rv = (pc->address >= pc->bc->size) ? 0 : 1;
    155 	return rv;
    156 }
    157