Skip to content

Commit 98708ff

Browse files
committed
its working
1 parent 5d6cf86 commit 98708ff

File tree

10 files changed

+181
-100
lines changed

10 files changed

+181
-100
lines changed

TODO

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -54,7 +54,8 @@ the os should reach out to a 9p configuration server, could serve the bootstrap
5454
bootloader:
5555
switch to that other one instead of loading with --kernel
5656

57-
spawn a thread with a handler on some hardcoded socket for p92000
57+
- error when you could have too much words, and `words` fails
58+
make it navigate the vfs
5859

5960
do the vfs first
6061
scheme and forth?
@@ -65,3 +66,5 @@ forth should handle string and the kb callback alright
6566

6667
fix up tinylisp to have variadic lambdas, or ribbit or zforth
6768
tinylisp and zzforth needs jumpbuffers, but i have task swtiching already, shouldnt be a problem
69+
70+
https://www.complang.tuwien.ac.at/schani/oldstuff/#schemeinforth

apps/zfconf.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -36,7 +36,7 @@
3636
* floating point numbers */
3737

3838
typedef float zf_cell;
39-
#define ZF_CELL_FMT "%x"
39+
#define ZF_CELL_FMT "%f"
4040
#define ZF_SCAN_FMT "%f"
4141

4242
/* zf_int use for bitops, some arch int type width is less than register width,

apps/zforth.h

Lines changed: 0 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -71,11 +71,6 @@ typedef enum {
7171
ZF_USERVAR_COUNT
7272
} zf_uservar_id;
7373

74-
typedef struct {
75-
zf_result last_error;
76-
int error_occurred;
77-
} zf_error_state;
78-
7974
typedef struct {
8075
/* Stacks and dictionary memory */
8176
zf_cell rstack[ZF_RSTACK_SIZE];

apps/zfortharch.c

Lines changed: 50 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,10 @@
11
#include "drivers/screen.h"
2+
#include "drivers/serial.h"
3+
#include "libc/string.h"
24
#include "libc/types.h"
35
#include "zforth.h"
46

57
zf_input_state zf_host_sys(zf_ctx *ctx, zf_syscall_id id, const char *input) {
6-
kernel_printf("zforth syscall: %d\n", id);
78
switch (id) {
89
case ZF_SYSCALL_EMIT: {
910
zf_cell c = zf_pop(ctx);
@@ -41,43 +42,62 @@ zf_input_state zf_host_sys(zf_ctx *ctx, zf_syscall_id id, const char *input) {
4142
return ZF_INPUT_INTERPRET;
4243
}
4344

45+
#include "drivers/serial.h"
46+
4447
void zf_host_trace(zf_ctx *ctx, const char *fmt, va_list va) {
45-
_vprintf(kernel_putc, fmt, va);
48+
_vprintf(serial_write, fmt, va);
4649
}
47-
zf_cell zf_host_parse_num(zf_ctx *ctx, const char *buf) {
4850

49-
if (!buf || !*buf)
50-
return 0;
51+
int atoi2(const char *str, int *result) {
52+
const char *original = str;
53+
int value = 0;
54+
int sign = 1;
55+
int has_digits = 0;
5156

52-
zf_cell result = 0;
53-
int negative = 0;
54-
const char *p = buf;
57+
while (*str == ' ' || *str == '\t' || *str == '\n' || *str == '\r' ||
58+
*str == '\f' || *str == '\v') {
59+
str++;
60+
}
5561

56-
if (*p == '-') {
57-
negative = 1;
58-
p++;
62+
if (*str == '-') {
63+
sign = -1;
64+
str++;
65+
} else if (*str == '+') {
66+
str++;
5967
}
6068

61-
if (p[0] == '0' && (p[1] == 'x' || p[1] == 'X')) {
62-
p += 2;
63-
while (*p) {
64-
if (*p >= '0' && *p <= '9') {
65-
result = result * 16 + (*p - '0');
66-
} else if (*p >= 'a' && *p <= 'f') {
67-
result = result * 16 + (*p - 'a' + 10);
68-
} else if (*p >= 'A' && *p <= 'F') {
69-
result = result * 16 + (*p - 'A' + 10);
70-
} else {
71-
break; // invalid hex digit
72-
}
73-
p++;
74-
}
75-
} else {
76-
while (*p >= '0' && *p <= '9') {
77-
result = result * 10 + (*p - '0');
78-
p++;
69+
while (*str >= '0' && *str <= '9') {
70+
has_digits = 1;
71+
value = value * 10 + (*str - '0');
72+
str++;
73+
}
74+
75+
while (*str) {
76+
if (*str != ' ' && *str != '\t' && *str != '\n' && *str != '\r' &&
77+
*str != '\f' && *str != '\v') {
78+
return 0;
7979
}
80+
str++;
81+
}
82+
83+
if (!has_digits) {
84+
return 0;
85+
}
86+
87+
if (result) {
88+
*result = sign * value;
89+
}
90+
return 1;
91+
}
92+
93+
// w/ some assumptions.
94+
zf_cell zf_host_parse_num(zf_ctx *ctx, const char *buf) {
95+
int value = 0;
96+
97+
if (atoi2(buf, &value)) {
98+
return (zf_cell)value;
8099
}
81100

82-
return negative ? -result : result;
101+
zf_abort(ctx, ZF_ABORT_NOT_A_WORD);
102+
return 0;
83103
}

disk/root/forth/core.f

Lines changed: 15 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -4,24 +4,20 @@
44
: emit 0 sys ;
55
: . 1 sys ;
66
: tell 2 sys ;
7-
: quit 128 sys ;
8-
: sin 129 sys ;
9-
: include 130 sys ;
10-
: save 131 sys ;
117

128

13-
( dictionary access for regular variable-length cells. These are shortcuts
14-
through the primitive operations are !!, @@ and ,, )
9+
( dictionary access for regular variable-length cells. These are shortcuts)
10+
( through the primitive operations are !!, @@ and ,, )
1511

1612
: ! 0 !! ;
1713
: @ 0 @@ ;
1814
: , 0 ,, ;
1915
: # 0 ## ;
2016

21-
( dictionary access for jmp instructions; these make sure to always use the
22-
maximium cell size for the target address to allow safe stubbing and
23-
updating of a jump address. `64` is the magic number for ZF_ACCESS_VAR_MAX,
24-
see zforth.c for details )
17+
( dictionary access for jmp instructions; these make sure to always use the )
18+
( maximium cell size for the target address to allow safe stubbing and )
19+
( updating of a jump address. `64` is the magic number for ZF_ACCESS_VAR_MAX, )
20+
( see zforth.c for details )
2521

2622
: !j 64 !! ;
2723
: ,j 64 ,, ;
@@ -34,6 +30,7 @@
3430

3531

3632
( some operators and shortcuts )
33+
3734
: 1+ 1 + ;
3835
: 1- 1 - ;
3936
: over 1 pick ;
@@ -52,17 +49,17 @@
5249
: .. dup . ;
5350
: here h @ ;
5451

55-
5652
( memory management )
5753

54+
5855
: allot h +! ;
5956
: var : ' lit , here 5 allot here swap ! 5 allot postpone ; ;
6057
: const : ' lit , , postpone ; ;
6158
: constant >r : r> postpone literal postpone ; ;
6259
: variable >r here r> postpone , constant ;
6360

64-
( 'begin' gets the current address, a jump or conditional jump back is generated
65-
by 'again', 'until' )
61+
( 'begin' gets the current address, a jump or conditional jump back is generated )
62+
( by 'again', 'until' )
6663

6764
: begin here ; immediate
6865
: again ' jmp , , ; immediate
@@ -83,10 +80,10 @@
8380
: times ( XT n -- ) { >r dup >r exe r> r> dup x} drop drop ;
8481

8582

86-
( 'if' prepares conditional jump, the target address '0' will later be
87-
overwritten by the 'else' or 'fi' words. Note that ,j and !j are used for
88-
writing the jump target address to the dictionary, this makes sure that the
89-
target address is always written with the same cell size)
83+
( 'if' prepares conditional jump, the target address '0' will later be )
84+
( overwritten by the 'else' or 'fi' words. Note that ,j and !j are used for )
85+
( writing the jump target address to the dictionary, this makes sure that the )
86+
( target address is always written with the same cell size )
9087

9188
: if ' jmp0 , here 0 ,j ; immediate
9289
: unless ' not , postpone if ; immediate
@@ -111,5 +108,4 @@
111108

112109
( Print string literal )
113110

114-
: ." compiling @ if postpone s" ' tell , else begin key dup 34 = if drop exit else emit fi again
115-
fi ; immediate
111+
: ." compiling @ if postpone s" ' tell , else begin key dup 34 = if drop exit else emit fi again fi ; immediate

disk/root/forth/dict.f

Lines changed: 3 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -2,35 +2,12 @@
22

33
( methods for handling the dictionary )
44

5-
( 'next' increases the given dictionary address by the size of the cell
6-
located at that address )
5+
( 'next' increases the given dictionary address by the size of the cell )
6+
( located at that address )
77

88
: next dup # + ;
99

1010
( 'words' generates a list of all define words )
1111

1212
: name dup @ 31 & swap next dup next rot tell @ ;
13-
: words latest @ begin name br dup 0 = until cr drop ;
14-
: prim? ( w -- bool ) @ 32 & ;
15-
: a->xt ( w -- xt ) dup dup @ 31 & swap next next + swap prim? if @ fi ;
16-
: xt->a ( xt -- w ) latest @ begin dup a->xt 2 pick = if swap drop exit fi next @ dup 0 = until swap drop ;
17-
: lit?jmp? ( a -- a boolean ) dup @ dup 1 = swap dup 18 = swap 19 = + + ;
18-
: disas ( a -- a ) dup dup . br br @ xt->a name drop lit?jmp? if br next dup @ . fi cr ;
19-
20-
( 'see' needs starting address on stack: e.g. ' words see )
21-
: see ( xt -- ) dup xt->a name cr drop begin disas next dup @ =0 until drop ;
22-
23-
( 'dump' memory make hex dump len bytes from addr )
24-
: hex_t ' lit , here dup , s" 0123456789abcdef" allot swap ! ; immediate
25-
: *hex_t hex_t ;
26-
: .hex *hex_t + @ emit ;
27-
: >nib ( n -- low high ) dup 15 & swap -16 & 16 / ;
28-
: ffemit ( n -- ) >nib .hex .hex ;
29-
: ffffemit ( n -- ) >nib >nib >nib { .hex 4 x} ;
30-
: @LSB ( addr -- LSB ) 2 @@ 255 & ;
31-
: between? ( n low_lim high_lim -- bool ) 2 pick > rot rot > & ;
32-
: 8hex ( a -- a_new ) { dup @LSB ffemit 32 emit 1+ 8 x} 32 emit ;
33-
: 16ascii ( a -- a_new ) 124 emit { dup @LSB dup 31 127 between? if emit else drop 46 emit fi 1+ 16 x} 124 emit ;
34-
: .addr ( a -- ) ffffemit ." " ;
35-
: 16line ( a -- a_new ) dup .addr dup { 8hex 2 x} drop 16ascii cr ;
36-
: dump ( addr len -- ) over + swap begin 16line over over < until drop drop ;
13+
: words latest @ begin name br dup 0 = until cr drop ;

drivers/serial.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -47,7 +47,7 @@ static int serial_is_transmit_empty() {
4747
return port_byte_in(SERIAL_COM1 + 5) & 0x20;
4848
}
4949

50-
static void serial_write(char c) {
50+
void serial_write(char c) {
5151
while (!serial_is_transmit_empty())
5252
;
5353
port_byte_out(SERIAL_COM1, c);

drivers/serial.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@ void serial_init();
77
void serial_puts(const char *str);
88
void serial_put_hex(uint32_t num);
99
void serial_debug_impl(char *file, int line, char *message);
10-
10+
void serial_write(char c);
1111
// dont use this directly
1212
void serial_printf(int cycl, char *file, int line, const char *fmt, ...);
1313
extern uint32_t tick;

kernel/kernel.c

Lines changed: 43 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -64,61 +64,88 @@ void vfs_print_current_tree(vfs *fs);
6464

6565
static zf_ctx *g_ctx = 0;
6666

67+
const char *zf_result_strings[] = {"OK",
68+
"ABORT: internal error",
69+
"ABORT: outside memory bounds",
70+
"ABORT: data stack underrun",
71+
"ABORT: data stack overrun",
72+
"ABORT: return stack underrun",
73+
"ABORT: return stack overrun",
74+
"ABORT: not a word",
75+
"ABORT: compile-only word",
76+
"ABORT: invalid size",
77+
"ABORT: division by zero",
78+
"ABORT: invalid user variable",
79+
"ABORT: external error"};
80+
81+
const char *zf_result_to_string(zf_result result) {
82+
if (result >= 0 &&
83+
result < sizeof(zf_result_strings) / sizeof(zf_result_strings[0])) {
84+
return zf_result_strings[result];
85+
}
86+
return "Unknown error";
87+
}
88+
6789
static void enter(const char *str) {
6890
if (g_ctx) {
6991
zf_result result = zf_eval(g_ctx, str);
7092

7193
if (result == ZF_OK) {
7294
kernel_printf(" ok\n");
7395
} else {
74-
kernel_printf(" error %d\n", result);
96+
kernel_printf(" error %s\n", zf_result_to_string(result));
7597
}
7698

7799
kernel_printf("> ");
78100
}
79101
}
80102

81103
static void bootstrap_zforth(zf_ctx *ctx, vfs *unified_vfs) {
82-
const char *forth_files[] = {"/fd/forth/dict.f", "/fd/forth/core.f", NULL};
83-
84-
uint8_t buffer[1024] = {0};
104+
const char *forth_files[] = {"/fd/forth/core.f", "/fd/forth/dict.f", NULL};
85105

106+
uint8_t buffer[RAMDISK_MAX_FILESIZE] = {0};
86107
for (int file_idx = 0; forth_files[file_idx] != NULL; file_idx++) {
87108
const char *filepath = forth_files[file_idx];
88-
109+
vfs_stat stat = {0};
110+
if (VFS_SUCCESS != unified_vfs->stat(unified_vfs, filepath, &stat)) {
111+
kernel_printf("error: file not found: %s\n", filepath);
112+
continue;
113+
}
114+
if (RAMDISK_MAX_FILESIZE < stat.size) {
115+
kernel_printf("error: file is over 64k: %s\n", filepath);
116+
}
89117
int fd = 0;
90118
if (VFS_SUCCESS !=
91119
unified_vfs->open(unified_vfs, filepath, VFS_READ, &fd)) {
92-
kernel_printf("file not found: %s\n", filepath);
93-
continue; // skip this file, try next one
120+
kernel_printf("error: could not open: %s\n", filepath);
121+
continue;
94122
}
95123

96124
memset(buffer, 0, sizeof(buffer));
97-
98125
int bytes_read = 0;
99126
int ret = unified_vfs->read(unified_vfs, fd, buffer, sizeof(buffer) - 1,
100127
buffer, &bytes_read);
101128

102129
if (ret != VFS_SUCCESS) {
103-
kernel_printf("error %d reading %s\n", ret, filepath);
104130
unified_vfs->close(unified_vfs, fd);
105131
continue;
106132
}
107133

108-
if (bytes_read > 0) {
109-
buffer[bytes_read] = '\0';
134+
if (bytes_read <= 0) {
135+
unified_vfs->close(unified_vfs, fd);
136+
continue;
110137
}
111138

139+
buffer[bytes_read] = '\0';
112140
unified_vfs->close(unified_vfs, fd);
113141

114142
zf_result result = zf_eval(ctx, (char *)buffer);
115143
if (result != ZF_OK) {
116-
kernel_printf("zforth error %d in file: %s\n", result, filepath);
117-
} else {
144+
kernel_printf(" error %s\n", zf_result_to_string(result));
118145
}
119146
}
120147

121-
kernel_printf("- zforth initialization complete\n");
148+
kernel_printf("- zForth initialization complete\n");
122149
}
123150

124151
void kernel_main(void) {
@@ -151,10 +178,10 @@ void kernel_main(void) {
151178
vfs_print_current_tree(unified_vfs);
152179

153180
zf_ctx ctx;
154-
zf_init(&ctx, 1);
181+
zf_init(&ctx, 0);
155182
zf_bootstrap(&ctx);
156183
bootstrap_zforth(&ctx, unified_vfs);
157-
184+
serial_debug("zf inited.");
158185
keyboard_ctx_t *kb = get_kb_ctx();
159186
kb->enter_handler = enter;
160187
g_ctx = &ctx;

0 commit comments

Comments
 (0)