From: Michael D. Lowis Date: Mon, 30 Nov 2015 00:47:10 +0000 (-0500) Subject: Switched to posix compliant makefile X-Git-Url: https://git.mdlowis.com/?a=commitdiff_plain;h=1cf84aff641680fbaafddb5683e8891bc4e3f433;p=projs%2Fonward.git Switched to posix compliant makefile --- diff --git a/Gemfile b/Gemfile deleted file mode 100755 index 6d8e888..0000000 --- a/Gemfile +++ /dev/null @@ -1,4 +0,0 @@ -source 'https://rubygems.org' -gem 'rake', '>= 0' -gem 'rscons', '>= 0' -gem 'rspec', '>= 0' diff --git a/Gemfile.lock b/Gemfile.lock deleted file mode 100755 index ba072f9..0000000 --- a/Gemfile.lock +++ /dev/null @@ -1,29 +0,0 @@ -GEM - remote: https://rubygems.org/ - specs: - diff-lcs (1.2.5) - json (1.8.1) - rake (10.3.2) - rscons (1.8.1) - json (~> 1.0) - rspec (3.1.0) - rspec-core (~> 3.1.0) - rspec-expectations (~> 3.1.0) - rspec-mocks (~> 3.1.0) - rspec-core (3.1.7) - rspec-support (~> 3.1.0) - rspec-expectations (3.1.2) - diff-lcs (>= 1.2.0, < 2.0) - rspec-support (~> 3.1.0) - rspec-mocks (3.1.3) - rspec-support (~> 3.1.0) - rspec-support (3.1.2) - -PLATFORMS - ruby - x86-mingw32 - -DEPENDENCIES - rake - rscons - rspec diff --git a/Makefile b/Makefile new file mode 100644 index 0000000..8ca9ea0 --- /dev/null +++ b/Makefile @@ -0,0 +1,63 @@ +#------------------------------------------------------------------------------ +# Build Configuration +#------------------------------------------------------------------------------ +# Update these variables according to your requirements. + +# tools +CC = c99 +LD = ${CC} +AR = ar + +# flags +INCS = -Isource/ -Itests/ +CPPFLAGS = -D_XOPEN_SOURCE=700 +CFLAGS += ${INCS} ${CPPFLAGS} +LDFLAGS += ${LIBS} +ARFLAGS = rcs + +#------------------------------------------------------------------------------ +# Build Targets and Rules +#------------------------------------------------------------------------------ +SRCS = source/onward.c source/main.c +OBJS = ${SRCS:.c=.o} +LIB = libonward.a +BIN = onward +TEST_SRCS = tests/atf.c tests/main.c tests/test_interpreter.c tests/test_vars.c +TEST_OBJS = ${TEST_SRCS:.c=.o} +TEST_BIN = testonward + +all: options ${BIN} ${TEST_BIN} + +options: + @echo "Toolchain Configuration:" + @echo " CC = ${CC}" + @echo " CFLAGS = ${CFLAGS}" + @echo " LD = ${LD}" + @echo " LDFLAGS = ${LDFLAGS}" + @echo " AR = ${AR}" + @echo " ARFLAGS = ${ARFLAGS}" + @echo " ARFLAGS = ${MAKEDEPEND}" + +${LIB}: ${OBJS} + @echo AR $@ + @${AR} ${ARFLAGS} $@ ${OBJS} + +${BIN}: ${LIB} + @echo LD $@ + @${LD} -o $@ ${LIB} ${LDFLAGS} + + +${TEST_BIN}: ${TEST_OBJS} ${LIB} + @echo LD $@ + @${LD} -o $@ ${TEST_OBJS} ${LIB} ${LDFLAGS} + -./$@ + +.c.o: + @echo CC $< + @${CC} ${CFLAGS} -c -o $@ $< + +clean: + @rm -f ${LIB} ${BIN} ${TEST_BIN} ${OBJS} ${TEST_OBJS} + +.PHONY: all options + diff --git a/build.rb b/build.rb deleted file mode 100755 index f48b8d6..0000000 --- a/build.rb +++ /dev/null @@ -1,49 +0,0 @@ -#!/usr/bin/env ruby -require './modules/build-system/setup' - -#------------------------------------------------------------------------------ -# Environment Definitions -#------------------------------------------------------------------------------ -# Define the default compiler environment -base_env = BuildEnv.new do |env| - env.build_root = 'build/' - # Compiler options - env["CFLAGS"] += ['-DLEAK_DETECT_LEVEL=1', '--std=c99', '-Wall', '-Wextra']#, '-Werror'] - env["CPPPATH"] += Dir['source/**/'] -end - -# Define the release environment -main_env = base_env.clone do |env| - env.build_root = 'build/release/' - env["CFLAGS"] += ['-O3'] -end - -# Define the test environment -test_env = base_env.clone do |env| - env.build_root = 'build/test/' - env["CPPPATH"] += Dir['modules/atf/source/**/'] - env['CFLAGS'] += ['-O0'] - if Opts[:profile].include? "coverage" - env['CFLAGS'] << '--coverage' - env['LDFLAGS'] << '--coverage' - end -end - -#------------------------------------------------------------------------------ -# Test Build Targets -#------------------------------------------------------------------------------ -unless Opts[:profile].include? "no-tests" - test_env.Program('onward-tests', [ - 'source/onward.c', - 'modules/atf/source/atf.c'] + - Dir['tests/**/*.c']) - test_env.Command('Unit Tests', ['./onward-tests'], 'CMD' => ['./onward-tests']) -end - -#------------------------------------------------------------------------------ -# Release Build Targets -#------------------------------------------------------------------------------ -main_env.Library('libonward.a', FileList['source/*.c']) -main_env.Program('onward', FileList['source/*.c'], - 'CFLAGS' => main_env['CFLAGS'] + ['-DSTANDALONE']) - diff --git a/source/main.c b/source/main.c new file mode 100644 index 0000000..50f2f94 --- /dev/null +++ b/source/main.c @@ -0,0 +1,189 @@ +#include +#include + +/* System Calls + *****************************************************************************/ +#include +#include + +static void syscall_open(void) +{ + intptr_t modenum = onward_aspop(); + char* fname = (char*)onward_aspop(); + char* mode; + switch (modenum) { + case 0: mode = "r"; break; + case 1: mode = "w"; break; + case 2: mode = "a"; break; + case 3: mode = "r+"; break; + case 4: mode = "w+"; break; + case 5: mode = "a+"; break; + default: mode = NULL; break; + } + onward_aspush(mode ? (intptr_t)fopen(fname, mode) : 0); +} + +static void syscall_close(void) +{ + onward_aspush(fclose((FILE*)onward_aspop())); +} + +static void syscall_read(void) +{ + size_t nbytes = (size_t)onward_aspop(); + FILE* fhndl = (FILE*)onward_aspop(); + void* dest = (void*)onward_aspop(); + onward_aspush(nbytes != fread(dest, 1u, nbytes, fhndl)); +} + +static void syscall_write(void) +{ + size_t nbytes = (size_t)onward_aspop(); + void* src = (void*)onward_aspop(); + FILE* fhndl = (FILE*)onward_aspop(); + onward_aspush(nbytes != fwrite(src, 1u, nbytes, fhndl)); +} + +static void syscall_seek(void) +{ + intptr_t nbytes = onward_aspop(); + intptr_t origin = onward_aspop(); + FILE* fhndl = (FILE*)onward_aspop(); + origin = (origin == 0) ? SEEK_CUR : (origin < 0) ? SEEK_SET : SEEK_END; + onward_aspush(fseek(fhndl, nbytes, origin)); +} + +static void syscall_alloc(void) +{ + onward_aspush((intptr_t)malloc((size_t)onward_aspop())); +} + +static void syscall_free(void) +{ + free((void*)onward_aspop()); +} + +typedef void (*syscall_fn_t)(void); + +static syscall_fn_t System_Calls[7] = { + /* File Operations */ + &syscall_open, + &syscall_close, + &syscall_read, + &syscall_write, + &syscall_seek, + + /* Memory Operations */ + &syscall_alloc, + &syscall_free, +}; + +/* Standalone Interpreter + *****************************************************************************/ +#include + +static bool Newline_Consumed = false; +value_t Argument_Stack[ARG_STACK_SZ]; +value_t Return_Stack[RET_STACK_SZ]; +value_t Word_Buffer[WORD_BUF_SZ]; + +defvar("infile", infile, 0u, LATEST_BUILTIN); +defvar("outfile", outfile, 0u, &infile_word); +defvar("errfile", errfile, 0u, &outfile_word); +defcode("syscall", syscall, &errfile_word, 0u) { + System_Calls[onward_aspop()](); +} + +defcode("dumpw", dumpw, &syscall, 0u) { + word_t* word = (word_t*)onward_aspop(); + printf("name:\t'%s'\n", word->name); + printf("flags:\t%#zx\n", word->flags); + printf("link:\t%p\n", word->link); + /* Print the word's instructions */ + if (word->flags & F_PRIMITIVE_MSK) { + printf("code:\t%p\n", word->code); + } else { + printf("code:"); + word_t** code = (word_t**)word->code; + while(*code) { + printf("\t%s", (*code)->name); + if ((*code == &lit) || (*code == &zbr) || (*code == &br)) + printf(" %zd", (intptr_t)*(++code)); + code++; + puts(""); + } + printf("\tret\n"); + } +} + +value_t fetch_char(void) +{ + value_t ch = (value_t)fgetc((FILE*)infile); + if ((char)ch == '\n') + Newline_Consumed = true; + return ch; +} + +void emit_char(value_t val) +{ + fputc((int)val, (FILE*)outfile); +} + +void print_stack(void) { + value_t* base = (value_t*)asb; + value_t* top = (value_t*)asp; + printf("( "); + int i; + if (top-5 >= base) + printf("... "); + for (i = 4; i >= 0; i--) { + value_t* curr = top-i; + if (curr > base) + printf("%#zx ", *curr); + } + puts(")"); + printf("errcode: %zd\n", errcode); + puts(!errcode ? "OK." : "?"); +} + +void parse(FILE* file) { + value_t old = infile; + infile = (value_t)file; + if (file == stdin) + printf(":> "); + while (!feof(file)) { + errcode = 0; + interp_code(); + if ((file == stdin) && Newline_Consumed) { + print_stack(); + printf(":> "); + Newline_Consumed = false; + errcode = 0; + } + } + infile = old; +} + +void parse_file(char* fname) { + FILE* file = fopen(fname, "r"); + if (file) { + parse(file); + fclose(file); + } +} + +int main(int argc, char** argv) { + int i; + /* Initialize implementation specific words */ + latest = (value_t)&dumpw; + infile = (value_t)stdin; + outfile = (value_t)stdout; + errfile = (value_t)stderr; + /* Load any dictionaries specified on the command line */ + for (i = 1; i < argc; i++) + parse_file(argv[i]); + printf("Memory Usage: %zd / %zd\n", here - (value_t)Word_Buffer, sizeof(Word_Buffer)); + /* Start the REPL */ + parse(stdin); + return 0; +} diff --git a/source/onward.c b/source/onward.c old mode 100755 new mode 100644 index 3b67f6f..c5095a5 --- a/source/onward.c +++ b/source/onward.c @@ -572,193 +572,3 @@ static value_t char_oneof(char ch, char* chs) { return ret; } -/* System Calls - *****************************************************************************/ -#ifdef STANDALONE -#include -#include - -static void syscall_open(void) -{ - intptr_t modenum = onward_aspop(); - char* fname = (char*)onward_aspop(); - char* mode; - switch (modenum) { - case 0: mode = "r"; break; - case 1: mode = "w"; break; - case 2: mode = "a"; break; - case 3: mode = "r+"; break; - case 4: mode = "w+"; break; - case 5: mode = "a+"; break; - default: mode = NULL; break; - } - onward_aspush(mode ? (intptr_t)fopen(fname, mode) : 0); -} - -static void syscall_close(void) -{ - onward_aspush(fclose((FILE*)onward_aspop())); -} - -static void syscall_read(void) -{ - size_t nbytes = (size_t)onward_aspop(); - FILE* fhndl = (FILE*)onward_aspop(); - void* dest = (void*)onward_aspop(); - onward_aspush(nbytes != fread(dest, 1u, nbytes, fhndl)); -} - -static void syscall_write(void) -{ - size_t nbytes = (size_t)onward_aspop(); - void* src = (void*)onward_aspop(); - FILE* fhndl = (FILE*)onward_aspop(); - onward_aspush(nbytes != fwrite(src, 1u, nbytes, fhndl)); -} - -static void syscall_seek(void) -{ - intptr_t nbytes = onward_aspop(); - intptr_t origin = onward_aspop(); - FILE* fhndl = (FILE*)onward_aspop(); - origin = (origin == 0) ? SEEK_CUR : (origin < 0) ? SEEK_SET : SEEK_END; - onward_aspush(fseek(fhndl, nbytes, origin)); -} - -static void syscall_alloc(void) -{ - onward_aspush((intptr_t)malloc((size_t)onward_aspop())); -} - -static void syscall_free(void) -{ - free((void*)onward_aspop()); -} - -typedef void (*syscall_fn_t)(void); - -static syscall_fn_t System_Calls[7] = { - /* File Operations */ - &syscall_open, - &syscall_close, - &syscall_read, - &syscall_write, - &syscall_seek, - - /* Memory Operations */ - &syscall_alloc, - &syscall_free, -}; -#endif - -/* Standalone Interpreter - *****************************************************************************/ -#ifdef STANDALONE -#include - -static bool Newline_Consumed = false; -value_t Argument_Stack[ARG_STACK_SZ]; -value_t Return_Stack[RET_STACK_SZ]; -value_t Word_Buffer[WORD_BUF_SZ]; - -defvar("infile", infile, 0u, LATEST_BUILTIN); -defvar("outfile", outfile, 0u, &infile_word); -defvar("errfile", errfile, 0u, &outfile_word); -defcode("syscall", syscall, &errfile_word, 0u) { - System_Calls[onward_aspop()](); -} - -defcode("dumpw", dumpw, &syscall, 0u) { - word_t* word = (word_t*)onward_aspop(); - printf("name:\t'%s'\n", word->name); - printf("flags:\t%#zx\n", word->flags); - printf("link:\t%p\n", word->link); - /* Print the word's instructions */ - if (word->flags & F_PRIMITIVE_MSK) { - printf("code:\t%p\n", word->code); - } else { - printf("code:"); - word_t** code = (word_t**)word->code; - while(*code) { - printf("\t%s", (*code)->name); - if ((*code == &lit) || (*code == &zbr) || (*code == &br)) - printf(" %zd", (intptr_t)*(++code)); - code++; - puts(""); - } - printf("\tret\n"); - } -} - -value_t fetch_char(void) -{ - value_t ch = (value_t)fgetc((FILE*)infile); - if ((char)ch == '\n') - Newline_Consumed = true; - return ch; -} - -void emit_char(value_t val) -{ - fputc((int)val, (FILE*)outfile); -} - -void print_stack(void) { - value_t* base = (value_t*)asb; - value_t* top = (value_t*)asp; - printf("( "); - int i; - if (top-5 >= base) - printf("... "); - for (i = 4; i >= 0; i--) { - value_t* curr = top-i; - if (curr > base) - printf("%#zx ", *curr); - } - puts(")"); - printf("errcode: %zd\n", errcode); - puts(!errcode ? "OK." : "?"); -} - -void parse(FILE* file) { - value_t old = infile; - infile = (value_t)file; - if (file == stdin) - printf(":> "); - while (!feof(file)) { - errcode = 0; - interp_code(); - if ((file == stdin) && Newline_Consumed) { - print_stack(); - printf(":> "); - Newline_Consumed = false; - errcode = 0; - } - } - infile = old; -} - -void parse_file(char* fname) { - FILE* file = fopen(fname, "r"); - if (file) { - parse(file); - fclose(file); - } -} - -int main(int argc, char** argv) { - int i; - /* Initialize implementation specific words */ - latest = (value_t)&dumpw; - infile = (value_t)stdin; - outfile = (value_t)stdout; - errfile = (value_t)stderr; - /* Load any dictionaries specified on the command line */ - for (i = 1; i < argc; i++) - parse_file(argv[i]); - printf("Memory Usage: %zd / %zd\n", here - (value_t)Word_Buffer, sizeof(Word_Buffer)); - /* Start the REPL */ - parse(stdin); - return 0; -} -#endif diff --git a/source/onward.h b/source/onward.h old mode 100755 new mode 100644 index e21135b..3f240ec --- a/source/onward.h +++ b/source/onward.h @@ -45,7 +45,7 @@ typedef struct { #define deccode(c_name) \ void c_name##_code(void); \ - const word_t c_name \ + const word_t c_name /** Define a built-in word that executes native code */ #define defcode(name_str, c_name, prev, flags) \ @@ -61,7 +61,7 @@ typedef struct { void c_name##_code(void) #define decword(c_name) \ - const word_t c_name \ + const word_t c_name /** Define a built-in word that is defined by references to other words. */ #define defword(name_str, c_name, prev, flags) \ @@ -78,25 +78,25 @@ typedef struct { #define decvar(c_name) \ value_t c_name; \ - const word_t c_name##_word \ + const word_t c_name##_word /** Define a built-in word representing a variable with the provided value */ #define defvar(name_str, c_name, initial, prev) \ - value_t c_name = initial; \ + extern value_t c_name; \ defcode(name_str, c_name##_word, prev, 0u) { \ - onward_aspush((value_t)&c_name); \ - } + onward_aspush((value_t)&c_name); } \ + value_t c_name = initial #define decconst(c_name) \ const value_t c_name; \ - const word_t c_name##_word \ + const word_t c_name##_word /** Define a built-in word representing a constant with the provided value */ #define defconst(name_str, c_name, value, prev) \ - const value_t c_name = value; \ + extern const value_t c_name; \ defcode(name_str, c_name##_word, prev, 0u) { \ - onward_aspush(c_name); \ - } + onward_aspush(c_name); } \ + const value_t c_name = value #define ERR_NONE (0x00) #define ERR_UNKNOWN_WORD (0x01) diff --git a/tests/atf.c b/tests/atf.c new file mode 100644 index 0000000..992f681 --- /dev/null +++ b/tests/atf.c @@ -0,0 +1,94 @@ +/** + @file atf.c + @brief See header for details + $Revision$ + $HeadURL$ +*/ +#include "atf.h" +#include +#include +#include +#ifndef NO_SIGNALS +#include +#endif + +char* Curr_Test = NULL; +char* Curr_File = NULL; +unsigned int Curr_Line = 0; +static unsigned int Total = 0; +static unsigned int Failed = 0; + +#ifndef NO_SIGNALS +static void handle_signal(int sig) { + /* Determine the signal name */ + char* sig_name = NULL; + switch(sig) { + case SIGABRT: sig_name = "SIGABRT"; break; + case SIGBUS: sig_name = "SIGBUS"; break; + case SIGFPE: sig_name = "SIGFPE"; break; + case SIGILL: sig_name = "SIGILL"; break; + case SIGSEGV: sig_name = "SIGSEGV"; break; + case SIGSYS: sig_name = "SIGSYS"; break; + /* If we don't recognize it then just return and let the default handler + catch it. */ + default: return; + } + /* Error and exit. No summary will be printed but the user will know which + test has crashed. */ + fprintf(stderr,"%s:%d:0:%s:CRASH (signal: %d)\n", Curr_File, Curr_Line, Curr_Test, sig); + Failed++; + (void)atf_print_results(); + exit(1); +} +#endif + +void atf_init(int argc, char** argv) { + /* I reserve the right to use these later */ + (void)argc; + (void)argv; + +#ifndef NO_SIGNALS + /* Init signal handler */ + signal(SIGABRT, handle_signal); + signal(SIGBUS, handle_signal); + signal(SIGFPE, handle_signal); + signal(SIGILL, handle_signal); + signal(SIGSEGV, handle_signal); + signal(SIGSYS, handle_signal); +#endif +} + +void atf_run_suite(suite_t suite) { + suite(); +} + +void atf_test_start(char* file, unsigned int line, char* name) { + Curr_File = file; + Curr_Line = line; + Curr_Test = name; + Total++; +} + +bool atf_test_assert(bool success, char* expr, char* file, int line) { + bool failed = !success; + if (failed) atf_test_fail(expr,file,line); + return failed; +} + +void atf_test_fail(char* expr, char* file, int line) { + Failed++; + printf("%s:%d:0:%s:FAIL:( %s )\n", file, line, Curr_Test, expr); \ +} + +int atf_print_results(void) { + static const char* results_string = + "\nUnit Test Summary" + "\n-----------------" + "\nTotal: %d" + "\nPassed: %d" + "\nFailed: %d" + "\n\n"; + printf(results_string, Total, Total - Failed, Failed); + return Failed; +} + diff --git a/tests/atf.h b/tests/atf.h new file mode 100644 index 0000000..0e2d2f1 --- /dev/null +++ b/tests/atf.h @@ -0,0 +1,45 @@ +/** + @file atf.h + @brief Aardvark Test Framework main interface file. + $Revision$ + $HeadURL$ +*/ +#ifndef TEST_H +#define TEST_H + +#include +#include + +typedef void (*suite_t)(void); + +extern char* Curr_Test; + +void atf_init(int argc, char** argv); + +void atf_run_suite(suite_t suite); + +void atf_test_start(char* file, unsigned int line, char* name); + +bool atf_test_assert(bool success, char* expr_str, char* file, int line); + +void atf_test_fail(char* expr, char* file, int line); + +int atf_print_results(void); + +#define CHECK(expr) \ + if(atf_test_assert((expr), #expr, __FILE__, __LINE__)) break + +#define TEST_SUITE(name) void name(void) + +#define TEST(desc) \ + for(atf_test_start(__FILE__,__LINE__,#desc); Curr_Test != NULL; Curr_Test = NULL) + +#define RUN_EXTERN_TEST_SUITE(name) \ + do { extern TEST_SUITE(name); atf_run_suite(&name); } while(0) + +#define RUN_TEST_SUITE(name) \ + atf_run_suite(&name) + +#define PRINT_TEST_RESULTS atf_print_results + +#endif /* TEST_H */ diff --git a/tests/main.c b/tests/main.c old mode 100755 new mode 100644 diff --git a/tests/test_vars.c b/tests/test_vars.c old mode 100755 new mode 100644