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'])
#include "onward.h"
#include <stdio.h>
+#include "syscall.h"
#define STACK_SZ (64u)
value_t Arg_Stack_Buf[STACK_SZ];
}
}
+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;
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 */
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);
/** Start a new word definition */
defcode(";", semicolon, &colon, F_IMMEDIATE_MSK) {
((word_t*)latest)->flags &= ~F_HIDDEN;
+ here += sizeof(value_t);
state = 0;
}
-
: immediate
latest @ \ Get the latest word
CELLSZ + \ Add offset to get to the flags field
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
+;
--- /dev/null
+#include "syscall.h"
+#include "onward.h"
+#include <stdio.h>
+#include <stdlib.h>
+
+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,
+};
+
--- /dev/null
+/**
+ @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 */