Beispiel #1
0
void BFInterpreter_compile(BFInterpreter *interpreter, FILE *input_file) {
    int pc = 0;
    int c = 0;
    char current_char;
    while ((c = fgetc(input_file)) != EOF)  {
        if (pc > MAX_TAPE_SIZE-1) {
            printf("Program is larger than the tape size. Exiting...\n");
            exit(1);
        }
        current_char = (char) c;
#ifdef DEBUG
        printf("Current token is: %c\n", current_char);
#endif

        if ((current_char == '+') || (current_char == '-') || (current_char == '>') 
            || (current_char == '<') || (current_char == '.') || (current_char == ',')) {
            interpreter->program_tape[pc].type = SIMPLE;
            interpreter->program_tape[pc].Instruction.SimpleInstruction.opcode = current_char;
            pc++;
        }
        if (current_char == '[') {
            Stack_push(&interpreter->jump_locations, pc);
            interpreter->program_tape[pc].type = JUMP;
            interpreter->program_tape[pc].Instruction.JumpInstruction.opcode = current_char;
            pc++;
        }
        if (current_char == ']') {
            if (Stack_empty(&interpreter->jump_locations)) {
                printf("Unmatched loop instruction!\n");
                exit(1);
            }
            unsigned int jl = Stack_pop(&interpreter->jump_locations);
            interpreter->program_tape[pc].type = JUMP;
            interpreter->program_tape[pc].Instruction.JumpInstruction.opcode = current_char;
            interpreter->program_tape[pc].Instruction.JumpInstruction.jump_location = jl;
            interpreter->program_tape[jl].Instruction.JumpInstruction.jump_location = pc;
#ifdef DEBUG
            printf("Instruction at program_tape[%d] will jump to location: %d\n", pc, jl);
            printf("Instruction at program_tape[%d] will jump to location: %d\n", jl, pc);
#endif
            pc++;
        }
    }
    if (!Stack_empty(&interpreter->jump_locations)) {
        printf("Unmatched loop instruction!\n");
        exit(1);
    }
}
Beispiel #2
0
AP_T pop(void) {
	if (!Stack_empty(sp))
		return Stack_pop(sp);
	else {
		Fmt_fprint(stderr, "?stack underflow\n");
		return AP_new(0);
	}
}
Beispiel #3
0
void free_IDs(Stack_T unmapped_IDs)
{
	uint32_t *ID;
	while (!Stack_empty(unmapped_IDs)) {
		ID = Stack_pop(unmapped_IDs);
		FREE(ID);
	}

	Stack_free(&unmapped_IDs);
}
Beispiel #4
0
void *Stack_pop(T stk) {
    struct elem *e = NULL;

    if (Stack_empty(stk) != 0)
        return NULL;
    e = stk->head;
    stk->head = stk->head->link;
    stk->count--;
    void *p = e->x;
    free(e);
    return p;
}
Beispiel #5
0
/* 
 * create a segment with the size of nums, and return the index of the segs of 
 * the mapped segment. There are two conditons, if the unmapped stack is not 
 * empty, we reuse the segment index stored in unmapped stack and pop that out.
 * otherwise we just create a new segments and addhi into segs, the return index
 * is the length of segs.
 */
uint32_t map_segment(Mem myMem, uint32_t nums)
{
	assert(myMem != NULL);
	Segment_T newSeg = Seg_new(nums);
	for (uint32_t i = 0; i < nums; i++) {
	      Seq_addhi((Seq_T)newSeg, (void*) (uintptr_t) 0);
	}
	uint32_t index;
	if (Stack_empty(myMem->unmapped) == 1) {
		Seq_addhi(myMem->segs, (void*) newSeg);
		index = Seq_length(myMem->segs) - 1;
		
	} else {
		index = (int) (uintptr_t) Stack_pop(myMem->unmapped);
		Seg_free(Seq_put(myMem->segs, index, (void*) newSeg));
	};
	return index;
}
Beispiel #6
0
int main(int argc, char *argv[]) {
	int c;
	sp = Stack_new();
	Fmt_register('D', AP_fmt);
	while ((c = getchar()) != EOF)
		switch (c) {
		case ' ': case '\t': case '\n': case '\f': case '\r':
			break;
		case '0': case '1': case '2': case '3': case '4':
		case '5': case '6': case '7': case '8': case '9': {
			char buf[512];
			{
				int i = 0;
				for ( ; c != EOF && isdigit(c); c = getchar(), i++)
					if (i < (int)sizeof (buf) - 1)
						buf[i] = c;
				if (i > (int)sizeof (buf) - 1) {
					i = (int)sizeof (buf) - 1;
					Fmt_fprint(stderr,
						"?integer constant exceeds %d digits\n", i);
				}
				buf[i] = 0;
				if (c != EOF)
					ungetc(c, stdin);
			}
			Stack_push(sp, AP_fromstr(buf, 10, NULL));
			break;
		}
		case '+': {
			AP_T y = pop(), x = pop();
			Stack_push(sp, AP_add(x, y));
			AP_free(&x);
			AP_free(&y);
			break;
		}
		case '-': {
			AP_T y = pop(), x = pop();
			Stack_push(sp, AP_sub(x, y));
			AP_free(&x);
			AP_free(&y);
			break;
		}
		case '*': {
			AP_T y = pop(), x = pop();
			Stack_push(sp, AP_mul(x, y));
			AP_free(&x);
			AP_free(&y);
			break;
		}
		case '/': {
			AP_T y = pop(), x = pop();
			if (AP_cmpi(y, 0) == 0) {
				Fmt_fprint(stderr, "?/ by 0\n");
				Stack_push(sp, AP_new(0));
			} else
				Stack_push(sp, AP_div(x, y));
			AP_free(&x);
			AP_free(&y);
			break;
		}
		case '%': {
			AP_T y = pop(), x = pop();
			if (AP_cmpi(y, 0) == 0) {
				Fmt_fprint(stderr, "?%% by 0\n");
				Stack_push(sp, AP_new(0));
			} else
				Stack_push(sp, AP_mod(x, y));
			AP_free(&x);
			AP_free(&y);
			break;
		}
		case '^': {
			AP_T y = pop(), x = pop();
			if (AP_cmpi(y, 0) <= 0) {
				Fmt_fprint(stderr, "?nonpositive power\n");
				Stack_push(sp, AP_new(0));
			} else
				Stack_push(sp, AP_pow(x, y, NULL));
			AP_free(&x);
			AP_free(&y);
			break;
		}
		case 'd': {
			AP_T x = pop();
			Stack_push(sp, x);
			Stack_push(sp, AP_addi(x, 0));
			break;
		}
		case 'p': {
			AP_T x = pop();
			Fmt_print("%D\n", x);
			Stack_push(sp, x);
			break;
		}
		case 'f':
			if (!Stack_empty(sp)) {
				Stack_T tmp = Stack_new();
				while (!Stack_empty(sp)) {
					AP_T x = pop();
					Fmt_print("%D\n", x);
					Stack_push(tmp, x);
				}
				while (!Stack_empty(tmp))
					Stack_push(sp, Stack_pop(tmp));
				Stack_free(&tmp);
			}
			break;
		case '~': {
			AP_T x = pop();
			Stack_push(sp, AP_neg(x));
			AP_free(&x);
			break;
		}
		case 'c': while (!Stack_empty(sp)) {
			  	AP_T x = Stack_pop(sp);
			  	AP_free(&x);
			  } break;
		case 'q': while (!Stack_empty(sp)) {
			  	AP_T x = Stack_pop(sp);
			  	AP_free(&x);
			  }
			  Stack_free(&sp);
			  return EXIT_SUCCESS;
		default:
			if (isprint(c))
				Fmt_fprint(stderr, "?'%c'", c);
			else
				Fmt_fprint(stderr, "?'\\%03o'", c);
			Fmt_fprint(stderr, " is unimplemented\n");
			break;
		}
	while (!Stack_empty(sp)) {
		AP_T x = Stack_pop(sp);
		AP_free(&x);
	}
	Stack_free(&sp);
	return EXIT_SUCCESS;
}
void execute_program(UM_state um)
{
        int ra =0;
        int rb =0;
        int rc =0;         
        //uint32_t val= 0;
        bool proceed = true;
        int num_instructions = get_words_in_seg(um->memory, 0);
        int i = um->instr_ctr;

        while (i < num_instructions && proceed) {
                uint32_t word = get_word(um->memory, 0, i);
                uint32_t op_code = get_op_code(word);

                /*if (op_code == 13) {
                        int ra = get_reg_num(word, LOAD_RA_LSB);
                        proceed &= valid_reg(ra);

                        uint32_t val = get_val(word);
                        (void) val;
                }

                else {*/
                        ra = get_reg_num(word, RA_LSB);
                        rb = get_reg_num(word, RB_LSB);
                        rc = get_reg_num(word, RC_LSB);

                        proceed &= valid_reg(ra);
                        proceed &= valid_reg(rb);
                        proceed &= valid_reg(rc);
                //}

                if (!proceed) {
                        break;
                }
                        
                if (op_code == 0) {
                        /* Conditional move - op code 0 */

                        if (val_in_reg(um, rc) != 0) {
                                uint32_t val = val_in_reg(um, rb);
                                set_reg_val(um, ra, val);
                        }
                                        
                } else if (op_code == 1) {
                        /* Segmented load - op code 1 */
                        uint32_t val = get_word(um->memory, val_in_reg(um, rb),
                                       val_in_reg(um, rc));
                        set_reg_val(um, ra, val);
                                        
                } else if (op_code == 2) {

                        /* Segmented store - op code 2 */

                        uint32_t ID = val_in_reg(um, ra);
                        uint32_t offset = val_in_reg(um, rb);
                        uint32_t val = val_in_reg(um, rc);

                        put_word(um->memory, ID, offset, val);
                                        
                } else if (op_code == 3) {

                        /* Add - op code 3 */
                        uint32_t val = (val_in_reg(um, rb) + val_in_reg(um, rc)) % UINT_MAX;
                        set_reg_val(um, ra, val);

                                        
                } else if (op_code == 4) {
                        /* Multiply - op code 4 */
                        uint32_t val = (val_in_reg(um, rb) * val_in_reg(um, rc)) % UINT_MAX;
                        set_reg_val(um, ra, val);
                                        
                } else if (op_code == 5) {
                        /* Divide - op code 5 */

                        uint32_t val = val_in_reg(um, rb) / val_in_reg(um, rc);
                        set_reg_val(um, ra, val);
                                        
                } else if (op_code == 6) {
                        /* Bitwise NAND - op code 6 */

                        uint32_t val = ~(val_in_reg(um, rb) & val_in_reg(um, rc));
                        set_reg_val(um, ra, val);
                                        
                } else if (op_code == 7) {
                        /* Halt */
                        proceed = false;
                                        
                } else if (op_code == 8) {
                        /* Map segment - op code 8 */

                        if (Stack_empty(um->unmapped_IDs)) {
                              
                                uint32_t num_words = val_in_reg(um, rc);

                                proceed &= create_segment(um->memory, num_words);             
                                set_reg_val(um, rb, (get_num_segs(um->memory) - 1));
                        }

                        else {
                                uint32_t ID = get_unmapped_ID(um);
                                uint32_t num_words = val_in_reg(um, rc);

                                proceed &= resize(um->memory, ID, num_words);

                                set_reg_val(um, rb, ID);
                        }

                } else if (op_code == 9) {
                        /* Unmap segment - op code 9 */
                        
                        uint32_t ID = val_in_reg(um, rc);
                        proceed &= clear_seg(um->memory, ID);
                        proceed &= add_unmapped_ID(um, ID);
                                        
                } else if (op_code == 10) {
                        /* Output - op code 10 */
                        uint32_t val = val_in_reg(um, rc);

                        if (val < 256) {
                                fprintf(stdout, "%c", (char) val);
                        } else {
                                proceed &= false;

                        }
                                        
                } else if (op_code == 11) {
                        /* Input - op code 11 */

                        uint32_t val = getc(stdin);

                        if ((int) val == EOF) {
                                val = ~0;

                        } else if (val > 255) {
                                proceed &= false;
                        }

                        set_reg_val(um, rc, val);
                                        
                } else if (op_code == 12) {
                        /* Load program - op code 12 */

                        uint32_t ID = val_in_reg(um, rb);

                        if (ID != 0) {
                                proceed &= clear_seg(um->memory, 0);

                                int num_words = get_words_in_seg(um->memory, ID);
                                
                                resize(um->memory, 0, num_words);

                                for (int i = 0; i < num_words; i++) {
                                        proceed &= put_word(um->memory, 0, i,
                                                               get_word(um->memory, ID, i));
                                }
                        }

                        um->instr_ctr = val_in_reg(um, rc);

                        num_instructions = 
                                get_words_in_seg(um->memory, 0);
                        i = um->instr_ctr;
                                        
                } else if (op_code == 13) {

                       /* Load value - op code 13 */
                        ra = get_reg_num(word, LOAD_RA_LSB);
                        proceed &= valid_reg(ra);

                        uint32_t val = get_val(word);
                        set_reg_val(um, ra, val);
                        
                } else {

                        fprintf(stderr, "op code doesn't exist\n");
                        proceed = false;
                }
                
                if (op_code != 12) {
                        i++;
                }
        }

        return;
}