From: Michael D. Lowis Date: Thu, 27 Nov 2014 04:20:16 +0000 (-0500) Subject: implemented if statements, loops and # style comments X-Git-Url: https://git.mdlowis.com/?a=commitdiff_plain;h=a2799461c00193ec185e7843a075c9253256a629;p=projs%2Fonward.git implemented if statements, loops and # style comments --- diff --git a/build.rb b/build.rb index eafcafc..c7c3dc5 100755 --- a/build.rb +++ b/build.rb @@ -35,6 +35,7 @@ end unless Opts[:profile].include? "no-tests" test_env.Program('onward-tests', [ 'source/onward/onward.c', + 'source/syscall.c', 'modules/atf/source/atf.c'] + Dir['tests/**/*.c']) test_env.Command('Unit Tests', ['./onward-tests'], 'CMD' => ['./onward-tests']) diff --git a/source/main.c b/source/main.c index 98ab5c6..dfa4fad 100755 --- a/source/main.c +++ b/source/main.c @@ -1,5 +1,6 @@ #include "onward.h" #include +#include "syscall.h" #define STACK_SZ (64u) value_t Arg_Stack_Buf[STACK_SZ]; @@ -29,6 +30,14 @@ defcode("dumpw", dumpw, LATEST_BUILTIN, 0u) { } } +defcode("syscall", syscall, &dumpw, 0u) { + System_Calls[onward_aspop()](); +} + +defvar("infile", infile, 0u, &syscall); +defvar("outfile", outfile, 0u, &infile_word); +defvar("errfile", errfile, 0u, &outfile_word); + void print_stack(void) { value_t* base = (value_t*)asb; value_t* top = (value_t*)asp; @@ -78,7 +87,7 @@ int main(int argc, char** argv) { STACK_SZ, Ram_Data_Buf, 8192/sizeof(value_t), - (word_t*)&dumpw + (word_t*)&errfile_word }; onward_init(&init_data); /* Load any dictionaries specified on the command line */ diff --git a/source/onward/onward.c b/source/onward/onward.c index e53ae64..2650e8c 100755 --- a/source/onward/onward.c +++ b/source/onward/onward.c @@ -11,7 +11,7 @@ defconst("VERSION", VERSION, 0, 0u); defconst("CELLSZ", CELLSZ, sizeof(value_t), &VERSION_word); /** Number of bits that make up a stack cell */ -defconst("BITCOUNT", BITCOUNT, SYS_BITCOUNT, &VERSION_word); +defconst("BITCOUNT", BITCOUNT, SYS_BITCOUNT, &CELLSZ_word); /** Bit mask to retrieve the "primitive" flag */ defconst("F_PRIMITIVE", F_PRIMITIVE, F_PRIMITIVE_MSK, &BITCOUNT_word); @@ -233,6 +233,7 @@ defword(":", colon, &rbrack, 0u) { /** Start a new word definition */ defcode(";", semicolon, &colon, F_IMMEDIATE_MSK) { ((word_t*)latest)->flags &= ~F_HIDDEN; + here += sizeof(value_t); state = 0; } diff --git a/source/onward/onward.ft b/source/onward/onward.ft index c6e12b0..50a2d55 100644 --- a/source/onward/onward.ft +++ b/source/onward/onward.ft @@ -1,4 +1,3 @@ - : immediate latest @ \ Get the latest word CELLSZ + \ Add offset to get to the flags field @@ -6,26 +5,72 @@ F_IMMEDIATE | ! \ Set the immediate bit ; immediate -\ : if immediate -\ ' 0br , \ compile 0branch -\ here @ \ save location of the offset on the stack -\ 0 , \ compile a dummy offset -\ ; -\ -\ : then immediate -\ dup -\ here @ swap - \ calculate the offset from the address saved on the stack -\ swap ! \ store the offset in the back-filled location -\ ; -\ -\ : else immediate -\ ' br , \ definite branch to just over the false-part -\ here @ \ save location of the offset on the stack -\ 0 , \ compile a dummy offset -\ swap \ now back-fill the original (if) offset -\ dup \ same as for then word above -\ here @ swap - -\ swap ! -\ ; +: [compile] immediate + word find , +; + +: # [compile] \ ; + +: #! [compile] \ ; + +: recurse immediate + latest @ , +; + +: if immediate + ' 0br , \ compile 0branch + here @ \ save location of the offset on the stack + 0 , \ compile a dummy offset +; + +: then immediate + dup + here @ swap - \ calculate the offset from the address saved on the stack + ! +; + +: else immediate + ' br , \ definite branch to just over the false-part + here @ \ save location of the offset on the stack + 0 , \ compile a dummy offset + swap \ now back-fill the original (if) offset + dup \ same as for then word above + here @ swap - \ calculate the offset from the address saved on the stack + ! +; + +: begin immediate here @ ; + +: until immediate + ' 0br , \ compile 0BRANCH + here @ - \ calculate the offset from the address saved on the stack + , \ compile the offset here +; + +: again immediate + ' br , \ compile branch + here @ - \ calculate the offset back + , \ compile the offset here +; + +: while immediate + ' 0br , \ compile 0branch + here @ \ save location of the offset2 on the stack + 0 , \ compile a dummy offset2 +; + +: repeat immediate + ' br , \ compile branch + swap \ get the original offset (from begin) + here @ - , \ and compile it after branch + dup + here @ swap - \ calculate the offset2 + ! \ and back-fill it in the original location +; + +: unless immediate + ' not , \ compile not (to reverse the test) + [compile] if \ continue by calling the normal if +; diff --git a/source/syscall.c b/source/syscall.c new file mode 100644 index 0000000..4972ea8 --- /dev/null +++ b/source/syscall.c @@ -0,0 +1,75 @@ +#include "syscall.h" +#include "onward.h" +#include +#include + +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); +} + +void syscall_close(void) +{ + onward_aspush(fclose((FILE*)onward_aspop())); +} + +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)); +} + +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)); +} + +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)); +} + +void syscall_alloc(void) +{ + onward_aspush((intptr_t)malloc((size_t)onward_aspop())); +} + +void syscall_free(void) +{ + free((void*)onward_aspop()); +} + +syscall_fn_t System_Calls[] = { + /* File Operations */ + &syscall_open, + &syscall_close, + &syscall_read, + &syscall_write, + &syscall_seek, + + /* Memory Operations */ + &syscall_alloc, + &syscall_free, +}; + diff --git a/source/syscall.h b/source/syscall.h new file mode 100644 index 0000000..53ece86 --- /dev/null +++ b/source/syscall.h @@ -0,0 +1,14 @@ +/** + @file sycall.h + @brief TODO: Describe this file + $Revision$ + $HeadURL$ +*/ +#ifndef SYCALL_H +#define SYCALL_H + +typedef void (*syscall_fn_t)(void); + +syscall_fn_t System_Calls[]; + +#endif /* SYCALL_H */