Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Browse files

send messages

  • Loading branch information...
commit 4091a8d80a7233cd9f16a3d2ace6656f51e0486b 1 parent b3271ac
@txus authored
View
9 Makefile
@@ -9,11 +9,14 @@ OBJECTS=$(patsubst %.c,%.o,$(SOURCES))
TEST_SRC=$(wildcard tests/*_tests.c)
TESTS=$(patsubst %.c,%,$(TEST_SRC))
+PROGRAMS_SRC=$(wildcard bin/*.c)
+PROGRAMS=$(patsubst %.c,%,$(PROGRAMS_SRC))
+
TARGET=build/libforkix.a
SO_TARGET=$(patsubst %.a,%.so,$(TARGET))
# The Target Build
-all: $(TARGET) $(SO_TARGET) tests
+all: $(TARGET) $(SO_TARGET) tests $(PROGRAMS)
dev: CFLAGS=-g -Wall -Isrc -Wall -Werror $(OPTFLAGS)
dev: all
@@ -23,6 +26,8 @@ $(TARGET): build $(OBJECTS)
ar rcs $@ $(OBJECTS)
ranlib $@
+$(PROGRAMS): CFLAGS += $(TARGET)
+
$(SO_TARGET): $(TARGET) $(OBJECTS)
$(CC) -shared -o $@ $(OBJECTS)
@@ -41,7 +46,7 @@ valgrind:
# The Cleaner
clean:
- rm -rf build $(OBJECTS) $(TESTS)
+ rm -rf build $(OBJECTS) $(TESTS) $(PROGRAMS)
rm -f tests/tests.log
find . -name "*.gc*" -exec rm {} \;
rm -rf `find . -name "*.dSYM" -print`
View
BIN  bin/fxvm
Binary file not shown
View
3  bin/fxvm.c
@@ -1,9 +1,10 @@
#include <stdio.h>
#include <forkix/dbg.h>
+#include <forkix/vm.h>
int
main(int argc, char *argv[])
{
- printf("Hello forkix!\n");
+ VM_start();
return 0;
}
View
12 src/forkix/call_frame.c
@@ -0,0 +1,12 @@
+#include <stdlib.h>
+#include <forkix/call_frame.h>
+
+CallFrame*
+CallFrame_new(int *ip, int *ret)
+{
+ CallFrame* cf = calloc(1, sizeof(CallFrame));
+ cf->ip = ip;
+ cf->ret = ret;
+ cf->locals = DArray_create(sizeof(VALUE), 10);
+ return cf;
+}
View
17 src/forkix/call_frame.h
@@ -0,0 +1,17 @@
+#ifndef _fx_call_frame_h_
+#define _fx_call_frame_h_
+
+#include <forkix/value.h>
+#include <forkix/darray.h>
+
+struct call_frame_s {
+ DArray *locals;
+ int *ip;
+ int *ret;
+};
+
+typedef struct call_frame_s CallFrame;
+
+CallFrame* CallFrame_new(int *ip, int *ret);
+
+#endif
View
1  src/forkix/darray.h
@@ -24,6 +24,7 @@ void DArray_clear_destroy(DArray *array);
#define DArray_last(A) ((A)->contents[(A)->end - 1])
#define DArray_first(A) ((A)->contents[0])
+#define DArray_at(A, I) ((A)->contents[(I)])
#define DArray_end(A) ((A)->end)
#define DArray_count(A) DArray_end(A)
#define DArray_max(A) ((A)->max)
View
9 src/forkix/state.c
@@ -0,0 +1,9 @@
+#include <forkix/state.h>
+
+STATE
+State_new(Hashmap *functions)
+{
+ STATE state = calloc(1, sizeof(STATE));
+ state->functions = functions;
+ return state;
+}
View
14 src/forkix/state.h
@@ -0,0 +1,14 @@
+#ifndef _fx_state_h_
+#define _fx_state_h_
+
+#include <forkix/hashmap.h>
+
+struct state_s {
+ Hashmap *functions;
+};
+typedef struct state_s State;
+#define STATE State*
+
+STATE State_new(Hashmap *functions);
+
+#endif
View
25 src/forkix/value.c
@@ -1,3 +1,4 @@
+#include <stdio.h>
#include <forkix/value.h>
#include <forkix/gc.h>
@@ -15,6 +16,21 @@ Value_destroy(VALUE o)
gc_dealloc(o);
}
+void
+Value_print(VALUE o)
+{
+ switch(o->type) {
+ case IntegerType: {
+ printf("#<Integer %p @value=%i>\n", o, VAL2INT(o));
+ break;
+ }
+ default: {
+ printf("#<Object %p>\n", o);
+ break;
+ }
+ }
+}
+
VALUE
Integer_new(int num)
{
@@ -23,3 +39,12 @@ Integer_new(int num)
return val;
}
+
+VALUE
+String_new(char* value)
+{
+ VALUE val = Value_new(StringType);
+ val->data.as_str = value;
+ return val;
+}
+
View
4 src/forkix/value.h
@@ -19,9 +19,13 @@ typedef struct val_s val_t;
VALUE Value_new(ValueType);
void Value_destroy(VALUE);
+void Value_print(VALUE);
VALUE Integer_new(int);
#define VAL2INT(o) (o->data.as_int)
+VALUE String_new(char*);
+#define VAL2STR(o) (o->data.as_str)
+
#endif
View
134 src/forkix/vm.c
@@ -1,7 +1,137 @@
#include <forkix/dbg.h>
+#include <forkix/value.h>
+#include <forkix/stack.h>
+#include <forkix/call_frame.h>
+#include <forkix/vm.h>
+#include <forkix/state.h>
+#include <forkix/bstrlib.h>
-void
-foo()
+static void dump(Stack* stack)
{
+ printf("---STACK---\n");
+ int i = 0;
+ STACK_FOREACH(stack, node) {
+ if(node) {
+ printf("%i. ", i);
+ Value_print((VALUE)node->value);
+ }
+ i++;
+ }
+}
+#define STATE_FN(A) (int*)Hashmap_get(state->functions, bfromcstr((A)))
+#define LITERAL(A) DArray_at(literals, (A))
+#define LOCAL(A) DArray_at(current_frame->locals, (A))
+
+void VM_start()
+{
+ int program[] = {
+ // main
+ PUSHINT, 1,
+ PUSHINT, 4,
+ SEND, 0, 2,
+ DUMP,
+ RET,
+ // add
+ PUSHLOCAL, 0,
+ PUSHLOCAL, 1,
+ ADD,
+ RET
+ };
+
+ Hashmap *fns = Hashmap_create(NULL, NULL);
+ int *main = &program[0];
+ int *add = &program[9];
+ Hashmap_set(fns, bfromcstr("main"), main);
+ Hashmap_set(fns, bfromcstr("add"), add);
+
+ STATE state = State_new(fns);
+
+ Stack *frames = Stack_create();
+ CallFrame *top_frame = CallFrame_new(STATE_FN("main"), NULL);
+ Stack_push(frames, top_frame);
+ VM_run(state, frames);
+}
+
+void VM_run(STATE state, Stack *frames)
+{
+ Stack *stack = Stack_create();
+
+ DArray *literals = DArray_create(sizeof(VALUE), 10);
+ DArray_push(literals, String_new("add"));
+
+ CallFrame *current_frame = (CallFrame*)(Stack_peek(frames));
+ printf("Starting at %i\n", *current_frame->ip);
+ int *ip = current_frame->ip;
+
+ while(1) {
+ switch(*ip) {
+ case PUSHINT: {
+ ip++;
+ debug("PUSHINT %i", *ip);
+ VALUE value = Integer_new(*ip);
+ Stack_push(stack, value);
+ break;
+ }
+ case ADD: {
+ debug("ADD");
+ VALUE op1 = Stack_pop(stack);
+ VALUE op2 = Stack_pop(stack);
+ int result = VAL2INT(op1) + VAL2INT(op2);
+
+ Stack_push(stack, Integer_new(result));
+ break;
+ }
+ case SEND: {
+ ip++;
+ int op1 = *ip;
+ ip++;
+ int op2 = *ip;
+
+ VALUE name = LITERAL(op1);
+ int argcount = op2;
+
+ int *fn = STATE_FN(VAL2STR(name));
+ CallFrame *new_frame = CallFrame_new(fn, ip++);
+
+ while(argcount--) {
+ DArray_push(new_frame->locals, Stack_pop(stack));
+ }
+ Stack_push(frames, new_frame);
+
+ current_frame = (CallFrame*)(Stack_peek(frames));
+ ip = current_frame->ip;
+ ip--;
+
+ debug("SEND %i %i", op1, op2);
+ break;
+ }
+ case PUSHLOCAL: {
+ ip++;
+ Stack_push(stack, LOCAL(*ip));
+ debug("PUSHLOCAL %i", *ip);
+ break;
+ }
+ case POP: {
+ debug("POP");
+ Stack_pop(stack);
+ break;
+ }
+ case RET: {
+ debug("RET");
+ CallFrame *old_frame = Stack_pop(frames);
+
+ ip = old_frame->ret;
+ if (ip == NULL) return; // if there's nowhere to return, exit
+
+ current_frame = (CallFrame*)(Stack_peek(frames));
+ break;
+ }
+ case DUMP: {
+ dump(stack);
+ break;
+ }
+ }
+ ip++;
+ }
}
View
26 src/forkix/vm.h
@@ -0,0 +1,26 @@
+#ifndef _fx_vm_h_
+#define _fx_vm_h_
+
+#include <forkix/stack.h>
+#include <forkix/state.h>
+
+typedef enum {
+ NOOP = 0,
+ PUSHINT,
+
+ PUSHLOCAL = 0x20,
+
+ ADD,
+
+ POP,
+
+ SEND = 0x80,
+ RET = 0x90,
+
+ DUMP,
+} OpCode;
+
+void VM_run(STATE state, Stack *frames);
+void VM_start();
+
+#endif
View
24 tests/value_tests.c
@@ -2,22 +2,33 @@
#include <forkix/value.h>
#include <assert.h>
-VALUE val = NULL;
+VALUE intval = NULL;
+VALUE strval = NULL;
char *test_integer_new()
{
- val = Integer_new(123);
+ intval = Integer_new(123);
- mu_assert(val->type == IntegerType, "failed assigning type");
- mu_assert(VAL2INT(val) == 123, "failed assigning integer value");
+ mu_assert(intval->type == IntegerType, "failed assigning type");
+ mu_assert(VAL2INT(intval) == 123, "failed assigning integer value");
+
+ return NULL;
+}
+
+char *test_string_new()
+{
+ strval = String_new("abc");
+
+ mu_assert(strval->type == StringType, "failed assigning type");
+ mu_assert(strcmp(VAL2STR(strval), "abc") == 0, "failed assigning string value");
return NULL;
}
char *test_destroy()
{
- Value_destroy(val);
- mu_assert(!val->type, "failed destroying value")
+ Value_destroy(intval);
+ mu_assert(!intval->type, "failed destroying integer value")
return NULL;
}
@@ -26,6 +37,7 @@ char *all_tests() {
mu_suite_start();
mu_run_test(test_integer_new);
+ mu_run_test(test_string_new);
mu_run_test(test_destroy);
return NULL;
Please sign in to comment.
Something went wrong with that request. Please try again.