From 06d110e28b988475fe0c17f32edd43c656fcc8dd Mon Sep 17 00:00:00 2001 From: Andrew Kesterson Date: Tue, 7 May 2024 18:06:01 -0400 Subject: [PATCH] WIP : About to rip out the old parser and solver, can't get things working the way I expect and the old code is in the way --- Makefile | 7 +- src/basic.c | 196 +++++++++++++++++++++++++++------------------------ src/basic.h | 7 +- src/string.c | 22 ++++++ src/string.h | 1 + 5 files changed, 136 insertions(+), 97 deletions(-) diff --git a/Makefile b/Makefile index 007f3ae..85e5be9 100644 --- a/Makefile +++ b/Makefile @@ -4,11 +4,14 @@ endif all: boot.img kernel.bin +src/%.S: src/%.c + ~/bin/bcc -ansi -0 -S -d -t $@ $< + src/%.o: src/%.c - bcc -ansi -0 -c -o $@ $< + ~/bin/bcc -ansi -0 -c -o $@ $< kernel.bin: src/screen.o src/conio.o src/string.o src/stdlib.o src/basic.o src/kernel.o - ld86 -d -M -o $@ $^ | tee ld86.out + ~/bin/ld86 -d -M -L/home/andrew/lib/bcc -lbcc -o $@ $^ | tee ld86.out asm/kernel_syms.S: kernel.bin cat ld86.out | \ diff --git a/src/basic.c b/src/basic.c index 7ee6ab8..3183c62 100644 --- a/src/basic.c +++ b/src/basic.c @@ -10,6 +10,7 @@ struct basic_expr math_expressions[32]; int basic_errno; int basic_last_stored_lineno; +int basic_repl_mode = 0; /* 0 = REPL mode, 1 = RUN mode */ char _tokenizer_value[BASIC_TOKENIZER_MAX_LENGTH]; char *_tokenizer_prev; @@ -39,44 +40,23 @@ void basic_cmd_rem(void *expr) void basic_cmd_list(void *data) { - basic_expr *expr; int i = 0; int limit = basic_last_stored_lineno; char *lineptr = NULL; - if ( data == NULL ) { - basic_errno = BASIC_ERR_INTERNAL_NULLPOINTER; - return; - } - - expr = basic_parse_expr((char *)data, 0); - if ( expr == NULL ) { - basic_errno = BASIC_ERR_INTERNAL_NULLPOINTER; - return; - } - /* The default state of the lval integer argument is zero. Nothing special happens in the parsing - * of a "LIST" command with no integer argument that ensures this, that's just the default state. - * So the only time expr->lval.i will be non-zero is if user said "LIST NNNN". We're relying on that here. - */ - if ( expr->lval.i != 0 ) { - limit = expr->lval.i; - } - /* - _cputs("Program listing from 0 - "); - memset((char *)&decimal, 0x00, 32); - itoa(limit, (char *)&decimal); - _cputs((char *)&decimal); - _cputs(":\n"); - */ + i = 0; + _cputs("OMG WTF BBQ\n"); for ( i = 0; i <= limit ; i++ ) { lineptr = basic_memory_line_address(i); + if ( lineptr == NULL ) { + continue; + } if ( (char)*lineptr != 0x00 ) { itoa(i+1, (char *)&decimal); _cputs((char *)&decimal); - /* this funky pointer dereferencing is to make bcc happy, it can't - * manage indexing the array and dereferencing that */ + _cputs(" WTF"); _cputs(lineptr); - _cputs("\n"); + _cputs("BBQ\n"); } } } @@ -86,17 +66,12 @@ void basic_cmd_print(void *data) struct basic_variable result; basic_expr *expr; if ( data == NULL ) { - _cputs("basic_cmd_print received null data\n"); basic_errno = BASIC_ERR_INTERNAL_NULLPOINTER; return; } - _cputs("basic_cmd_print parsing \""); - _cputs((char *)data); - _cputs("\"\n"); expr = basic_parse_expr((char *)data, 0); if ( expr == NULL ) { - _cputs("basic_cmd_print failed to parse the data it was given\n"); basic_errno = BASIC_ERR_INTERNAL_NULLPOINTER; return; } @@ -104,15 +79,8 @@ void basic_cmd_print(void *data) memset((void *)&result, 0x00, sizeof(struct basic_variable)); basic_solve_expr(expr, &result); if ( basic_errno != 0 ) { - _cputs("basic_cmd_print exiting on error\n"); return; } else { - _cputs("basic_cmd_print printing\n"); - _cputs("Should probably be : "); - _cputs(tokenizer_token()); - _cputs(" .. or "); - _cputs(result.value.str); - _cputs("\n"); basic_print_var(&result); } } @@ -126,18 +94,12 @@ void basic_cmd_run(void *data) basic_errno = 0; lineptr = basic_memory_line_address(i); if ( (char)*lineptr != 0x00 ) { - _cputs("Running ["); - itoa(i+1, (char *)&decimal); - _cputs((char *)&decimal); - _cputs("] "); - _cputs(lineptr); - _cputs("\n"); - rc = basic_run_line(lineptr, 0); + rc = basic_run_line_v2(lineptr, 0); if ( rc != 0 || basic_errno != 0 ) { _cputs("Error at Line "); itoa(i+1, (char *)&decimal); - _cputs((char *)&decimal); _cputs(": "); + _cputs((char *)&decimal); _cputs("\n"); return; } @@ -197,9 +159,6 @@ _tokenize_copy: return NULL; } memcpy((void *)&_tokenizer_value, (void *)orig, len); - lstrip((char *)&_tokenizer_value, (char *)&tmpbuff, " "); - rstrip((char *)&tmpbuff, (char *)&_tokenizer_value, " "); - _tokenizer_prev_next = (ptr + 1); return ptr; } @@ -220,6 +179,36 @@ char *basic_memory_line_address(int lineno) return ((char *)&basic_memory_lines) + (lineno * BASIC_MAX_LINE_LENGTH); } +int basic_memory_line_store(char *content, int lineno) +{ + int i = 0; + char *ptr = NULL; + char *dest = NULL; + + if ( lineno < 0 || lineno > BASIC_MAX_LINES ) { + basic_errno = BASIC_ERR_INVALID_ARGUMENTS; + return 1; + } + + dest = basic_memory_line_address(lineno); + if ( lineno > basic_last_stored_lineno ) { + /* The memory between here and there is probably uninitialized. When we come back + * through to LIST those lines later we may find garbage. Let's clean it up. + */ + for ( i = basic_last_stored_lineno+1; i <= lineno ; i++ ) { + ptr = basic_memory_line_address(i); + memset(ptr, 0x00, BASIC_MAX_LINE_LENGTH); + } + } + lineno -= 1; + i = (int) memcpy(basic_memory_line_address(lineno), content, strlen(content)); + if ( i == 0 ) { + basic_errno = BASIC_ERR_INTERNAL_NULLPOINTER; + return 1; + } + basic_last_stored_lineno = lineno; +} + int basic_solve_expr(struct basic_expr *expr, struct basic_variable *result) { if ( expr == NULL || result == NULL ) { @@ -229,20 +218,13 @@ int basic_solve_expr(struct basic_expr *expr, struct basic_variable *result) switch (expr->type) { case BASIC_OPTP_NONE: - _cputs("basic_solve_expr processing constant\n"); if ( expr->lval_type == BASIC_LVAL_CONST_INT ) { result->flags = (result->flags | BASIC_VARFLAG_TINT | BASIC_VARFLAG_INIT); result->value.i = expr->lval.i; } else if ( expr->lval_type == BASIC_LVAL_CONST_STR ) { - _cputs("basic_solve_expr processing string: "); result->flags = (result->flags | BASIC_VARFLAG_TSTR | BASIC_VARFLAG_INIT); result->value.str = (char *)expr->lval.ptr; - _cputs((char *)expr->lval.ptr); - _cputs(" => "); - _cputs(result->value.str); - _cputs("\n"); } else { - _cputs("basic_solve_expr exiting early\n"); basic_errno = BASIC_ERR_INTERNAL_UNIMPLEMENTED; return 0; } @@ -316,39 +298,17 @@ int basic_solve_expr(struct basic_expr *expr, struct basic_variable *result) case BASIC_OPTP_STOR: /* this funky pointer dereferencing is to make bcc happy, it can't * manage indexing the array and dereferencing that */ - #ifndef __GNUC__ - _cputs("Storing line\n"); - #endif if ( memcpy( basic_memory_line_address(expr->lval.i-1), (char *)expr->rval.ptr, strlen((char *)expr->rval.ptr) ) == NULL ) { - #ifndef __GNUC__ - _cputs("NULL POINTER\n"); - #endif basic_errno = BASIC_ERR_INTERNAL_NULLPOINTER; return 0; } result->flags = (result->flags | BASIC_VARFLAG_TSTR | BASIC_VARFLAG_INIT); result->value.ptr = BASIC_MESSAGE_OK; basic_last_stored_lineno = expr->lval.i-1; - #ifdef __GNUC__ - printf("basic_memory_lines[%d] = \"%s\"\n", (expr->lval.i-1), (char *)expr->rval.ptr); - #else - memset((char *)&decimal, 0x00, 32); - _cputs("basic_memory_lines["); - itoa(expr->lval.i, (char *)&decimal); - _cputs((char *)&decimal); - _cputs(" indexed as "); - itoa(basic_last_stored_lineno, (char *)&decimal); - _cputs((char *)&decimal); - _cputs("] = \""); - _cputs(expr->rval.ptr); - _cputs("\" (Stored \""); - _cputs(basic_memory_line_address(basic_last_stored_lineno)); - _cputs("\")\n"); - #endif break; case BASIC_OPTP_ASN: basic_errno = BASIC_ERR_INTERNAL_UNIMPLEMENTED; @@ -387,9 +347,6 @@ struct basic_expr *basic_parse_expr(char *expbuf, int require_line_numbers) ret->type = BASIC_OPTP_STOR; ret->lval_type = BASIC_LVAL_CONST_INT; ret->lval.i = atoi(token); - #ifdef __GNUC__ - printf("Stored line number %d for %s\n", ret->lval.i, token); - #endif ret->rval.ptr = expbuf; ret->rval_type = BASIC_RVAL_PTR; break; @@ -466,9 +423,6 @@ struct basic_expr *basic_parse_expr(char *expbuf, int require_line_numbers) */ ret->lval_type = BASIC_LVAL_CONST_STR; ret->lval.ptr = expbuf - strlen(token); - _cputs("basic_parse_expr string constant ret->lval.ptr = "); - _cputs((char *)ret->lval.ptr); - _cputs("\n"); return ret; break; } @@ -481,6 +435,55 @@ struct basic_expr *basic_parse_expr(char *expbuf, int require_line_numbers) return ret; } +int basic_run_line_v2(char *codeline, int repl_mode) +{ + char *buffptr; + char *token; + int rc = 0; + int lineno = 0; + + if ( codeline == NULL ) { + basic_errno = BASIC_ERR_INTERNAL_NULLPOINTER; + return 1; + } + + /* Continue as long as there's text left in the buffer */ + buffptr = lstripseek(codeline, " "); + while ( buffptr != NULL ) { + buffptr = _tokenize(buffptr, " "); + token = tokenizer_token(); + + /* is it a line number? If so, store it and do nothing else.*/ + if ( isdigit(*token) ) { + memset((char *)&decimal, 0x00, 32); + lineno = atoi(token); + basic_memory_line_store(buffptr, lineno); + return 0; + /* Is it a command? */ + } else if ( strcmp(token, "PRINT") == 0 ) { + basic_cmd_print(buffptr); + return basic_errno; + } else if ( strcmp(token, "LIST") == 0 ) { + basic_cmd_list(NULL); + return basic_errno; + } else if ( strcmp(token, "RUN") == 0 ) { + basic_repl_mode = 1; + return basic_errno; + } else { + basic_errno = BASIC_ERR_INTERNAL_UNDEFINED_BEHAVIOR; + } + + /* Report errors */ + if ( basic_errno != 0 ) { + basic_report_error("Parsing error: "); + } + + /* Move to the next thing in the line and process it */ + buffptr = lstripseek(buffptr, " "); + } + return 0; +} + int basic_run_line(char *codeline, int repl_mode) { /* @@ -551,7 +554,6 @@ void basic_print_var(basic_variable *var) basic_errno = BASIC_ERR_INTERNAL_NULLPOINTER; return; } else { - _cputs("basic_print_var has string:\n"); _cputs(var->value.str); } } @@ -560,24 +562,34 @@ void basic_print_var(basic_variable *var) void basic_repl(void) { char keybuff[512]; + int i; + char *ptr; blankScreen(); setCursorPosition(0, 0); - _cputs("Piquant Basic v0.1\n\n"); + _cputs("Piquant Basic v0.1\n"); + _cputs("READY\n"); + + basic_repl_mode = 1; + /*basic_memory_line_store("LIST", 10); + basic_memory_line_store("PRINT HELLO\n", 20); + basic_memory_line_store("PRINT WORLD\n", 30); + basic_memory_line_store("PRINT GOODBYE\n", 40);*/ while ( 1 ) { basic_errno = 0; + if ( basic_repl_mode == 1 ) { + basic_cmd_run(NULL); + basic_repl_mode = 0; + } _cputs("> "); /* Read */ - memset((void *)&keybuff, 0x00, 512); if ( _cgets((char *)&keybuff) != NULL ) { _cputs("\n"); /* Eval and Print */ - basic_run_line((char *)&keybuff, 1); + basic_run_line_v2((char *)&keybuff, 1); } - /* The loop hangs without this here. WTF? */ - _cputs("\n"); } } diff --git a/src/basic.h b/src/basic.h index 4714cc1..1381fb3 100644 --- a/src/basic.h +++ b/src/basic.h @@ -2,8 +2,8 @@ #define _BASIC_H_ /* Per MS BASIC-80 ref page 1-2 */ -#define BASIC_MAX_LINES sizeof(int) -#define BASIC_MAX_LINE_LENGTH 255 +#define BASIC_MAX_LINES 65535 +#define BASIC_MAX_LINE_LENGTH 72 #define BASIC_OPTP_NONE 0 /* No operation (only valid when LVAL is CONST and no RVAL) */ #define BASIC_OPTP_ADD 1 /* Add */ @@ -46,7 +46,7 @@ #define BASIC_MESSAGE_OK "OK\n" -#define BASIC_TOKENIZER_TOKENS "+-/%*=" +#define BASIC_TOKENIZER_TOKENS " =+-*/^{}%#$!'\\,;:&?<>/@_" #define BASIC_TOKENIZER_MAX_LENGTH 512 #define BASIC_VARNAME_MAX_LENGTH 16 @@ -105,4 +105,5 @@ void basic_cmd_run(void *data); void basic_print_var(basic_variable *var); void basic_report_error(char *prefix); char *basic_memory_line_address(int lineno); +int basic_memory_line_store(char *content, int lineno); #endif /* _BASIC_H_ */ diff --git a/src/string.c b/src/string.c index ed59b15..f262fdb 100644 --- a/src/string.c +++ b/src/string.c @@ -107,6 +107,28 @@ _lstrip_outer_continue: return stripped; } +char *lstripseek(char *s, char *strip) +{ + int stripped = 0; + char *stripptr = strip; + if ( s == NULL || strip == NULL ) { + return NULL; + } + while ( *s != 0 ) { + stripped = 0; + for ( stripptr = strip; *stripptr != 0; stripptr += 1) { + if ( *s == *stripptr ) { + stripped = 1; + } + } + if ( stripped == 0 ) { + return s; + } + s += 1; + } + return NULL; +} + int rstrip(char *s1, char *s2, char *strip) { int stripped = 0; diff --git a/src/string.h b/src/string.h index c4824cf..3b5bb89 100644 --- a/src/string.h +++ b/src/string.h @@ -10,4 +10,5 @@ void *memcpy(void *dest, void *src, size_t n); int strcmp(char *s1, char *s2); int lstrip(char *s1, char *s2, char *strip); int rstrip(char *s1, char *s2, char *strip); +char *lstripseek(char *s, char *strip); #endif /* _STRING_H_ */