From 5c82a0bfe8aa31e1ddd90f16c9ce170f177b638a Mon Sep 17 00:00:00 2001 From: nisstyre56 Date: Thu, 2 Oct 2014 15:52:23 -0400 Subject: [PATCH] rename, add pairs to RTS --- closures.c => RTS.c | 55 ++++++++++++++++++++++++++++++++++++++++----- RTS.h | 30 +++++++++++++------------ codegen.c | 10 +++++++++ manager.c | 27 ++++++++++++++++++++++ manager.h | 4 ++++ tokenize.c | 9 ++++++++ tokenize.h | 3 ++- 7 files changed, 118 insertions(+), 20 deletions(-) rename closures.c => RTS.c (65%) create mode 100644 codegen.c create mode 100644 manager.c create mode 100644 manager.h diff --git a/closures.c b/RTS.c similarity index 65% rename from closures.c rename to RTS.c index 73ea986..d12f8a1 100644 --- a/closures.c +++ b/RTS.c @@ -4,6 +4,7 @@ #include "error.h" #include "RTS.h" +/* Test case stuff */ #ifndef LIB static svalue_t* make_doubleadder_inner_inner(svalue_t *, svalue_t **); @@ -18,6 +19,15 @@ make_doubleadder(svalue_t *, svalue_t **); inline svalue_t box_value(svalue_variants_t value, stype_t type) { + /* + * Creates a boxed value which is just + * a tagged union where the value is the unboxed + * value and the tag is an enum value describing + * what the unboxed value represents + * We do this so that all values are of the same "type" + * and this makes it a lot simpler to pass around parameters, + * environments, closures, etc... + */ svalue_t val; switch (type) { @@ -35,6 +45,9 @@ box_value(svalue_variants_t value, case STRING: val.value.string = value.string; val.type_tag = type; + case PAIR: + val.value.pair = value.pair; + val.type_tag = type; case CLOSURE: val.value.closure = value.closure; val.type_tag = type; @@ -88,8 +101,8 @@ box_string(char *chars, size_t n) { } inline svalue_t * -box_closure(closure_t *closure) { - svalue_t *val = calloc(sizeof (svalue_t), 1); +box_closure(sc_closure_t *closure) { + svalue_t *val = malloc(sizeof (svalue_t)); CHECK(val); svalue_variants_t value_val; value_val.closure = closure; @@ -97,6 +110,20 @@ box_closure(closure_t *closure) { return val; } +inline svalue_t * +box_pair(svalue_t *left, svalue_t *right) { + sc_pair_t pair; + pair.left = left; + pair.right = right; + + svalue_t *val = malloc(sizeof (svalue_t)); + CHECK(val); + + svalue_variants_t value_val; + value_val.pair = pair; + *val = box_value(value_val, PAIR); + return val; +} inline svalue_t* make_closure(svalue_t *(*func)(svalue_t*, svalue_t**), @@ -107,7 +134,7 @@ make_closure(svalue_t *(*func)(svalue_t*, svalue_t**), * closure or else it is undefined behavior when it is invoked * since it would get deallocated when this function returns */ - closure_t *closure = malloc(sizeof (closure_t)); + sc_closure_t *closure = malloc(sizeof (sc_closure_t)); closure->func = func; closure->fvars = fvars; return box_closure(closure); @@ -118,7 +145,16 @@ invoke(svalue_t *closure, svalue_t *val) { return closure->value.closure->func(val, closure->value.closure->fvars); } +/* + * The process for closure conversion basically involves finding all of the free variables + * This will give the number of variables the environment must hold in total + * Hence we can figure out how much memory to allocate for them! + * Then the process of creating a closure simply involves assigning the bound variables to the environment + * before returning the closure (created with make_closure) + * Problem: how do we handle escaping functions? C can't do this afaik. + */ +/* More testing stuff */ #ifndef LIB static inline svalue_t* make_doubleadder_inner_inner(svalue_t *z, svalue_t **env) { @@ -141,19 +177,28 @@ make_doubleadder(svalue_t *x, svalue_t **env) { return make_closure(make_doubleadder_inner, env); } -/*svalue_t **env extend(uint32_t n, svalue_t *v*/ - int main(void) { (void)box_float; (void)box_double; (void)box_string; + /*Allocate an environment + * The environment size depends on how many nested functions there are ? + */ svalue_t **env = calloc(sizeof (svalue_t *), 2); + /* Get the final closure */ svalue_t *closure1 = make_closure(make_doubleadder, env); + /* Invoke the closure that the closure returns */ svalue_t *c1 = invoke(closure1, box_int(23)); svalue_t *c2 = invoke(c1, box_int(5)); svalue_t *result = invoke(c2, box_int(334)); + /* The final result */ printf("print 23 + 5 + 334 == %d\n", result->value.integer); + svalue_t *a = box_int(123); + svalue_t *b = box_int(455); + svalue_t *improper = box_pair(a, b); + improper->value.pair.right = improper; + printf("(%d, %d)\n", improper->value.pair.left->value.integer, improper->value.pair.right->value.pair.left->value.integer); return 0; } #endif diff --git a/RTS.h b/RTS.h index d52c737..7934aca 100644 --- a/RTS.h +++ b/RTS.h @@ -4,6 +4,13 @@ typedef char *string; } sc_string_t; +typedef + struct { + struct svalue_t *left; + struct svalue_t *right; + } + sc_pair_t; + /* This is not the most space efficient representation * However it is an easy to understand and debug one */ @@ -13,7 +20,8 @@ typedef float floating; double doublev; sc_string_t string; - struct closure_t *closure; + sc_pair_t pair; + struct sc_closure_t *closure; } svalue_variants_t; /* The tag values for each different type */ @@ -23,12 +31,13 @@ typedef FLOAT = 1, DOUBLE = 2, STRING = 3, - CLOSURE = 4 + CLOSURE = 4, + PAIR = 5 } stype_t; /* An actual boxed scheme value */ typedef - struct { + struct svalue_t { stype_t type_tag; svalue_variants_t value; } svalue_t; @@ -45,22 +54,15 @@ typedef * way */ typedef - struct closure_t { + struct sc_closure_t { svalue_t *(*func)(svalue_t*, svalue_t**); svalue_t **fvars; - } closure_t; - -typedef - struct { - svalue_t head; - struct cell *tail; - } - cell; + } sc_closure_t; svalue_t box_value(svalue_variants_t, stype_t); -closure_t* +svalue_t* make_closure(svalue_t *(*func)(svalue_t*, svalue_t**), svalue_t**); @@ -82,4 +84,4 @@ box_string(char *, size_t); svalue_t * -box_closure(closure_t*); +box_closure(sc_closure_t*); diff --git a/codegen.c b/codegen.c new file mode 100644 index 0000000..07c3c17 --- /dev/null +++ b/codegen.c @@ -0,0 +1,10 @@ +#include +#include +#include +#include +#include +#include +#include +#include "error.h" +#include "maa.h" +#include "RTS.h" diff --git a/manager.c b/manager.c new file mode 100644 index 0000000..cd28697 --- /dev/null +++ b/manager.c @@ -0,0 +1,27 @@ +#include +#include +#include +#include "error.h" +#include "RTS.h" +#include "manager.h" + +#define sc_size sizeof(svalue_t) + +svalue_t * acquire(void *val, + svalue_t *(*box_val)(void *)) { + svalue_t *new_val = box_val(val); + CHECK(val); + return new_val; +} + +int main(void) { + return 0; +} + +/* + * Outline of garbage collection algorithm + * we mark things accessible from a certain environment + * when things get removed from an environment we decrement their reference count + * periodically we go through and unmark things? + */ + diff --git a/manager.h b/manager.h new file mode 100644 index 0000000..3317081 --- /dev/null +++ b/manager.h @@ -0,0 +1,4 @@ +svalue_t * acquire(void *, + svalue_t *(* )(void *)); + + diff --git a/tokenize.c b/tokenize.c index 4aaa1a7..09bbbac 100644 --- a/tokenize.c +++ b/tokenize.c @@ -80,6 +80,15 @@ make_token(token_val_t val, return result; } +token_t +testfunc(void) { + token_val_t wspace = { + .whitespace=true + }; + return make_token(wspace, QUOTE); +} + + bool push_token(token_stream *tokens, token_t token) { diff --git a/tokenize.h b/tokenize.h index 191c787..c2633f3 100644 --- a/tokenize.h +++ b/tokenize.h @@ -69,4 +69,5 @@ match_symbol(source_t, uint32_t, const uint32_t); int free_token(const void *, const void *); - +token_t +testfunc(void);