Skip to content

Commit

Permalink
feat: Add interpreter vm implementation
Browse files Browse the repository at this point in the history
  • Loading branch information
fabianishere committed Mar 25, 2019
1 parent 38f88bc commit f2fc53f
Show file tree
Hide file tree
Showing 4 changed files with 146 additions and 1 deletion.
7 changes: 7 additions & 0 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ project(brainfuck
include(CTest)

option(ENABLE_PARSER_BRAINFUCK "Enable brainfuck parser implementation" ON)
option(ENABLE_VM_INTERPRETER "Enable interpreter" ON)
option(ENABLE_CLI "Enable the command line interface" ON)
option(ENABLE_EDITLINE "Enable GNU readline functionality provided by the editline library" ON)
option(ENABLE_EXTENSION_DEBUG "Enable the debug extension for brainfuck")
Expand Down Expand Up @@ -41,6 +42,8 @@ add_library(brainfuck
src/parser/brainfuck.h
src/parser/brainfuck.c
src/vm/vm.c
src/vm/interpreter.h
src/vm/interpreter.c
)
set_target_properties(brainfuck PROPERTIES C_STANDARD 90)
target_include_directories(brainfuck PUBLIC
Expand All @@ -57,6 +60,10 @@ if(ENABLE_PARSER_BRAINFUCK)
target_compile_definitions(brainfuck PUBLIC BRAINFUCK_PARSER_BRAINFUCK_ENABLED)
endif()

if(ENABLE_VM_INTERPRETER)
target_compile_definitions(brainfuck PUBLIC BRAINFUCK_VM_INTERPRETER_ENABLED)
endif()

if(ENABLE_CLI)
add_executable(brainfuck-cli src/cli.c)
set_target_properties(brainfuck-cli PROPERTIES
Expand Down
101 changes: 101 additions & 0 deletions src/vm/interpreter.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,101 @@
/*
* Copyright (c) 2019 Fabian Mastenbroek
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*/

#include <brainfuck/brainfuck.h>
#include <brainfuck/vm.h>
#include <brainfuck/ir.h>

#include "../brainfuck.h"


static struct BrainfuckVmContext * alloc(struct BrainfuckVm *vm)
{
struct BrainfuckVmContext *ctx = BRAINFUCK_ALLOC(sizeof(struct BrainfuckVmContext));

if (ctx) {
ctx->vm = vm;
ctx->memory = NULL;
ctx->memory_size = 0;
ctx->read = NULL;
ctx->write = NULL;
}

return ctx;
}

static void dealloc(struct BrainfuckVmContext *ctx)
{
BRAINFUCK_DEALLOC(ctx);
}

static int run(struct BrainfuckVmContext *ctx,
const struct BrainfuckProgram *program)
{
register struct BrainfuckInstruction *inst = program->head;
register uint8_t *mem = ctx->memory;
register int index = 0;

while (inst) {
switch(inst->opcode) {
case ADD:
mem[index + inst->operands[0].i32] += inst->operands[1].i32;
break;
case MOV:
index += inst->operands[0].i32;
break;
case CPY:
mem[index + inst->operands[1].i32] = mem[index + inst->operands[0].i32];
break;
case MUL:
mem[index + inst->operands[1].i32] = mem[index + inst->operands[0].i32] * inst->operands[2].i8;
break;
case CLR:
mem[index + inst->operands[0].i32] = 0;
break;
case IN:
mem[index + inst->operands[0].i32] = (uint8_t) ctx->read();
break;
case OUT:
ctx->write(mem[index + inst->operands[0].i32]);
break;
case JNZ:
if (!mem[index])
break;
/* Fallthrough */
case JMP:
inst = inst->operands[0].ref;
continue;
case NOP:
break;
}
inst = inst->next;
}
return BRAINFUCK_EOK;
}

struct BrainfuckVm brainfuck_vm_interpreter = {
.name = "interpreter",
.version = "1.0.0",
.alloc = &alloc,
.dealloc = &dealloc,
.run = &run,
};
32 changes: 32 additions & 0 deletions src/vm/interpreter.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
/*
* Copyright (c) 2019 Fabian Mastenbroek
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*/

#ifndef BRAINFUCK_VM_INTERPRETER_H
#define BRAINFUCK_VM_INTERPRETER_H

#include <brainfuck/vm.h>

#ifdef BRAINFUCK_VM_INTERPRETER_ENABLED
extern struct BrainfuckVm brainfuck_vm_interpreter;
#endif

#endif /* BRAINFUCK_VM_INTERPRETER_H */
7 changes: 6 additions & 1 deletion src/vm/vm.c
Original file line number Diff line number Diff line change
Expand Up @@ -26,11 +26,16 @@
#include <brainfuck/vm.h>

#include "../brainfuck.h"
#include "interpreter.h"

/**
* Internal array containing the available virtual machine implementations.
*/
static struct BrainfuckVm *vms[] = {NULL};
static struct BrainfuckVm *vms[] = {
#ifdef BRAINFUCK_VM_INTERPRETER_ENABLED
&brainfuck_vm_interpreter,
#endif
};

struct BrainfuckVmContext * brainfuck_vm_alloc(struct BrainfuckVm *vm)
{
Expand Down

0 comments on commit f2fc53f

Please sign in to comment.