diff --git a/.clang-format b/.clang-format new file mode 100644 index 0000000..00175ab --- /dev/null +++ b/.clang-format @@ -0,0 +1,121 @@ +--- +Language: Cpp +# BasedOnStyle: LLVM +AccessModifierOffset: -2 +AlignAfterOpenBracket: AlwaysBreak +AlignConsecutiveAssignments: false +AlignConsecutiveDeclarations: false +AlignEscapedNewlines: Right +AlignOperands: true +AlignTrailingComments: true +AllowAllParametersOfDeclarationOnNextLine: true +AllowShortBlocksOnASingleLine: false +AllowShortCaseLabelsOnASingleLine: false +AllowShortFunctionsOnASingleLine: All +AllowShortIfStatementsOnASingleLine: false +AllowShortLoopsOnASingleLine: false +AlwaysBreakAfterDefinitionReturnType: None +AlwaysBreakAfterReturnType: None +AlwaysBreakBeforeMultilineStrings: false +AlwaysBreakTemplateDeclarations: MultiLine +BinPackArguments: true +BinPackParameters: true +BraceWrapping: + AfterClass: false + AfterControlStatement: false + AfterEnum: false + AfterFunction: false + AfterNamespace: false + AfterObjCDeclaration: false + AfterStruct: false + AfterUnion: false + AfterExternBlock: false + BeforeCatch: false + BeforeElse: false + IndentBraces: false + SplitEmptyFunction: true + SplitEmptyRecord: true + SplitEmptyNamespace: true +BreakBeforeBinaryOperators: None +BreakBeforeBraces: Attach +BreakBeforeInheritanceComma: false +BreakInheritanceList: BeforeColon +BreakBeforeTernaryOperators: true +BreakConstructorInitializersBeforeComma: false +BreakConstructorInitializers: BeforeColon +BreakAfterJavaFieldAnnotations: false +BreakStringLiterals: true +ColumnLimit: 90 +CommentPragmas: '^ IWYU pragma:' +CompactNamespaces: false +ConstructorInitializerAllOnOneLineOrOnePerLine: false +ConstructorInitializerIndentWidth: 4 +ContinuationIndentWidth: 4 +Cpp11BracedListStyle: true +DerivePointerAlignment: false +DisableFormat: false +ExperimentalAutoDetectBinPacking: false +FixNamespaceComments: true +ForEachMacros: + - foreach + - Q_FOREACH + - BOOST_FOREACH +IncludeBlocks: Preserve +IncludeCategories: + - Regex: '^"(llvm|llvm-c|clang|clang-c)/' + Priority: 2 + - Regex: '^(<|"(gtest|gmock|isl|json)/)' + Priority: 3 + - Regex: '.*' + Priority: 1 +IncludeIsMainRegex: '(Test)?$' +IndentCaseLabels: true +IndentPPDirectives: None +IndentWidth: 4 +IndentWrappedFunctionNames: false +JavaScriptQuotes: Leave +JavaScriptWrapImports: true +KeepEmptyLinesAtTheStartOfBlocks: true +MacroBlockBegin: '' +MacroBlockEnd: '' +MaxEmptyLinesToKeep: 1 +NamespaceIndentation: None +ObjCBinPackProtocolList: Auto +ObjCBlockIndentWidth: 2 +ObjCSpaceAfterProperty: false +ObjCSpaceBeforeProtocolList: true +PenaltyBreakAssignment: 2 +PenaltyBreakBeforeFirstCallParameter: 19 +PenaltyBreakComment: 300 +PenaltyBreakFirstLessLess: 120 +PenaltyBreakString: 1000 +PenaltyBreakTemplateDeclaration: 10 +PenaltyExcessCharacter: 1000000 +PenaltyReturnTypeOnItsOwnLine: 60 +PointerAlignment: Right +ReflowComments: true +SortIncludes: true +SortUsingDeclarations: true +SpaceAfterCStyleCast: false +SpaceAfterTemplateKeyword: true +SpaceBeforeAssignmentOperators: true +SpaceBeforeCpp11BracedList: false +SpaceBeforeCtorInitializerColon: true +SpaceBeforeInheritanceColon: true +SpaceBeforeParens: ControlStatements +SpaceBeforeRangeBasedForLoopColon: true +SpaceInEmptyParentheses: false +SpacesBeforeTrailingComments: 1 +SpacesInAngles: false +SpacesInContainerLiterals: true +SpacesInCStyleCastParentheses: false +SpacesInParentheses: false +SpacesInSquareBrackets: false +Standard: Cpp11 +StatementMacros: + - Q_UNUSED + - QT_REQUIRE_VERSION +TabWidth: 8 +UseTab: Never +... + diff --git a/format.sh b/format.sh new file mode 100755 index 0000000..e4e1f87 --- /dev/null +++ b/format.sh @@ -0,0 +1,4 @@ +#!/bin/bash + +clang-format -i -style=file $(find ./src/ -name '*.c'; find ./src/ -iname '*.h' ) + diff --git a/src/compiler.c b/src/compiler.c index fc4d5b9..1a2bd67 100644 --- a/src/compiler.c +++ b/src/compiler.c @@ -1,17 +1,18 @@ -#include #include #include +#include -#include +#include #include -#include +#include +#include #include -#include +#include #include -#include #include + #include #include @@ -19,75 +20,73 @@ #include #ifdef __APPLE__ -char *target_preamble = \ -" .section __TEXT,__text\n" \ -" .global _main\n" \ -" .p2align 4, 0x90\n" \ -"_main:\n" \ -" .cfi_startproc\n" \ -" pushq %rbp\n" \ -" .cfi_def_cfa_offset 16\n" \ -" .cfi_offset %rbp, -16\n" \ -" movq %rsp, %rbp\n" \ -" .cfi_def_cfa_register %rbp\n" \ -" xorl %eax, %eax\n" \ -" call _run_scheme\n" \ -" popq %rbp\n" \ -" retq\n" \ -" .cfi_endproc\n" \ -".global _scheme_code\n" \ -"_scheme_code:\n" \ -" leaq str(%rip), %rax\n" \ -" retq\n" \ -".global _scheme_code_size\n" \ -"_scheme_code_size:\n" \ -" leaq str_size(%rip), %rax\n" \ -" movq (%rax), %rax\n" \ -" retq\n" \ -".section __DATA,_data\n" \ -"meta:\n" \ -" .quad 0 # meta_obj.next\n" \ -" .long 0 # meta_obj.mark\n" \ -" .long 0 # meta_obj.size\n" \ -" .long 0 # meta_obj.type_def\n" \ -"str:\n"; - -char *target_size = "\n" \ -"str_size :\n" \ -" .quad "; +char *target_preamble = " .section __TEXT,__text\n" + " .global _main\n" + " .p2align 4, 0x90\n" + "_main:\n" + " .cfi_startproc\n" + " pushq %rbp\n" + " .cfi_def_cfa_offset 16\n" + " .cfi_offset %rbp, -16\n" + " movq %rsp, %rbp\n" + " .cfi_def_cfa_register %rbp\n" + " xorl %eax, %eax\n" + " call _run_scheme\n" + " popq %rbp\n" + " retq\n" + " .cfi_endproc\n" + ".global _scheme_code\n" + "_scheme_code:\n" + " leaq str(%rip), %rax\n" + " retq\n" + ".global _scheme_code_size\n" + "_scheme_code_size:\n" + " leaq str_size(%rip), %rax\n" + " movq (%rax), %rax\n" + " retq\n" + ".section __DATA,_data\n" + "meta:\n" + " .quad 0 # meta_obj.next\n" + " .long 0 # meta_obj.mark\n" + " .long 0 # meta_obj.size\n" + " .long 0 # meta_obj.type_def\n" + "str:\n"; + +char *target_size = "\n" + "str_size :\n" + " .quad "; char *target_postamble = "\n"; #elif __linux__ -char *target_preamble = \ -" .text\n" \ -" .globl main\n" \ -"main:\n" \ -" pushq %rbp\n" \ -" movq %rsp, %rbp\n" \ -" call run_scheme@PLT\n" \ -" popq %rbp\n" \ -" ret\n"\ -".globl scheme_code\n" \ -"scheme_code:\n" \ -" leaq str(%rip), %rax\n" \ -" retq\n" \ -".globl scheme_code_size\n" \ -"scheme_code_size:\n" \ -" leaq str_size(%rip), %rax\n" \ -" movq (%rax), %rax\n" \ -" retq\n" \ -" .data\n"\ -"meta:\n" \ -" .quad 0 # meta_obj.next\n" \ -" .long 0 # meta_obj.mark\n" \ -" .long 0 # meta_obj.size\n" \ -" .long 0 # meta_obj.type_def\n" \ -"str:\n"; - -char *target_size = "\n" \ -"str_size :\n" \ -" .quad "; +char *target_preamble = " .text\n" + " .globl main\n" + "main:\n" + " pushq %rbp\n" + " movq %rsp, %rbp\n" + " call run_scheme@PLT\n" + " popq %rbp\n" + " ret\n" + ".globl scheme_code\n" + "scheme_code:\n" + " leaq str(%rip), %rax\n" + " retq\n" + ".globl scheme_code_size\n" + "scheme_code_size:\n" + " leaq str_size(%rip), %rax\n" + " movq (%rax), %rax\n" + " retq\n" + " .data\n" + "meta:\n" + " .quad 0 # meta_obj.next\n" + " .long 0 # meta_obj.mark\n" + " .long 0 # meta_obj.size\n" + " .long 0 # meta_obj.type_def\n" + "str:\n"; + +char *target_size = "\n" + "str_size :\n" + " .quad "; char *target_postamble = "\n"; #endif @@ -104,12 +103,16 @@ struct options { }; void usage(options_type *opts) { - fprintf(stderr, "Usage: %s [--no-pre] [--no-baselib] [--no-assemble] \n", opts->exe); + fprintf( + stderr, + "Usage: %s [--no-pre] [--no-baselib] [--no-assemble] " + "\n", + opts->exe); exit(-1); } /* A very crude cli options parser */ -void parse_options (int argc, char **argv, options_type *opts) { +void parse_options(int argc, char **argv, options_type *opts) { int i = 1; char *arg = 0; @@ -117,17 +120,17 @@ void parse_options (int argc, char **argv, options_type *opts) { /* check for file argument */ if (argc < 2 || argc > 5) { - usage(opts); + usage(opts); } while (i < argc) { arg = argv[i]; - if (strcmp(arg, "--no-pre") == 0 ) { + if (strcmp(arg, "--no-pre") == 0) { opts->pre_post_amble = false; - } else if(strcmp(arg, "--no-baselib") == 0 ) { + } else if (strcmp(arg, "--no-baselib") == 0) { opts->include_baselib = false; - } else if(strcmp(arg, "--no-assemble") == 0 ) { + } else if (strcmp(arg, "--no-assemble") == 0) { opts->assemble = false; } else { if (!opts->filename) { @@ -141,7 +144,7 @@ void parse_options (int argc, char **argv, options_type *opts) { } if (opts->filename == 0) { - usage(opts); + usage(opts); } } @@ -152,22 +155,25 @@ void writeToFile(options_type *opts, char *asm_str, size_t length) { int err = 0; /* if not output file is given, write directly to output. */ - if(!opts->outfile) { + if (!opts->outfile) { out = stdout; } else { out = fopen(opts->outfile, "w"); } if (!out) { - (void)fprintf(stderr, "Error %i while opening output file '%s'\n", errno, opts->outfile); + (void)fprintf( + stderr, "Error %i while opening output file '%s'\n", errno, opts->outfile); assert(0); } wrote = fwrite(asm_str, 1, length, out); if (wrote != length || (err = ferror(out))) { - (void)fprintf(stderr, - "Error %i while writing to output file '%s' Wrote: %zu Expected to Write: %zu\n", + (void)fprintf( + stderr, + "Error %i while writing to output file '%s' Wrote: %zu " + "Expected to Write: %zu\n", err, opts->outfile, wrote, length); assert(0); } @@ -193,7 +199,7 @@ size_t buildAttachment(gc_type *gc, char *asm_str, char **target) { buffer_write(target_buf, (uint8_t *)target_preamble, strlen(target_preamble)); buffer_write(target_buf, (uint8_t *)line_prefix, strlen(line_prefix)); - for (size_t i = 0; i < length ; i++) { + for (size_t i = 0; i < length; i++) { output_len = snprintf(output, 512, "%i", code_ref[i]); buffer_write(target_buf, (uint8_t *)output, output_len); @@ -227,8 +233,8 @@ size_t buildAttachment(gc_type *gc, char *asm_str, char **target) { return length; } -int main(int argc, char**argv) { - options_type opts = { 0, 0, 0, true, true, true}; +int main(int argc, char **argv) { + options_type opts = {0, 0, 0, true, true, true}; gc_type *gc = gc_create(sizeof(object_type)); size_t length = 0; char *asm_str = 0; @@ -237,7 +243,6 @@ int main(int argc, char**argv) { char realpath_buf[PATH_MAX]; char compiler_home[PATH_MAX]; - /* needed to setup locale aware printf . . . I need to do a great deal more research here */ setlocale(LC_ALL, ""); @@ -272,7 +277,8 @@ int main(int argc, char**argv) { length = buildAttachment(gc, asm_str, &asm_str); } - /* Write the assembled code out to a file *without the null* at the end of the string. */ + /* Write the assembled code out to a file *without the null* at the end of + * the string. */ writeToFile(&opts, asm_str, length - 1); /* Clean up the garabge collector */ diff --git a/src/include/asm.h b/src/include/asm.h index e55d776..2d8d23c 100644 --- a/src/include/asm.h +++ b/src/include/asm.h @@ -1,10 +1,8 @@ #ifndef _ASM_ #define _ASM_ - /* Generate a compiled code ref given a string of insomniac asm */ size_t asm_string(gc_type *gc, char *str, uint8_t **code_ref); - #endif diff --git a/src/include/buffer.h b/src/include/buffer.h index d95f79d..f7c231a 100644 --- a/src/include/buffer.h +++ b/src/include/buffer.h @@ -13,7 +13,7 @@ void buffer_create(gc_type *gc, buffer_type **buf_ret); void buffer_reset(buffer_type *buf); /* write bytes into the buffer */ -void buffer_write(buffer_type *buf, uint8_t * bytes, size_t length); +void buffer_write(buffer_type *buf, uint8_t *bytes, size_t length); /* return the number of bytes in a buffer */ size_t buffer_size(buffer_type *buf); diff --git a/src/include/cell.h b/src/include/cell.h index c02616a..458a5fe 100644 --- a/src/include/cell.h +++ b/src/include/cell.h @@ -58,7 +58,7 @@ typedef struct vector { } vector_type; /* holds a portion of the vm's execution state */ -typedef void * closure_type; +typedef void *closure_type; /* holds a library handle */ typedef struct library { diff --git a/src/include/emit.h b/src/include/emit.h index 3530dd7..4809fd8 100644 --- a/src/include/emit.h +++ b/src/include/emit.h @@ -4,37 +4,37 @@ #include /* Mask off an 8 bit chunk of a number */ -#define BYTE(i,b) ((((uint64_t)0xFF << (b *8)) & i ) >> (b * 8)) - +#define BYTE(i, b) ((((uint64_t)0xFF << (b * 8)) & i) >> (b * 8)) /* EMIT Macros */ -#define EMIT(buf, op, size) { \ - uint8_t code_ref[] = { op }; \ - buffer_write(buf, code_ref, size); \ +#define EMIT(buf, op, size) \ + { \ + uint8_t code_ref[] = {op}; \ + buffer_write(buf, code_ref, size); \ } /* 64bit Literal value */ -#define INT_64(i) BYTE(i,0), BYTE(i,1), BYTE(i,2), BYTE(i,3), \ - BYTE(i,4), BYTE(i,5), BYTE(i,6), BYTE(i,7) +#define INT_64(i) \ + BYTE(i, 0), BYTE(i, 1), BYTE(i, 2), BYTE(i, 3), BYTE(i, 4), BYTE(i, 5), BYTE(i, 6), \ + BYTE(i, 7) #define LIT_FIXNUM(i) OP_LIT_FIXNUM, INT_64(i) -#define LIT_CHAR(i) OP_LIT_CHAR, BYTE(i,0), BYTE(i,1), BYTE(i,2), BYTE(i,3) +#define LIT_CHAR(i) OP_LIT_CHAR, BYTE(i, 0), BYTE(i, 1), BYTE(i, 2), BYTE(i, 3) #define EMIT_LIT_FIXNUM(buf, i) EMIT(buf, LIT_FIXNUM(i), 9) #define EMIT_LIT_CHAR(buf, i) EMIT(buf, LIT_CHAR(i), 5) -#define EMIT_LIT_STRING(buf, str) \ - { \ - vm_int length = strlen(str); \ - EMIT(buf, INT_64(length), 8); \ - buffer_write(buf, (uint8_t *)str, length); \ -} +#define EMIT_LIT_STRING(buf, str) \ + { \ + vm_int length = strlen(str); \ + EMIT(buf, INT_64(length), 8); \ + buffer_write(buf, (uint8_t *)str, length); \ + } /* core of all jump operations */ #define JMP(type, target) type, INT_64(target) -#define EMIT_JMP_BODY(buf, type, target) \ - EMIT(buf, JMP(type, target), 9) +#define EMIT_JMP_BODY(buf, type, target) EMIT(buf, JMP(type, target), 9) #define EMIT_JMP(buf, target) EMIT_JMP_BODY(buf, OP_JMP, target) #define EMIT_JNF(buf, target) EMIT_JMP_BODY(buf, OP_JMP, target) diff --git a/src/include/gc.h b/src/include/gc.h index 12cf63a..e0b7db5 100644 --- a/src/include/gc.h +++ b/src/include/gc.h @@ -1,9 +1,9 @@ #ifndef _GC_ #define _GC_ -#include "cell.h" /* type definitions */ -#include /* for the malloc lines */ +#include "cell.h" /* type definitions */ #include /* for offsetof */ +#include /* for the malloc lines */ /* structure that contains the core of our GC implementation */ typedef void gc_type; diff --git a/src/include/hash.h b/src/include/hash.h index a81b605..a07184e 100644 --- a/src/include/hash.h +++ b/src/include/hash.h @@ -6,11 +6,7 @@ typedef uint32_t hash_type; /* comparison type */ -typedef enum { - GT = 1, - EQ = 0, - LT = -1 -} cmp_type; +typedef enum { GT = 1, EQ = 0, LT = -1 } cmp_type; /* definition of a simple hash table api */ typedef void hashtable_type; @@ -18,36 +14,30 @@ typedef void hashtable_type; /* definition of a hash function */ typedef hash_type (*hash_fn)(void *key); -typedef cmp_type(*hash_cmp)(void *key1, void *key2); +typedef cmp_type (*hash_cmp)(void *key1, void *key2); /* construct a new hash table instance */ -void hash_create(gc_type *gc, hash_fn fn, - hash_cmp cmp, hashtable_type **ret); +void hash_create(gc_type *gc, hash_fn fn, hash_cmp cmp, hashtable_type **ret); /* duplicate an existing hash table in cow mode */ -void hash_cow(gc_type *gc, hashtable_type *src, - hashtable_type **ret); +void hash_cow(gc_type *gc, hashtable_type *src, hashtable_type **ret); /* macro to make string hash tables easier to deal with */ -#define hash_create_string(gc, ret) \ - hash_create(gc, &hash_string, &hash_string_cmp, ret) +#define hash_create_string(gc, ret) hash_create(gc, &hash_string, &hash_string_cmp, ret) /* macro to make string hash tables easier to deal with */ -#define hash_create_pointer(gc, ret) \ +#define hash_create_pointer(gc, ret) \ hash_create(gc, &hash_pointer, &hash_pointer_cmp, ret) /* bind a key and value in the given table */ -void hash_set(hashtable_type *hash, void *key, void* value); +void hash_set(hashtable_type *hash, void *key, void *value); /* remove a given key from the table */ void hash_erase(hashtable_type *hash, void *key); - /* returns true on the key being found in the given hash table */ -uint8_t hash_get(hashtable_type *hash, void *key, - void **value); - +uint8_t hash_get(hashtable_type *hash, void *key, void **value); void hash_info(hashtable_type *hash); diff --git a/src/include/ops.h b/src/include/ops.h index b0e49f5..742aa4b 100644 --- a/src/include/ops.h +++ b/src/include/ops.h @@ -7,15 +7,15 @@ typedef enum op { OP_NOP, /* does nothing */ - OP_LIT_EMPTY, /* Literal empty pair */ + OP_LIT_EMPTY, /* Literal empty pair */ OP_LIT_FIXNUM, /* 64bit Integer Literal */ - OP_LIT_CHAR, /* 32 bit character Literal */ + OP_LIT_CHAR, /* 32 bit character Literal */ OP_LIT_TRUE, /* literals for true and false */ OP_LIT_FALSE, - OP_LIT_STRING, /* Define a string literal */ - OP_LIT_SYMBOL, /* Define a symbol literal */ + OP_LIT_STRING, /* Define a string literal */ + OP_LIT_SYMBOL, /* Define a symbol literal */ OP_MAKE_SYMBOL, /* Take a string and turn it into a symbol */ OP_CONS, /* Cons instruction */ @@ -24,37 +24,38 @@ typedef enum op { OP_SET_CAR, /* set car and cdr */ OP_SET_CDR, - OP_MAKE_VECTOR, /* create an empty vector */ + OP_MAKE_VECTOR, /* create an empty vector */ OP_MAKE_BYTE_VECTOR, /* create an empty byte vector */ - OP_MAKE_RECORD, /* create an empty record */ - OP_INDEX_SET, /* set a column in a given vector */ - OP_INDEX_REF, /* read the index into a vector an put it on the stack */ - OP_VECTOR_LENGTH, /* return the length of a vector */ - OP_SLICE, /* returns a slice of a vector */ + OP_MAKE_RECORD, /* create an empty record */ + OP_INDEX_SET, /* set a column in a given vector */ + OP_INDEX_REF, /* read the index into a vector an put it on the stack */ + OP_VECTOR_LENGTH, /* return the length of a vector */ + OP_SLICE, /* returns a slice of a vector */ /* jump operations Jumps are relative */ - OP_CALL, /* call the given target and leave return on stack */ - OP_ADOPT, /* create a closure for the given target */ - OP_PROC, /* create a closure for the given target */ - OP_JMP, /* just a jump */ - OP_JNF, /* jump if not false */ - OP_RET, /* return to closure on stack */ - OP_JIN, /* jump into coderef of clsure on the stack */ - OP_CALL_IN, /* call to closure on stack */ + OP_CALL, /* call the given target and leave return on stack */ + OP_ADOPT, /* create a closure for the given target */ + OP_PROC, /* create a closure for the given target */ + OP_JMP, /* just a jump */ + OP_JNF, /* jump if not false */ + OP_RET, /* return to closure on stack */ + OP_JIN, /* jump into coderef of clsure on the stack */ + OP_CALL_IN, /* call to closure on stack */ OP_TAIL_CALL_IN, /* call to closure on stack without adding a return. */ OP_CONTINUE, /* an exception handling routine for the current environment */ - OP_RESTORE, /* restore the current exception handler when done handling exceptions */ + OP_RESTORE, /* restore the current exception handler when done handling + exceptions */ OP_BIND, /* bind a value to a symbol */ OP_SET, /* set the value of a symbol */ OP_READ, /* retrieve the value bound to a symbol */ - OP_SWAP, /* Swap the top two items on the stack */ - OP_ROT, /* Rotate the top three items on the stack */ + OP_SWAP, /* Swap the top two items on the stack */ + OP_ROT, /* Rotate the top three items on the stack */ OP_DUP_REF, /* Duplicate the reference on the op of the stack */ - OP_DROP, /* drop the top item on the stack */ - OP_DEPTH, /* current stack depth */ + OP_DROP, /* drop the top item on the stack */ + OP_DEPTH, /* current stack depth */ /* Math functions */ OP_ADD, @@ -71,16 +72,16 @@ typedef enum op { OP_EQ, /* A simple equivalence operation */ - OP_OUTPUT, /* Outputs what ever is currently on the top of the stack */ - OP_FD_READ, /* From a file descriptor */ + OP_OUTPUT, /* Outputs what ever is currently on the top of the stack */ + OP_FD_READ, /* From a file descriptor */ OP_FD_WRITE, /* Write to a file descriptor */ - OP_OPEN, /* Open a file */ - OP_CLOSE, /* Close a file */ + OP_OPEN, /* Open a file */ + OP_CLOSE, /* Close a file */ OP_SLURP, /* load a file into a string */ - OP_ASM, /* assemble the given string */ + OP_ASM, /* assemble the given string */ - OP_IMPORT, /* load a dll */ + OP_IMPORT, /* load a dll */ OP_CALL_EXT, /* call a function exported by the dll */ /* Each of these tests to see if the object on top of the stack is of the @@ -110,5 +111,4 @@ typedef enum op { OP_MAX_INS /* must be the last instruction in list */ } op_type; - #endif diff --git a/src/include/vm.h b/src/include/vm.h index 5df5b9d..8995f77 100644 --- a/src/include/vm.h +++ b/src/include/vm.h @@ -36,30 +36,28 @@ typedef struct binding { /* This is a nightmarish hack to allow an unmanaged pointer to be passed scheme code. */ -#define UNSTUFF_POINTER(pointer, type) \ - *(type*)(pointer->value.byte_vector.vector) - -#define STUFF_POINTER(vm, pointer, type) \ -({ \ - object_type *obj = vm_make_byte_vector(vm, sizeof (type)); \ - type* f = (type*)(obj->value.byte_vector.vector); \ - *f = pointer; \ - obj; \ -}) - - -#define STUFFED_POINTER_OP(fn_name, pointer, type) \ -void fn_name(vm_type *vm, gc_type *gc) { \ - object_type *obj = 0; \ - gc_register_root(gc, (void **)&obj); \ - \ - /* We can ignore this. */ \ - vm_pop(vm); \ - obj = STUFF_POINTER(vm, pointer, type); \ - vm_push(vm, obj); \ - \ - gc_unregister_root(gc, (void **)&obj); \ -} +#define UNSTUFF_POINTER(pointer, type) *(type *)(pointer->value.byte_vector.vector) + +#define STUFF_POINTER(vm, pointer, type) \ + ({ \ + object_type *obj = vm_make_byte_vector(vm, sizeof(type)); \ + type *f = (type *)(obj->value.byte_vector.vector); \ + *f = pointer; \ + obj; \ + }) + +#define STUFFED_POINTER_OP(fn_name, pointer, type) \ + void fn_name(vm_type *vm, gc_type *gc) { \ + object_type *obj = 0; \ + gc_register_root(gc, (void **)&obj); \ + \ + /* We can ignore this. */ \ + vm_pop(vm); \ + obj = STUFF_POINTER(vm, pointer, type); \ + vm_push(vm, obj); \ + \ + gc_unregister_root(gc, (void **)&obj); \ + } #define STUFF_FILE_POINTER(fn_name, pointer) STUFFED_POINTER_OP(fn_name, pointer, FILE *) diff --git a/src/libinsomniac_asm/asm_core.c b/src/libinsomniac_asm/asm_core.c index 66e2b0f..2017cfb 100644 --- a/src/libinsomniac_asm/asm_core.c +++ b/src/libinsomniac_asm/asm_core.c @@ -19,17 +19,17 @@ void asm_lit_char(buffer_type *buf, yyscan_t *scanner) { str = get_text(scanner); c = *str; - if(strcmp(str, "newline")==0) { + if (strcmp(str, "newline") == 0) { c = '\n'; - } else if(strcmp(str, "space")==0) { + } else if (strcmp(str, "space") == 0) { c = ' '; - } else if(strcmp(str, "eof")==0) { + } else if (strcmp(str, "eof") == 0) { c = -1; - } else if(*str=='x' && strlen(str) > 1) { /* Hex encoded charater */ - c = strtoul(str+1, 0, 16); + } else if (*str == 'x' && strlen(str) > 1) { /* Hex encoded charater */ + c = strtoul(str + 1, 0, 16); } EMIT_LIT_CHAR(buf, c); @@ -53,8 +53,8 @@ void asm_lit_string(buffer_type *buf, yyscan_t *scanner) { } /* do we have an empty string? */ - if(token == STRING_END_TOKEN) { - if(empty) { + if (token == STRING_END_TOKEN) { + if (empty) { EMIT_LIT_STRING(buf, ""); } return; @@ -68,16 +68,15 @@ void asm_lit_string(buffer_type *buf, yyscan_t *scanner) { /* Save this label and its location in memory for latter lookup */ -void asm_label(gc_type *gc, buffer_type *buf, - hashtable_type *labels, char *str) { +void asm_label(gc_type *gc, buffer_type *buf, hashtable_type *labels, char *str) { vm_int *addr = 0; char *key = 0; - gc_register_root(gc, (void**)&key); - gc_register_root(gc, (void**)&addr); + gc_register_root(gc, (void **)&key); + gc_register_root(gc, (void **)&addr); /* defensively copy the label name */ - gc_alloc(gc, 0, strlen(str)+1, (void **)&key); + gc_alloc(gc, 0, strlen(str) + 1, (void **)&key); strcpy(key, str); /* save location */ @@ -86,13 +85,11 @@ void asm_label(gc_type *gc, buffer_type *buf, hash_set(labels, key, addr); - gc_unregister_root(gc, (void**)&key); - gc_unregister_root(gc, (void**)&addr); - + gc_unregister_root(gc, (void **)&key); + gc_unregister_root(gc, (void **)&addr); } -void asm_jump(gc_type *gc, buffer_type *buf, - yyscan_t *scanner, jump_type **jump_list) { +void asm_jump(gc_type *gc, buffer_type *buf, yyscan_t *scanner, jump_type **jump_list) { static int init = 0; static gc_type_def jump_def = 0; @@ -100,7 +97,7 @@ void asm_jump(gc_type *gc, buffer_type *buf, char *label = 0; /* TODO: This is a hack */ - if(!init) { + if (!init) { init = 1; jump_def = gc_register_type(gc, sizeof(jump_type)); @@ -121,13 +118,13 @@ void asm_jump(gc_type *gc, buffer_type *buf, jump->lineno = yyasmget_lineno(scanner); /* make sure we have a label */ - if(yyasmlex(scanner) != LABEL_TOKEN) { + if (yyasmlex(scanner) != LABEL_TOKEN) { assert(0); } /* save a copy of the label */ label = get_text(scanner); - gc_alloc(gc, 0, strlen(label)+1, (void **)&(jump->label)); + gc_alloc(gc, 0, strlen(label) + 1, (void **)&(jump->label)); strcpy(jump->label, label); /* put this jump at the head of the @@ -138,22 +135,21 @@ void asm_jump(gc_type *gc, buffer_type *buf, gc_unregister_root(gc, (void **)&jump); /* Make sure we have space to write target */ - EMIT(buf, INT_64(0),8); - + EMIT(buf, INT_64(0), 8); } -void rewrite_jumps(uint8_t *code_ref, jump_type *jump_list, - hashtable_type *labels) { +void rewrite_jumps(uint8_t *code_ref, jump_type *jump_list, hashtable_type *labels) { vm_int target = 0; vm_int *label_addr = 0; - /* rewrite jumps */ - while(jump_list) { - + /* rewrite jumps */ + while (jump_list) { /* look up label */ - if(!hash_get(labels, jump_list->label, (void **)&label_addr)) { - printf("Undefined jump to '%s' @ %" PRIi64 " on line %" PRIi64 "\n", jump_list->label, jump_list->addr, jump_list->lineno); + if (!hash_get(labels, jump_list->label, (void **)&label_addr)) { + printf( + "Undefined jump to '%s' @ %" PRIi64 " on line %" PRIi64 "\n", + jump_list->label, jump_list->addr, jump_list->lineno); assert(0); } @@ -161,18 +157,16 @@ void rewrite_jumps(uint8_t *code_ref, jump_type *jump_list, target = *label_addr - jump_list->addr; target -= 8; /* adjust for addr field */ - /* get bytes, there should be 8 */ - uint8_t addr[] = { INT_64(target)}; + uint8_t addr[] = {INT_64(target)}; /* write bytes into code_ref */ - for(int i=0; i < 8; i++) { + for (int i = 0; i < 8; i++) { code_ref[jump_list->addr + i] = addr[i]; } jump_list = jump_list->next; } - } /* Entry point for the assembler. code_ref is assumed to be attached @@ -185,7 +179,6 @@ size_t asm_string(gc_type *gc, char *str, uint8_t **code_ref) { jump_type *jump_list = 0; size_t length = 0; - gc_register_root(gc, &buf); gc_register_root(gc, &labels); gc_register_root(gc, (void **)&jump_list); @@ -201,57 +194,55 @@ size_t asm_string(gc_type *gc, char *str, uint8_t **code_ref) { yyasm_scan_string(str, scanner); /* match until there is nothing left to match */ - while((token = yyasmlex(scanner)) != END_OF_FILE) { + while ((token = yyasmlex(scanner)) != END_OF_FILE) { /* Handle individual tokens */ - switch((int)token) { - case OP_LIT_FIXNUM: - asm_lit_fixnum(buf, scanner); - break; - - case OP_LIT_CHAR: - asm_lit_char(buf, scanner); - break; - - case STRING_START_TOKEN: - EMIT(buf, OP_LIT_STRING, 1); - asm_lit_string(buf, scanner); - break; - - case SYMBOL_START_TOKEN: - EMIT(buf, OP_LIT_SYMBOL, 1); - asm_lit_string(buf, scanner); - break; - - case OP_JMP: - case OP_JNF: - case OP_CALL: - case OP_PROC: - case OP_CONTINUE: - EMIT(buf, token, 1); /* emit the jump operation */ - asm_jump(gc, buf, scanner, &jump_list); - break; - - case LABEL_TOKEN: - asm_label(gc, buf, labels, get_text(scanner)); - break; - - default: - /* All instructions not defined otherwise, are their token. - But there are things that can be returned as a token, that - are not an instruction. So we have to constrain things to - the correct range. */ - if (token < OP_MAX_INS) { - EMIT(buf, token, 1); - } - break; - + switch ((int)token) { + case OP_LIT_FIXNUM: + asm_lit_fixnum(buf, scanner); + break; + + case OP_LIT_CHAR: + asm_lit_char(buf, scanner); + break; + + case STRING_START_TOKEN: + EMIT(buf, OP_LIT_STRING, 1); + asm_lit_string(buf, scanner); + break; + + case SYMBOL_START_TOKEN: + EMIT(buf, OP_LIT_SYMBOL, 1); + asm_lit_string(buf, scanner); + break; + + case OP_JMP: + case OP_JNF: + case OP_CALL: + case OP_PROC: + case OP_CONTINUE: + EMIT(buf, token, 1); /* emit the jump operation */ + asm_jump(gc, buf, scanner, &jump_list); + break; + + case LABEL_TOKEN: + asm_label(gc, buf, labels, get_text(scanner)); + break; + + default: + /* All instructions not defined otherwise, are their token. + But there are things that can be returned as a token, that + are not an instruction. So we have to constrain things to + the correct range. */ + if (token < OP_MAX_INS) { + EMIT(buf, token, 1); + } + break; } } yyasmlex_destroy(scanner); - /* build a code_ref */ length = buffer_size(buf); gc_alloc(gc, 0, length, (void **)code_ref); diff --git a/src/libinsomniac_asm/asm_internal.h b/src/libinsomniac_asm/asm_internal.h index 5c9dfec..66ce96e 100644 --- a/src/libinsomniac_asm/asm_internal.h +++ b/src/libinsomniac_asm/asm_internal.h @@ -2,17 +2,18 @@ #define _ASM_INTERNAL_ #include -#include -#include + #include +#include +#include /* custom tokens required by asm that are not ops */ -#define END_OF_FILE OP_MAX_INS+1 -#define LABEL_TOKEN OP_MAX_INS+2 +#define END_OF_FILE OP_MAX_INS + 1 +#define LABEL_TOKEN OP_MAX_INS + 2 -#define STRING_START_TOKEN OP_MAX_INS+3 -#define STRING_END_TOKEN OP_MAX_INS+4 -#define SYMBOL_START_TOKEN OP_MAX_INS+5 +#define STRING_START_TOKEN OP_MAX_INS + 3 +#define STRING_END_TOKEN OP_MAX_INS + 4 +#define SYMBOL_START_TOKEN OP_MAX_INS + 5 typedef struct jump jump_type; @@ -26,8 +27,6 @@ struct jump { }; /* return text of the matched string */ -char * get_text(void *scanner); - - +char *get_text(void *scanner); #endif diff --git a/src/libinsomniac_bootstrap/bootstrap_core.c b/src/libinsomniac_bootstrap/bootstrap_core.c index 104a539..42033c9 100644 --- a/src/libinsomniac_bootstrap/bootstrap_core.c +++ b/src/libinsomniac_bootstrap/bootstrap_core.c @@ -1,328 +1,337 @@ #include "bootstrap_internal.h" + #include "scheme.h" + #include "lexer.h" #include #include -#include #include +#include #include /* Add an include path to the include stack */ void push_include_path(compiler_core_type *compiler, char *file_name) { - compiler->include_depth++; + compiler->include_depth++; - gc_alloc(compiler->gc, 0, strlen(file_name) + 1, - (void **)&(compiler->include_stack[compiler->include_depth])); + gc_alloc( + compiler->gc, 0, strlen(file_name) + 1, + (void **)&(compiler->include_stack[compiler->include_depth])); - strcpy(compiler->include_stack[compiler->include_depth], file_name); + strcpy(compiler->include_stack[compiler->include_depth], file_name); } /* Pop the current include path off the stack */ void pop_include_path(compiler_core_type *compiler) { - /* null out this path so it can be garbage collected */ - if (compiler->include_depth >= 0) { - compiler->include_stack[compiler->include_depth] = 0; - } + /* null out this path so it can be garbage collected */ + if (compiler->include_depth >= 0) { + compiler->include_stack[compiler->include_depth] = 0; + } - compiler->include_depth--; + compiler->include_depth--; } /* Make a label */ void gen_label(compiler_core_type *compiler, buffer_type **buf) { - char c[22]; - int written = 0; + char c[22]; + int written = 0; - buffer_create(compiler->gc, buf); - buffer_write(*buf, (uint8_t *)"_label_", 7); + buffer_create(compiler->gc, buf); + buffer_write(*buf, (uint8_t *)"_label_", 7); - /* Add an incrementing suffix to the label */ - written = snprintf(c, 22, "%"PRIi64, compiler->label_index); - buffer_write(*buf, (uint8_t *)c, written); + /* Add an incrementing suffix to the label */ + written = snprintf(c, 22, "%" PRIi64, compiler->label_index); + buffer_write(*buf, (uint8_t *)c, written); - compiler->label_index++; + compiler->label_index++; } /* Setup gc types */ /* Instruction Stream type setup */ gc_type_def register_stream_type(gc_type *gc) { - gc_type_def type = 0; + gc_type_def type = 0; - type = gc_register_type(gc, sizeof(ins_stream_type)); - /* we only need to register the head */ - gc_register_pointer(gc, type, offsetof(ins_stream_type, head)); + type = gc_register_type(gc, sizeof(ins_stream_type)); + /* we only need to register the head */ + gc_register_pointer(gc, type, offsetof(ins_stream_type, head)); - return type; + return type; } /* Setup a literal node */ gc_type_def register_node_literal_type(gc_type *gc) { - gc_type_def type = 0; + gc_type_def type = 0; - type = gc_register_type(gc, sizeof(ins_node_type)); - gc_register_pointer(gc, type, offsetof(ins_node_type, next)); - gc_register_pointer(gc, type, offsetof(ins_node_type, value) + - offsetof(node_value_type, literal)); + type = gc_register_type(gc, sizeof(ins_node_type)); + gc_register_pointer(gc, type, offsetof(ins_node_type, next)); + gc_register_pointer( + gc, type, offsetof(ins_node_type, value) + offsetof(node_value_type, literal)); - /* Add other fields here */ + /* Add other fields here */ - return type; + return type; } /* setup an single instruction stream node */ gc_type_def register_node_single_type(gc_type *gc) { - gc_type_def type = 0; + gc_type_def type = 0; - type = gc_register_type(gc, sizeof(ins_node_type)); - gc_register_pointer(gc, type, offsetof(ins_node_type, next)); - gc_register_pointer(gc, type, offsetof(ins_node_type, value) + - offsetof(node_value_type, stream)); + type = gc_register_type(gc, sizeof(ins_node_type)); + gc_register_pointer(gc, type, offsetof(ins_node_type, next)); + gc_register_pointer( + gc, type, offsetof(ins_node_type, value) + offsetof(node_value_type, stream)); - return type; + return type; } /* setup an two instruction stream node */ gc_type_def register_node_double_type(gc_type *gc) { - gc_type_def type = 0; + gc_type_def type = 0; - type = gc_register_type(gc, sizeof(ins_node_type)); - gc_register_pointer(gc, type, offsetof(ins_node_type, next)); + type = gc_register_type(gc, sizeof(ins_node_type)); + gc_register_pointer(gc, type, offsetof(ins_node_type, next)); - gc_register_pointer(gc, type, offsetof(ins_node_type, value) + - offsetof(node_value_type, two) + offsetof(two_stream_type, stream1)); - gc_register_pointer(gc, type, offsetof(ins_node_type, value) + - offsetof(node_value_type, two) + offsetof(two_stream_type, stream2)); + gc_register_pointer( + gc, type, + offsetof(ins_node_type, value) + offsetof(node_value_type, two) + + offsetof(two_stream_type, stream1)); + gc_register_pointer( + gc, type, + offsetof(ins_node_type, value) + offsetof(node_value_type, two) + + offsetof(two_stream_type, stream2)); - return type; + return type; } /* Compiler core type */ gc_type_def register_compiler_type(gc_type *gc) { - gc_type_def type = 0; + gc_type_def type = 0; - type = gc_register_type(gc, sizeof(compiler_core_type)); - gc_register_pointer(gc, type, offsetof(compiler_core_type, stream)); - gc_register_pointer(gc, type, offsetof(compiler_core_type, include_stack)); + type = gc_register_type(gc, sizeof(compiler_core_type)); + gc_register_pointer(gc, type, offsetof(compiler_core_type, stream)); + gc_register_pointer(gc, type, offsetof(compiler_core_type, include_stack)); - return type; + return type; } /* Setup Include */ /* Pushes a new file into the lexer's input stream while preserving * the existing stream. */ -void setup_include(compiler_core_type* compiler, ins_stream_type *arg) { - - FILE *include_file = 0; - char *file_name = 0; - char new_include_path_buf[PATH_MAX]; - char *new_include_path = 0; - char new_file_name[PATH_MAX]; - char raw_file_name[PATH_MAX]; - size_t length = 0; - - /* Get the file name for this node */ - file_name = arg->head->value.literal; - - /* Unless the file starts with a / look for it in the current include directory */ - if (file_name[0] == '/' || compiler->include_depth < 0) { - include_file = fopen(file_name, "r"); - } else { - - /* setup include path */ - strcpy(new_include_path_buf, compiler->include_stack[compiler->include_depth]); - new_include_path = dirname(new_include_path_buf); - - /* add 1 for null and 1 for / */ - length = strlen(new_include_path) + strlen(file_name) + 2; - - if (length > PATH_MAX) { - (void)fprintf(stderr, "Error %i! Including '%s' - Search path too long: %zi characters\n", - errno, file_name, length); - parse_error(compiler, compiler->scanner, "Unable to open include file!"); - assert(0); +void setup_include(compiler_core_type *compiler, ins_stream_type *arg) { + + FILE *include_file = 0; + char *file_name = 0; + char new_include_path_buf[PATH_MAX]; + char *new_include_path = 0; + char new_file_name[PATH_MAX]; + char raw_file_name[PATH_MAX]; + size_t length = 0; + + /* Get the file name for this node */ + file_name = arg->head->value.literal; + + /* Unless the file starts with a / look for it in the current include + * directory */ + if (file_name[0] == '/' || compiler->include_depth < 0) { + include_file = fopen(file_name, "r"); + } else { + + /* setup include path */ + strcpy(new_include_path_buf, compiler->include_stack[compiler->include_depth]); + new_include_path = dirname(new_include_path_buf); + + /* add 1 for null and 1 for / */ + length = strlen(new_include_path) + strlen(file_name) + 2; + + if (length > PATH_MAX) { + (void)fprintf( + stderr, + "Error %i! Including '%s' - Search path too long: %zi " + "characters\n", + errno, file_name, length); + parse_error(compiler, compiler->scanner, "Unable to open include file!"); + assert(0); + } + + /* Assmeble the new filename */ + strcpy(raw_file_name, new_include_path); + strcat(raw_file_name, "/"); + strcat(raw_file_name, file_name); + + /* Resolve the path so it makes sense later */ + file_name = realpath(raw_file_name, new_file_name); + + include_file = fopen(file_name, "r"); } - /* Assmeble the new filename */ - strcpy(raw_file_name, new_include_path); - strcat(raw_file_name, "/"); - strcat(raw_file_name, file_name); + if (!include_file) { + /* TODO: Add file name tracking to compiler so we can + report what file include failed in. */ - /* Resolve the path so it makes sense later */ - file_name = realpath(raw_file_name, new_file_name); - - include_file = fopen(file_name, "r"); - } - - if ( !include_file ) { - /* TODO: Add file name tracking to compiler so we can - report what file include failed in. */ - - (void)fprintf(stderr, "Error %i! Including '%s'\n", errno, raw_file_name); - parse_error(compiler, compiler->scanner, "Unable to open include file!'"); - } else { - parse_push_state(compiler, include_file); - push_include_path(compiler, file_name); - } + (void)fprintf(stderr, "Error %i! Including '%s'\n", errno, raw_file_name); + parse_error(compiler, compiler->scanner, "Unable to open include file!'"); + } else { + parse_push_state(compiler, include_file); + push_include_path(compiler, file_name); + } } /* Create an instance of the compiler */ void compiler_create(gc_type *gc, compiler_type **comp_void, char *compiler_home) { - compiler_core_type *compiler = 0; - static gc_type_def stream_gc_type = 0; - static gc_type_def node_literal_gc_type = 0; - static gc_type_def node_single_gc_type = 0; - static gc_type_def node_double_gc_type = 0; - static gc_type_def compiler_gc_type = 0; - - /* setup gc types */ - if (!compiler_gc_type) { - compiler_gc_type = register_compiler_type(gc); - stream_gc_type = register_stream_type(gc); - node_literal_gc_type = register_node_literal_type(gc); - node_single_gc_type = register_node_single_type(gc); - node_double_gc_type = register_node_double_type(gc); - } - - gc_register_root(gc, (void **)&compiler); - - /* create a compiler instance */ - gc_alloc_type(gc, 0, compiler_gc_type, (void **)&compiler); - - compiler->gc = gc; - compiler->label_index = 0; - /*compiler->preamble = "lib/preamble.asm"; - compiler->postamble = "lib/postamble.asm";*/ - strcpy(compiler->home, compiler_home); - - /* setup gc types */ - compiler->stream_gc_type = stream_gc_type; - - compiler->node_types[STREAM_LITERAL] = node_literal_gc_type; - compiler->node_types[STREAM_SYMBOL] = node_literal_gc_type; - compiler->node_types[STREAM_STRING] = node_literal_gc_type; - compiler->node_types[STREAM_OP] = node_literal_gc_type; - - compiler->node_types[STREAM_QUOTED] = node_single_gc_type; - compiler->node_types[STREAM_LOAD] = node_single_gc_type; - compiler->node_types[STREAM_ASM] = node_single_gc_type; - compiler->node_types[STREAM_ASM_STREAM] = node_single_gc_type; - compiler->node_types[STREAM_COND] = node_single_gc_type; - compiler->node_types[STREAM_AND] = node_single_gc_type; - compiler->node_types[STREAM_OR] = node_single_gc_type; - compiler->node_types[STREAM_RECORD_TYPE] = node_single_gc_type; - - compiler->node_types[STREAM_BIND] = node_double_gc_type; - compiler->node_types[STREAM_STORE] = node_double_gc_type; - - compiler->node_types[STREAM_LET_STAR] = node_double_gc_type; - - compiler->node_types[STREAM_TWO_ARG] = node_double_gc_type; - compiler->node_types[STREAM_IF] = node_double_gc_type; - compiler->node_types[STREAM_MATH] = node_double_gc_type; - - compiler->node_types[STREAM_LAMBDA] = node_double_gc_type; - compiler->node_types[STREAM_CALL] = node_double_gc_type; - - *comp_void = compiler; - - /* Add a stream route to the compiler object */ - stream_create(compiler, &(compiler->stream)); - - /* Add the include stack array */ - /* TODO: Look at statically allocating this */ - compiler->include_depth = -1; - gc_alloc_pointer_array(gc, 0, MAX_INCLUDE_DEPTH, (void **)&(compiler->include_stack)); - - gc_unregister_root(gc, (void **)&compiler); + compiler_core_type *compiler = 0; + static gc_type_def stream_gc_type = 0; + static gc_type_def node_literal_gc_type = 0; + static gc_type_def node_single_gc_type = 0; + static gc_type_def node_double_gc_type = 0; + static gc_type_def compiler_gc_type = 0; + + /* setup gc types */ + if (!compiler_gc_type) { + compiler_gc_type = register_compiler_type(gc); + stream_gc_type = register_stream_type(gc); + node_literal_gc_type = register_node_literal_type(gc); + node_single_gc_type = register_node_single_type(gc); + node_double_gc_type = register_node_double_type(gc); + } + + gc_register_root(gc, (void **)&compiler); + + /* create a compiler instance */ + gc_alloc_type(gc, 0, compiler_gc_type, (void **)&compiler); + + compiler->gc = gc; + compiler->label_index = 0; + /*compiler->preamble = "lib/preamble.asm"; + compiler->postamble = "lib/postamble.asm";*/ + strcpy(compiler->home, compiler_home); + + /* setup gc types */ + compiler->stream_gc_type = stream_gc_type; + + compiler->node_types[STREAM_LITERAL] = node_literal_gc_type; + compiler->node_types[STREAM_SYMBOL] = node_literal_gc_type; + compiler->node_types[STREAM_STRING] = node_literal_gc_type; + compiler->node_types[STREAM_OP] = node_literal_gc_type; + + compiler->node_types[STREAM_QUOTED] = node_single_gc_type; + compiler->node_types[STREAM_LOAD] = node_single_gc_type; + compiler->node_types[STREAM_ASM] = node_single_gc_type; + compiler->node_types[STREAM_ASM_STREAM] = node_single_gc_type; + compiler->node_types[STREAM_COND] = node_single_gc_type; + compiler->node_types[STREAM_AND] = node_single_gc_type; + compiler->node_types[STREAM_OR] = node_single_gc_type; + compiler->node_types[STREAM_RECORD_TYPE] = node_single_gc_type; + + compiler->node_types[STREAM_BIND] = node_double_gc_type; + compiler->node_types[STREAM_STORE] = node_double_gc_type; + + compiler->node_types[STREAM_LET_STAR] = node_double_gc_type; + + compiler->node_types[STREAM_TWO_ARG] = node_double_gc_type; + compiler->node_types[STREAM_IF] = node_double_gc_type; + compiler->node_types[STREAM_MATH] = node_double_gc_type; + + compiler->node_types[STREAM_LAMBDA] = node_double_gc_type; + compiler->node_types[STREAM_CALL] = node_double_gc_type; + + *comp_void = compiler; + + /* Add a stream route to the compiler object */ + stream_create(compiler, &(compiler->stream)); + + /* Add the include stack array */ + /* TODO: Look at statically allocating this */ + compiler->include_depth = -1; + gc_alloc_pointer_array(gc, 0, MAX_INCLUDE_DEPTH, (void **)&(compiler->include_stack)); + + gc_unregister_root(gc, (void **)&compiler); } /* Compile a string */ void compile_string(compiler_type *comp_void, char *str, bool include_baselib) { - compiler_core_type *compiler = (compiler_core_type *)comp_void; - ins_stream_type *baselib = 0; /* TODO: should be gc root */ - char path[PATH_MAX]; + compiler_core_type *compiler = (compiler_core_type *)comp_void; + ins_stream_type *baselib = 0; /* TODO: should be gc root */ + char path[PATH_MAX]; - /* Actually parse the input stream. */ - yylex_init_extra(compiler, &(compiler->scanner)); - yy_scan_string(str, compiler->scanner); + /* Actually parse the input stream. */ + yylex_init_extra(compiler, &(compiler->scanner)); + yy_scan_string(str, compiler->scanner); - /* TODO: Need a better way to handle GC than leaking */ - gc_protect(compiler->gc); + /* TODO: Need a better way to handle GC than leaking */ + gc_protect(compiler->gc); - /* Inject include for base library */ - if (include_baselib) { - strcpy(path, compiler->home); - strcat(path, "/lib/baselib.scm"); + /* Inject include for base library */ + if (include_baselib) { + strcpy(path, compiler->home); + strcat(path, "/lib/baselib.scm"); - STREAM_NEW(baselib, string, path); - setup_include(compiler, baselib); - } + STREAM_NEW(baselib, string, path); + setup_include(compiler, baselib); + } - parse_internal(compiler, compiler->scanner); + parse_internal(compiler, compiler->scanner); - gc_unprotect(compiler->gc); + gc_unprotect(compiler->gc); - yylex_destroy(compiler->scanner); + yylex_destroy(compiler->scanner); } /* Compile a file */ void compile_file(compiler_type *comp_void, char *file_name, bool include_baselib) { - compiler_core_type *compiler = (compiler_core_type *)comp_void; - ins_stream_type *baselib = 0; /* TODO: should be gc root */ - FILE *in = 0; - char path[PATH_MAX]; - - /* Actually parse the input stream. */ - yylex_init_extra(compiler, &(compiler->scanner)); - - in = fopen(file_name, "r"); - if (!in) { - (void)fprintf(stderr, "Error %i while attempting to open '%s'\n", - errno, file_name); - assert(0); - } + compiler_core_type *compiler = (compiler_core_type *)comp_void; + ins_stream_type *baselib = 0; /* TODO: should be gc root */ + FILE *in = 0; + char path[PATH_MAX]; + + /* Actually parse the input stream. */ + yylex_init_extra(compiler, &(compiler->scanner)); + + in = fopen(file_name, "r"); + if (!in) { + (void)fprintf( + stderr, "Error %i while attempting to open '%s'\n", errno, file_name); + assert(0); + } - yy_switch_to_buffer( - yy_create_buffer(in, YY_BUF_SIZE, compiler->scanner), compiler->scanner); + yy_switch_to_buffer( + yy_create_buffer(in, YY_BUF_SIZE, compiler->scanner), compiler->scanner); - push_include_path(compiler, file_name); + push_include_path(compiler, file_name); - /* TODO: Need a better way to handle GC than leaking */ - gc_protect(compiler->gc); + /* TODO: Need a better way to handle GC than leaking */ + gc_protect(compiler->gc); - /* Inject include for base library */ - if (include_baselib) { - strcpy(path, compiler->home); - strcat(path, "/lib/baselib.scm"); + /* Inject include for base library */ + if (include_baselib) { + strcpy(path, compiler->home); + strcat(path, "/lib/baselib.scm"); - STREAM_NEW(baselib, string, path); - setup_include(compiler, baselib); - } + STREAM_NEW(baselib, string, path); + setup_include(compiler, baselib); + } - parse_internal(compiler, compiler->scanner); + parse_internal(compiler, compiler->scanner); - gc_unprotect(compiler->gc); + gc_unprotect(compiler->gc); - yylex_destroy(compiler->scanner); + yylex_destroy(compiler->scanner); } /* Convert an instruction stream into assembly */ -void compiler_code_gen(compiler_type *comp_void, buffer_type * buf, - bool bootstrap) { +void compiler_code_gen(compiler_type *comp_void, buffer_type *buf, bool bootstrap) { - compiler_core_type *compiler = (compiler_core_type *)comp_void; + compiler_core_type *compiler = (compiler_core_type *)comp_void; - /* Walk the instruction stream and output it to our buffer */ - emit_stream(compiler, buf, compiler->stream, false); + /* Walk the instruction stream and output it to our buffer */ + emit_stream(compiler, buf, compiler->stream, false); - /* Add appropriate bootstraping code */ - if (bootstrap) { - /* TODO: Split bootstrap up into pre and post amble functions */ - emit_bootstrap(compiler, buf); - } + /* Add appropriate bootstraping code */ + if (bootstrap) { + /* TODO: Split bootstrap up into pre and post amble functions */ + emit_bootstrap(compiler, buf); + } } - diff --git a/src/libinsomniac_bootstrap/bootstrap_emit.c b/src/libinsomniac_bootstrap/bootstrap_emit.c index 6b96d75..d786c32 100644 --- a/src/libinsomniac_bootstrap/bootstrap_emit.c +++ b/src/libinsomniac_bootstrap/bootstrap_emit.c @@ -1,9 +1,11 @@ #include "bootstrap_internal.h" + #include "scheme.h" + #include "lexer.h" -#include #include +#include /* Emit a generic operations */ void emit_op(buffer_type *buf, char *str) { @@ -17,9 +19,9 @@ void emit_op(buffer_type *buf, char *str) { /* Emit a label */ void emit_label(buffer_type *buf, buffer_type *label) { - buffer_append(buf, label, -1); - buffer_write(buf, (uint8_t *) ":", 1); - emit_newline(buf); + buffer_append(buf, label, -1); + buffer_write(buf, (uint8_t *)":", 1); + emit_newline(buf); } /* Emit a jmp/call/proc/jnf instruction */ @@ -27,658 +29,660 @@ void emit_jump_label(buffer_type *buf, op_type type, buffer_type *label) { char *c = 0; switch (type) { - case OP_CALL: - c = "call"; - break; + case OP_CALL: + c = "call"; + break; - case OP_PROC: - c = "proc"; - break; + case OP_PROC: + c = "proc"; + break; - case OP_JMP: - c = "jmp"; - break; + case OP_JMP: + c = "jmp"; + break; - case OP_JNF: - c = "jnf"; - break; + case OP_JNF: + c = "jnf"; + break; - default: - fprintf(stderr, "op_type not a known jump instruction %i", type); - assert(0); + default: + fprintf(stderr, "op_type not a known jump instruction %i", type); + assert(0); } /* Output the jmp */ emit_indent(buf); - buffer_write(buf, (uint8_t*)c, strlen(c)); - buffer_write(buf, (uint8_t*)" ", 1); + buffer_write(buf, (uint8_t *)c, strlen(c)); + buffer_write(buf, (uint8_t *)" ", 1); buffer_append(buf, label, -1); emit_newline(buf); } /* Emit a cond expression */ -void emit_cond(compiler_core_type *compiler, buffer_type *buf, - ins_node_type *node, bool allow_tail_call) { +void emit_cond( + compiler_core_type *compiler, buffer_type *buf, ins_node_type *node, + bool allow_tail_call) { - buffer_type *next_label = 0; - buffer_type *done_label = 0; + buffer_type *next_label = 0; + buffer_type *done_label = 0; - ins_node_type *clause = 0; + ins_node_type *clause = 0; - gc_register_root(compiler->gc, &next_label); - gc_register_root(compiler->gc, &done_label); + gc_register_root(compiler->gc, &next_label); + gc_register_root(compiler->gc, &done_label); - gen_label(compiler, &done_label); + gen_label(compiler, &done_label); - emit_comment(buf, "--Cond Start--"); + emit_comment(buf, "--Cond Start--"); - clause = node->value.stream->head; + clause = node->value.stream->head; - while (clause) { - node = clause->value.stream->head; + while (clause) { + node = clause->value.stream->head; - emit_comment(buf, "----Cond Clause----"); + emit_comment(buf, "----Cond Clause----"); - /* Emit the test */ - emit_stream(compiler, buf, node->value.two.stream1, false); + /* Emit the test */ + emit_stream(compiler, buf, node->value.two.stream1, false); - emit_op(buf, "not"); - gen_label(compiler, &next_label); - emit_jump_label(buf, OP_JNF, next_label); + emit_op(buf, "not"); + gen_label(compiler, &next_label); + emit_jump_label(buf, OP_JNF, next_label); - /* Emit the body */ - emit_stream(compiler, buf, node->value.two.stream2, allow_tail_call); + /* Emit the body */ + emit_stream(compiler, buf, node->value.two.stream2, allow_tail_call); - /* Emit jump to end */ - emit_jump_label(buf, OP_JMP, done_label); + /* Emit jump to end */ + emit_jump_label(buf, OP_JMP, done_label); - emit_label(buf, next_label); + emit_label(buf, next_label); - clause = clause->next; - } + clause = clause->next; + } - emit_comment(buf, "--Cond Fall-Through--"); + emit_comment(buf, "--Cond Fall-Through--"); - /* In the event no case matches, follow our defined stack discipline */ - emit_op(buf, "()"); + /* In the event no case matches, follow our defined stack discipline */ + emit_op(buf, "()"); - emit_label(buf, done_label); - emit_comment(buf, "--Cond End--"); + emit_label(buf, done_label); + emit_comment(buf, "--Cond End--"); - gc_unregister_root(compiler->gc, &next_label); - gc_unregister_root(compiler->gc, &done_label); + gc_unregister_root(compiler->gc, &next_label); + gc_unregister_root(compiler->gc, &done_label); } /* Emit an If */ -void emit_if(compiler_core_type *compiler, buffer_type *buf, - ins_node_type *node, bool allow_tail_call) { +void emit_if( + compiler_core_type *compiler, buffer_type *buf, ins_node_type *node, + bool allow_tail_call) { - buffer_type *true_label = 0; - buffer_type *done_label = 0; + buffer_type *true_label = 0; + buffer_type *done_label = 0; - ins_node_type *body = node->value.two.stream2->head; /* If body streams */ + ins_node_type *body = node->value.two.stream2->head; /* If body streams */ - gc_register_root(compiler->gc, &true_label); - gc_register_root(compiler->gc, &done_label); + gc_register_root(compiler->gc, &true_label); + gc_register_root(compiler->gc, &done_label); - gen_label(compiler, &true_label); - gen_label(compiler, &done_label); + gen_label(compiler, &true_label); + gen_label(compiler, &done_label); - emit_comment(buf, "--If Start--"); - emit_stream(compiler, buf, node->value.two.stream1, false); - - emit_jump_label(buf, OP_JNF, true_label); + emit_comment(buf, "--If Start--"); + emit_stream(compiler, buf, node->value.two.stream1, false); - /* */ - emit_stream(compiler, buf, body->value.two.stream2, allow_tail_call); + emit_jump_label(buf, OP_JNF, true_label); - /* jmp done */ - emit_jump_label(buf, OP_JMP, done_label); + /* */ + emit_stream(compiler, buf, body->value.two.stream2, allow_tail_call); - /* true: */ - emit_comment(buf, "--If true--"); - emit_label(buf, true_label); + /* jmp done */ + emit_jump_label(buf, OP_JMP, done_label); - /* */ - emit_stream(compiler, buf, body->value.two.stream1, allow_tail_call); + /* true: */ + emit_comment(buf, "--If true--"); + emit_label(buf, true_label); - /* done: */ - emit_comment(buf, "--If Done--"); + /* */ + emit_stream(compiler, buf, body->value.two.stream1, allow_tail_call); - /* emit label */ - emit_label(buf, done_label); + /* done: */ + emit_comment(buf, "--If Done--"); - emit_comment(buf, "--If End--"); + /* emit label */ + emit_label(buf, done_label); + emit_comment(buf, "--If End--"); - gc_unregister_root(compiler->gc, &done_label); - gc_unregister_root(compiler->gc, &true_label); + gc_unregister_root(compiler->gc, &done_label); + gc_unregister_root(compiler->gc, &true_label); } /* Handle and(true)/or(false) */ -void emit_bool(compiler_core_type *compiler, buffer_type *buf, - ins_node_type *tree, bool allow_tail_call, bool and_or) { +void emit_bool( + compiler_core_type *compiler, buffer_type *buf, ins_node_type *tree, + bool allow_tail_call, bool and_or) { - ins_node_type *exp = 0; - bool pushed = false; - bool no_args = true; + ins_node_type *exp = 0; + bool pushed = false; + bool no_args = true; - buffer_type *done_label = 0; - buffer_type *next_label = 0; + buffer_type *done_label = 0; + buffer_type *next_label = 0; - gc_register_root(compiler->gc, &done_label); - gc_register_root(compiler->gc, &next_label); + gc_register_root(compiler->gc, &done_label); + gc_register_root(compiler->gc, &next_label); - gen_label(compiler, &done_label); + gen_label(compiler, &done_label); - /* a null stream is possible */ - if (tree && tree->value.stream) { - exp = tree->value.stream->head; - } + /* a null stream is possible */ + if (tree && tree->value.stream) { + exp = tree->value.stream->head; + } - emit_comment(buf, "--Bool Operator Start--"); + emit_comment(buf, "--Bool Operator Start--"); - while(exp) { - no_args = false; + while (exp) { + no_args = false; - /* Tail calls cannot be allowed here */ - pushed = emit_node(compiler, buf, exp, false); + /* Tail calls cannot be allowed here */ + pushed = emit_node(compiler, buf, exp, false); - exp = exp->next; + exp = exp->next; - /* TODO: Look at optimizing this out */ - if (!pushed) { - emit_op(buf, "()"); - } + /* TODO: Look at optimizing this out */ + if (!pushed) { + emit_op(buf, "()"); + } - if (exp) { - emit_op(buf, "dup"); + if (exp) { + emit_op(buf, "dup"); - if (and_or) { - /* and case */ - gen_label(compiler, &next_label); + if (and_or) { + /* and case */ + gen_label(compiler, &next_label); - emit_jump_label(buf, OP_JNF, next_label); - emit_jump_label(buf, OP_JMP, done_label); + emit_jump_label(buf, OP_JNF, next_label); + emit_jump_label(buf, OP_JMP, done_label); - emit_label(buf, next_label); - } else { - /* or case */ - emit_jump_label(buf, OP_JNF, done_label); - } + emit_label(buf, next_label); + } else { + /* or case */ + emit_jump_label(buf, OP_JNF, done_label); + } - /* ignore intermediate results */ - emit_op(buf, "drop"); + /* ignore intermediate results */ + emit_op(buf, "drop"); + } } - } - /* If there were no arguments, treat this as a literal - * #t or #f */ - if (no_args) { - if (and_or) { - emit_op(buf, "#t"); - } else { - emit_op(buf, "#f"); + /* If there were no arguments, treat this as a literal + * #t or #f */ + if (no_args) { + if (and_or) { + emit_op(buf, "#t"); + } else { + emit_op(buf, "#f"); + } } - } - emit_label(buf, done_label); + emit_label(buf, done_label); - emit_comment(buf, "--Bool Operator End--"); + emit_comment(buf, "--Bool Operator End--"); - gc_unregister_root(compiler->gc, &done_label); - gc_unregister_root(compiler->gc, &next_label); + gc_unregister_root(compiler->gc, &done_label); + gc_unregister_root(compiler->gc, &next_label); } /* Emit framing code for a lambda */ -void emit_lambda(compiler_core_type *compiler, buffer_type *buf, - ins_node_type *node) { +void emit_lambda(compiler_core_type *compiler, buffer_type *buf, ins_node_type *node) { - ins_stream_type *formals = 0; /* Part of the tree, so don't need to watch it. */ - ins_node_type *formal_node = 0; - bool bind_rest = false; + ins_stream_type *formals = 0; /* Part of the tree, so don't need to watch it. */ + ins_node_type *formal_node = 0; + bool bind_rest = false; - buffer_type *proc_label = 0; - buffer_type *skip_label = 0; + buffer_type *proc_label = 0; + buffer_type *skip_label = 0; - gc_register_root(compiler->gc, &proc_label); - gc_register_root(compiler->gc, &skip_label); + gc_register_root(compiler->gc, &proc_label); + gc_register_root(compiler->gc, &skip_label); - gen_label(compiler, &proc_label); - gen_label(compiler, &skip_label); + gen_label(compiler, &proc_label); + gen_label(compiler, &skip_label); - /* calling convention is ( args ret -- ) */ + /* calling convention is ( args ret -- ) */ - /* jmp skip_label */ - emit_jump_label(buf, OP_JMP, skip_label); + /* jmp skip_label */ + emit_jump_label(buf, OP_JMP, skip_label); - /* proc_label: */ - emit_label(buf, proc_label); + /* proc_label: */ + emit_label(buf, proc_label); - /* swap -- flip args and return */ - emit_op(buf, "swap"); + /* swap -- flip args and return */ + emit_op(buf, "swap"); - /* output formal binding code */ - emit_comment(buf, "-- Formals --"); - formals = node->value.two.stream1; + /* output formal binding code */ + emit_comment(buf, "-- Formals --"); + formals = node->value.two.stream1; - /* If there are no formals, drop the arguments */ - formal_node = formals->head; + /* If there are no formals, drop the arguments */ + formal_node = formals->head; - /* Loop until we're at the end of the list we're looking at a () */ - while (formal_node && formal_node->type != STREAM_LITERAL) { + /* Loop until we're at the end of the list we're looking at a () */ + while (formal_node && formal_node->type != STREAM_LITERAL) { - /* If we see the end of the list here, we're binding anything left in the - arguments list to this symbol. */ - bind_rest = (formal_node && formal_node->next == 0); + /* If we see the end of the list here, we're binding anything left in + the arguments list to this symbol. */ + bind_rest = (formal_node && formal_node->next == 0); - emit_comment(buf, "----"); + emit_comment(buf, "----"); - if (bind_rest) { - /* If we have a single node, bind everything to it. */ - if (formal_node->next) { - emit_op(buf, "cdr"); - } - } else { - emit_op(buf, "dup"); - emit_op(buf, "car"); - } + if (bind_rest) { + /* If we have a single node, bind everything to it. */ + if (formal_node->next) { + emit_op(buf, "cdr"); + } + } else { + emit_op(buf, "dup"); + emit_op(buf, "car"); + } - emit_literal(buf, formal_node); + emit_literal(buf, formal_node); - emit_op(buf, "bind"); + emit_op(buf, "bind"); - formal_node = formal_node->next; + formal_node = formal_node->next; - /* If we're at the last node or binding the rest, don't cdr */ - if (!bind_rest && formal_node && formal_node->type != STREAM_LITERAL) { - emit_op(buf, "cdr"); + /* If we're at the last node or binding the rest, don't cdr */ + if (!bind_rest && formal_node && formal_node->type != STREAM_LITERAL) { + emit_op(buf, "cdr"); + } } - } - /* Drop the () at the end of the arguments list */ - emit_comment(buf, "----"); - if (!bind_rest) { - emit_op(buf, "drop"); - } + /* Drop the () at the end of the arguments list */ + emit_comment(buf, "----"); + if (!bind_rest) { + emit_op(buf, "drop"); + } - /* output body */ - emit_comment(buf, "-- Body --"); - emit_stream(compiler, buf, node->value.two.stream2, true); + /* output body */ + emit_comment(buf, "-- Body --"); + emit_stream(compiler, buf, node->value.two.stream2, true); - /* swap ret */ - /* TODO Add a check for tail call to avoid garbage instructions in the - stream */ - emit_op(buf, "swap ret"); + /* swap ret */ + /* TODO Add a check for tail call to avoid garbage instructions in the + stream */ + emit_op(buf, "swap ret"); - /* skip_label: */ - emit_label(buf, skip_label); + /* skip_label: */ + emit_label(buf, skip_label); - /* proc proc_label: */ - emit_jump_label(buf, OP_PROC, proc_label); + /* proc proc_label: */ + emit_jump_label(buf, OP_PROC, proc_label); - gc_unregister_root(compiler->gc, &skip_label); - gc_unregister_root(compiler->gc, &proc_label); + gc_unregister_root(compiler->gc, &skip_label); + gc_unregister_root(compiler->gc, &proc_label); } /* Emit framing code for a let*. */ -void emit_let_star(compiler_core_type *compiler, buffer_type *buf, - ins_node_type *node, bool allow_tail_call) { +void emit_let_star( + compiler_core_type *compiler, buffer_type *buf, ins_node_type *node, + bool allow_tail_call) { - buffer_type *body_label = 0; - buffer_type *next_label = 0; + buffer_type *body_label = 0; + buffer_type *next_label = 0; - gc_register_root(compiler->gc, &body_label); - gc_register_root(compiler->gc, &next_label); + gc_register_root(compiler->gc, &body_label); + gc_register_root(compiler->gc, &next_label); - gen_label(compiler, &body_label); - gen_label(compiler, &next_label); + gen_label(compiler, &body_label); + gen_label(compiler, &next_label); - emit_comment(buf, "-- Let* --"); + emit_comment(buf, "-- Let* --"); - /* Call the label for the let body. */ - if (allow_tail_call) { - emit_op(buf, "()"); - emit_jump_label(buf, OP_PROC, body_label); - emit_op(buf, "tail_call_in"); - } else { - emit_jump_label(buf, OP_CALL, body_label); - emit_jump_label(buf, OP_JMP, next_label); - } + /* Call the label for the let body. */ + if (allow_tail_call) { + emit_op(buf, "()"); + emit_jump_label(buf, OP_PROC, body_label); + emit_op(buf, "tail_call_in"); + } else { + emit_jump_label(buf, OP_CALL, body_label); + emit_jump_label(buf, OP_JMP, next_label); + } - emit_label(buf, body_label); + emit_label(buf, body_label); - /* tail_call_in requires args, but let* doesn't so we need to drop them. */ - if (allow_tail_call) { - emit_op(buf, "swap drop"); - } + /* tail_call_in requires args, but let* doesn't so we need to drop them. */ + if (allow_tail_call) { + emit_op(buf, "swap drop"); + } - emit_comment(buf, "-- Binding List--"); - emit_stream(compiler, buf, node->value.two.stream1, false); - emit_op(buf, "drop"); /* Inefficient, but works */ - emit_comment(buf, "-- Binding List End--"); + emit_comment(buf, "-- Binding List--"); + emit_stream(compiler, buf, node->value.two.stream1, false); + emit_op(buf, "drop"); /* Inefficient, but works */ + emit_comment(buf, "-- Binding List End--"); - emit_comment(buf, "-- Let* Body--"); - emit_stream(compiler, buf, node->value.two.stream2, allow_tail_call); - emit_comment(buf, "-- Let* Body End--"); + emit_comment(buf, "-- Let* Body--"); + emit_stream(compiler, buf, node->value.two.stream2, allow_tail_call); + emit_comment(buf, "-- Let* Body End--"); - emit_op(buf, "swap ret"); + emit_op(buf, "swap ret"); - emit_label(buf, next_label); + emit_label(buf, next_label); - emit_comment(buf, "-- Let* End --"); + emit_comment(buf, "-- Let* End --"); - gc_unregister_root(compiler->gc, &next_label); - gc_unregister_root(compiler->gc, &body_label); + gc_unregister_root(compiler->gc, &next_label); + gc_unregister_root(compiler->gc, &body_label); } /* Build a function call */ -void emit_call(compiler_core_type *compiler, buffer_type *buf, - ins_node_type *call, bool tail_call) { - ins_node_type *head = 0; - bool pushed = false; +void emit_call( + compiler_core_type *compiler, buffer_type *buf, ins_node_type *call, bool tail_call) { + ins_node_type *head = 0; + bool pushed = false; - emit_comment(buf, "--Call Start--"); + emit_comment(buf, "--Call Start--"); - /* Arugments are always a list */ - emit_op(buf, "()"); + /* Arugments are always a list */ + emit_op(buf, "()"); - /* Walk arguments and evaluate them */ - head = call->value.two.stream2->head; - while (head) { - pushed = emit_node(compiler, buf, head, false); + /* Walk arguments and evaluate them */ + head = call->value.two.stream2->head; + while (head) { + pushed = emit_node(compiler, buf, head, false); - /* Always take a slot */ - if (!pushed) { - emit_op(buf, "()"); - } + /* Always take a slot */ + if (!pushed) { + emit_op(buf, "()"); + } - emit_op(buf, "cons"); - head = head->next; - } - - emit_stream(compiler, buf, call->value.two.stream1, false); + emit_op(buf, "cons"); + head = head->next; + } - /* Rely on a vm level hack to make tail calls work */ - if (tail_call) { - emit_op(buf, "tail_call_in"); - } else { - emit_op(buf, "call_in"); - } + emit_stream(compiler, buf, call->value.two.stream1, false); - emit_comment(buf, "--Call End--"); + /* Rely on a vm level hack to make tail calls work */ + if (tail_call) { + emit_op(buf, "tail_call_in"); + } else { + emit_op(buf, "call_in"); + } + emit_comment(buf, "--Call End--"); } /* Given a literal instrcution node, output it to our buffer */ void emit_literal(buffer_type *buf, ins_node_type *ins) { - emit_op(buf, ins->value.literal); + emit_op(buf, ins->value.literal); } /* Output a string to the asm buffer */ void emit_string(buffer_type *buf, ins_node_type *ins) { - char *quote = "\""; + char *quote = "\""; - emit_indent(buf); - buffer_write(buf, (uint8_t*)quote, 1); - buffer_write(buf, (uint8_t*)ins->value.literal, strlen(ins->value.literal)); - buffer_write(buf, (uint8_t*)quote, 1); - emit_newline(buf); + emit_indent(buf); + buffer_write(buf, (uint8_t *)quote, 1); + buffer_write(buf, (uint8_t *)ins->value.literal, strlen(ins->value.literal)); + buffer_write(buf, (uint8_t *)quote, 1); + emit_newline(buf); } /* Emit a quoted structure */ void emit_quoted(buffer_type *buf, ins_stream_type *tree) { - ins_node_type *head = tree->head; - bool is_list = false; + ins_node_type *head = tree->head; + bool is_list = false; - emit_comment(buf, "--Quoted Start--"); + emit_comment(buf, "--Quoted Start--"); - /* Loop through all the nodes in the quoted object */ - while (head) { - switch (head->type) { - case STREAM_QUOTED: - emit_quoted(buf, head->value.stream); - break; - - case STREAM_LITERAL: - case STREAM_SYMBOL: - emit_literal(buf, head); - break; - - case STREAM_STRING: - emit_string(buf, head); - break; - - default: - fprintf(stderr, "Unknown instructions type %i in stream!\n", head->type); - break; - } + /* Loop through all the nodes in the quoted object */ + while (head) { + switch (head->type) { + case STREAM_QUOTED: + emit_quoted(buf, head->value.stream); + break; - if (is_list) { - emit_op(buf, "cons"); - } + case STREAM_LITERAL: + case STREAM_SYMBOL: + emit_literal(buf, head); + break; + + case STREAM_STRING: + emit_string(buf, head); + break; + + default: + fprintf(stderr, "Unknown instructions type %i in stream!\n", head->type); + break; + } - head = head->next; + if (is_list) { + emit_op(buf, "cons"); + } - /* If we get to a second iteration, then we have a quoted list */ - is_list = true; - } - emit_comment(buf, "--Quoted End--"); + head = head->next; + + /* If we get to a second iteration, then we have a quoted list */ + is_list = true; + } + emit_comment(buf, "--Quoted End--"); } /* Emit a record type definition call */ -void emit_record_type(compiler_core_type *compiler, buffer_type *buf, ins_stream_type *def) { +void emit_record_type( + compiler_core_type *compiler, buffer_type *buf, ins_stream_type *def) { - buffer_type *loop_label = 0; - buffer_type *done_label = 0; + buffer_type *loop_label = 0; + buffer_type *done_label = 0; - gc_register_root(compiler->gc, &loop_label); - gc_register_root(compiler->gc, &done_label); + gc_register_root(compiler->gc, &loop_label); + gc_register_root(compiler->gc, &done_label); - emit_comment(buf, "--Record Start--"); + emit_comment(buf, "--Record Start--"); - /* output arguments list the same as quoted */ - emit_quoted(buf, def); + /* output arguments list the same as quoted */ + emit_quoted(buf, def); - /* output call to record-type-factory */ - emit_op(buf, "s\"record-type-factory\""); - emit_op(buf, "@"); - emit_op(buf, "call_in"); /* Assumed that this cannot be a tail call */ + /* output call to record-type-factory */ + emit_op(buf, "s\"record-type-factory\""); + emit_op(buf, "@"); + emit_op(buf, "call_in"); /* Assumed that this cannot be a tail call */ - /* build binding code */ - emit_comment(buf, "--Record Binding--"); + /* build binding code */ + emit_comment(buf, "--Record Binding--"); - gen_label(compiler, &loop_label); - gen_label(compiler, &done_label); + gen_label(compiler, &loop_label); + gen_label(compiler, &done_label); - emit_label(buf, loop_label); + emit_label(buf, loop_label); - /* do binding test */ - emit_op(buf, "dup"); - emit_op(buf, "null?"); + /* do binding test */ + emit_op(buf, "dup"); + emit_op(buf, "null?"); - emit_jump_label(buf, OP_JNF, done_label); + emit_jump_label(buf, OP_JNF, done_label); - emit_op(buf, "dup"); + emit_op(buf, "dup"); - /* pull pair of the form ( sym . value ) */ - emit_op(buf, "car"); + /* pull pair of the form ( sym . value ) */ + emit_op(buf, "car"); - /* extract symbol and value and bind the two */ - emit_op(buf, "dup"); - emit_op(buf, "cdr"); - emit_op(buf, "swap"); - emit_op(buf, "car"); - emit_op(buf, "bind"); + /* extract symbol and value and bind the two */ + emit_op(buf, "dup"); + emit_op(buf, "cdr"); + emit_op(buf, "swap"); + emit_op(buf, "car"); + emit_op(buf, "bind"); - /* next entry in list */ - emit_op(buf, "cdr"); - emit_jump_label(buf, OP_JMP, loop_label); + /* next entry in list */ + emit_op(buf, "cdr"); + emit_jump_label(buf, OP_JMP, loop_label); - emit_label(buf, done_label); - emit_comment(buf, "--Record End--"); + emit_label(buf, done_label); + emit_comment(buf, "--Record End--"); - gc_unregister_root(compiler->gc, &done_label); - gc_unregister_root(compiler->gc, &loop_label); + gc_unregister_root(compiler->gc, &done_label); + gc_unregister_root(compiler->gc, &loop_label); } /* Emit a single stream structure */ void emit_asm(compiler_core_type *compiler, buffer_type *buf, ins_stream_type *tree) { - ins_node_type *head = tree->head; - - emit_comment(buf, "--Raw ASM Start--"); - - /* Loop through all the nodes in the single object */ - while (head) { - switch (head->type) { - case STREAM_ASM_STREAM: - emit_comment(buf, "----Escape ASM Start----"); - emit_stream(compiler, buf, head->value.stream, false); - emit_comment(buf, "----Escape ASM End----"); - break; - - default: - emit_literal(buf, head); - break; + ins_node_type *head = tree->head; + + emit_comment(buf, "--Raw ASM Start--"); + + /* Loop through all the nodes in the single object */ + while (head) { + switch (head->type) { + case STREAM_ASM_STREAM: + emit_comment(buf, "----Escape ASM Start----"); + emit_stream(compiler, buf, head->value.stream, false); + emit_comment(buf, "----Escape ASM End----"); + break; + + default: + emit_literal(buf, head); + break; + } + head = head->next; } - head = head->next; - } - emit_comment(buf, "--Raw ASM End--"); + emit_comment(buf, "--Raw ASM End--"); } /* Output dual instruction stream ops */ -void emit_double(compiler_core_type *compiler, buffer_type *buf, - ins_node_type *node, char *op) { +void emit_double( + compiler_core_type *compiler, buffer_type *buf, ins_node_type *node, char *op) { - emit_stream(compiler, buf, node->value.two.stream1, false); - emit_stream(compiler, buf, node->value.two.stream2, false); - emit_op(buf, op); + emit_stream(compiler, buf, node->value.two.stream1, false); + emit_stream(compiler, buf, node->value.two.stream2, false); + emit_op(buf, op); } /* Decide how to output an expressione element */ -bool emit_node(compiler_core_type *compiler, buffer_type *buf, - ins_node_type *head, bool allow_tail_call) { - bool pushed = false; - - /* Process each instruction in the stream */ - switch (head->type) { - case STREAM_LITERAL: - case STREAM_SYMBOL: - case STREAM_OP: /* ASM should be on it's own */ - emit_literal(buf, head); - pushed = true; - break; - - case STREAM_STRING: - emit_string(buf, head); - pushed = true; - break; - - case STREAM_QUOTED: - emit_quoted(buf, head->value.stream); - pushed = true; - break; - - case STREAM_RECORD_TYPE: - emit_record_type(compiler, buf, head->value.stream); - pushed = true; - break; - - case STREAM_ASM: - emit_asm(compiler, buf, head->value.stream); - pushed = true; - break; - - case STREAM_LOAD: - /* Simple load form symbol operation */ - emit_stream(compiler, buf, head->value.stream, false); - emit_op(buf, "@"); - pushed = true; - break; - - case STREAM_COND: - emit_cond(compiler, buf, head, allow_tail_call); - pushed = true; - break; - - case STREAM_IF: - emit_if(compiler, buf, head, allow_tail_call); - pushed = true; - break; - - case STREAM_AND: - emit_bool(compiler, buf, head, allow_tail_call, true); - pushed = true; - break; - - case STREAM_OR: - emit_bool(compiler, buf, head, allow_tail_call, false); - pushed = true; - break; - - case STREAM_MATH: - emit_double(compiler, buf, - head->value.two.stream2->head, - head->value.two.stream1->head->value.literal); - pushed = true; - break; - - case STREAM_LAMBDA: - emit_lambda(compiler, buf, head); - pushed = true; - break; - - case STREAM_CALL: - emit_call(compiler, buf, head, allow_tail_call && !head->next); - pushed = true; - break; - - case STREAM_BIND: - emit_double(compiler, buf, head, "bind"); - break; - - case STREAM_STORE: - emit_double(compiler, buf, head, "!"); - break; - - case STREAM_LET_STAR: - emit_let_star(compiler, buf, head, allow_tail_call); - pushed = true; - break; - - default: - fprintf(stderr, "Unknown instructions type %i in stream!\n", head->type); - break; - } - - return pushed; -} +bool emit_node( + compiler_core_type *compiler, buffer_type *buf, ins_node_type *head, + bool allow_tail_call) { + bool pushed = false; -/* Walk an instruction stream and write it to the buffer in 'pretty' form */ -void emit_stream(compiler_core_type *compiler, buffer_type *buf, - ins_stream_type *tree, bool allow_tail_call) { - ins_node_type *head = 0; - bool pushed = false; + /* Process each instruction in the stream */ + switch (head->type) { + case STREAM_LITERAL: + case STREAM_SYMBOL: + case STREAM_OP: /* ASM should be on it's own */ + emit_literal(buf, head); + pushed = true; + break; + + case STREAM_STRING: + emit_string(buf, head); + pushed = true; + break; + + case STREAM_QUOTED: + emit_quoted(buf, head->value.stream); + pushed = true; + break; + + case STREAM_RECORD_TYPE: + emit_record_type(compiler, buf, head->value.stream); + pushed = true; + break; + + case STREAM_ASM: + emit_asm(compiler, buf, head->value.stream); + pushed = true; + break; + + case STREAM_LOAD: + /* Simple load form symbol operation */ + emit_stream(compiler, buf, head->value.stream, false); + emit_op(buf, "@"); + pushed = true; + break; + + case STREAM_COND: + emit_cond(compiler, buf, head, allow_tail_call); + pushed = true; + break; + + case STREAM_IF: + emit_if(compiler, buf, head, allow_tail_call); + pushed = true; + break; + + case STREAM_AND: + emit_bool(compiler, buf, head, allow_tail_call, true); + pushed = true; + break; + + case STREAM_OR: + emit_bool(compiler, buf, head, allow_tail_call, false); + pushed = true; + break; + + case STREAM_MATH: + emit_double( + compiler, buf, head->value.two.stream2->head, + head->value.two.stream1->head->value.literal); + pushed = true; + break; + + case STREAM_LAMBDA: + emit_lambda(compiler, buf, head); + pushed = true; + break; + + case STREAM_CALL: + emit_call(compiler, buf, head, allow_tail_call && !head->next); + pushed = true; + break; + + case STREAM_BIND: + emit_double(compiler, buf, head, "bind"); + break; + + case STREAM_STORE: + emit_double(compiler, buf, head, "!"); + break; + + case STREAM_LET_STAR: + emit_let_star(compiler, buf, head, allow_tail_call); + pushed = true; + break; + + default: + fprintf(stderr, "Unknown instructions type %i in stream!\n", head->type); + break; + } + return pushed; +} - if (tree) { - head = tree->head; - } +/* Walk an instruction stream and write it to the buffer in 'pretty' form */ +void emit_stream( + compiler_core_type *compiler, buffer_type *buf, ins_stream_type *tree, + bool allow_tail_call) { + ins_node_type *head = 0; + bool pushed = false; + + if (tree) { + head = tree->head; + } - while (head) { - /* Set to true if the node pushes to the stack */ - pushed = emit_node(compiler, buf, head, allow_tail_call && !(head->next)); + while (head) { + /* Set to true if the node pushes to the stack */ + pushed = emit_node(compiler, buf, head, allow_tail_call && !(head->next)); - head = head->next; + head = head->next; - /* We treat a stream like a begin block, only the - last node can leave something on the stack. */ - if (head && pushed) { - emit_op(buf, "drop"); + /* We treat a stream like a begin block, only the + last node can leave something on the stack. */ + if (head && pushed) { + emit_op(buf, "drop"); + } } - } - if (!pushed) { - emit_op(buf, "()"); - } + if (!pushed) { + emit_op(buf, "()"); + } } - diff --git a/src/libinsomniac_bootstrap/bootstrap_emit_formatting.c b/src/libinsomniac_bootstrap/bootstrap_emit_formatting.c index c10b0ae..0bb8fe0 100644 --- a/src/libinsomniac_bootstrap/bootstrap_emit_formatting.c +++ b/src/libinsomniac_bootstrap/bootstrap_emit_formatting.c @@ -20,6 +20,3 @@ void emit_comment(buffer_type *buf, char *str) { buffer_write(buf, (uint8_t *)str, strlen(str)); emit_newline(buf); } - - - diff --git a/src/libinsomniac_bootstrap/bootstrap_internal.h b/src/libinsomniac_bootstrap/bootstrap_internal.h index 2f2ddf1..1abc364 100644 --- a/src/libinsomniac_bootstrap/bootstrap_internal.h +++ b/src/libinsomniac_bootstrap/bootstrap_internal.h @@ -2,11 +2,12 @@ #define _BOOTSTRAP_INTERNAL #include -#include + #include +#include +#include #include #include -#include /* Define the maximum include depth that we will support */ #define MAX_INCLUDE_DEPTH 64 @@ -80,7 +81,6 @@ struct ins_stream { ins_node_type *tail; }; - struct compiler_core { gc_type *gc; @@ -103,31 +103,36 @@ struct compiler_core { void emit_bootstrap(compiler_core_type *compiler, buffer_type *buf); -bool emit_node(compiler_core_type *compiler, buffer_type *buf, - ins_node_type *head, bool allow_tail_call); -void emit_stream(compiler_core_type *compiler, buffer_type *buf, - ins_stream_type *tree, bool allow_tail_call); +bool emit_node( + compiler_core_type *compiler, buffer_type *buf, ins_node_type *head, + bool allow_tail_call); +void emit_stream( + compiler_core_type *compiler, buffer_type *buf, ins_stream_type *tree, + bool allow_tail_call); void emit_literal(buffer_type *buf, ins_node_type *ins); void emit_string(buffer_type *buf, ins_node_type *ins); void emit_quoted(buffer_type *buf, ins_stream_type *tree); -void emit_asm(compiler_core_type *compiler, buffer_type *buf, - ins_stream_type *tree); -void emit_double(compiler_core_type *compiler, buffer_type *buf, - ins_node_type *node, char *op); +void emit_asm(compiler_core_type *compiler, buffer_type *buf, ins_stream_type *tree); +void emit_double( + compiler_core_type *compiler, buffer_type *buf, ins_node_type *node, char *op); -void emit_cond(compiler_core_type *compiler, buffer_type *buf, - ins_node_type *tree, bool allow_tail_call); -void emit_if(compiler_core_type *compiler, buffer_type *buf, - ins_node_type *tree, bool allow_tail_call); +void emit_cond( + compiler_core_type *compiler, buffer_type *buf, ins_node_type *tree, + bool allow_tail_call); +void emit_if( + compiler_core_type *compiler, buffer_type *buf, ins_node_type *tree, + bool allow_tail_call); -void emit_let_star(compiler_core_type *compiler, buffer_type *output, - ins_node_type *node, bool allow_tail_call); +void emit_let_star( + compiler_core_type *compiler, buffer_type *output, ins_node_type *node, + bool allow_tail_call); -void emit_bool(compiler_core_type *compiler, buffer_type *buf, - ins_node_type *tree, bool allow_tail_call, bool and_or); +void emit_bool( + compiler_core_type *compiler, buffer_type *buf, ins_node_type *tree, + bool allow_tail_call, bool and_or); void emit_newline(buffer_type *buf); void emit_indent(buffer_type *buf); @@ -137,16 +142,15 @@ void emit_label(buffer_type *buf, buffer_type *label); void emit_op(buffer_type *buf, char *str); void emit_jump_label(buffer_type *buf, op_type type, buffer_type *label); -void emit_lambda(compiler_core_type *compiler, buffer_type *output, - ins_node_type *node); -void emit_call(compiler_core_type *compiler, buffer_type *buf, - ins_node_type *call, bool tail_call); -void emit_record_type(compiler_core_type *compiler, buffer_type *buf, - ins_stream_type *def); +void emit_lambda(compiler_core_type *compiler, buffer_type *output, ins_node_type *node); +void emit_call( + compiler_core_type *compiler, buffer_type *buf, ins_node_type *call, bool tail_call); +void emit_record_type( + compiler_core_type *compiler, buffer_type *buf, ins_stream_type *def); void gen_label(compiler_core_type *compiler, buffer_type **buf); -void setup_include(compiler_core_type* compiler, ins_stream_type *arg); +void setup_include(compiler_core_type *compiler, ins_stream_type *arg); /* Instruction Stream builder routines */ void stream_create(compiler_core_type *compiler, ins_stream_type **stream); @@ -154,16 +158,17 @@ void stream_create(compiler_core_type *compiler, ins_stream_type **stream); void stream_concat(ins_stream_type *stream, ins_stream_type *source); void stream_append(ins_stream_type *stream, ins_node_type *node); -void stream_alloc_node(compiler_core_type *compiler, node_type type, - ins_node_type **node); +void stream_alloc_node( + compiler_core_type *compiler, node_type type, ins_node_type **node); -#define BUILD_SINGLE_SIGNATURE(name) \ -void stream_##name(compiler_core_type *compiler, ins_stream_type *stream, \ - ins_stream_type *arg1) +#define BUILD_SINGLE_SIGNATURE(name) \ + void stream_##name( \ + compiler_core_type *compiler, ins_stream_type *stream, ins_stream_type *arg1) -#define BUILD_DOUBLE_SIGNATURE(name) \ -void stream_##name(compiler_core_type *compiler, ins_stream_type *stream, \ - ins_stream_type *arg1, ins_stream_type *arg2) +#define BUILD_DOUBLE_SIGNATURE(name) \ + void stream_##name( \ + compiler_core_type *compiler, ins_stream_type *stream, ins_stream_type *arg1, \ + ins_stream_type *arg2) /* Nodes that hold a stream of instructions */ BUILD_SINGLE_SIGNATURE(asm); @@ -192,26 +197,20 @@ BUILD_DOUBLE_SIGNATURE(lambda); BUILD_DOUBLE_SIGNATURE(call); /* Special Literals */ -void stream_boolean(compiler_core_type *compiler, - ins_stream_type *stream, int b); -void stream_char(compiler_core_type *compiler, - ins_stream_type *stream, char *str); +void stream_boolean(compiler_core_type *compiler, ins_stream_type *stream, int b); +void stream_char(compiler_core_type *compiler, ins_stream_type *stream, char *str); -void stream_symbol(compiler_core_type *compiler, - ins_stream_type *stream, char *str); +void stream_symbol(compiler_core_type *compiler, ins_stream_type *stream, char *str); /* These are identical to bare */ -void stream_bare(compiler_core_type *compiler, - ins_stream_type *stream, node_type type, char *str); +void stream_bare( + compiler_core_type *compiler, ins_stream_type *stream, node_type type, char *str); -#define stream_string(comp, stream, num) \ - stream_bare(comp, stream, STREAM_STRING, num) +#define stream_string(comp, stream, num) stream_bare(comp, stream, STREAM_STRING, num) -#define stream_literal(comp, stream, num) \ - stream_bare(comp, stream, STREAM_LITERAL, num) +#define stream_literal(comp, stream, num) stream_bare(comp, stream, STREAM_LITERAL, num) -#define stream_op(comp, stream, num) \ - stream_bare(comp, stream, STREAM_OP, num) +#define stream_op(comp, stream, num) stream_bare(comp, stream, STREAM_OP, num) /* Scheme parser */ int parse_internal(compiler_core_type *compiler, void *scanner); @@ -224,10 +223,10 @@ void pop_include_path(compiler_core_type *compiler); /* Define some macros to make the parser code easier */ #define NEW_STREAM(var) stream_create(compiler, &var) -#define STREAM(var, type, ...) \ - stream_##type(compiler, var, __VA_ARGS__) +#define STREAM(var, type, ...) stream_##type(compiler, var, __VA_ARGS__) -#define STREAM_NEW(var, type, ...) NEW_STREAM(var); \ - STREAM(var, type, __VA_ARGS__); +#define STREAM_NEW(var, type, ...) \ + NEW_STREAM(var); \ + STREAM(var, type, __VA_ARGS__); #endif diff --git a/src/libinsomniac_bootstrap/bootstrap_preamble.c b/src/libinsomniac_bootstrap/bootstrap_preamble.c index 2dcb19d..c2c057a 100644 --- a/src/libinsomniac_bootstrap/bootstrap_preamble.c +++ b/src/libinsomniac_bootstrap/bootstrap_preamble.c @@ -4,46 +4,44 @@ /* Emit preamble code needed to boot strap the scheme system */ void emit_bootstrap(compiler_core_type *compiler, buffer_type *out_buf) { - gc_type *gc = compiler->gc; - size_t count = 0; - buffer_type *buf = 0; - char path[PATH_MAX]; + gc_type *gc = compiler->gc; + size_t count = 0; + buffer_type *buf = 0; + char path[PATH_MAX]; - gc_register_root(gc, (void **)&buf); + gc_register_root(gc, (void **)&buf); - buffer_create(gc, &buf); + buffer_create(gc, &buf); + /* load the preamble code into our buffer */ + strcpy(path, compiler->home); + strcat(path, "/lib/preamble.asm"); + count = buffer_load(buf, path); - /* load the preamble code into our buffer */ - strcpy(path, compiler->home); - strcat(path, "/lib/preamble.asm"); - count = buffer_load(buf, path); + /* Make sure the preamble actually loaded */ + if (count == -1) { + fprintf(stderr, "Error loading preamble! %s", path); + exit(-3); + } - /* Make sure the preamble actually loaded */ - if (count == -1) { - fprintf(stderr, "Error loading preamble! %s", path); - exit(-3); - } + /* append the compiled compiled code to the temp buffer */ + buffer_append(buf, out_buf, -1); - /* append the compiled compiled code to the temp buffer */ - buffer_append(buf, out_buf, -1); + /* load the post amble */ + strcpy(path, compiler->home); + strcat(path, "/lib/postamble.asm"); + count = buffer_load(buf, path); - /* load the post amble */ - strcpy(path, compiler->home); - strcat(path, "/lib/postamble.asm"); - count = buffer_load(buf, path); + if (count == -1) { + fprintf(stderr, "Error loading postamble! %s", path); + exit(-4); + } - if (count == -1) { - fprintf(stderr, "Error loading postamble! %s", path); - exit(-4); - } + /* replace the compiler buffer with the new one */ + /* out_buf = buf; */ + buffer_reset(out_buf); - /* replace the compiler buffer with the new one */ - /* out_buf = buf; */ - buffer_reset(out_buf); + buffer_append(out_buf, buf, -1); - buffer_append(out_buf, buf, -1); - - gc_unregister_root(gc, (void **)&buf); + gc_unregister_root(gc, (void **)&buf); } - diff --git a/src/libinsomniac_bootstrap/bootstrap_stream.c b/src/libinsomniac_bootstrap/bootstrap_stream.c index 5b73baa..04b225b 100644 --- a/src/libinsomniac_bootstrap/bootstrap_stream.c +++ b/src/libinsomniac_bootstrap/bootstrap_stream.c @@ -3,11 +3,11 @@ #include /* Allocate a new instruction node */ -void stream_alloc_node(compiler_core_type *compiler, node_type type, - ins_node_type **node) { +void stream_alloc_node( + compiler_core_type *compiler, node_type type, ins_node_type **node) { - gc_alloc_type(compiler->gc, 0, compiler->node_types[type], (void **)node); - (*node)->type = type; + gc_alloc_type(compiler->gc, 0, compiler->node_types[type], (void **)node); + (*node)->type = type; } /* add source to the end of stream */ @@ -50,5 +50,3 @@ void stream_append(ins_stream_type *stream, ins_node_type *node) { void stream_create(compiler_core_type *compiler, ins_stream_type **stream) { gc_alloc_type(compiler->gc, 0, compiler->stream_gc_type, (void **)stream); } - - diff --git a/src/libinsomniac_bootstrap/bootstrap_stream_nodes.c b/src/libinsomniac_bootstrap/bootstrap_stream_nodes.c index 83a2552..115192b 100644 --- a/src/libinsomniac_bootstrap/bootstrap_stream_nodes.c +++ b/src/libinsomniac_bootstrap/bootstrap_stream_nodes.c @@ -1,42 +1,42 @@ #include "bootstrap_internal.h" -#include #include +#include -#define BUILD_SINGLE_STREAM(name, type) \ -BUILD_SINGLE_SIGNATURE(name) { \ - \ - ins_node_type *ins_node = 0; \ - \ - gc_register_root(compiler->gc, (void **)&ins_node); \ - \ - stream_alloc_node(compiler, type, &ins_node); \ - \ - ins_node->value.stream = arg1; \ - \ - /* add the boolean to our instruction stream */ \ - stream_append(stream, ins_node); \ - \ - gc_unregister_root(compiler->gc, (void **)&ins_node); \ -} +#define BUILD_SINGLE_STREAM(name, type) \ + BUILD_SINGLE_SIGNATURE(name) { \ + \ + ins_node_type *ins_node = 0; \ + \ + gc_register_root(compiler->gc, (void **)&ins_node); \ + \ + stream_alloc_node(compiler, type, &ins_node); \ + \ + ins_node->value.stream = arg1; \ + \ + /* add the boolean to our instruction stream */ \ + stream_append(stream, ins_node); \ + \ + gc_unregister_root(compiler->gc, (void **)&ins_node); \ + } -#define BUILD_DOUBLE_STREAM(name, type) \ -BUILD_DOUBLE_SIGNATURE(name) { \ - \ - ins_node_type *ins_node = 0; \ - \ - gc_register_root(compiler->gc, (void **)&ins_node); \ - \ - stream_alloc_node(compiler, type, &ins_node); \ - \ - ins_node->value.two.stream1 = arg1; \ - ins_node->value.two.stream2 = arg2; \ - \ - /* add the boolean to our instruction stream */ \ - stream_append(stream, ins_node); \ - \ - gc_unregister_root(compiler->gc, (void **)&ins_node); \ -} +#define BUILD_DOUBLE_STREAM(name, type) \ + BUILD_DOUBLE_SIGNATURE(name) { \ + \ + ins_node_type *ins_node = 0; \ + \ + gc_register_root(compiler->gc, (void **)&ins_node); \ + \ + stream_alloc_node(compiler, type, &ins_node); \ + \ + ins_node->value.two.stream1 = arg1; \ + ins_node->value.two.stream2 = arg2; \ + \ + /* add the boolean to our instruction stream */ \ + stream_append(stream, ins_node); \ + \ + gc_unregister_root(compiler->gc, (void **)&ins_node); \ + } /* Single stream nodes */ BUILD_SINGLE_STREAM(quoted, STREAM_QUOTED) @@ -63,12 +63,11 @@ BUILD_SINGLE_STREAM(or, STREAM_OR) BUILD_DOUBLE_STREAM(lambda, STREAM_LAMBDA) BUILD_DOUBLE_STREAM(call, STREAM_CALL) - /* TODO: These can probably be re-written as a macro */ /* Build a bare asm instruction/literal */ -void stream_bare(compiler_core_type *compiler, ins_stream_type *stream, - node_type type, char *lit) { +void stream_bare( + compiler_core_type *compiler, ins_stream_type *stream, node_type type, char *lit) { ins_node_type *ins_node = 0; size_t length = 0; @@ -79,8 +78,7 @@ void stream_bare(compiler_core_type *compiler, ins_stream_type *stream, /* generate the literal string */ length = strlen(lit) + 1; - gc_alloc(compiler->gc, 0, length, - (void **) &(ins_node->value.literal)); + gc_alloc(compiler->gc, 0, length, (void **)&(ins_node->value.literal)); strncpy(ins_node->value.literal, lit, length); @@ -91,8 +89,7 @@ void stream_bare(compiler_core_type *compiler, ins_stream_type *stream, } /* Build a boolean literal */ -void stream_boolean(compiler_core_type *compiler, - ins_stream_type *stream, int b) { +void stream_boolean(compiler_core_type *compiler, ins_stream_type *stream, int b) { char c = 't'; ins_node_type *ins_node = 0; @@ -100,14 +97,14 @@ void stream_boolean(compiler_core_type *compiler, gc_register_root(compiler->gc, (void **)&ins_node); /* if b is false, c should be f */ - if(!b) { + if (!b) { c = 'f'; } stream_alloc_node(compiler, STREAM_LITERAL, &ins_node); /* generate the literal string */ - gc_alloc(compiler->gc, 0, 4, (void **) &(ins_node->value.literal)); + gc_alloc(compiler->gc, 0, 4, (void **)&(ins_node->value.literal)); snprintf(ins_node->value.literal, 4, "#%c", c); /* add the boolean to our instruction stream */ @@ -117,8 +114,7 @@ void stream_boolean(compiler_core_type *compiler, } /* Add a character literal */ -void stream_char(compiler_core_type *compiler, - ins_stream_type *stream, char *str) { +void stream_char(compiler_core_type *compiler, ins_stream_type *stream, char *str) { ins_node_type *ins_node = 0; size_t length = 0; @@ -129,8 +125,7 @@ void stream_char(compiler_core_type *compiler, /* generate the literal string */ length = strlen(str) + 3; - gc_alloc(compiler->gc, 0, length, - (void **) &(ins_node->value.literal)); + gc_alloc(compiler->gc, 0, length, (void **)&(ins_node->value.literal)); snprintf(ins_node->value.literal, length, "#\\%s", str); @@ -141,8 +136,7 @@ void stream_char(compiler_core_type *compiler, } /* Add a symbol */ -void stream_symbol(compiler_core_type *compiler, - ins_stream_type *stream, char *str) { +void stream_symbol(compiler_core_type *compiler, ins_stream_type *stream, char *str) { ins_node_type *ins_node = 0; size_t length = 0; @@ -153,8 +147,7 @@ void stream_symbol(compiler_core_type *compiler, /* generate the literal string */ length = strlen(str) + 4; - gc_alloc(compiler->gc, 0, length, - (void **) &(ins_node->value.literal)); + gc_alloc(compiler->gc, 0, length, (void **)&(ins_node->value.literal)); snprintf(ins_node->value.literal, length, "s\"%s\"", str); @@ -163,4 +156,3 @@ void stream_symbol(compiler_core_type *compiler, gc_unregister_root(compiler->gc, (void **)&ins_node); } - diff --git a/src/libinsomniac_buffer/buffer_core.c b/src/libinsomniac_buffer/buffer_core.c index 71c62cc..f6c8bfb 100644 --- a/src/libinsomniac_buffer/buffer_core.c +++ b/src/libinsomniac_buffer/buffer_core.c @@ -1,7 +1,6 @@ #include "buffer_internal.h" #include - gc_type_def create_buffer_type(gc_type *gc) { gc_type_def type = 0; @@ -24,17 +23,16 @@ void buffer_create(gc_type *gc, buffer_type **buf_ret) { static gc_type_def buffer_gc_type = 0; static gc_type_def block_gc_type = 0; - buffer_internal_type * buf = 0; + buffer_internal_type *buf = 0; gc_protect(gc); /* make sure types are registered */ - if(!init) { + if (!init) { buffer_gc_type = create_buffer_type(gc); block_gc_type = create_block_type(gc); } - /* allocate a new buffer object */ gc_alloc_type(gc, 0, buffer_gc_type, (void **)&buf); @@ -43,7 +41,7 @@ void buffer_create(gc_type *gc, buffer_type **buf_ret) { /* allocate our first block */ /* buf->head = buf->tail = gc_alloc_type(buf->gc, 0, buf->block_gc_type); */ - gc_alloc_type(buf->gc, 0, buf->block_gc_type, (void**)&(buf->tail)); + gc_alloc_type(buf->gc, 0, buf->block_gc_type, (void **)&(buf->tail)); buf->head = buf->tail; /* save our buffer in the passed in pointer */ @@ -54,14 +52,14 @@ void buffer_create(gc_type *gc, buffer_type **buf_ret) { /* Empty the given buffer and free space allocated to it. */ void buffer_reset(buffer_type *buf_void) { - buffer_internal_type *buf= (buffer_internal_type *)buf_void; + buffer_internal_type *buf = (buffer_internal_type *)buf_void; - /* Empty contents of buffer */ - buf->used = 0; + /* Empty contents of buffer */ + buf->used = 0; - /* Buffers always have at least one allocated block */ - buf->head = buf->tail; - buf->head->next = 0; + /* Buffers always have at least one allocated block */ + buf->head = buf->tail; + buf->head->next = 0; } /* allocate a new buffer block and place it at the head of the list */ @@ -73,52 +71,49 @@ void buffer_push(buffer_internal_type *buf) { gc_alloc_type(buf->gc, 0, buf->block_gc_type, (void **)&new_tail); buf->tail->next = new_tail; - buf->tail=new_tail; + buf->tail = new_tail; gc_unprotect(buf->gc); } /* write data into the given buffer */ void buffer_write(buffer_type *buf_void, uint8_t *bytes, size_t length) { - buffer_internal_type *buf=(buffer_internal_type *)buf_void; + buffer_internal_type *buf = (buffer_internal_type *)buf_void; size_t write_offset = (buf->used % BLOCK_SIZE); int block_remaining = BLOCK_SIZE - write_offset; size_t offset = 0; - /* make sure that we have a block allocated */ - if(!block_remaining) { + if (!block_remaining) { buffer_push(buf); } /* deal with data of less than block size */ - if(length < block_remaining) { + if (length < block_remaining) { block_remaining = length; } /* Copy data into individual blocks */ - while(length > 0) { + while (length > 0) { /* copy data to from our passed in value array to the buffer */ - memcpy(&(buf->tail->block[write_offset]), &(bytes[offset]), - block_remaining); + memcpy(&(buf->tail->block[write_offset]), &(bytes[offset]), block_remaining); /* update write location and count down length */ offset += block_remaining; buf->used += block_remaining; - length -= block_remaining; /* Do we need another block? */ - if(!(buf->used % BLOCK_SIZE)) { + if (!(buf->used % BLOCK_SIZE)) { write_offset = 0; buffer_push(buf); } /* do we have more than a block left ? */ - if(length >= BLOCK_SIZE) { + if (length >= BLOCK_SIZE) { block_remaining = BLOCK_SIZE; } else { block_remaining = length; @@ -137,20 +132,20 @@ size_t buffer_read(buffer_type *buf_void, uint8_t *dest_ptr, size_t length) { block = buf->head; /* walk all blocks and copy them into the destination buffer */ - while((block != 0) && (offset < length)) { + while ((block != 0) && (offset < length)) { /* do we have a whole block or a partial one */ copy_amount = length - offset; /* only copy a block at a time */ - if(copy_amount >= BLOCK_SIZE) { + if (copy_amount >= BLOCK_SIZE) { copy_amount = BLOCK_SIZE; } /* copy data from block to destination */ memcpy(&(dest[offset]), &(block->block[0]), copy_amount); - offset+=copy_amount; + offset += copy_amount; /* move to next block */ block = block->next; @@ -169,25 +164,25 @@ size_t buffer_append(buffer_type *buf_void, buffer_type *src_void, size_t length block = buf->head; /* if size is set to -1, then look it via buffer_size */ - if(length == -1) { - length = buffer_size(src_void); + if (length == -1) { + length = buffer_size(src_void); } /* walk all blocks and copy them into the destination buffer */ - while((block != 0) && (offset < length)) { + while ((block != 0) && (offset < length)) { /* do we have a whole block or a partial one */ copy_amount = length - offset; /* only copy a block at a time */ - if(copy_amount >= BLOCK_SIZE) { + if (copy_amount >= BLOCK_SIZE) { copy_amount = BLOCK_SIZE; } /* copy data from block to destination */ buffer_write(buf_void, block->block, copy_amount); - offset+=copy_amount; + offset += copy_amount; /* move to next block */ block = block->next; @@ -198,8 +193,6 @@ size_t buffer_append(buffer_type *buf_void, buffer_type *src_void, size_t length /* return the size of the buffer */ size_t buffer_size(buffer_type *buf_void) { - buffer_internal_type *buf=(buffer_internal_type *)buf_void; + buffer_internal_type *buf = (buffer_internal_type *)buf_void; return buf->used; } - - diff --git a/src/libinsomniac_buffer/buffer_internal.h b/src/libinsomniac_buffer/buffer_internal.h index c42c6ca..a1a582a 100644 --- a/src/libinsomniac_buffer/buffer_internal.h +++ b/src/libinsomniac_buffer/buffer_internal.h @@ -1,9 +1,10 @@ #ifndef _BUFFER_INTERNAL_ #define _BUFFER_INTERNAL_ -#include #include + #include +#include typedef struct block block_type; @@ -13,7 +14,6 @@ struct block { block_type *next; }; - /* wrapper object for a buffer */ typedef struct buffer { /* garbage collector that created this buffer */ @@ -30,5 +30,4 @@ typedef struct buffer { gc_type_def block_gc_type; } buffer_internal_type; - #endif diff --git a/src/libinsomniac_buffer/buffer_load.c b/src/libinsomniac_buffer/buffer_load.c index 1f857cb..e5ad060 100644 --- a/src/libinsomniac_buffer/buffer_load.c +++ b/src/libinsomniac_buffer/buffer_load.c @@ -1,9 +1,9 @@ #include "buffer_internal.h" +#include #include -#include #include -#include +#include #include /* slurp a file into a buffer */ @@ -16,12 +16,12 @@ size_t buffer_load(buffer_type *buf, char *file) { fd = open(file, O_RDONLY); /* make sure that we could open the file */ - if(fd == -1 ) { + if (fd == -1) { return -1; } /* read everything into our elastic buffer */ - while((count = read(fd, bytes, BLOCK_SIZE))) { + while ((count = read(fd, bytes, BLOCK_SIZE))) { buffer_write(buf, (uint8_t *)bytes, count); loaded += count; } @@ -31,7 +31,6 @@ size_t buffer_load(buffer_type *buf, char *file) { return loaded; } - /* Use our buffer library to slurp a file into a string */ size_t buffer_load_string(gc_type *gc, char *file, char **str) { size_t count = 0; @@ -44,12 +43,12 @@ size_t buffer_load_string(gc_type *gc, char *file, char **str) { count = buffer_load(buf, file); /* Make sure we could read the file */ - if (count == -1 ) { + if (count == -1) { printf("Unable to load file: %s\n", file); exit(-2); } - gc_alloc(gc, 0, count+1, (void **)str); + gc_alloc(gc, 0, count + 1, (void **)str); buffer_read(buf, (uint8_t *)*str, count); diff --git a/src/libinsomniac_gc/gc_core.c b/src/libinsomniac_gc/gc_core.c index 25bb3f9..10074dc 100644 --- a/src/libinsomniac_gc/gc_core.c +++ b/src/libinsomniac_gc/gc_core.c @@ -10,13 +10,12 @@ gc_type *gc_create(size_t cell_size) { gc->current_mark = RED; gc->protect_count = 0; gc->cell_size = cell_size; - gc->size_granularity = sizeof(meta_obj_type)+ cell_size; + gc->size_granularity = sizeof(meta_obj_type) + cell_size; /* used to keep track of type definitions */ gc->type_defs = 0; gc->num_types = 0; - /* register the ARRAY type as type 0 */ gc->array_type = gc_register_type(gc, sizeof(void *)); gc_register_array(gc, gc->array_type, 0); @@ -26,7 +25,7 @@ gc_type *gc_create(size_t cell_size) { /* deallocate a GC instance */ void gc_destroy(gc_type *gc_void) { - if(gc_void) { + if (gc_void) { /* cast back to our internal type */ gc_ms_type *gc = (gc_ms_type *)gc_void; @@ -54,7 +53,7 @@ void gc_unprotect(gc_type *gc_void) { /* make sure we have paired protects */ assert(gc->protect_count >= 0); - if(!gc->protect_count && !gc->dead_list) { + if (!gc->protect_count && !gc->dead_list) { sweep(gc); } } @@ -73,13 +72,12 @@ void gc_register_root(gc_type *gc_void, void **root) { /* unregister a root point */ /* TODO: This is going to be very inefficient */ void gc_unregister_root(gc_type *gc_void, void **root) { - gc_ms_type *gc=(gc_ms_type *)gc_void; + gc_ms_type *gc = (gc_ms_type *)gc_void; meta_root_type *meta = gc->root_list; meta_root_type *prev = 0; - /* search until we find an object that matches our root pointer */ - while(meta->next && meta->root != root) { + while (meta->next && meta->root != root) { prev = meta; meta = meta->next; } @@ -88,7 +86,7 @@ void gc_unregister_root(gc_type *gc_void, void **root) { assert(meta->root == root); /* we are not the first element in the list */ - if(prev) { + if (prev) { prev->next = meta->next; } else { /* it was the first item on the list */ gc->root_list = meta->next; @@ -136,17 +134,16 @@ void gc_alloc_pointer_array(gc_type *gc_void, uint8_t perm, size_t cells, void * *ret = obj_from_meta(meta); } - /* remove permenant status from a given cell */ void gc_de_perm(gc_type *gc_void, void *obj_in) { - gc_ms_type *gc=(gc_ms_type *)gc_void; + gc_ms_type *gc = (gc_ms_type *)gc_void; meta_obj_type *meta = gc->perm_list; meta_obj_type *prev = 0; - meta_obj_type *obj=meta_from_obj(obj_in); + meta_obj_type *obj = meta_from_obj(obj_in); /* nothing to unmark */ - if(obj->mark != PERM) { + if (obj->mark != PERM) { return; } @@ -154,13 +151,13 @@ void gc_de_perm(gc_type *gc_void, void *obj_in) { obj->mark = gc->current_mark; /* search for our object in the perm list */ - while(meta->next && meta != obj) { + while (meta->next && meta != obj) { prev = meta; meta = meta->next; } /* we are not the first element in the list */ - if(prev) { + if (prev) { prev->next = meta->next; } else { /* it was the first item on the list */ gc->perm_list = meta->next; @@ -180,12 +177,14 @@ void gc_stats(gc_type *gc_void) { assert(gc); - active=count_list(&(gc->active_list)); - dead=count_list(&(gc->dead_list)); - perm=count_list(&(gc->perm_list)); + active = count_list(&(gc->active_list)); + dead = count_list(&(gc->dead_list)); + perm = count_list(&(gc->perm_list)); - printf("GC statistics active:%" PRIi64 " dead:%" PRIi64 " perm:%" PRIi64 " Allocations : %"PRIi64 "\n", - active, dead, perm, gc->allocations); + printf( + "GC statistics active:%" PRIi64 " dead:%" PRIi64 " perm:%" PRIi64 + " Allocations : %" PRIi64 "\n", + active, dead, perm, gc->allocations); } /* initiate a sweep of objects in the active list */ @@ -194,4 +193,3 @@ void gc_sweep(gc_type *gc_void) { sweep(gc); } - diff --git a/src/libinsomniac_gc/gc_internal.h b/src/libinsomniac_gc/gc_internal.h index 4cdac97..35b0161 100644 --- a/src/libinsomniac_gc/gc_internal.h +++ b/src/libinsomniac_gc/gc_internal.h @@ -1,16 +1,15 @@ #ifndef _GC_INTERNAL_ #define _GC_INTERNAL_ -#include +#include #include +#include #include -#include #include /* for offsetof */ #include - /* An internal GC structure to represent an allocated object */ typedef struct meta_obj meta_obj_type; typedef struct meta_root meta_root_type; @@ -29,10 +28,7 @@ typedef enum mark { } mark_type; /* are we looking at a pointer or an array */ -typedef enum meta_ptr { - PTR, - ARRAY -} meta_ptr_type; +typedef enum meta_ptr { PTR, ARRAY } meta_ptr_type; /* meta object wrapper */ struct meta_obj { @@ -42,7 +38,7 @@ struct meta_obj { gc_type_def type_def; uint8_t obj[]; /* contained object */ - /* object_type obj; */ + /* object_type obj; */ }; /* root pointers that need to be searched */ @@ -65,20 +61,19 @@ struct meta_obj_ptr_def { meta_obj_ptr_def_type *next; }; - /* the internal type used by the GC to keep track of things */ typedef struct gc_ms { meta_obj_type *active_list; /* list of reachable objects */ - meta_obj_type *dead_list; /* list of unreachable objects */ + meta_obj_type *dead_list; /* list of unreachable objects */ meta_obj_type *perm_list; /* list of objects we treat as permenant */ meta_root_type *root_list; /* list of root pointers */ meta_obj_def_type *type_defs; /* definitions of various types */ - uint32_t num_types; /* number of types */ + uint32_t num_types; /* number of types */ - size_t cell_size; /* size of a normal cell */ + size_t cell_size; /* size of a normal cell */ size_t size_granularity; /* the actual size of a normal cell*/ vm_int protect_count; @@ -101,7 +96,6 @@ void destroy_types(gc_ms_type *gc, meta_obj_def_type *type_list, uint32_t num_ty /* count how many objects are in a given list */ vm_int count_list(meta_obj_type **list); - /* Pick the next mark to use while sweeping */ mark_type set_next_mark(gc_ms_type *gc); @@ -128,5 +122,4 @@ void gc_free(gc_ms_type *gc, void *obj); /* #define FREE(ptr) free(ptr) */ #define FREE(ptr) gc_free(gc, ptr); - #endif diff --git a/src/libinsomniac_gc/gc_internals.c b/src/libinsomniac_gc/gc_internals.c index 5707ad2..41ee9d0 100644 --- a/src/libinsomniac_gc/gc_internals.c +++ b/src/libinsomniac_gc/gc_internals.c @@ -1,12 +1,11 @@ #include "gc_internal.h" - vm_int count_list(meta_obj_type **list) { vm_int count = 0; meta_obj_type *meta = 0; meta = *list; - while(meta) { + while (meta) { count++; meta = meta->next; } @@ -20,7 +19,7 @@ void destroy_list(gc_ms_type *gc, meta_obj_type **list) { /* retrieve the first list value */ meta = *list; - while(meta) { + while (meta) { meta_obj_type *next = meta->next; /* free the object we are holding onto and @@ -42,18 +41,18 @@ meta_obj_type *internal_alloc(gc_ms_type *gc, uint8_t perm, size_t size) { /* adjust the requested size with the size of our meta object */ - real_size = sizeof(meta_obj_type)+size; + real_size = sizeof(meta_obj_type) + size; /* only attempt reuse on cell sized objects */ - if(size == gc->cell_size) { + if (size == gc->cell_size) { /* if there are no available objects, sweep */ - if(!gc->dead_list) { + if (!gc->dead_list) { sweep(gc); } /* only attempt reallocation for cell sized things */ - if(gc->dead_list) { + if (gc->dead_list) { /* reuse an object */ meta = gc->dead_list; gc->dead_list = meta->next; @@ -64,20 +63,20 @@ meta_obj_type *internal_alloc(gc_ms_type *gc, uint8_t perm, size_t size) { /* If we didn't find an object, create one. */ - if(!meta) { + if (!meta) { /* create a new obect */ meta = MALLOC(real_size); } /* reset the allocation size */ - meta->size=size; + meta->size = size; /* make sure we have an object */ assert(meta); /* Attach a permenant object to the list of perm objects */ - if(perm) { + if (perm) { meta->mark = PERM; /* attach the new object to our gc */ @@ -99,9 +98,8 @@ void *gc_malloc(gc_ms_type *gc, size_t size) { size_t real_size = size; /* if we have a gc, use size_granularity */ - if(gc) { - real_size += gc->size_granularity - - (real_size % gc->size_granularity); + if (gc) { + real_size += gc->size_granularity - (real_size % gc->size_granularity); gc->allocations++; } @@ -110,7 +108,7 @@ void *gc_malloc(gc_ms_type *gc, size_t size) { /* Count frees */ void gc_free(gc_ms_type *gc, void *obj) { - if(gc) { + if (gc) { gc->allocations--; } free(obj); @@ -126,15 +124,14 @@ mark_type set_next_mark(gc_ms_type *gc) { /* preallocate a chunk of memory, only use with an empty dead list */ void pre_alloc(gc_ms_type *gc) { - void *obj=0; + void *obj = 0; gc_protect(gc); - for(int i = 0; i < 1000; i++) { - gc_alloc(gc, 0, gc->cell_size, (void**)&obj); + for (int i = 0; i < 1000; i++) { + gc_alloc(gc, 0, gc->cell_size, (void **)&obj); } gc_unprotect(gc); gc_sweep(gc); /* sweep the garbage collector */ } - diff --git a/src/libinsomniac_gc/gc_offset.c b/src/libinsomniac_gc/gc_offset.c index b7646a9..bb19df9 100644 --- a/src/libinsomniac_gc/gc_offset.c +++ b/src/libinsomniac_gc/gc_offset.c @@ -3,16 +3,16 @@ /* return a pointer to the meta object for a given object */ meta_obj_type *meta_from_obj(void *obj) { /* make sure a null stays a null */ - if(!obj) { + if (!obj) { return 0; } - return (meta_obj_type *)(((uint8_t *)obj)-offsetof(meta_obj_type, obj)); + return (meta_obj_type *)(((uint8_t *)obj) - offsetof(meta_obj_type, obj)); } /* return a pointer to the given object for a given meta object */ void *obj_from_meta(meta_obj_type *meta) { - if(!meta) { + if (!meta) { return 0; } diff --git a/src/libinsomniac_gc/gc_sweep.c b/src/libinsomniac_gc/gc_sweep.c index 520187e..6581e9c 100644 --- a/src/libinsomniac_gc/gc_sweep.c +++ b/src/libinsomniac_gc/gc_sweep.c @@ -1,37 +1,35 @@ #include "gc_internal.h" - /* walk every object in an object graph and mark it */ void mark_object(meta_obj_type *meta, mark_type mark) { /* don't change the mark on perm objects */ - if(meta->mark == PERM) { + if (meta->mark == PERM) { return; } else { meta->mark = mark; } } - /* walk a graph of objects and mark them */ void mark_graph(gc_ms_type *gc, meta_obj_type *meta, mark_type mark) { meta_obj_ptr_def_type *root_list = 0; int64_t size = 0; int64_t size_max = 0; - void *obj=0; - void **next_obj=0; + void *obj = 0; + void **next_obj = 0; /* return if we don't have an object */ - if(!meta) { + if (!meta) { return; } /* we have already marked this object */ - if(meta->mark == mark) { + if (meta->mark == mark) { return; } - if(meta->mark == DEAD) { + if (meta->mark == DEAD) { printf("Active object in dead list!\n"); assert(0); } @@ -39,38 +37,38 @@ void mark_graph(gc_ms_type *gc, meta_obj_type *meta, mark_type mark) { /* mark this object */ mark_object(meta, mark); - /* make sure this is a typed object */ - if(meta->type_def >= 0) { + if (meta->type_def >= 0) { /* Load the definition for this type of object */ root_list = gc->type_defs[meta->type_def].root_list; /* walk the list of poitners internal to this object */ - while(root_list) { + while (root_list) { obj = obj_from_meta(meta); next_obj = (void **)((uint8_t *)obj + root_list->offset); - switch(root_list->type) { - case PTR: - /* mark any pointed to objects */ - mark_graph(gc, meta_from_obj(*next_obj), mark); - break; + switch (root_list->type) { + case PTR: + /* mark any pointed to objects */ + mark_graph(gc, meta_from_obj(*next_obj), mark); + break; - case ARRAY: - /* determine the size of the array based on size of the allocation */ - size_max = (meta->size / gc->type_defs[gc->array_type].size); + case ARRAY: + /* determine the size of the array based on size of the + * allocation */ + size_max = (meta->size / gc->type_defs[gc->array_type].size); - /* mark all objects in array */ - for(size = 0; size < size_max; size++) { - mark_graph(gc, meta_from_obj(next_obj[size]), mark); - } + /* mark all objects in array */ + for (size = 0; size < size_max; size++) { + mark_graph(gc, meta_from_obj(next_obj[size]), mark); + } - break; + break; - default: - assert(0); - break; + default: + assert(0); + break; } root_list = root_list->next; @@ -83,10 +81,10 @@ void mark_list(gc_ms_type *gc, meta_obj_type *list, mark_type mark) { meta_obj_type *meta = 0; meta = list; - while(meta) { + while (meta) { mark_graph(gc, meta, mark); - meta=meta->next; + meta = meta->next; } } @@ -95,45 +93,44 @@ void mark_root(gc_ms_type *gc, meta_root_type *list, mark_type mark) { meta_root_type *meta = 0; meta = list; - while(meta) { + while (meta) { mark_graph(gc, meta_from_obj(*(meta->root)), mark); - meta=meta->next; + meta = meta->next; } } - /* move, unmarked objects to dead list */ -void sweep_list(gc_ms_type * gc, mark_type mark) { +void sweep_list(gc_ms_type *gc, mark_type mark) { meta_obj_type *active = gc->active_list; meta_obj_type *new_active = 0; meta_obj_type *dead = gc->dead_list; /* don't sweep if protection is active */ - if(gc->protect_count) { + if (gc->protect_count) { return; } - while(active) { - meta_obj_type *next=active->next; + while (active) { + meta_obj_type *next = active->next; /* do we have a dead object */ - if(active->mark == mark) { + if (active->mark == mark) { /* move our object to the head of the active list */ - active->next=new_active; - new_active=active; + active->next = new_active; + new_active = active; } else { /* Do we have a cell sized object or something else? */ - if(active->size == gc->cell_size) { + if (active->size == gc->cell_size) { /* move our object to the head of the new dead list */ active->next = dead; active->mark = DEAD; /* mark as dead */ - dead=active; + dead = active; } else { /* Free things that are not cell sized */ @@ -141,15 +138,14 @@ void sweep_list(gc_ms_type * gc, mark_type mark) { } } - active=next; + active = next; } /* replace existing lists */ - gc->active_list=new_active; - gc->dead_list=dead; + gc->active_list = new_active; + gc->dead_list = dead; } - /* the guts of sweep */ void sweep(gc_ms_type *gc) { mark_type mark; @@ -157,7 +153,7 @@ void sweep(gc_ms_type *gc) { assert(gc); /* Check protection status before sweeping */ - if(gc->protect_count) { + if (gc->protect_count) { return; } @@ -168,7 +164,7 @@ void sweep(gc_ms_type *gc) { /* mark all objects reachable from our defined root pointers */ - if(gc->root_list) { + if (gc->root_list) { mark_root(gc, gc->root_list, mark); } @@ -179,8 +175,7 @@ void sweep(gc_ms_type *gc) { /* allocate some cell sized objects to make things easier */ - if(!gc->dead_list) { + if (!gc->dead_list) { pre_alloc(gc); } } - diff --git a/src/libinsomniac_gc/gc_types.c b/src/libinsomniac_gc/gc_types.c index f2caced..df126dc 100644 --- a/src/libinsomniac_gc/gc_types.c +++ b/src/libinsomniac_gc/gc_types.c @@ -1,18 +1,17 @@ #include "gc_internal.h" #include - /* register a new type with the GC */ gc_type_def gc_register_type(gc_type *gc_void, size_t size) { gc_ms_type *gc = (gc_ms_type *)gc_void; - size_t array_size = sizeof(meta_obj_def_type) * (gc->num_types + 1); + size_t array_size = sizeof(meta_obj_def_type) * (gc->num_types + 1); meta_obj_def_type *type_defs = 0; uint32_t new_type = gc->num_types; /* if we don't have any types defined, define a new array */ - if(!gc->num_types) { + if (!gc->num_types) { gc->type_defs = MALLOC(array_size); } else { @@ -37,12 +36,10 @@ void gc_register_pointer(gc_type *gc_void, gc_type_def type, size_t offset) { gc_ms_type *gc = (gc_ms_type *)gc_void; meta_obj_ptr_def_type *meta_type = MALLOC_TYPE(meta_obj_ptr_def_type); - meta_type->next = gc->type_defs[type].root_list; meta_type->type = PTR; meta_type->offset = offset; gc->type_defs[type].root_list = meta_type; - } /* register a pointer offset with the GC */ @@ -50,31 +47,27 @@ void gc_register_array(gc_type *gc_void, gc_type_def type, size_t offset) { gc_ms_type *gc = (gc_ms_type *)gc_void; meta_obj_ptr_def_type *meta_type = MALLOC_TYPE(meta_obj_ptr_def_type); - meta_type->next = gc->type_defs[type].root_list; meta_type->type = ARRAY; meta_type->offset = offset; gc->type_defs[type].root_list = meta_type; - } /* clean up when shutting down a GC instance */ void destroy_types(gc_ms_type *gc, meta_obj_def_type *type_list, uint32_t num_types) { - meta_obj_ptr_def_type *next=0; - meta_obj_ptr_def_type *type_def=0; - + meta_obj_ptr_def_type *next = 0; + meta_obj_ptr_def_type *type_def = 0; - for(int i=0; inext; + while (type_def) { + next = type_def->next; FREE(type_def); - type_def=next; + type_def = next; } - } FREE(type_list); } diff --git a/src/libinsomniac_hash/hash_core.c b/src/libinsomniac_hash/hash_core.c index f553fd8..e054c31 100644 --- a/src/libinsomniac_hash/hash_core.c +++ b/src/libinsomniac_hash/hash_core.c @@ -7,18 +7,17 @@ static gc_type_def key_value_type_def = 0; /* create a hashtable using the given function and comparator */ -void hash_create(gc_type *gc, hash_fn fn, - hash_cmp cmp, hashtable_type **ret) { +void hash_create(gc_type *gc, hash_fn fn, hash_cmp cmp, hashtable_type **ret) { hash_internal_type *table = 0; /* register the hashtable type with the gc */ - if(!hashtable_type_def) { + if (!hashtable_type_def) { hashtable_type_def = register_hashtable(gc); key_value_type_def = register_key_value(gc); } - gc_register_root(gc, (void**)&table); + gc_register_root(gc, (void **)&table); gc_alloc_type(gc, 0, hashtable_type_def, (void **)&table); @@ -34,7 +33,7 @@ void hash_create(gc_type *gc, hash_fn fn, *ret = (hashtable_type *)table; - gc_unregister_root(gc, (void**)&table); + gc_unregister_root(gc, (void **)&table); } /* create a cow copy of an existing hashtable */ @@ -50,20 +49,18 @@ void hash_cow(gc_type *gc, hashtable_type *src, hashtable_type **ret) { (*table)->copy_on_write = true; } - - /* add a value to the hash */ -void hash_set(hashtable_type *void_table, void *key, void * value) { +void hash_set(hashtable_type *void_table, void *key, void *value) { key_value_type *kv = 0; - hash_internal_type *table=(hash_internal_type *)void_table; + hash_internal_type *table = (hash_internal_type *)void_table; size_t new_size = 0; kv = hash_find(table, key, CREATE); kv->value = value; /* check to see if we need to resize hash */ - if(hash_load(table) > MAX_LOAD) { + if (hash_load(table) > MAX_LOAD) { /* calculate new size */ new_size = floor(table->entries / TARGET_LOAD) + 1; hash_resize(table, new_size); @@ -72,34 +69,32 @@ void hash_set(hashtable_type *void_table, void *key, void * value) { /* remove a key from the tables */ void hash_erase(hashtable_type *void_table, void *key) { - hash_internal_type *table=(hash_internal_type *)void_table; + hash_internal_type *table = (hash_internal_type *)void_table; hash_find(table, key, DELETE); } /* retrieve the value bound to a key in the table */ -uint8_t hash_get(hashtable_type *void_table, void *key, void ** value) { +uint8_t hash_get(hashtable_type *void_table, void *key, void **value) { key_value_type *kv = 0; hash_internal_type *table = (hash_internal_type *)void_table; kv = hash_find(table, key, READ); /* does the given key exist in the table ?*/ - if(!kv) { + if (!kv) { return 0; } /* we found the value, do we have somewhere to put it? */ - if(value) { + if (value) { *(value) = kv->value; } return 1; } - /* locate or create a key_value_object the given key */ -key_value_type *hash_find(hash_internal_type *table, - void *key, hash_action_type action) { +key_value_type *hash_find(hash_internal_type *table, void *key, hash_action_type action) { hash_type hash = (*table->calc_hash)(key); hash_type index = hash % table->size; /* calculate the search table index */ key_value_type *kv = 0; @@ -114,16 +109,16 @@ key_value_type *hash_find(hash_internal_type *table, } /* is there anything at the given index? */ - if((kv = table->table[index])) { + if ((kv = table->table[index])) { /* search through the list of key value pairs */ - while(kv) { - if((*table->compare)(key, kv->key) == EQ) { + while (kv) { + if ((*table->compare)(key, kv->key) == EQ) { /* do the delete if needed */ - if(action == DELETE) { + if (action == DELETE) { /* Do we have a chain? */ - if(prev_kv) { + if (prev_kv) { /* Remove node from chain */ prev_kv->next = kv->next; } else { @@ -140,8 +135,8 @@ key_value_type *hash_find(hash_internal_type *table, } /* we did not find the key, should we create it? */ - if(action == CREATE) { - gc_register_root(table->gc, (void**)&kv); + if (action == CREATE) { + gc_register_root(table->gc, (void **)&kv); gc_alloc_type(table->gc, 0, table->key_value, (void **)&kv); @@ -153,12 +148,11 @@ key_value_type *hash_find(hash_internal_type *table, table->entries++; - gc_unregister_root(table->gc, (void**)&kv); + gc_unregister_root(table->gc, (void **)&kv); return kv; } - return 0; } @@ -173,26 +167,22 @@ void hash_resize(hash_internal_type *table, size_t size) { old_table = table->table; old_size = table->size; - gc_alloc_pointer_array(table->gc, - 0, - size, - (void **)&(table->table)); + gc_alloc_pointer_array(table->gc, 0, size, (void **)&(table->table)); table->size = size; table->entries = 0; /* do we need to copy old entries into the new table */ - if(old_table) { + if (old_table) { /* enumerate all old entries and add them to the new table */ - for(int i=0; i < old_size; i++) { + for (int i = 0; i < old_size; i++) { kv = old_table[i]; - while(kv) { + while (kv) { /* save the previous value in the new table */ - hash_find(table, kv->key, CREATE) - ->value = kv->value; + hash_find(table, kv->key, CREATE)->value = kv->value; kv = kv->next; } @@ -207,10 +197,9 @@ float hash_load(hash_internal_type *table) { return (table->entries * 1.0) / table->size; } - /* output some useful stats about a hash table */ void hash_info(hashtable_type *void_table) { - hash_internal_type *table=(hash_internal_type *)void_table; + hash_internal_type *table = (hash_internal_type *)void_table; key_value_type *kv = 0; uint64_t max = 0; @@ -218,16 +207,16 @@ void hash_info(hashtable_type *void_table) { uint64_t active_chains = 0; - - printf("Hash Info: Entries %lu Size %lu Load %f COW %i\n", - table->entries, table->size, hash_load(table), table->copy_on_write); + printf( + "Hash Info: Entries %lu Size %lu Load %f COW %i\n", table->entries, table->size, + hash_load(table), table->copy_on_write); printf("\tHash Keys: "); - for(int i=0; i < table->size; i++) { + for (int i = 0; i < table->size; i++) { kv = table->table[i]; current = 0; - while(kv) { + while (kv) { /* save the previous value in the new table */ printf(" %s", (char *)kv->key); @@ -235,15 +224,16 @@ void hash_info(hashtable_type *void_table) { kv = kv->next; } - if(current > 0 ) { + if (current > 0) { active_chains++; } - if(current > max ) { + if (current > max) { max = current; } } - printf("\n\tLongest Chain %" PRIi64 " Active Chains %" PRIi64 " Average Chain %f\n", - max, active_chains, (table->entries * 1.0) / active_chains); + printf( + "\n\tLongest Chain %" PRIi64 " Active Chains %" PRIi64 " Average Chain %f\n", max, + active_chains, (table->entries * 1.0) / active_chains); } diff --git a/src/libinsomniac_hash/hash_internal.h b/src/libinsomniac_hash/hash_internal.h index 0671649..3895f30 100644 --- a/src/libinsomniac_hash/hash_internal.h +++ b/src/libinsomniac_hash/hash_internal.h @@ -13,11 +13,7 @@ typedef struct hash_internal hash_internal_type; typedef struct key_value key_value_type; -typedef enum { - READ, - DELETE, - CREATE -} hash_action_type; +typedef enum { READ, DELETE, CREATE } hash_action_type; struct key_value { void *key; @@ -46,8 +42,7 @@ gc_type_def register_key_value(gc_type *gc); /* resize/allocate hashtable array */ void hash_resize(hash_internal_type *table, size_t size); -key_value_type *hash_find(hash_internal_type *table, - void *key, hash_action_type create); +key_value_type *hash_find(hash_internal_type *table, void *key, hash_action_type create); float hash_load(hash_internal_type *table); diff --git a/src/libinsomniac_hash/hash_pointer_functions.c b/src/libinsomniac_hash/hash_pointer_functions.c index 10ebeb6..46ef4ad 100644 --- a/src/libinsomniac_hash/hash_pointer_functions.c +++ b/src/libinsomniac_hash/hash_pointer_functions.c @@ -5,7 +5,7 @@ hash_type hash_pointer(void *key) { hash_type hash = 0; uint8_t *bytes = (uint8_t *)&key; - for(size_t i=0; i < sizeof(void *); i++) { + for (size_t i = 0; i < sizeof(void *); i++) { hash *= 32; hash += bytes[i]; } @@ -16,8 +16,7 @@ hash_type hash_pointer(void *key) { /* simple pointer comparison */ cmp_type hash_pointer_cmp(void *key1, void *key2) { - - if(key1 > key2) { + if (key1 > key2) { return GT; } else if (key1 < key2) { diff --git a/src/libinsomniac_hash/hash_string_functions.c b/src/libinsomniac_hash/hash_string_functions.c index 0c1df2a..6de872d 100644 --- a/src/libinsomniac_hash/hash_string_functions.c +++ b/src/libinsomniac_hash/hash_string_functions.c @@ -7,7 +7,7 @@ hash_type hash_string(void *key) { hash_type hash = 0; uint8_t *bytes = key; - for(size_t i=0; bytes[i] != 0; i++) { + for (size_t i = 0; bytes[i] != 0; i++) { /* see http://www.cse.yorku.ca/~oz/hash.html */ hash = bytes[i] + (hash << 6) + (hash << 16) - hash; } @@ -21,10 +21,9 @@ cmp_type hash_string_cmp(void *void_key1, void *void_key2) { uint8_t *key2 = (uint8_t *)void_key2; while (*key1 == *key2 && *key1 != 0 && *key2 != 0) { - key1++; - key2++; + key1++; + key2++; } - return *key1 == *key2 ? EQ : - *key1 > *key2 ? GT : LT; + return *key1 == *key2 ? EQ : *key1 > *key2 ? GT : LT; } diff --git a/src/libinsomniac_hash/hash_types.c b/src/libinsomniac_hash/hash_types.c index cab46b2..d31cde6 100644 --- a/src/libinsomniac_hash/hash_types.c +++ b/src/libinsomniac_hash/hash_types.c @@ -1,37 +1,26 @@ #include "hash_internal.h" - gc_type_def register_hashtable(gc_type *gc) { gc_type_def hashtable = 0; - hashtable = - gc_register_type(gc, sizeof(hash_internal_type)); + hashtable = gc_register_type(gc, sizeof(hash_internal_type)); /* register the table itself */ - gc_register_pointer(gc, hashtable, - offsetof(hash_internal_type, table)); + gc_register_pointer(gc, hashtable, offsetof(hash_internal_type, table)); return hashtable; } - gc_type_def register_key_value(gc_type *gc) { gc_type_def key_value = 0; - key_value = gc_register_type(gc, - sizeof(key_value_type)); + key_value = gc_register_type(gc, sizeof(key_value_type)); - gc_register_pointer(gc, key_value, - offsetof(key_value_type, - key)); + gc_register_pointer(gc, key_value, offsetof(key_value_type, key)); - gc_register_pointer(gc, key_value, - offsetof(key_value_type, - value)); + gc_register_pointer(gc, key_value, offsetof(key_value_type, value)); - gc_register_pointer(gc, key_value, - offsetof(key_value_type, - next)); + gc_register_pointer(gc, key_value, offsetof(key_value_type, next)); return key_value; } diff --git a/src/libinsomniac_io/io_core.c b/src/libinsomniac_io/io_core.c index c0f540d..9ad4058 100644 --- a/src/libinsomniac_io/io_core.c +++ b/src/libinsomniac_io/io_core.c @@ -2,11 +2,8 @@ #include - /* Say Hello */ -void hello_world(vm_type *vm, gc_type *gc) { - printf("\nHELLO WORLD!\n"); -} +void hello_world(vm_type *vm, gc_type *gc) { printf("\nHELLO WORLD!\n"); } void say_something(vm_type *vm, gc_type *gc) { object_type *port = 0; @@ -46,5 +43,5 @@ binding_type export_list[] = { {"io-hello-world", &hello_world}, {"io-say", &say_something}, - {0,0}, + {0, 0}, }; diff --git a/src/libinsomniac_io/io_internal.h b/src/libinsomniac_io/io_internal.h index b17fe6f..f0f89dd 100644 --- a/src/libinsomniac_io/io_internal.h +++ b/src/libinsomniac_io/io_internal.h @@ -3,5 +3,4 @@ #include - #endif diff --git a/src/libinsomniac_runtime/runtime_core.c b/src/libinsomniac_runtime/runtime_core.c index 77c7057..a853194 100644 --- a/src/libinsomniac_runtime/runtime_core.c +++ b/src/libinsomniac_runtime/runtime_core.c @@ -3,7 +3,7 @@ extern uint64_t scheme_code_size(); extern uint8_t *scheme_code(); -int run_scheme(int argc, char**argv) { +int run_scheme(int argc, char **argv) { size_t code_size = (size_t)scheme_code_size(); uint8_t *code = scheme_code(); gc_type *gc = gc_create(sizeof(object_type)); diff --git a/src/libinsomniac_runtime/runtime_internal.h b/src/libinsomniac_runtime/runtime_internal.h index f6b284e..4e842ed 100644 --- a/src/libinsomniac_runtime/runtime_internal.h +++ b/src/libinsomniac_runtime/runtime_internal.h @@ -1,12 +1,12 @@ #ifndef _RUNTIME_INTERNAL_ #define _RUNTIME_INTERNAL_ -#include #include +#include -#include -#include #include +#include +#include #include #include diff --git a/src/libinsomniac_vm/libinsomniac_vm_instructions/vm_instructions_internal.h b/src/libinsomniac_vm/libinsomniac_vm_instructions/vm_instructions_internal.h index b78ce11..7683e87 100644 --- a/src/libinsomniac_vm/libinsomniac_vm_instructions/vm_instructions_internal.h +++ b/src/libinsomniac_vm/libinsomniac_vm_instructions/vm_instructions_internal.h @@ -6,8 +6,8 @@ #include #include #include -#include #include +#include #define MIN(a, b) (a > b ? b : a) #define MAX(a, b) (a > b ? a : b) diff --git a/src/libinsomniac_vm/libinsomniac_vm_instructions/vm_internals.c b/src/libinsomniac_vm/libinsomniac_vm_instructions/vm_internals.c index fbf2798..eda844b 100644 --- a/src/libinsomniac_vm/libinsomniac_vm_instructions/vm_internals.c +++ b/src/libinsomniac_vm/libinsomniac_vm_instructions/vm_internals.c @@ -1,6 +1,4 @@ #include "vm_instructions_internal.h" /* output the current state of the garbage collector */ -void op_gc_stats(vm_internal_type *vm) { - gc_stats(vm->gc); -} +void op_gc_stats(vm_internal_type *vm) { gc_stats(vm->gc); } diff --git a/src/libinsomniac_vm/libinsomniac_vm_instructions/vm_io.c b/src/libinsomniac_vm/libinsomniac_vm_instructions/vm_io.c index 9e8dedb..c9a62fc 100644 --- a/src/libinsomniac_vm/libinsomniac_vm_instructions/vm_io.c +++ b/src/libinsomniac_vm/libinsomniac_vm_instructions/vm_io.c @@ -36,7 +36,7 @@ void op_open(vm_internal_type *vm) { vm->reg1 = write = vm_pop(vm); vm->reg2 = path = vm_pop(vm); - if (!write || write->type != BOOL ) { + if (!write || write->type != BOOL) { throw(vm, "Open expected a boolean for write!", 1, write); } else if (!path || path->type != STRING) { throw(vm, "Open expected a string for path!", 1, path); @@ -57,7 +57,7 @@ void op_open(vm_internal_type *vm) { vm->reg1->value.integer = errno; vm->reg2 = vm_make_string(vm, err, strlen(err)); - throw (vm, "There was an error opening the file", 2, vm->reg1, vm->reg2); + throw(vm, "There was an error opening the file", 2, vm->reg1, vm->reg2); } else { vm_push(vm, vm->reg1); } @@ -87,7 +87,7 @@ void op_close(vm_internal_type *vm) { vm->reg2 = vm_make_string(vm, err, strlen(err)); - throw (vm, "There was an error closing the file", 2, vm->reg1, vm->reg2); + throw(vm, "There was an error closing the file", 2, vm->reg1, vm->reg2); } } @@ -149,7 +149,6 @@ void op_fd_read(vm_internal_type *vm) { vm_int bytes_read = 0; char *err = 0; - vm->reg1 = fd = vm_pop(vm); vm->reg2 = num = vm_pop(vm); @@ -165,7 +164,8 @@ void op_fd_read(vm_internal_type *vm) { vm->reg3 = u8 = vm_make_byte_vector(vm, num->value.integer); - bytes_read = read(fd->value.integer, u8->value.byte_vector.vector, num->value.integer); + bytes_read = + read(fd->value.integer, u8->value.byte_vector.vector, num->value.integer); if (bytes_read < 0) { err = strerror(errno); @@ -183,4 +183,3 @@ void op_fd_read(vm_internal_type *vm) { vm_push(vm, vm->reg3); } } - diff --git a/src/libinsomniac_vm/libinsomniac_vm_instructions/vm_jump.c b/src/libinsomniac_vm/libinsomniac_vm_instructions/vm_jump.c index 914b9ca..438afba 100644 --- a/src/libinsomniac_vm/libinsomniac_vm_instructions/vm_jump.c +++ b/src/libinsomniac_vm/libinsomniac_vm_instructions/vm_jump.c @@ -1,15 +1,13 @@ #include "vm_instructions_internal.h" - /* jump if the top of stack is not false */ void op_jnf(vm_internal_type *vm) { - object_type *obj =0 ; + object_type *obj = 0; vm_int target = parse_int(vm); vm->reg1 = obj = vm_pop(vm); - if(!(obj && obj->type == BOOL && - !obj->value.boolean)) { + if (!(obj && obj->type == BOOL && !obj->value.boolean)) { vm->env->ip += target; } } @@ -21,7 +19,6 @@ void op_jmp(vm_internal_type *vm) { vm->env->ip += target; } - /* create a procedure reference based on the current address and jump to target */ void op_call(vm_internal_type *vm) { @@ -44,39 +41,38 @@ void op_call(vm_internal_type *vm) { /* Rebind the parent of a proc to change the symbol look up environment */ void op_adopt(vm_internal_type *vm) { - object_type *child = 0; - object_type *parent = 0; - object_type *adopted = 0; - env_type *env = 0; + object_type *child = 0; + object_type *parent = 0; + object_type *adopted = 0; + env_type *env = 0; - gc_register_root(vm->gc, (void **)&env); + gc_register_root(vm->gc, (void **)&env); - vm->reg1 = parent = vm_pop(vm); - vm->reg2 = child = vm_pop(vm); + vm->reg1 = parent = vm_pop(vm); + vm->reg2 = child = vm_pop(vm); - if(!parent || parent->type != CLOSURE) { - throw(vm, "Attempt to adopt with non-closure", 1, parent); + if (!parent || parent->type != CLOSURE) { + throw(vm, "Attempt to adopt with non-closure", 1, parent); - } else if(!child || child->type != CLOSURE) { - throw(vm, "Attempt to adopt non-closure", 1, child); + } else if (!child || child->type != CLOSURE) { + throw(vm, "Attempt to adopt non-closure", 1, child); - } else { - vm->reg3 = adopted = vm_alloc(vm, CLOSURE); + } else { + vm->reg3 = adopted = vm_alloc(vm, CLOSURE); - /* copy the child into the new closure */ - clone_env(vm, (env_type **)&env, - ((env_type *)child->value.closure), true); + /* copy the child into the new closure */ + clone_env(vm, (env_type **)&env, ((env_type *)child->value.closure), true); - adopted->value.closure = env; + adopted->value.closure = env; - /* Setup adopted to use bindings/parent of parent */ - env->parent = ((env_type *)parent->value.closure)->parent; - env->bindings = ((env_type *)parent->value.closure)->bindings; + /* Setup adopted to use bindings/parent of parent */ + env->parent = ((env_type *)parent->value.closure)->parent; + env->bindings = ((env_type *)parent->value.closure)->bindings; - vm_push(vm, adopted); - } + vm_push(vm, adopted); + } - gc_unregister_root(vm->gc, (void **)&env); + gc_unregister_root(vm->gc, (void **)&env); } /* create a procedure reference based on target and leave it @@ -95,7 +91,7 @@ void op_proc(vm_internal_type *vm) { clone_env(vm, &env, vm->env, false); /* update the ip */ - env->ip +=target; + env->ip += target; closure->value.closure = env; @@ -113,7 +109,7 @@ void op_jin(vm_internal_type *vm) { vm->reg1 = closure = vm_pop(vm); - if(!closure || closure->type != CLOSURE) { + if (!closure || closure->type != CLOSURE) { throw(vm, "Attempt to jump to non-closure", 1, closure); } else { @@ -141,7 +137,7 @@ void op_ret(vm_internal_type *vm) { vm->reg1 = closure = vm_pop(vm); - if(!closure || closure->type != CLOSURE) { + if (!closure || closure->type != CLOSURE) { throw(vm, "Attempt to jump to non-closure", 1, closure); } else { @@ -151,7 +147,6 @@ void op_ret(vm_internal_type *vm) { } } - /* call indirect operation */ void op_call_in(vm_internal_type *vm) { object_type *closure = 0; @@ -159,7 +154,7 @@ void op_call_in(vm_internal_type *vm) { vm->reg1 = closure = vm_pop(vm); - if(!closure || closure->type != CLOSURE) { + if (!closure || closure->type != CLOSURE) { throw(vm, "Attempt to jump to non-closure", 1, closure); } else { @@ -184,7 +179,7 @@ void op_tail_call_in(vm_internal_type *vm) { vm->reg1 = closure = vm_pop(vm); - if(!closure || closure->type != CLOSURE) { + if (!closure || closure->type != CLOSURE) { throw(vm, "Attempt to jump to non-closure", 1, closure); } else { diff --git a/src/libinsomniac_vm/libinsomniac_vm_instructions/vm_library.c b/src/libinsomniac_vm/libinsomniac_vm_instructions/vm_library.c index 6d37bf8..9f0086f 100644 --- a/src/libinsomniac_vm/libinsomniac_vm_instructions/vm_library.c +++ b/src/libinsomniac_vm/libinsomniac_vm_instructions/vm_library.c @@ -22,7 +22,7 @@ void op_import(vm_internal_type *vm) { obj = vm_pop(vm); - if(!obj || obj->type != STRING) { + if (!obj || obj->type != STRING) { throw(vm, "Attempt to import with non-string filename", 1, obj); } else { @@ -35,21 +35,22 @@ void op_import(vm_internal_type *vm) { /* if we have already imported this library, return the existing library object */ - if(hash_get(vm->import_table, path, (void**)&lib)) { + if (hash_get(vm->import_table, path, (void **)&lib)) { vm_push(vm, lib); } else { /* check if the library has been loaded */ handle = dlopen(path, RTLD_NOW | RTLD_LOCAL | RTLD_NOLOAD); /* load the library if it has not been loaded */ - if(!handle) { - /* handle = dlopen(obj->value.string.bytes, RTLD_NOW | RTLD_LOCAL | RTLD_DEEPBIND); */ + if (!handle) { + /* handle = dlopen(obj->value.string.bytes, RTLD_NOW | + * RTLD_LOCAL | RTLD_DEEPBIND); */ /* RTLD_DEEPBIND is not defined on osx ... */ handle = dlopen(path, RTLD_NOW | RTLD_LOCAL); } /* check to make sure we did not run into an error */ - if(!handle) { + if (!handle) { throw(vm, dlerror(), 1, obj); } else { lib = vm_alloc(vm, LIBRARY); @@ -57,13 +58,13 @@ void op_import(vm_internal_type *vm) { dlerror(); /* Clear error states */ export_list = (binding_type **)dlsym(handle, "export_list"); - if((msg = dlerror())) { + if ((msg = dlerror())) { throw(vm, msg, 1, obj); } else { func_count = 0; - while(((binding_type *)export_list)[func_count].func) { + while (((binding_type *)export_list)[func_count].func) { func_count++; } @@ -90,13 +91,11 @@ void op_import(vm_internal_type *vm) { func_count = 0; /* count the number of functions */ - while(((binding_type *)export_list)[func_count].func) { + while (((binding_type *)export_list)[func_count].func) { symbol = ((binding_type *)export_list)[func_count].symbol; /* create string object */ - obj = vm_make_string(vm, - symbol, - strlen(symbol)); + obj = vm_make_string(vm, symbol, strlen(symbol)); /* make our string into a symbol */ make_symbol(vm, &obj); @@ -141,13 +140,13 @@ void op_call_ext(vm_internal_type *vm) { depth = vm->depth; /* Save depth before call */ - if(!obj || !lib || obj->type != FIXNUM || lib->type != LIBRARY) { + if (!obj || !lib || obj->type != FIXNUM || lib->type != LIBRARY) { throw(vm, "Invalid arguments to call_ext", 2, obj, lib); } else { func = obj->value.integer; - if(func > lib->value.library.func_count) { + if (func > lib->value.library.func_count) { throw(vm, "Invalid function number", 2, obj, lib); } else { @@ -159,7 +158,7 @@ void op_call_ext(vm_internal_type *vm) { /* Make sure that something was returned */ if (vm->depth != depth) { - throw(vm, "Stack uneven after call_ext", 0 ); + throw(vm, "Stack uneven after call_ext", 0); } gc_unregister_root(vm->gc, (void **)&lib); @@ -169,7 +168,7 @@ void op_call_ext(vm_internal_type *vm) { /* assemble a string on the stack into a proc */ void op_asm(vm_internal_type *vm) { object_type *obj = 0; - object_type *closure =0; + object_type *closure = 0; env_type *env = 0; uint8_t *code_ref = 0; @@ -182,7 +181,7 @@ void op_asm(vm_internal_type *vm) { obj = vm_pop(vm); - if(!obj || obj->type != STRING) { + if (!obj || obj->type != STRING) { throw(vm, "Attempt to assemble non-string", 1, obj); } else { @@ -210,5 +209,4 @@ void op_asm(vm_internal_type *vm) { gc_unregister_root(vm->gc, (void **)&code_ref); gc_unregister_root(vm->gc, (void **)&closure); gc_unregister_root(vm->gc, (void **)&obj); - } diff --git a/src/libinsomniac_vm/libinsomniac_vm_instructions/vm_list.c b/src/libinsomniac_vm/libinsomniac_vm_instructions/vm_list.c index 4f107ab..1e1d8e3 100644 --- a/src/libinsomniac_vm/libinsomniac_vm_instructions/vm_list.c +++ b/src/libinsomniac_vm/libinsomniac_vm_instructions/vm_list.c @@ -19,10 +19,10 @@ void op_car(vm_internal_type *vm) { vm->reg1 = obj = vm_pop(vm); - if(obj && obj->type == PAIR) { + if (obj && obj->type == PAIR) { vm->reg1 = obj = obj->value.pair.car; - vm_push(vm,obj); + vm_push(vm, obj); } else { @@ -36,10 +36,10 @@ void op_cdr(vm_internal_type *vm) { vm->reg1 = obj = vm_pop(vm); - if(obj && obj->type == PAIR) { + if (obj && obj->type == PAIR) { vm->reg1 = obj = obj->value.pair.cdr; - vm_push(vm,obj); + vm_push(vm, obj); } else { @@ -55,14 +55,16 @@ void op_set_car(vm_internal_type *vm) { vm->reg1 = obj = vm_pop(vm); vm->reg2 = pair = vm_pop(vm); - if(obj && pair && pair->type == PAIR) { + if (obj && pair && pair->type == PAIR) { pair->value.pair.car = obj; vm_push(vm, pair); } else { - throw(vm, "Attempt to set the car of a non-pair or set car to non-object", 2, obj, pair); + throw( + vm, "Attempt to set the car of a non-pair or set car to non-object", 2, obj, + pair); } } @@ -74,13 +76,15 @@ void op_set_cdr(vm_internal_type *vm) { vm->reg1 = obj = vm_pop(vm); vm->reg2 = pair = vm_pop(vm); - if(obj && pair && pair->type == PAIR) { + if (obj && pair && pair->type == PAIR) { pair->value.pair.cdr = obj; vm_push(vm, pair); } else { - throw(vm, "Attempt to set the cdr of a non-pair or set cdr to non-object", 2, obj, pair); + throw( + vm, "Attempt to set the cdr of a non-pair or set cdr to non-object", 2, obj, + pair); } } diff --git a/src/libinsomniac_vm/libinsomniac_vm_instructions/vm_literals.c b/src/libinsomniac_vm/libinsomniac_vm_instructions/vm_literals.c index 82bb14e..b90a370 100644 --- a/src/libinsomniac_vm/libinsomniac_vm_instructions/vm_literals.c +++ b/src/libinsomniac_vm/libinsomniac_vm_instructions/vm_literals.c @@ -20,7 +20,7 @@ void op_lit_char(vm_internal_type *vm) { uint8_t byte = 0; /* ip should be pointed at the instructions argument */ - for(int i=4; i>=0; i--) { + for (int i = 4; i >= 0; i--) { byte = vm->env->code_ref[vm->env->ip + i]; character = character << 8; @@ -37,19 +37,13 @@ void op_lit_char(vm_internal_type *vm) { } /* push the empty object onto the stack */ -void op_lit_empty(vm_internal_type *vm) { - vm_push(vm, vm->empty); -} +void op_lit_empty(vm_internal_type *vm) { vm_push(vm, vm->empty); } /* push a true object onto the stack */ -void op_lit_true(vm_internal_type *vm) { - vm_push(vm, vm->vm_true); -} +void op_lit_true(vm_internal_type *vm) { vm_push(vm, vm->vm_true); } /* push a true object onto the stack */ -void op_lit_false(vm_internal_type *vm) { - vm_push(vm, vm->vm_false); -} +void op_lit_false(vm_internal_type *vm) { vm_push(vm, vm->vm_false); } /* load a string litteral and push it onto the stack*/ void op_lit_symbol(vm_internal_type *vm) { diff --git a/src/libinsomniac_vm/libinsomniac_vm_instructions/vm_locations.c b/src/libinsomniac_vm/libinsomniac_vm_instructions/vm_locations.c index b624470..dd59d50 100644 --- a/src/libinsomniac_vm/libinsomniac_vm_instructions/vm_locations.c +++ b/src/libinsomniac_vm/libinsomniac_vm_instructions/vm_locations.c @@ -12,18 +12,13 @@ void op_bind(vm_internal_type *vm) { value = vm_pop(vm); /* make sure the key is a symbol */ - if(!key || key->type != SYMBOL) { + if (!key || key->type != SYMBOL) { throw(vm, "Attempt to bind with non-symbol", 2, key, value); - } else if (hash_get(vm->env->bindings, - key->value.string.bytes, 0)) { - throw( - vm, "Attempt to bind previously bound symbol", 2, key, value - ); + } else if (hash_get(vm->env->bindings, key->value.string.bytes, 0)) { + throw(vm, "Attempt to bind previously bound symbol", 2, key, value); } else { /* do the actual bind */ - hash_set(vm->env->bindings, - key->value.string.bytes, - value); + hash_set(vm->env->bindings, key->value.string.bytes, value); } gc_unregister_root(vm->gc, (void **)&value); @@ -41,8 +36,8 @@ void op_read(vm_internal_type *vm) { key = vm_pop(vm); /* make sure the key is a symbol */ - if(!key || key->type != SYMBOL) { - throw(vm,"Attempt to read with non-symbol", 1, key); + if (!key || key->type != SYMBOL) { + throw(vm, "Attempt to read with non-symbol", 1, key); /* there has to be a better way to do this */ gc_unregister_root(vm->gc, (void **)&value); @@ -53,14 +48,12 @@ void op_read(vm_internal_type *vm) { /* search all environments and parents for key */ env = vm->env; - while(env && !hash_get(env->bindings, - key->value.string.bytes, - (void**)&value)) { + while (env && !hash_get(env->bindings, key->value.string.bytes, (void **)&value)) { env = env->parent; } /* we didn't find anything */ - if(!value) { + if (!value) { throw(vm, "Attempt to read undefined symbol", 1, key); } else { @@ -85,7 +78,7 @@ void op_set(vm_internal_type *vm) { value = vm_pop(vm); /* make sure the key is a symbol */ - if(!key || key->type != SYMBOL) { + if (!key || key->type != SYMBOL) { throw(vm, "Attempt to set with non-symbol", 2, key, value); gc_unregister_root(vm->gc, (void **)&value); @@ -96,22 +89,19 @@ void op_set(vm_internal_type *vm) { /* search all environments and parents for key */ env = vm->env; - while(env && !done) { + while (env && !done) { /* did we find a binding for the symbol? */ - if(hash_get(env->bindings, - key->value.string.bytes, 0)) { + if (hash_get(env->bindings, key->value.string.bytes, 0)) { done = 1; /* save the value */ - hash_set(env->bindings, - key->value.string.bytes, - value); + hash_set(env->bindings, key->value.string.bytes, value); } env = env->parent; } /* don't allow writing of undefined symbols */ - if(!done) { + if (!done) { throw(vm, "Attempt to set undefined symbol", 2, key, value); } @@ -127,7 +117,7 @@ void op_set_exit(vm_internal_type *vm) { value = vm_pop(vm); /* make sure the key is a symbol */ - if(!value || value->type != FIXNUM) { + if (!value || value->type != FIXNUM) { throw(vm, "Attempt to set non-number exit status", 1, value); } else { @@ -136,4 +126,3 @@ void op_set_exit(vm_internal_type *vm) { gc_unregister_root(vm->gc, (void **)&value); } - diff --git a/src/libinsomniac_vm/libinsomniac_vm_instructions/vm_logic.c b/src/libinsomniac_vm/libinsomniac_vm_instructions/vm_logic.c index 33a2752..ffb0bd5 100644 --- a/src/libinsomniac_vm/libinsomniac_vm_instructions/vm_logic.c +++ b/src/libinsomniac_vm/libinsomniac_vm_instructions/vm_logic.c @@ -9,37 +9,33 @@ void op_eq(vm_internal_type *vm) { vm->reg1 = obj1 = vm_pop(vm); vm->reg2 = obj2 = vm_pop(vm); - /* make sure we have actual objects */ - if((!obj1 || !obj2) - && (obj1->type != obj2->type)) { + if ((!obj1 || !obj2) && (obj1->type != obj2->type)) { vm_push(vm, vm->vm_false); } else { /* Do comparisons for special types */ - switch(obj1->type) { - case FIXNUM: - result = obj1->value.integer == obj2->value.integer; - break; - case BOOL: - result = obj1->value.boolean == obj2->value.boolean; - break; - case CHAR: - result = obj1->value.character == obj2->value.character; - break; - case STRING: - result = !strcmp(obj1->value.string.bytes, - obj2->value.string.bytes); - break; - default: - result = obj1 == obj2; - break; + switch (obj1->type) { + case FIXNUM: + result = obj1->value.integer == obj2->value.integer; + break; + case BOOL: + result = obj1->value.boolean == obj2->value.boolean; + break; + case CHAR: + result = obj1->value.character == obj2->value.character; + break; + case STRING: + result = !strcmp(obj1->value.string.bytes, obj2->value.string.bytes); + break; + default: + result = obj1 == obj2; + break; } /* push the result onto the stack */ vm_push(vm, result ? vm->vm_true : vm->vm_false); } - } /* return the boolean inverse of the given object */ @@ -48,13 +44,13 @@ void op_not(vm_internal_type *vm) { vm->reg1 = obj = vm_pop(vm); - if(!obj) { + if (!obj) { printf("Stack Underrun!"); assert(0); } /* only #f is false */ - if(obj->type == BOOL && !obj->value.boolean) { + if (obj->type == BOOL && !obj->value.boolean) { vm_push(vm, vm->vm_true); } else { vm_push(vm, vm->vm_false); diff --git a/src/libinsomniac_vm/libinsomniac_vm_instructions/vm_math.h b/src/libinsomniac_vm/libinsomniac_vm_instructions/vm_math.h index 29ff10c..f507957 100644 --- a/src/libinsomniac_vm/libinsomniac_vm_instructions/vm_math.h +++ b/src/libinsomniac_vm/libinsomniac_vm_instructions/vm_math.h @@ -2,64 +2,60 @@ #define _VM_MATH_ /* Math operations */ -#define NUMERIC_OP(fn_name, op) \ -void fn_name(vm_internal_type *vm) { \ - object_type *num1 = 0; \ - object_type *num2 = 0; \ - object_type *result = 0; \ - \ - /* verify that the firt two objects are number */ \ - vm->reg2 = num2 = vm_pop(vm); \ - vm->reg1 = num1 = vm_pop(vm); \ - \ - /* TODO: replace this with sane exception \ - handler */ \ - if(!num1 || num1->type != FIXNUM || \ - !num2 || num2->type != FIXNUM) { \ - printf("Attempt to calculate with non-number\n");\ - output_object(stdout,num1); \ - printf("\n"); \ - output_object(stdout,num2); \ - assert(0); \ - } \ - \ - vm->reg3 = result = vm_alloc(vm, FIXNUM); \ - \ - result->value.integer = \ - num1->value.integer op num2->value.integer; \ - vm_push(vm, result); \ -} \ +#define NUMERIC_OP(fn_name, op) \ + void fn_name(vm_internal_type *vm) { \ + object_type *num1 = 0; \ + object_type *num2 = 0; \ + object_type *result = 0; \ + \ + /* verify that the firt two objects are number */ \ + vm->reg2 = num2 = vm_pop(vm); \ + vm->reg1 = num1 = vm_pop(vm); \ + \ + /* TODO: replace this with sane exception \ + handler */ \ + if (!num1 || num1->type != FIXNUM || !num2 || num2->type != FIXNUM) { \ + printf("Attempt to calculate with non-number\n"); \ + output_object(stdout, num1); \ + printf("\n"); \ + output_object(stdout, num2); \ + assert(0); \ + } \ + \ + vm->reg3 = result = vm_alloc(vm, FIXNUM); \ + \ + result->value.integer = num1->value.integer op num2->value.integer; \ + vm_push(vm, result); \ + } - -#define NUMERIC_LOGIC(fn_name, op) \ -void fn_name(vm_internal_type *vm) { \ - object_type *num1 = 0; \ - object_type *num2 = 0; \ - object_type *result = 0; \ - \ - /* verify that the firt two objects are number */ \ - vm->reg2 = num2 = vm_pop(vm); \ - vm->reg1 = num1 = vm_pop(vm); \ - \ - /* TODO: replace this with sane exception \ - handler */ \ - if(!num1 || num1->type != FIXNUM || \ - !num2 || num2->type != FIXNUM) { \ - printf("Attempt to compare with non-number\n");\ - printf("\""); \ - output_object(stdout,num1); \ - printf("\"\n\""); \ - output_object(stdout,num2); \ - printf("\"\n"); \ - assert(0); \ - } \ - \ - if(num1->value.integer op num2->value.integer) { \ - result = vm->vm_true; \ - } else { \ - result = vm->vm_false; \ - } \ - vm_push(vm, result); \ -} \ +#define NUMERIC_LOGIC(fn_name, op) \ + void fn_name(vm_internal_type *vm) { \ + object_type *num1 = 0; \ + object_type *num2 = 0; \ + object_type *result = 0; \ + \ + /* verify that the firt two objects are number */ \ + vm->reg2 = num2 = vm_pop(vm); \ + vm->reg1 = num1 = vm_pop(vm); \ + \ + /* TODO: replace this with sane exception \ + handler */ \ + if (!num1 || num1->type != FIXNUM || !num2 || num2->type != FIXNUM) { \ + printf("Attempt to compare with non-number\n"); \ + printf("\""); \ + output_object(stdout, num1); \ + printf("\"\n\""); \ + output_object(stdout, num2); \ + printf("\"\n"); \ + assert(0); \ + } \ + \ + if (num1->value.integer op num2->value.integer) { \ + result = vm->vm_true; \ + } else { \ + result = vm->vm_false; \ + } \ + vm_push(vm, result); \ + } #endif diff --git a/src/libinsomniac_vm/libinsomniac_vm_instructions/vm_ops.c b/src/libinsomniac_vm/libinsomniac_vm_instructions/vm_ops.c index 96f224e..d8ef6b5 100644 --- a/src/libinsomniac_vm/libinsomniac_vm_instructions/vm_ops.c +++ b/src/libinsomniac_vm/libinsomniac_vm_instructions/vm_ops.c @@ -3,7 +3,6 @@ #include "vm_math.h" #include "vm_types.h" - /* Math operations */ NUMERIC_OP(op_add, +) NUMERIC_OP(op_sub, -) @@ -22,18 +21,17 @@ TYPE_OP(op_is_char, TYPE_TEST(CHAR)) TYPE_OP(op_is_string, TYPE_TEST(STRING)) TYPE_OP(op_is_symbol, TYPE_TEST(SYMBOL)) TYPE_OP(op_is_vector, TYPE_TEST(VECTOR)) -TYPE_OP(op_is_slice, (TYPE_TEST(VECTOR) || TYPE_TEST(BYTE_VECTOR)) && obj->value.vector.slice) +TYPE_OP( + op_is_slice, (TYPE_TEST(VECTOR) || TYPE_TEST(BYTE_VECTOR)) && obj->value.vector.slice) TYPE_OP(op_is_byte_vector, TYPE_TEST(BYTE_VECTOR)) TYPE_OP(op_is_record, TYPE_TEST(RECORD)) TYPE_OP(op_is_pair, TYPE_TEST(PAIR)) TYPE_OP(op_is_empty, TYPE_TEST(EMPTY)) TYPE_OP(op_is_closure, TYPE_TEST(CLOSURE)) TYPE_OP(op_is_library, TYPE_TEST(LIBRARY)) -TYPE_OP(op_is_self, \ - (TYPE_TEST(FIXNUM) || TYPE_TEST(BOOL) || TYPE_TEST(CHAR) || TYPE_TEST(STRING) \ - || TYPE_TEST(VECTOR) || TYPE_TEST(BYTE_VECTOR) ) \ -) - +TYPE_OP( + op_is_self, (TYPE_TEST(FIXNUM) || TYPE_TEST(BOOL) || TYPE_TEST(CHAR) || + TYPE_TEST(STRING) || TYPE_TEST(VECTOR) || TYPE_TEST(BYTE_VECTOR))) /* setup of instructions in given vm instance */ void setup_instructions(vm_internal_type *vm) { @@ -65,7 +63,6 @@ void setup_instructions(vm_internal_type *vm) { vm->ops[OP_SET] = &op_set; vm->ops[OP_READ] = &op_read; - /* stack operations */ vm->ops[OP_SWAP] = &op_swap; vm->ops[OP_ROT] = &op_rot; @@ -105,13 +102,12 @@ void setup_instructions(vm_internal_type *vm) { vm->ops[OP_CALL] = &op_call; vm->ops[OP_ADOPT] = &op_adopt; vm->ops[OP_PROC] = &op_proc; - vm->ops[OP_RET] = &op_ret; /* return */ - vm->ops[OP_JIN] = &op_jin; /* jump indirect */ + vm->ops[OP_RET] = &op_ret; /* return */ + vm->ops[OP_JIN] = &op_jin; /* jump indirect */ vm->ops[OP_CALL_IN] = &op_call_in; /* call indirect */ vm->ops[OP_TAIL_CALL_IN] = &op_tail_call_in; - - vm->ops[OP_IMPORT] = &op_import; /* dlopen a dll */ + vm->ops[OP_IMPORT] = &op_import; /* dlopen a dll */ vm->ops[OP_CALL_EXT] = &op_call_ext; /* call an imported function */ /* Exception Handline */ @@ -138,4 +134,3 @@ void setup_instructions(vm_internal_type *vm) { /* internals operations */ vm->ops[OP_GC_STATS] = &op_gc_stats; } - diff --git a/src/libinsomniac_vm/libinsomniac_vm_instructions/vm_stack.c b/src/libinsomniac_vm/libinsomniac_vm_instructions/vm_stack.c index 69c7ad0..30ec277 100644 --- a/src/libinsomniac_vm/libinsomniac_vm_instructions/vm_stack.c +++ b/src/libinsomniac_vm/libinsomniac_vm_instructions/vm_stack.c @@ -20,7 +20,6 @@ void op_rot(vm_internal_type *vm) { vm_push(vm, vm->reg1); vm_push(vm, vm->reg3); vm_push(vm, vm->reg2); - } /* duplicate the reference on top of the stack */ @@ -43,6 +42,4 @@ void op_depth(vm_internal_type *vm) { } /* drop the top item on the stack */ -void op_drop(vm_internal_type *vm) { - vm_pop(vm); -} +void op_drop(vm_internal_type *vm) { vm_pop(vm); } diff --git a/src/libinsomniac_vm/libinsomniac_vm_instructions/vm_types.h b/src/libinsomniac_vm/libinsomniac_vm_instructions/vm_types.h index 34be681..c9c7ee5 100644 --- a/src/libinsomniac_vm/libinsomniac_vm_instructions/vm_types.h +++ b/src/libinsomniac_vm/libinsomniac_vm_instructions/vm_types.h @@ -4,19 +4,17 @@ #define TYPE_TEST(obj_type) obj->type == obj_type /* A macro that can be used to define a set of type checks */ -#define TYPE_OP(fn_name, type_test) \ -void fn_name(vm_internal_type *vm) { \ - object_type *obj = 0; \ - \ - vm->reg1 = obj = vm_pop(vm); \ - \ - if(obj && type_test) { \ - vm_push(vm, vm->vm_true); \ - } else { \ - vm_push(vm, vm->vm_false); \ - } \ - \ -} \ - +#define TYPE_OP(fn_name, type_test) \ + void fn_name(vm_internal_type *vm) { \ + object_type *obj = 0; \ + \ + vm->reg1 = obj = vm_pop(vm); \ + \ + if (obj && type_test) { \ + vm_push(vm, vm->vm_true); \ + } else { \ + vm_push(vm, vm->vm_false); \ + } \ + } #endif diff --git a/src/libinsomniac_vm/libinsomniac_vm_instructions/vm_vector.c b/src/libinsomniac_vm/libinsomniac_vm_instructions/vm_vector.c index 45a17e8..60893e9 100644 --- a/src/libinsomniac_vm/libinsomniac_vm_instructions/vm_vector.c +++ b/src/libinsomniac_vm/libinsomniac_vm_instructions/vm_vector.c @@ -59,7 +59,7 @@ void op_vector_length(vm_internal_type *vm) { vm->reg1 = obj = vm_pop(vm); if (!obj || (obj->type != VECTOR && obj->type != BYTE_VECTOR)) { - throw(vm, "Attempt to read vector length of non-vector!", 1, obj); + throw(vm, "Attempt to read vector length of non-vector!", 1, obj); } vm->reg2 = length = vm_alloc(vm, FIXNUM); @@ -83,8 +83,11 @@ void op_index_set(vm_internal_type *vm) { index = obj_index->value.integer; - assert(vector && (vector->type == VECTOR || vector->type == RECORD || vector->type == BYTE_VECTOR) && - vector->value.vector.length >= index); + assert( + vector && + (vector->type == VECTOR || vector->type == RECORD || + vector->type == BYTE_VECTOR) && + vector->value.vector.length >= index); /* do the set */ if (vector->type == VECTOR || vector->type == RECORD) { @@ -109,8 +112,11 @@ void op_index_ref(vm_internal_type *vm) { index = obj_index->value.integer; - assert(vector && (vector->type == VECTOR || vector->type == RECORD || vector->type == BYTE_VECTOR) && - vector->value.vector.length >= index); + assert( + vector && + (vector->type == VECTOR || vector->type == RECORD || + vector->type == BYTE_VECTOR) && + vector->value.vector.length >= index); /* do the read */ if (vector->type == VECTOR || vector->type == RECORD) { @@ -135,26 +141,29 @@ void op_slice(vm_internal_type *vm) { vm->reg2 = end = vm_pop(vm); vm->reg3 = start = vm_pop(vm); - assert(vector && (vector->type == VECTOR || vector->type == BYTE_VECTOR) && vector->value.vector.length >= end->value.integer); + assert( + vector && (vector->type == VECTOR || vector->type == BYTE_VECTOR) && + vector->value.vector.length >= end->value.integer); length = end->value.integer - start->value.integer; assert(length >= 0); - /* Vector and bytevector have the same internal structure, the only difference - are the final pointer types. We can use this to avoid extraneous allocations - and make accessing the members easier. */ + /* Vector and bytevector have the same internal structure, the only + difference are the final pointer types. We can use this to avoid + extraneous allocations and make accessing the members easier. */ vm->reg2 = vm_alloc(vm, vector->type); vm->reg2->value.byte_vector.length = MIN(length, vector->value.byte_vector.length); vm->reg2->value.byte_vector.slice = true; /* We need to know the type to determine the size to offset by. */ if (vector->type == VECTOR) { - vm->reg2->value.vector.vector = vector->value.vector.vector + start->value.integer; + vm->reg2->value.vector.vector = + vector->value.vector.vector + start->value.integer; } else { - vm->reg2->value.byte_vector.vector = vector->value.byte_vector.vector + start->value.integer; + vm->reg2->value.byte_vector.vector = + vector->value.byte_vector.vector + start->value.integer; } vm_push(vm, vm->reg2); } - diff --git a/src/libinsomniac_vm/vm_alloc.c b/src/libinsomniac_vm/vm_alloc.c index 0f70e6f..e94ce04 100644 --- a/src/libinsomniac_vm/vm_alloc.c +++ b/src/libinsomniac_vm/vm_alloc.c @@ -3,46 +3,46 @@ /* Deal with cell alloction */ object_type *vm_alloc(vm_type *vm_void, cell_type type) { vm_internal_type *vm = (vm_internal_type *)vm_void; - object_type *obj=0; + object_type *obj = 0; if (type == EMPTY && vm->empty) { - return vm->empty; + return vm->empty; } /* Allocate an object using the GC type system */ gc_alloc_type(vm->gc, 0, vm->types[type], (void **)&obj); - obj->type=type; + obj->type = type; return obj; } /* Create a string object from the given string */ object_type *vm_make_string(vm_type *vm_void, char *buf, vm_int length) { - vm_internal_type *vm=(vm_internal_type *)vm_void; + vm_internal_type *vm = (vm_internal_type *)vm_void; object_type *obj = 0; /* construct a new string object using the length and passed in character buffer */ - gc_register_root(vm->gc, (void**)&obj); + gc_register_root(vm->gc, (void **)&obj); obj = vm_alloc(vm, STRING); obj->value.string.length = length; - gc_alloc(vm->gc, 0, length+1, (void**)&(obj->value.string.bytes)); + gc_alloc(vm->gc, 0, length + 1, (void **)&(obj->value.string.bytes)); strncpy(obj->value.string.bytes, buf, length); - gc_unregister_root(vm->gc, (void**)&obj); + gc_unregister_root(vm->gc, (void **)&obj); return obj; } /* Allocate an empty byte vector of the given size */ object_type *vm_make_byte_vector(vm_type *vm_void, vm_int length) { - vm_internal_type *vm=(vm_internal_type *)vm_void; + vm_internal_type *vm = (vm_internal_type *)vm_void; object_type *obj = 0; - gc_register_root(vm->gc, (void**)&obj); + gc_register_root(vm->gc, (void **)&obj); obj = vm_alloc(vm, BYTE_VECTOR); obj->value.byte_vector.length = length; @@ -51,17 +51,17 @@ object_type *vm_make_byte_vector(vm_type *vm_void, vm_int length) { /* allocate an array of pointers */ gc_alloc(vm->gc, 0, length, (void **)&(obj->value.byte_vector.vector)); - gc_unregister_root(vm->gc, (void**)&obj); + gc_unregister_root(vm->gc, (void **)&obj); return obj; } /* Allocate an empty vector of the given size */ object_type *vm_make_vector(vm_type *vm_void, vm_int length) { - vm_internal_type *vm=(vm_internal_type *)vm_void; + vm_internal_type *vm = (vm_internal_type *)vm_void; object_type *obj = 0; - gc_register_root(vm->gc, (void**)&obj); + gc_register_root(vm->gc, (void **)&obj); obj = vm_alloc(vm, VECTOR); obj->value.vector.length = length; @@ -70,7 +70,7 @@ object_type *vm_make_vector(vm_type *vm_void, vm_int length) { /* allocate an array of pointers */ gc_alloc_pointer_array(vm->gc, 0, length, (void **)&(obj->value.vector.vector)); - gc_unregister_root(vm->gc, (void**)&obj); + gc_unregister_root(vm->gc, (void **)&obj); return obj; } diff --git a/src/libinsomniac_vm/vm_core.c b/src/libinsomniac_vm/vm_core.c index c805a7b..b4a3531 100644 --- a/src/libinsomniac_vm/vm_core.c +++ b/src/libinsomniac_vm/vm_core.c @@ -1,16 +1,16 @@ #include "vm_internal.h" -void vm_create(gc_type *gc, vm_type **vm_ret ) { +void vm_create(gc_type *gc, vm_type **vm_ret) { gc_type_def vm_type_def = 0; vm_internal_type *vm = 0; - gc_register_root(gc, (void**)&vm); + gc_register_root(gc, (void **)&vm); vm_type_def = create_vm_type(gc); /* create a permanent vm object */ /* vm = gc_alloc_type(gc, 1, vm_type_def); */ - gc_alloc_type(gc, 0, vm_type_def, (void**)&vm); + gc_alloc_type(gc, 0, vm_type_def, (void **)&vm); vm->gc = gc; @@ -49,10 +49,9 @@ void vm_create(gc_type *gc, vm_type **vm_ret ) { /* save off the vm pointer to our external pointer */ *vm_ret = vm; - gc_unregister_root(gc, (void**)&vm); + gc_unregister_root(gc, (void **)&vm); } - /* Deallocate the vm instance */ void vm_destroy(vm_type *vm_raw) { /* if(vm_raw) { */ @@ -84,7 +83,7 @@ object_type *vm_pop(vm_type *vm_void) { object_type *obj = 0; /* return 0 if the stack is empty */ - if(vm->stack_root->type == EMPTY) { + if (vm->stack_root->type == EMPTY) { fprintf(stderr, "Stack Under Run!\n"); assert(0); return 0; @@ -98,7 +97,6 @@ object_type *vm_pop(vm_type *vm_void) { return obj; } - /* reset a vm instance into a clean state */ void vm_reset(vm_type *vm_void) { vm_internal_type *vm = (vm_internal_type *)vm_void; @@ -109,6 +107,4 @@ void vm_reset(vm_type *vm_void) { push_env(vm); } -void vm_output_object(FILE *fout, object_type *obj) { - output_object(fout, obj); -} +void vm_output_object(FILE *fout, object_type *obj) { output_object(fout, obj); } diff --git a/src/libinsomniac_vm/vm_env.c b/src/libinsomniac_vm/vm_env.c index 89ab2fb..c45e354 100644 --- a/src/libinsomniac_vm/vm_env.c +++ b/src/libinsomniac_vm/vm_env.c @@ -17,7 +17,7 @@ void push_env(vm_internal_type *vm) { /* if we have a parent, save off the parents ip and code_ref */ - if(vm->env->parent) { + if (vm->env->parent) { vm->env->code_ref = vm->env->parent->code_ref; vm->env->ip = vm->env->parent->ip; vm->env->length = vm->env->parent->length; @@ -27,8 +27,7 @@ void push_env(vm_internal_type *vm) { } /* create a copy of the environment in a new environment */ -void clone_env(vm_internal_type *vm, env_type **target, - env_type *env, bool cow) { +void clone_env(vm_internal_type *vm, env_type **target, env_type *env, bool cow) { gc_alloc_type(vm->gc, 0, vm->env_type, (void **)target); @@ -42,7 +41,7 @@ void clone_env(vm_internal_type *vm, env_type **target, /* pop off the current environment */ void pop_env(vm_internal_type *vm) { - if(vm->env) { + if (vm->env) { vm->env = vm->env->parent; } } diff --git a/src/libinsomniac_vm/vm_eval.c b/src/libinsomniac_vm/vm_eval.c index 25579bd..947bcd5 100644 --- a/src/libinsomniac_vm/vm_eval.c +++ b/src/libinsomniac_vm/vm_eval.c @@ -1,6 +1,5 @@ #include "vm_internal.h" - /* Evaluate the given object using the provided vm instance */ int vm_eval(vm_type *vm_void, size_t length, uint8_t *code_ref) { vm_internal_type *vm = (vm_internal_type *)vm_void; @@ -13,18 +12,17 @@ int vm_eval(vm_type *vm_void, size_t length, uint8_t *code_ref) { vm->env->length = length; /* iterate over instrcutions */ - while(vm->env->ip < vm->env->length) { + while (vm->env->ip < vm->env->length) { /* load instrcutions */ op_code = vm->env->code_ref[vm->env->ip]; op_call = vm->ops[op_code]; - /* incerement ip so it points to any arguments or the next instructions */ vm->env->ip++; /* call instruction */ - if(op_call) { + if (op_call) { (*op_call)(vm); /* Clean up after instructions */ vm->reg1 = vm->reg2 = vm->reg3 = 0; diff --git a/src/libinsomniac_vm/vm_internal.h b/src/libinsomniac_vm/vm_internal.h index 4eb1153..17add3a 100644 --- a/src/libinsomniac_vm/vm_internal.h +++ b/src/libinsomniac_vm/vm_internal.h @@ -1,16 +1,16 @@ #ifndef _VM_INTERNAL_ #define _VM_INTERNAL_ +#include #include #include #include -#include - #include -#include -#include + #include +#include +#include #include #define OUTPUT_MAX_DEPTH 100 @@ -25,14 +25,12 @@ #define LIB_EXT_LEN 3 #endif - typedef struct vm_internal vm_internal_type; typedef struct env env_type; /* Function pointer for operations */ typedef void (*fn_type)(vm_internal_type *vm); - /* An environment, "stack frame" in a language like C */ struct env { @@ -92,7 +90,7 @@ void cons(vm_type *vm, object_type *car, object_type *cdr, object_type **pair_ou vm_int parse_int(vm_internal_type *vm); void parse_string(vm_internal_type *vm, object_type **obj); void make_symbol(vm_internal_type *vm, object_type **obj); -void throw(vm_internal_type *vm, char *msg, int num, ...); +void throw(vm_internal_type * vm, char *msg, int num, ...); void vm_load_buf(vm_internal_type *vm, char *file, object_type **obj); diff --git a/src/libinsomniac_vm/vm_output.c b/src/libinsomniac_vm/vm_output.c index d7b4bde..c41dfa0 100644 --- a/src/libinsomniac_vm/vm_output.c +++ b/src/libinsomniac_vm/vm_output.c @@ -10,7 +10,7 @@ void output_pair(FILE *fout, object_type *pair) { do { /* print a space only if we are not on the first pair */ - if(flag) { + if (flag) { fprintf(fout, " "); } @@ -22,26 +22,24 @@ void output_pair(FILE *fout, object_type *pair) { output_object(fout, car); flag = 1; - length ++; - - } while(pair && pair->type == PAIR && length < OUTPUT_MAX_LENGTH); + length++; + } while (pair && pair->type == PAIR && length < OUTPUT_MAX_LENGTH); /* print a . if need one */ - if(!pair || pair->type != EMPTY) { + if (!pair || pair->type != EMPTY) { fprintf(fout, " . "); output_object(fout, pair); } - - fprintf(fout,")"); + fprintf(fout, ")"); } /* characters are stored in UTF-32 internally while strings and io should be in UTF-8 */ void output_char(FILE *fout, object_type *character) { /* 7 byte output buffer (UTF-8 maxes out at 6 */ - char char_buf[] = {0,0,0, 0,0,0, 0}; + char char_buf[] = {0, 0, 0, 0, 0, 0, 0}; /* encode the string in utf8 */ utf8_encode_char(char_buf, character->value.character); @@ -59,12 +57,11 @@ void output_vector(FILE *fout, object_type *vector) { output them */ fprintf(fout, "#("); - for(index = 0; index < vector->value.vector.length; index++) { - if(index > 0) { + for (index = 0; index < vector->value.vector.length; index++) { + if (index > 0) { fprintf(fout, " "); } - output_object(fout, - vector->value.vector.vector[index]); + output_object(fout, vector->value.vector.vector[index]); } fprintf(fout, ")"); @@ -77,8 +74,8 @@ void output_byte_vector(FILE *fout, object_type *vector) { output them */ fprintf(fout, "#u8("); - for(index = 0; index < vector->value.vector.length; index++) { - if(index > 0) { + for (index = 0; index < vector->value.vector.length; index++) { + if (index > 0) { fprintf(fout, " "); } fprintf(fout, "%u", vector->value.byte_vector.vector[index]); @@ -95,81 +92,81 @@ void output_object(FILE *fout, object_type *obj) { depth++; if (depth >= OUTPUT_MAX_DEPTH) { - fprintf(fout, " ..."); - depth--; - return; + fprintf(fout, " ..."); + depth--; + return; } /* make sure we have an object */ - if(!obj) { + if (!obj) { fprintf(fout, ""); return; } - switch(obj->type) { - - case FIXNUM: /* deal with a standard fixnum */ - fprintf(fout, "%" PRIi64, obj->value.integer); - break; - - case EMPTY: /* The object is an empty pair */ - fprintf(fout, "()"); - break; - - case PAIR: - output_pair(fout, obj); - break; - - case CHAR: - output_char(fout, obj); - break; - - case STRING: - case SYMBOL: - fprintf(fout, "%s", obj->value.string.bytes); - break; - - case VECTOR: - output_vector(fout, obj); - break; - - case BYTE_VECTOR: - output_byte_vector(fout, obj); - break; - - case BOOL: - if(obj->value.boolean) { - fprintf(fout, "#t"); - } else { - fprintf(fout, "#f"); - } - break; - - case CLOSURE: - env = (env_type *)obj->value.closure; - - fprintf(fout, "{"); - while (env) { - fprintf(fout, " %p ", (void *)obj, - (void *)env, - (void *)env->bindings, - (void *)env->parent); - hash_info(env->bindings); - fprintf(fout, ">\n"); - env = env->parent; - } - fprintf(fout, "}"); - - break; - - case LIBRARY: - fprintf(fout, "", (void *)obj, + switch (obj->type) { + + case FIXNUM: /* deal with a standard fixnum */ + fprintf(fout, "%" PRIi64, obj->value.integer); + break; + + case EMPTY: /* The object is an empty pair */ + fprintf(fout, "()"); + break; + + case PAIR: + output_pair(fout, obj); + break; + + case CHAR: + output_char(fout, obj); + break; + + case STRING: + case SYMBOL: + fprintf(fout, "%s", obj->value.string.bytes); + break; + + case VECTOR: + output_vector(fout, obj); + break; + + case BYTE_VECTOR: + output_byte_vector(fout, obj); + break; + + case BOOL: + if (obj->value.boolean) { + fprintf(fout, "#t"); + } else { + fprintf(fout, "#f"); + } + break; + + case CLOSURE: + env = (env_type *)obj->value.closure; + + fprintf(fout, "{"); + while (env) { + fprintf( + fout, " %p ", (void *)obj, (void *)env, + (void *)env->bindings, (void *)env->parent); + hash_info(env->bindings); + fprintf(fout, ">\n"); + env = env->parent; + } + fprintf(fout, "}"); + + break; + + case LIBRARY: + fprintf( + fout, "", (void *)obj, (void *)obj->value.library.handle, obj->value.library.func_count); - break; + break; - default: - fprintf(fout, "", (void *)obj); - break; + default: + fprintf(fout, "", (void *)obj); + break; } depth--; diff --git a/src/libinsomniac_vm/vm_types.c b/src/libinsomniac_vm/vm_types.c index 812799e..45da6bc 100644 --- a/src/libinsomniac_vm/vm_types.c +++ b/src/libinsomniac_vm/vm_types.c @@ -1,6 +1,5 @@ #include "vm_internal.h" - /* setup the definition of a fix num type */ gc_type_def register_basic(gc_type *gc) { return gc_register_type(gc, sizeof(object_type)); @@ -11,14 +10,15 @@ gc_type_def register_pair(gc_type *gc) { gc_type_def pair = 0; pair = gc_register_type(gc, sizeof(object_type)); - gc_register_pointer(gc, pair, - offsetof(object_type, value) + offsetof(value_type, pair) + - offsetof(pair_type, car)); - - gc_register_pointer(gc, pair, - offsetof(object_type, value) + offsetof(value_type, pair) + - offsetof(pair_type, cdr)); + gc_register_pointer( + gc, pair, + offsetof(object_type, value) + offsetof(value_type, pair) + + offsetof(pair_type, car)); + gc_register_pointer( + gc, pair, + offsetof(object_type, value) + offsetof(value_type, pair) + + offsetof(pair_type, cdr)); return pair; } @@ -28,9 +28,10 @@ gc_type_def register_string(gc_type *gc) { gc_type_def str = 0; str = gc_register_type(gc, sizeof(object_type)); - gc_register_pointer(gc, str, - offsetof(object_type, value) + offsetof(value_type, string) + - offsetof(string_type, bytes)); + gc_register_pointer( + gc, str, + offsetof(object_type, value) + offsetof(value_type, string) + + offsetof(string_type, bytes)); return str; } @@ -40,8 +41,8 @@ gc_type_def register_closure(gc_type *gc) { gc_type_def closure = 0; closure = gc_register_type(gc, sizeof(object_type)); - gc_register_pointer(gc, closure, - offsetof(object_type, value) + offsetof(value_type, closure)); + gc_register_pointer( + gc, closure, offsetof(object_type, value) + offsetof(value_type, closure)); return closure; } @@ -55,15 +56,15 @@ gc_type_def register_library(gc_type *gc) { return library; } - /* register a vector type */ gc_type_def register_vector(gc_type *gc) { gc_type_def vector = 0; vector = gc_register_type(gc, sizeof(object_type)); - gc_register_pointer(gc, vector, - offsetof(object_type, value) + offsetof(value_type, vector) + - offsetof(vector_type, vector)); + gc_register_pointer( + gc, vector, + offsetof(object_type, value) + offsetof(value_type, vector) + + offsetof(vector_type, vector)); return vector; } @@ -74,19 +75,16 @@ gc_type_def register_env(gc_type *gc) { env = gc_register_type(gc, sizeof(env_type)); - gc_register_pointer(gc, env, - offsetof(env_type, code_ref)); - gc_register_pointer(gc, env, - offsetof(env_type, bindings)); - gc_register_pointer(gc, env, - offsetof(env_type, parent)); + gc_register_pointer(gc, env, offsetof(env_type, code_ref)); + gc_register_pointer(gc, env, offsetof(env_type, bindings)); + gc_register_pointer(gc, env, offsetof(env_type, parent)); return env; } /* setup gc type definitions */ void create_types(vm_internal_type *vm) { - gc_type *gc=vm->gc; + gc_type *gc = vm->gc; vm->types[FIXNUM] = register_basic(gc); vm->types[PAIR] = register_pair(gc); @@ -105,35 +103,24 @@ void create_types(vm_internal_type *vm) { vm->env_type = register_env(gc); } - /* create/registers the default vm internal type */ gc_type_def create_vm_type(gc_type *gc) { gc_type_def vm_type_def = 0; vm_type_def = gc_register_type(gc, sizeof(vm_internal_type)); - gc_register_pointer(gc, vm_type_def, - offsetof(vm_internal_type, stack_root)); - gc_register_pointer(gc, vm_type_def, - offsetof(vm_internal_type, empty)); - gc_register_pointer(gc, vm_type_def, - offsetof(vm_internal_type, vm_true)); - gc_register_pointer(gc, vm_type_def, - offsetof(vm_internal_type, vm_false)); - - gc_register_pointer(gc, vm_type_def, - offsetof(vm_internal_type, reg1)); - gc_register_pointer(gc, vm_type_def, - offsetof(vm_internal_type, reg2)); - gc_register_pointer(gc, vm_type_def, - offsetof(vm_internal_type, reg3)); - - gc_register_pointer(gc, vm_type_def, - offsetof(vm_internal_type, symbol_table)); - gc_register_pointer(gc, vm_type_def, - offsetof(vm_internal_type, import_table)); - gc_register_pointer(gc, vm_type_def, - offsetof(vm_internal_type, env)); + gc_register_pointer(gc, vm_type_def, offsetof(vm_internal_type, stack_root)); + gc_register_pointer(gc, vm_type_def, offsetof(vm_internal_type, empty)); + gc_register_pointer(gc, vm_type_def, offsetof(vm_internal_type, vm_true)); + gc_register_pointer(gc, vm_type_def, offsetof(vm_internal_type, vm_false)); + + gc_register_pointer(gc, vm_type_def, offsetof(vm_internal_type, reg1)); + gc_register_pointer(gc, vm_type_def, offsetof(vm_internal_type, reg2)); + gc_register_pointer(gc, vm_type_def, offsetof(vm_internal_type, reg3)); + + gc_register_pointer(gc, vm_type_def, offsetof(vm_internal_type, symbol_table)); + gc_register_pointer(gc, vm_type_def, offsetof(vm_internal_type, import_table)); + gc_register_pointer(gc, vm_type_def, offsetof(vm_internal_type, env)); return vm_type_def; } diff --git a/src/libinsomniac_vm/vm_utf8.c b/src/libinsomniac_vm/vm_utf8.c index 722e403..8f82789 100644 --- a/src/libinsomniac_vm/vm_utf8.c +++ b/src/libinsomniac_vm/vm_utf8.c @@ -3,23 +3,23 @@ #include /* for getc */ -#define BIT_MASK(i) ((uint32_t)0xFFFFFFFF >> (32 - i )) +#define BIT_MASK(i) ((uint32_t)0xFFFFFFFF >> (32 - i)) #define NOT_MASK(i) ((uint32_t)0xFFFFFFFF << i) #define UTF8_TAIL 0x80 #define UTF8_8TH_BIT 0x80 -#define UTF8_HEAD(i) (0xFE << (6-i)) +#define UTF8_HEAD(i) (0xFE << (6 - i)) int utf8_head_count_bytes(char c) { int count = 0; - while((c & UTF8_8TH_BIT ) !=0 && count < 6) { - c <<=1; + while ((c & UTF8_8TH_BIT) != 0 && count < 6) { + c <<= 1; count++; } /* if there are no set bits, we have 1 byte */ - if (count == 0 ) { + if (count == 0) { count = 1; } @@ -36,7 +36,7 @@ void utf8_read_char(vm_char *character) { in_c = getchar(); /* handle eof */ - if(in_c == EOF) { + if (in_c == EOF) { *character = -1; return; } @@ -48,7 +48,7 @@ void utf8_read_char(vm_char *character) { /* a count of one means that the head is the only byte */ - if(bytes == 1) { + if (bytes == 1) { *character = c; return; } @@ -60,7 +60,7 @@ void utf8_read_char(vm_char *character) { /* read in the other utf8 bytes, start at one because we have already read one byte. */ - for(int i = 1; i < bytes ; i++) { + for (int i = 1; i < bytes; i++) { c = getchar(); /* shift 6 bits left */ @@ -76,67 +76,67 @@ void utf8_encode_char(char *output, vm_char character) { bzero(output, 7); /* walk through each of the possible mappings */ - if(!(character & NOT_MASK(7))) { - output[0]=(uint8_t)(character & BIT_MASK(7)); + if (!(character & NOT_MASK(7))) { + output[0] = (uint8_t)(character & BIT_MASK(7)); - } else if(!(character & NOT_MASK(11))) { - output[1]=UTF8_TAIL | (uint8_t)(character & BIT_MASK(6)); + } else if (!(character & NOT_MASK(11))) { + output[1] = UTF8_TAIL | (uint8_t)(character & BIT_MASK(6)); character >>= 6; - output[0]=UTF8_HEAD(1) | (uint8_t)character; + output[0] = UTF8_HEAD(1) | (uint8_t)character; - } else if(!(character & NOT_MASK(16))) { - output[2]=UTF8_TAIL | (uint8_t)(character & BIT_MASK(6)); + } else if (!(character & NOT_MASK(16))) { + output[2] = UTF8_TAIL | (uint8_t)(character & BIT_MASK(6)); character >>= 6; - output[1]=UTF8_TAIL | (uint8_t)(character & BIT_MASK(6)); + output[1] = UTF8_TAIL | (uint8_t)(character & BIT_MASK(6)); character >>= 6; - output[0]=UTF8_HEAD(2) | (uint8_t)character; + output[0] = UTF8_HEAD(2) | (uint8_t)character; - } else if(!(character & NOT_MASK(21))) { - output[3]=UTF8_TAIL | (uint8_t)(character & BIT_MASK(6)); + } else if (!(character & NOT_MASK(21))) { + output[3] = UTF8_TAIL | (uint8_t)(character & BIT_MASK(6)); character >>= 6; - output[2]=UTF8_TAIL | (uint8_t)(character & BIT_MASK(6)); + output[2] = UTF8_TAIL | (uint8_t)(character & BIT_MASK(6)); character >>= 6; - output[1]=UTF8_TAIL | (uint8_t)(character & BIT_MASK(6)); + output[1] = UTF8_TAIL | (uint8_t)(character & BIT_MASK(6)); character >>= 6; - output[0]=UTF8_HEAD(3) | (uint8_t)character; + output[0] = UTF8_HEAD(3) | (uint8_t)character; - } else if(!(character & NOT_MASK(26))) { - output[4]=UTF8_TAIL | (uint8_t)(character & BIT_MASK(6)); + } else if (!(character & NOT_MASK(26))) { + output[4] = UTF8_TAIL | (uint8_t)(character & BIT_MASK(6)); character >>= 6; - output[3]=UTF8_TAIL | (uint8_t)(character & BIT_MASK(6)); + output[3] = UTF8_TAIL | (uint8_t)(character & BIT_MASK(6)); character >>= 6; - output[2]=UTF8_TAIL | (uint8_t)(character & BIT_MASK(6)); + output[2] = UTF8_TAIL | (uint8_t)(character & BIT_MASK(6)); character >>= 6; - output[1]=UTF8_TAIL | (uint8_t)(character & BIT_MASK(6)); + output[1] = UTF8_TAIL | (uint8_t)(character & BIT_MASK(6)); character >>= 6; - output[0]=UTF8_HEAD(4) | (uint8_t)character; + output[0] = UTF8_HEAD(4) | (uint8_t)character; - } else if(!(character & NOT_MASK(31))) { - output[5]=UTF8_TAIL | (uint8_t)(character & BIT_MASK(6)); + } else if (!(character & NOT_MASK(31))) { + output[5] = UTF8_TAIL | (uint8_t)(character & BIT_MASK(6)); character >>= 6; - output[4]=UTF8_TAIL | (uint8_t)(character & BIT_MASK(6)); + output[4] = UTF8_TAIL | (uint8_t)(character & BIT_MASK(6)); character >>= 6; - output[3]=UTF8_TAIL | (uint8_t)(character & BIT_MASK(6)); + output[3] = UTF8_TAIL | (uint8_t)(character & BIT_MASK(6)); character >>= 6; - output[2]=UTF8_TAIL | (uint8_t)(character & BIT_MASK(6)); + output[2] = UTF8_TAIL | (uint8_t)(character & BIT_MASK(6)); character >>= 6; - output[1]=UTF8_TAIL | (uint8_t)(character & BIT_MASK(6)); + output[1] = UTF8_TAIL | (uint8_t)(character & BIT_MASK(6)); character >>= 6; - output[0]=UTF8_HEAD(5) | (uint8_t)character; + output[0] = UTF8_HEAD(5) | (uint8_t)character; } } diff --git a/src/libinsomniac_vm/vm_util.c b/src/libinsomniac_vm/vm_util.c index cdd712d..18ef66f 100644 --- a/src/libinsomniac_vm/vm_util.c +++ b/src/libinsomniac_vm/vm_util.c @@ -1,28 +1,26 @@ #include "vm_internal.h" #include +#include #include -#include #include -#include +#include #include - /* return the instruction/byte at the given address */ uint8_t vm_peek(vm_internal_type *vm, vm_int offset) { - vm_int addr = vm->env->ip + offset; + vm_int addr = vm->env->ip + offset; - if (addr > vm->env->length) { - return OP_NOP; - } + if (addr > vm->env->length) { + return OP_NOP; + } - return vm->env->code_ref[addr]; + return vm->env->code_ref[addr]; } /* create a list of pairs */ -void cons(vm_type *vm_void, object_type *car, object_type *cdr, - object_type **pair_out) { - vm_internal_type *vm=(vm_internal_type *)vm_void; +void cons(vm_type *vm_void, object_type *car, object_type *cdr, object_type **pair_out) { + vm_internal_type *vm = (vm_internal_type *)vm_void; *pair_out = vm_alloc(vm, PAIR); @@ -36,7 +34,7 @@ vm_int parse_int(vm_internal_type *vm) { uint8_t byte = 0; /* ip should be pointed at the instructions argument */ - for(int i=7; i>=0; i--) { + for (int i = 7; i >= 0; i--) { byte = vm->env->code_ref[vm->env->ip + i]; num = num << 8; @@ -67,19 +65,16 @@ void parse_string(vm_internal_type *vm, object_type **obj) { /* either make the given object into a symbol or replace it with the symbol version */ void make_symbol(vm_internal_type *vm, object_type **obj) { - if(!hash_get(vm->symbol_table, - (*obj)->value.string.bytes, (void **)obj)) { + if (!hash_get(vm->symbol_table, (*obj)->value.string.bytes, (void **)obj)) { (*obj)->type = SYMBOL; - hash_set(vm->symbol_table, - (*obj)->value.string.bytes, (*obj)); + hash_set(vm->symbol_table, (*obj)->value.string.bytes, (*obj)); } - } /* throw an exception */ -void throw(vm_internal_type *vm, char *msg, int num, ...) { +void throw(vm_internal_type * vm, char *msg, int num, ...) { va_list ap; object_type *exception = 0; object_type *cons_temp = 0; @@ -95,7 +90,7 @@ void throw(vm_internal_type *vm, char *msg, int num, ...) { /* save off any given objects */ va_start(ap, num); - for(int i = 0; i < num ; i++) { + for (int i = 0; i < num; i++) { obj = va_arg(ap, object_type *); cons(vm, obj, exception, &cons_temp); exception = cons_temp; @@ -117,7 +112,7 @@ void throw(vm_internal_type *vm, char *msg, int num, ...) { obj = vm_make_string(vm, msg, strlen(msg)); /* put everything in a pair */ - cons(vm, obj, exception, &cons_temp); + cons(vm, obj, exception, &cons_temp); exception = cons_temp; /* put the exception itself on the stack */ @@ -129,13 +124,12 @@ void throw(vm_internal_type *vm, char *msg, int num, ...) { /* we did not find a handler ! */ /* go hunting for the exception handler routine */ - while(vm->env && !vm->env->handler) { + while (vm->env && !vm->env->handler) { vm->env = vm->env->parent; } - /* did we find a handler ? */ - if(vm->env) { + if (vm->env) { clone_env(vm, (env_type **)&(vm->env), vm->env, false); /* disable exception handler while handling exceptions */ @@ -162,7 +156,6 @@ void throw(vm_internal_type *vm, char *msg, int num, ...) { assert(0); } - /* load a file into a string */ void vm_load_buf(vm_internal_type *vm, char *file, object_type **obj) { size_t count = 0; @@ -173,4 +166,3 @@ void vm_load_buf(vm_internal_type *vm, char *file, object_type **obj) { (*obj)->value.string.length = count; } - diff --git a/src/main.c b/src/main.c index 12c7c44..a642d24 100644 --- a/src/main.c +++ b/src/main.c @@ -1,14 +1,14 @@ -#include #include +#include -#include -#include #include +#include +#include #include +#include #include #include -#include #include @@ -31,7 +31,7 @@ int eval_string(vm_type *vm, gc_type *gc, char *str) { return ret_value; } -int main(int argc, char**argv) { +int main(int argc, char **argv) { gc_type *gc = gc_create(sizeof(object_type)); vm_type *vm = 0; char *code_str = 0; @@ -42,7 +42,7 @@ int main(int argc, char**argv) { setlocale(LC_ALL, ""); /* check for file argument */ - if(argc < 2) { + if (argc < 2) { fprintf(stderr, "Usage: %s \n", argv[0]); exit(-1); }