commit 6720d6ea90c80e4f32c7356251be8985e3266a9b parent d8c1f68d45e1aee828c8d8f0820ad36ef513addb Author: Paul Longtine <paullongtine@gmail.com> Date: Thu Jan 21 13:24:07 2016 updated specification, updated ns.(c|h), added test for ns Diffstat: doc/SPECIFICATION | 71 ++++++++++++++++++++++++---------------- src/vm/Makefile | 4 +- src/vm/inc/ht.h | 2 +- src/vm/inc/ns.h | 53 +++++++++++++----------------- src/vm/inc/stk.h | 2 +- src/vm/inc/types.h | 47 +--------------------------- src/vm/inc/var.h | 47 +++++++++++++++++++++++++++- src/vm/src/ht.c | 2 +- src/vm/src/ns.c | 85 ++++++++++++++++++++++++++++++++++++++---------- src/vm/src/stk.c | 2 +- src/vm/src/types.c | 26 +--------------- src/vm/src/var.c | 26 +++++++++++++++- src/vm/tests/ht/test | Bin 13493 -> 0 bytes src/vm/tests/ns/Makefile | 26 +++++++++++++++- src/vm/tests/ns/test.c | 8 +++++- src/vm/tests/stk/Makefile | 4 +- src/vm/tests/stk/test.c | 2 +- 17 files changed, 252 insertions(+), 155 deletions(-)
diff --git a/doc/SPECIFICATION b/doc/SPECIFICATION @@ -27,27 +27,36 @@ RUNTIME 'Function' in this case means a callable block of code which may or may not retu rn a value. +Scopes are handled by referencing to either the Global Scope, Local Scope. +Local Scope is denoted by '1' in the scope arguement when handling variables, +and this scope is initialized when evaluating any new block of code. When a diff +erent block of code is called, a new scope is initialized and the old scope is +pushed on to the local scope stack. The local scope stack keeps track of previou +s-level scopes, such as when a function returns the local scope stack is popped, +deconstructing variables on the popped local stack. + +Global scope variables (denoted by a '0' in the scope arguement) are persistient +through the runtime as they handle all function definitions, objects, and +variables declared in the global scope. + +---------+ - |Function | -> Function is 'defined', when called with reference a new scope is - +---------+ formed, along with arguements being supplied. Can support object - oriented behaviour with preserving scopes, and providing access - methods to member functions. - - Variables (and functions) exist under various scopes. The scopes are as -follows: - * Temporary Scope - * Local Scope - * Global Scope - - Temporary scope variables are variables declared outside the Root method. -The Root method is the code that is ran any time a 'module' of code is evaluated -and/or imported. A 'module' is any file containing code. Local Scope variables -are variables in which are visible to the module, and only the module. Global -scope variables are visible anywhere within the runtime. + |Function | -> Functions are defined with a reference, called with the same + +---------+ reference. The top elements on the stack are used as arguements + when calling a function, which must align with the parameter + types. + + +---------------+ + |Class | + | +---------+ | -> Classes are defined as wrappers around functions. Special + | |Function | | functions such as the Constructor function and the Deconst + | +---------+ | ructor exist to initialze/clean up properties. + +---------------+ + + A stack is used to keep a local group of values to manipulate. Values are pushed on to the stack and are operated upon, and the values in the stack can -but assigned or re-assigned to variables. +be assigned or re-assigned to variables. Bytecode Instructions @@ -80,10 +89,11 @@ Stack manipulation ------------------------------------------------------------------------------- Variable management ------------------------------------------------------------------------------- - DEC S<type> D<ref> - declare variable of type - LOV D<ref> - loads reference variable on to stack - STV D<ref> - stores TOS to reference variable - LOC D<ref> D<data> - loads constant + DEC S<scope> S<type> D<ref> - declare variable of type + LOV S<scope> D<ref> - loads reference variable on to stack + STV S<scope> D<ref> - stores TOS to reference variable + LOC S<scope> D<ref> D<data> - loads constant into variable + CTS D<data> - loads constant into stack ------------------------------------------------------------------------------- Type management @@ -132,12 +142,19 @@ Manipulating High-order Object Variables For arrays, key-value arrays, etc ------------------------------------------------------------------------------- - PUSH D<ref> - Push TOS on to <ref>, expects <ref> to be an object that - supports the scheme. - AT D<ref> - Push element in structure at TOS (assumes index of sorts) - for <ref> object. Assumes <ref> supports the scheme. - DEL D<ref> D<index> - Delete element in structure at TOS (assumes index of - sorts) for <ref> object. + PUSH - Push TOS on to TOS1, expects TOS1 to be an object hat + supports the scheme. + + DEL - Delete element in structure at TOS (assumes index of + sorts) for <ref> object. +------------------------------------------------------------------------------- +Functions/classes +------------------------------------------------------------------------------- + DEFUN D<ref> S<type> D<args> - Un-funs everything. no, no- it defines a + function. D<ref> is its name, S<type> is the + return value, D<args> is the args. + + DECLASS D<ref> - Defines a class ------------------------------------------------------------------------------- LEXICAL ANALYSIS diff --git a/src/vm/Makefile b/src/vm/Makefile @@ -9,7 +9,7 @@ DEPS = $(INC_DIR)/is_mdata.h \ fh.h \ bc.h \ is.h \ - types.h \ + var.h \ stk.h \ ht.h \ ns.h @@ -18,7 +18,7 @@ OBJ = $(SRC_DIR)/main.o \ $(SRC_DIR)/fh.o \ $(SRC_DIR)/bc.o \ $(SRC_DIR)/is.o \ - $(SRC_DIR)/types.o\ + $(SRC_DIR)/var.o \ $(SRC_DIR)/stk.o \ $(SRC_DIR)/ht.o \ $(SRC_DIR)/ns.o diff --git a/src/vm/inc/ht.h b/src/vm/inc/ht.h @@ -9,7 +9,7 @@ #include <limits.h> #include <string.h> -#include "types.h" +#include "var.h" #include "helper.h" typedef struct ht_entry { diff --git a/src/vm/inc/ns.h b/src/vm/inc/ns.h @@ -1,14 +1,4 @@ /* `ns` Namespace implementation - * - * Each variable that exists and accessed will be via a level on a namespace - * instance. For example, at the root of a program, a namespace is initialized - * and variables declared at this level are accessable everywhere. When a func - * is called, a new namespace level is initialized and variables declared on - * that level will be destroyed/inaccessable when the function returns and the - * new level is 'popped', going up a level. - * - * When a variable is queued, it will search through all the levels of the - * namespace to retreive the proper value. */ #ifndef NS_H @@ -16,41 +6,46 @@ #include <stdlib.h> -#include "types.h" +#include "var.h" #include "helper.h" +typedef struct ns_cont { + int size; + var_cont** names; + struct ns_cont* next; +} ns_cont; + typedef struct ns_t { - void* placeholder; + ns_cont* root; + ns_cont* last; } ns_t; -/* Initializes namespace. +/* Initializes namespace of size */ -ns_t* ns_init(void); +ns_t* ns_init(int); -/* Initializes new namspace level. - */ -void ns_new(ns_t*); +ns_cont* ns_cont_init(int); -/* Pushes new namespace level to a pre-initialized state +/* Cleans up memory */ -void ns_push(ns_t*, ns_t*); +void ns_del(ns_t*); + +void ns_cont_del(ns_cont*); -/* Pops last namespace level. Destroys all data initialized at level. +/* Pushes namespace of size */ -void ns_pop_del(ns_t*); +void ns_push(ns_t*, int); -/* Pops last namespace level. Keeps data, returns pointer. +/* Pops last namespace level */ -ns_t* ns_pop(ns_t*); +void ns_pop(ns_t*); -/* Declares a variable of name char*. - * Return code denotes a success or failure. (bool) +/* Declares a variable, at root or last namespace */ -int ns_dec(ns_t*, char*); +void ns_dec(ns_t*, b_type, int, int); -/* Sets variable to value. - * Return code denotes a success or failure. (bool) +/* Sets variable to value, at root or last namespace */ -int ns_set(ns_t*, char*, var_cont*); +void ns_set(ns_t*, int, int, var_cont*); #endif // NS_H diff --git a/src/vm/inc/stk.h b/src/vm/inc/stk.h @@ -7,7 +7,7 @@ #include <stdlib.h> #include <stdio.h> -#include "types.h" +#include "var.h" #include "helper.h" typedef struct stk_t { diff --git a/src/vm/inc/types.h b/src/vm/inc/types.h @@ -1,47 +0,0 @@ -/* types.h -> Provide implemenation of types - */ - -#ifndef TYPES_H -#define TYPES_H - -#include <stdlib.h> -#include <stdio.h> - -typedef enum { - VOID, - FUNC, - OBJECT, - G_INT, - G_FLOAT, - G_CHAR, - G_STRING, - S_ARRAY, - D_ARRAY, - K_ARRAY, - G_FIFO -} b_type; - -typedef struct var_cont { - b_type type; - void* data; -} var_cont; - -typedef void var_data_void; - -typedef int var_data_int; - -typedef char var_data_char; - -typedef struct var_data_str { - char* str; -} var_data_str; - -/* Initialze variable with type - */ -var_cont* var_new(b_type); - -/* Frees variable - */ -void var_del(var_cont*); - -#endif // TYPES_H diff --git a/src/vm/inc/var.h b/src/vm/inc/var.h @@ -0,0 +1,47 @@ +/* types.h -> Provide implemenation of types + */ + +#ifndef TYPES_H +#define TYPES_H + +#include <stdlib.h> +#include <stdio.h> + +typedef enum { + VOID, + FUNC, + OBJECT, + G_INT, + G_FLOAT, + G_CHAR, + G_STRING, + S_ARRAY, + D_ARRAY, + K_ARRAY, + G_FIFO +} b_type; + +typedef struct var_cont { + b_type type; + void* data; +} var_cont; + +typedef void var_data_void; + +typedef int var_data_int; + +typedef char var_data_char; + +typedef struct var_data_str { + char* str; +} var_data_str; + +/* Initialze variable with type + */ +var_cont* var_new(b_type); + +/* Frees variable + */ +void var_del(var_cont*); + +#endif // TYPES_H diff --git a/src/vm/src/ht.c b/src/vm/src/ht.c @@ -6,7 +6,7 @@ #include <string.h> #include "ht.h" -#include "types.h" +#include "var.h" #include "helper.h" ht_t* ht_init(int size) diff --git a/src/vm/src/ns.c b/src/vm/src/ns.c @@ -1,44 +1,95 @@ #include <stdlib.h> #include "ns.h" -#include "types.h" +#include "var.h" #include "helper.h" -ns_t* ns_init(void) +ns_t* ns_init(int size) { - ns_t* namespace = (ns_t*)malloc(sizeof(ns_t)); - ASSERT(namespace != NULL, "Could not allocate memory\n"); + ns_t* ns = (ns_t*)malloc(sizeof(ns_t)); + ASSERT(ns != NULL, "Could not allocate memory\n"); + + ns->root = ns_cont_init(size); + ns->last = NULL; - return namespace; + return ns; } -void ns_new(ns_t* namespace) +ns_cont* ns_cont_init(int size) { - return; + ns_cont* new = (ns_cont*)malloc(sizeof(ns_cont)); + ASSERT(new != NULL, "Could not allocate memory\n"); + + new->names = (var_cont**)malloc(sizeof(var_cont*)*size); + ASSERT(new->names != NULL, "Could not allocate memory\n"); + + new->size = size; + + for (int i = 0; i < size; i++) + { + new->names[i] = NULL; + } + + new->next = NULL; + + return new; } -void ns_push(ns_t* namespace, ns_t* namespace_append) +void ns_del(ns_t* ns) { - return; + while (ns->last->next != NULL) + ns_pop(ns); + + free(ns); } -void ns_pop_del(ns_t* namespace) +void ns_cont_del(ns_cont* container) { - return; + for (int i = 0; i < container->size; i++) + { + if (container->names[i] != NULL) + var_del(container->names[i]); + } + + free(container->names); + + free(container); } -ns_t* ns_pop(ns_t* namespace) +void ns_push(ns_t* ns, int size) { - return namespace; + ns_cont* new = ns_cont_init(size); + + if (ns->last == NULL) + { + new->next = ns->root; + ns->last = new; + } + else + { + new->next = ns->last; + ns->last = new; + } +} + +void ns_pop(ns_t* ns) +{ + if (ns->last->next != NULL) { + ns_cont* newlast = ns->last->next; + + ns_cont_del(ns->last); + + ns->last = newlast; + } } -int ns_dec(ns_t* namespace, char* name) +void ns_dec(ns_t* ns, b_type type, int scope, int name) { - return 0; + return; } -int ns_set(ns_t* namespace, char* name, var_cont* data) +void ns_set(ns_t* ns, int scope, int name, var_cont* data) { - return 0; + return; } diff --git a/src/vm/src/stk.c b/src/vm/src/stk.c @@ -2,7 +2,7 @@ #include <stdio.h> #include "stk.h" -#include "types.h" +#include "var.h" #include "helper.h" stk_t* stk_new( void ) diff --git a/src/vm/src/types.c b/src/vm/src/types.c @@ -1,26 +0,0 @@ -#include <stdlib.h> -#include <stdio.h> - -#include "types.h" -#include "helper.h" - -var_cont* var_new(b_type type) -{ - var_cont* new = (var_cont*)malloc(sizeof(var_cont)); - ASSERT(new != NULL, "Could not allocate memory\n"); - - new->type = type; - new->data = NULL; - return new; -} - -void var_del(var_cont* var) -{ - if (var == NULL) - return; - - if (var->data != NULL) - free(var->data); - - free(var); -} diff --git a/src/vm/src/var.c b/src/vm/src/var.c @@ -0,0 +1,26 @@ +#include <stdlib.h> +#include <stdio.h> + +#include "var.h" +#include "helper.h" + +var_cont* var_new(b_type type) +{ + var_cont* new = (var_cont*)malloc(sizeof(var_cont)); + ASSERT(new != NULL, "Could not allocate memory\n"); + + new->type = type; + new->data = NULL; + return new; +} + +void var_del(var_cont* var) +{ + if (var == NULL) + return; + + if (var->data != NULL) + free(var->data); + + free(var); +} diff --git a/src/vm/tests/ht/test b/src/vm/tests/ht/test Binary files differ diff --git a/src/vm/tests/ns/Makefile b/src/vm/tests/ns/Makefile @@ -0,0 +1,26 @@ +SRC_DIR = ../../src +INC_DIR = ../../inc + +CC = gcc +CFLAGS = -std=c99 -Wall -I$(INC_DIR) + +DEPS = i$(INC_DIR)/helper.h \ + ns.h \ + var.h \ + +OBJ = test.o \ + $(SRC_DIR)/ns.o \ + $(SRC_DIR)/var.o + +OUT = test + +%.o: %.c $(DEPS) + $(CC) $(CFLAGS) -c -o $@ $< + +$(OUT): $(OBJ) + $(CC) $(CFLAGS) -o $@ $^ + +clean: + rm *.o + rm $(SRC_DIR)/*.o + rm $(OUT) diff --git a/src/vm/tests/ns/test.c b/src/vm/tests/ns/test.c @@ -0,0 +1,8 @@ +#include <stdio.h> + +#include "ns.h" + +int main( void ) +{ + return 0; +} diff --git a/src/vm/tests/stk/Makefile b/src/vm/tests/stk/Makefile @@ -6,11 +6,11 @@ CFLAGS = -std=c99 -Wall -I$(INC_DIR) DEPS = i$(INC_DIR)/helper.h \ stk.h \ - types.h \ + var.h \ OBJ = test.o \ $(SRC_DIR)/stk.o \ - $(SRC_DIR)/types.o + $(SRC_DIR)/var.o OUT = test diff --git a/src/vm/tests/stk/test.c b/src/vm/tests/stk/test.c @@ -1,7 +1,7 @@ #include <stdio.h> #include "stk.h" -#include "types.h" +#include "var.h" void printstk(stk_t* stk)