restored folder structure

This commit is contained in:
2018-10-27 19:49:38 +02:00
parent bd0a0bcb74
commit a2fedb21c7
17 changed files with 20 additions and 20 deletions

19
interpreter/Makefile Normal file
View File

@@ -0,0 +1,19 @@
CC=gcc
objects= stack.o method_dispatcher/method_dispatcher.o interpreter/core_methods.o interpreter/interpreter.o
all: $(objects) test
CFLAG= -c -O -o
%.o: %.c
$(CC) $(CFLAG) $@ $<
.PHONY: test
test:
cd test && make
cd method_dispatcher/test && make
cd interpreter/test && make
clean:
- rm $(objects)

20
interpreter/base.h Normal file
View File

@@ -0,0 +1,20 @@
#ifndef bci_base_h__
#define bci_base_h__
#include <inttypes.h>
#include "stack.h"
#define BCI_CORE_NUM_REG 40
// Note that void * state will later be casted to
// machine_state_t.
typedef char (* bci_core_method_t)(uint8_t small_arg
, void * state);
#define BCI_CORE_RESULT_RESERVED_BITS 0b11000000
#define BCI_CORE_RESULT_APPLICATION_BITS 0b00111111
#define BCI_CORE_SMALL_ARG_MASK 0b0000000000111111
#define BCI_CORE_OPCODE_MASK 0b1111111111000000
#endif

View File

@@ -0,0 +1,14 @@
CC=gcc
all: test_interpreter
interpreter: clean
$(CC) -g ../../stack.c ../interpreter.c ../core_methods.c ../../method_dispatcher/method_dispatcher.c test_interpreter.c -o interpreter
test_interpreter: interpreter
valgrind ./interpreter
clean:

View File

@@ -0,0 +1,158 @@
#include <stdlib.h>
#include "method_dispatcher.h"
dispatch_tree_t dispatch_tree_t_new(void)
{
dispatch_tree_t tree = malloc(sizeof(struct dispatch_tree_s));
tree->root = NULL;
return tree;
}
void dispatch_tree_t_del(dispatch_tree_t tree)
{
dispatch_tree_node_t_del(tree->root);
free(tree);
}
dispatch_tree_node_t dispatch_tree_node_t_new(uint16_t word
, bci_core_method_t method)
{
dispatch_tree_node_t node = malloc(sizeof(struct dispatch_tree_node_s));
node->higher = NULL;
node->lower = 0;
node->method = method;
node->word = word;
return node;
}
void dispatch_tree_node_t_del(dispatch_tree_node_t node)
{
if(node->higher)
{
dispatch_tree_node_t_del(node->higher);
}
if(node->lower)
{
dispatch_tree_node_t_del(node->lower);
}
free(node);
}
char dispatch_tree_t_insert(dispatch_tree_t tree
, uint16_t word
, bci_core_method_t method)
{
dispatch_tree_node_t new_node = dispatch_tree_node_t_new(word, method);
if(!new_node)
{
return 1;
}
// explicitly handle empty tree
if(!tree->root)
{
tree->root = new_node;
return 0;
}
// non-empty tree
dispatch_tree_node_t this_node = tree->root;
dispatch_tree_node_t parent_node = NULL;
// search for place
do
{
parent_node = this_node;
if(parent_node->word < word)
{
this_node = parent_node->higher;
continue;
}
if(parent_node->word > word)
{
this_node = parent_node->lower;
continue;
}
if(parent_node->word == word)
{
// we already have that key.
return 2;
}
}
while(this_node);
if(parent_node->word < word)
{
parent_node->higher = new_node;
}
if(parent_node->word > word)
{
parent_node->lower = new_node;
}
return 0;
}
bci_core_method_t dispatch_tree_t_dispatch(dispatch_tree_t tree
, uint16_t word)
{
dispatch_tree_node_t this_node = tree->root;
while(this_node)
{
if(this_node->word < word)
{
this_node = this_node->higher;
continue;
}
if(this_node->word > word)
{
this_node = this_node->lower;
continue;
}
if(this_node->word == word)
{
return this_node->method;
}
}
return NULL;
}
dispatch_tree_autoinserter_t dispatch_tree_autoinserter_t_new(dispatch_tree_t tree)
{
dispatch_tree_autoinserter_t autoinserter = malloc(
sizeof(struct dispatch_tree_autoinserter_s));
if(!autoinserter)
{
return NULL;
}
autoinserter->mayor = 2;
autoinserter->minor = 1;
autoinserter->tree = tree;
return autoinserter;
}
void dispatch_tree_autoinserter_t_del(dispatch_tree_autoinserter_t autoinserter)
{
free(autoinserter);
}
uint16_t dispatch_tree_autoinserter_t_insert(
dispatch_tree_autoinserter_t autoinserter
, bci_core_method_t method)
{
uint16_t opcode = 0b1111111111;
opcode *= autoinserter->minor;
opcode /= autoinserter->mayor;
opcode <<= 6;
dispatch_tree_t_insert(autoinserter->tree, opcode, method);
autoinserter->minor = (autoinserter->minor + 2) % autoinserter->mayor;
if(autoinserter->minor == 1)
{
autoinserter->mayor *= 2;
}
return opcode;
}

View File

@@ -0,0 +1,87 @@
#ifndef bci_method_dispatcher_h__
#define bci_method_dispatcher_h__
#include <inttypes.h>
#include "../base.h"
typedef struct dispatch_tree_node_s
{
struct dispatch_tree_node_s * higher;
struct dispatch_tree_node_s * lower;
uint16_t word;
bci_core_method_t method;
} * dispatch_tree_node_t;
typedef struct dispatch_tree_s
{
dispatch_tree_node_t root;
} * dispatch_tree_t;
dispatch_tree_t dispatch_tree_t_new(void);
/*
* This deletes the tree and will invoke dispatch_tree_node_t_del on
* tree->root (which will delete all the other nodes recursively).
* If you want to keep nodes you have to explicityl remove the reference to
* them by setting them to NULL.
* */
void dispatch_tree_t_del(dispatch_tree_t tree);
dispatch_tree_node_t dispatch_tree_node_t_new(uint16_t word
, bci_core_method_t method);
/*
* This deletes the node an will invoke dispatch_tree_node_t_del on
* node->higher and node->lower. If you want to keep those nodes
* you have to explicitly clear the reference by setting them to NULL.
* */
void dispatch_tree_node_t_del(dispatch_tree_node_t node);
/*
* Insert a new key-value-pair into the tree.
*
* Return codes:
* 0: OK
* 1: out of memory
* 2: key already in tree
* */
char dispatch_tree_t_insert(dispatch_tree_t tree
, uint16_t word
, bci_core_method_t method);
bci_core_method_t dispatch_tree_t_dispatch(dispatch_tree_t tree
, uint16_t word);
typedef struct dispatch_tree_autoinserter_s
{
uint16_t mayor;
uint16_t minor;
dispatch_tree_t tree;
} * dispatch_tree_autoinserter_t;
dispatch_tree_autoinserter_t dispatch_tree_autoinserter_t_new(dispatch_tree_t tree);
void dispatch_tree_autoinserter_t_del(dispatch_tree_autoinserter_t autoinserter);
/*
* This function inserts a new method into the tree and automatically
* chooses the optimal word to prevent degeneration.
*
* NOTE:
* When inserting mutliple methods this function acts deterministic,
* IF AND ONLY IF the order of the methods is not changed.
*
* The assembler will bring an analogous function that allows one
* to determine the opcodes of the methods.
*
* NOTE:
* This algorithm will not work for more that 1023 registered opcodes.
* This limit is however considered acceptable.
*
* */
uint16_t dispatch_tree_autoinserter_t_insert(
dispatch_tree_autoinserter_t autoinserter
, bci_core_method_t method);
#endif

View File

@@ -0,0 +1,14 @@
CC=gcc
all: test_method_dispatcher
method_dispatcher: clean
$(CC) -g ../method_dispatcher.c test_method_dispatcher.c -o method_dispatcher
test_method_dispatcher: method_dispatcher
valgrind ./method_dispatcher
clean:
-rm method_dispatcher

View File

@@ -0,0 +1,63 @@
#include <stdio.h>
#include "../method_dispatcher.h"
char m1(uint8_t small_arg, void * state);
char m2(uint8_t small_arg, void * state);
char m3(uint8_t small_arg, void * state);
char m4(uint8_t small_arg, void * state);
char m5(uint8_t small_arg, void * state);
int main(void)
{
printf("sizeof struct dispatch_tree_node_s: %zd\n", sizeof(struct dispatch_tree_node_s));
dispatch_tree_t tree = dispatch_tree_t_new();
dispatch_tree_t_insert(tree, 3 << 6, m3);
dispatch_tree_t_insert(tree, 2 << 6, m2);
dispatch_tree_t_insert(tree, 1 << 6, m1);
dispatch_tree_t_insert(tree, 4 << 6, m4);
dispatch_tree_t_insert(tree, 5 << 6, m5);
int i;
for(i = 1; i < 6; i++)
{
dispatch_tree_t_dispatch(tree, i << 6)(i, NULL);
}
dispatch_tree_t_del(tree);
bci_core_method_t methods[5] = {m1, m2, m3, m4, m5};
tree = dispatch_tree_t_new();
dispatch_tree_autoinserter_t inserter = dispatch_tree_autoinserter_t_new(tree);
for(i = 0; i < 5; i++)
{
printf("%u\n", dispatch_tree_autoinserter_t_insert(inserter, methods[i]));
}
dispatch_tree_autoinserter_t_del(inserter);
dispatch_tree_t_del(tree);
return 0;
}
char m1(uint8_t small_arg, void * state)
{
printf("m1: %d\n", small_arg);
}
char m2(uint8_t small_arg, void * state)
{
printf("m2: %d\n", small_arg);
}
char m3(uint8_t small_arg, void * state)
{
printf("m3: %d\n", small_arg);
}
char m4(uint8_t small_arg, void * state)
{
printf("m4: %d\n", small_arg);
}
char m5(uint8_t small_arg, void * state)
{
printf("m5: %d\n", small_arg);
}

40
interpreter/stack.c Normal file
View File

@@ -0,0 +1,40 @@
#include <stdlib.h>
#include "stack.h"
char bci_stack_t_push(bci_stack_t * stack, uint16_t value)
{
bci_stack_t node = malloc(sizeof(struct bci_stack_s));
if(!node)
{
return 1;
}
node->next = *stack;
node->value = value;
*stack = node;
return 0;
}
char bci_stack_t_pop(bci_stack_t * stack, uint16_t * result)
{
bci_stack_t this_node;
if(!*stack)
{
return 1;
}
this_node = *stack;
*result = this_node->value;
*stack = this_node->next;
free(this_node);
return 0;
}
void bci_stack_t_del(bci_stack_t * stack)
{
bci_stack_t this_node;
while(*stack)
{
this_node = *stack;
*stack = this_node->next;
free(this_node);
}
}

20
interpreter/stack.h Normal file
View File

@@ -0,0 +1,20 @@
#ifndef bci_stack_h__
#define bci_stack_h__
#include <inttypes.h>
typedef struct bci_stack_s
{
struct bci_stack_s * next;
uint16_t value;
} * bci_stack_t;
char bci_stack_t_push(bci_stack_t * stack, uint16_t value);
char bci_stack_t_pop(bci_stack_t * stack, uint16_t * result);
/*
* Deletes the entire (!) stack.
*
* */
void bci_stack_t_del(bci_stack_t * stack);
#endif

View File

@@ -1,14 +1,12 @@
CC=gcc
all: test_interpreter
interpreter: clean
$(CC) -g ../../stack.c ../interpreter.c ../core_methods.c ../../method_dispatcher/method_dispatcher.c test_interpreter.c -o interpreter
test_interpreter: interpreter
valgrind ./interpreter
all: test_stack
stack: clean
$(CC) -g ../stack.c test_stack.c -o stack
test_stack: stack
valgrind ./stack
clean:
-rm stack

View File

@@ -0,0 +1,34 @@
#include <stdio.h>
#include "../stack.h"
#include <assert.h>
int main(void)
{
bci_stack_t stack = NULL;
int i;
uint16_t res;
char status = 0;
for(i = 0; i < 10; i++)
{
bci_stack_t_push(&stack, (uint16_t) i);
}
--i;
while(!status)
{
status = bci_stack_t_pop(&stack, &res);
if(!status)
{
assert(res == i--);
}
}
for(i = 0; i < 10; i++)
{
bci_stack_t_push(&stack, (uint16_t) i);
}
bci_stack_t_del(&stack);
return 0;
}