From cf5883d40166e6216eabfc9ed4edd7314fc1511c Mon Sep 17 00:00:00 2001 From: Andrew Kesterson Date: Mon, 26 Jan 2015 21:55:55 -0800 Subject: [PATCH] Woohoo we have math --- Makefile | 2 +- asm/kernel_syms.S | 26 +-------- src/basic.c | 146 +++++++++++++++++++++++++++++++++++++++++----- src/basic.h | 41 ++++++++++--- 4 files changed, 164 insertions(+), 51 deletions(-) diff --git a/Makefile b/Makefile index cfbcb00..f1792a4 100644 --- a/Makefile +++ b/Makefile @@ -3,7 +3,7 @@ all: boot.img kernel.bin src/%.o: src/%.c bcc -ansi -0 -c -o $@ $< -kernel.bin: src/kernel.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 asm/kernel_syms.S: kernel.bin diff --git a/asm/kernel_syms.S b/asm/kernel_syms.S index e727dac..4b0f4d5 100644 --- a/asm/kernel_syms.S +++ b/asm/kernel_syms.S @@ -1,26 +1,2 @@ -_extern_c_backupCursor: - jmp 0x1000:0x001e -_extern_c_blankScreen: - jmp 0x1000:0x03b6 -_extern_c_strlen: - jmp 0x1000:0x00ba _extern_c_main: - jmp 0x1000:0x0412 -_extern_c_getkey: - jmp 0x1000:0x0155 -_extern_c_repl: - jmp 0x1000:0x02ea -_extern_c_strcmp: - jmp 0x1000:0x0265 -_extern_c_advanceCursor: - jmp 0x1000:0x0067 -_extern_c_setCursorPosition: - jmp 0x1000:0x0000 -_extern_c_memset: - jmp 0x1000:0x0227 -_extern_c_putc: - jmp 0x1000:0x00a0 -_extern_c_puts: - jmp 0x1000:0x00f4 -_extern_c_gets: - jmp 0x1000:0x017b + jmp 0x1000:0x0d90 diff --git a/src/basic.c b/src/basic.c index 35a5f60..65db475 100644 --- a/src/basic.c +++ b/src/basic.c @@ -4,7 +4,7 @@ #include "string.h" #include "stdlib.h" -struct basic_math_expr math_expressions[8]; +struct basic_expr math_expressions[32]; int basic_errno; char _tokenizer_value[BASIC_TOKENIZER_MAX_LENGTH]; @@ -50,14 +50,98 @@ char *_tokenize(char *ptr, char token) return &_tokenizer_value; } -struct basic_math_expr *basic_parse_expr(char *expbuf) +int basic_solve_expr(struct basic_expr *expr, struct basic_variable *result) { - struct basic_math_expr *ret = &math_expressions[0]; + if ( expr == NULL || result == NULL ) { + basic_errno = BASIC_ERR_INTERNAL_NULLPOINTER; + return NULL; + } + + switch (expr->type) { + case BASIC_OPTP_ADD: + if ( expr->lval_type != BASIC_LVAL_CONST || + ( expr->rval_type != BASIC_RVAL_CONST ) ) { + basic_errno = BASIC_ERR_INVALID_ARGUMENTS; + return NULL; + } + result->flags = (result->flags | BASIC_VARFLAG_TINT | BASIC_VARFLAG_INIT); + result->value = (int)expr->lval + (int)expr->rval; + break; + case BASIC_OPTP_SUB: + if ( expr->lval_type != BASIC_LVAL_CONST || + ( expr->rval_type != BASIC_RVAL_CONST ) ) { + basic_errno = BASIC_ERR_INVALID_ARGUMENTS; + return NULL; + } + result->flags = (result->flags | BASIC_VARFLAG_TINT | BASIC_VARFLAG_INIT); + result->value = (int)expr->lval - (int)expr->rval; + break; + case BASIC_OPTP_MUL: + if ( expr->lval_type != BASIC_LVAL_CONST || + ( expr->rval_type != BASIC_RVAL_CONST ) ) { + basic_errno = BASIC_ERR_INVALID_ARGUMENTS; + return NULL; + } + result->flags = (result->flags | BASIC_VARFLAG_TINT | BASIC_VARFLAG_INIT); + result->value = (int)expr->lval * (int)expr->rval; + break; + case BASIC_OPTP_DIV: + if ( expr->lval_type != BASIC_LVAL_CONST || + ( expr->rval_type != BASIC_RVAL_CONST ) ) { + basic_errno = BASIC_ERR_INVALID_ARGUMENTS; + return NULL; + } + if ( expr->rval == 0 ) { + basic_errno = BASIC_ERR_MATH_DBZ; + return NULL; + } + result->flags = (result->flags | BASIC_VARFLAG_TINT | BASIC_VARFLAG_INIT); + result->value = (int)expr->lval / (int)expr->rval; + break; + case BASIC_OPTP_MOD: + if ( expr->lval_type != BASIC_LVAL_CONST || + ( expr->rval_type != BASIC_RVAL_CONST ) ) { + basic_errno = BASIC_ERR_INVALID_ARGUMENTS; + return NULL; + } + if ( expr->rval == 0 ) { + basic_errno = BASIC_ERR_MATH_DBZ; + return NULL; + } + result->flags = (result->flags | BASIC_VARFLAG_TINT | BASIC_VARFLAG_INIT); + result->value = ((int)expr->lval) - (((int)expr->lval / (int)expr->rval)*(int)expr->rval); + break; + case BASIC_OPTP_EQL: + if ( expr->lval_type != BASIC_LVAL_CONST || + ( expr->rval_type != BASIC_RVAL_CONST ) ) { + basic_errno = BASIC_ERR_INVALID_ARGUMENTS; + return NULL; + } + result->flags = (result->flags | BASIC_VARFLAG_TINT | BASIC_VARFLAG_INIT); + if ((int)expr->lval == (int)expr->rval) { + result->value = BASIC_CONST_TRUE; + } else { + result->value = BASIC_CONST_FALSE; + } + break; + case BASIC_OPTP_ASN: + basic_errno = BASIC_ERR_INTERNAL_UNIMPLEMENTED; + return NULL; + default: + basic_errno = BASIC_ERR_INTERNAL_UNDEFINED_BEHAVIOR; + return NULL; + } + return 1; +} + +struct basic_expr *basic_parse_expr(char *expbuf) +{ + struct basic_expr *ret = &math_expressions[0]; char flags = 0; char *subptr = 0; _tokenizer_init(); - memset(ret, 0x0, sizeof(struct basic_math_expr)); + memset(ret, 0x0, sizeof(struct basic_expr)); while ( *expbuf != '\0' ) { if ( *expbuf == ' ' ) { @@ -69,24 +153,26 @@ struct basic_math_expr *basic_parse_expr(char *expbuf) return NULL; } else if ( ret->type == 0x0 ) { ret->lval = atoi(_tokenize(expbuf, ' ')); + ret->lval_type = BASIC_LVAL_CONST; flags = (flags + BASIC_FOUND_LVAL); } else if ( ret->type != 0x0 && ((flags & BASIC_FOUND_RVAL) == BASIC_FOUND_RVAL)) { basic_errno = BASIC_ERR_SYNTAX_MULTIPLE_RVALUES; return NULL; } else if ( ret->type != 0x0 ) { ret->rval = atoi(_tokenize(expbuf, ' ')); + ret->rval_type = BASIC_RVAL_CONST; } } else if ( ret->type == 0x0 ) { if ( *expbuf == '+' ) { - ret->type = BASIC_MATH_ADD; + ret->type = BASIC_OPTP_ADD; } else if ( *expbuf == '*' ) { - ret->type = BASIC_MATH_MUL; + ret->type = BASIC_OPTP_MUL; } else if ( *expbuf == '-' ) { - ret->type = BASIC_MATH_SUB; + ret->type = BASIC_OPTP_SUB; } else if ( *expbuf == '/' ) { - ret->type = BASIC_MATH_DIV; + ret->type = BASIC_OPTP_DIV; } else if ( *expbuf == '%' ) { - ret->type = BASIC_MATH_MOD; + ret->type = BASIC_OPTP_MOD; } else { basic_errno = BASIC_ERR_SYNTAX_GENERAL; return NULL; @@ -104,16 +190,25 @@ void basic_run(void) { char keybuff[512]; char outbuff[128]; - char decimal; + char decimal[2]; - struct basic_math_expr *expr; + struct basic_expr *expr; + struct basic_variable result; + + decimal[0] = 0; + decimal[1] = 0; blankScreen(); setCursorPosition(0, 0); _cputs("Piquant Basic v0.1\n\n"); while ( 1 ) { + memset((void *)&result, 0x00, sizeof(struct basic_variable)); + expr = NULL; _cputs("> "); + + /* Read */ + memset((void *)&keybuff, 0x00, 512); memset((void *)&outbuff, 0x00, 128); if ( _cgets((char *)&keybuff) != NULL ) { @@ -124,30 +219,49 @@ void basic_run(void) expr = basic_parse_expr((char *)&keybuff); if ( expr == NULL ) { - _cputs("Syntax Error: "); - decimal = dtoa(basic_errno); + _cputs("Error: "); + decimal[0] = dtoa(basic_errno); _cputs(&decimal); _cputs("\n"); + basic_errno = 0; continue; } - decimal = dtoa(expr->type); + /* Debug */ + + decimal[0] = dtoa(expr->type); memcpy(&outbuff, "Expression type: \0", strlen("Expression type: \0")); strncat(&outbuff, &decimal, 1); _cputs(&outbuff); _cputs("\n"); - decimal = dtoa(expr->lval); + decimal[0] = dtoa(expr->lval); memcpy(&outbuff, "Expression lval: \0", strlen("Expression lval: \0")); strncat(&outbuff, &decimal, 1); _cputs(&outbuff); _cputs("\n"); - decimal = dtoa(expr->rval); + decimal[0] = dtoa(expr->rval); memcpy(&outbuff, "Expression rval: \0", strlen("Expression rval: \0")); strncat(&outbuff, &decimal, 1); _cputs(&outbuff); _cputs("\n"); + + /* Evaluate */ + basic_solve_expr(expr, &result); + if ( basic_errno != 0 ) { + _cputs("Error: "); + decimal[0] = dtoa(basic_errno); + _cputs(&decimal); + _cputs("\n"); + } else { + if ( ( (result.flags & BASIC_VARFLAG_INIT) == BASIC_VARFLAG_INIT ) && + ( (result.flags & BASIC_VARFLAG_TINT) == BASIC_VARFLAG_TINT ) ) { + decimal[0] = dtoa((int)result.value); + _cputs(&decimal); + _cputs("\n"); + } + } } } } diff --git a/src/basic.h b/src/basic.h index 9ee8bae..dcf61f1 100644 --- a/src/basic.h +++ b/src/basic.h @@ -1,17 +1,20 @@ #ifndef _BASIC_H_ #define _BASIC_H_ -#define BASIC_MATH_ADD 1 -#define BASIC_MATH_SUB 2 -#define BASIC_MATH_MUL 3 -#define BASIC_MATH_DIV 4 -#define BASIC_MATH_MOD 5 +#define BASIC_OPTP_ADD 1 +#define BASIC_OPTP_SUB 2 +#define BASIC_OPTP_MUL 3 +#define BASIC_OPTP_DIV 4 +#define BASIC_OPTP_MOD 5 +#define BASIC_OPTP_EQL 6 +#define BASIC_OPTP_ASN 7 #define BASIC_LVAL_EXPR 0 #define BASIC_LVAL_VAR 1 -#define BASIC_RVAL_EXPR 2 -#define BASIC_RVAL_VAR 3 -#define BASIC_RVAL_CONST 4 +#define BASIC_LVAL_CONST 2 +#define BASIC_RVAL_EXPR 3 +#define BASIC_RVAL_VAR 4 +#define BASIC_RVAL_CONST 5 #define BASIC_FOUND_LVAL 0x0001 #define BASIC_FOUND_RVAL 0x0002 @@ -20,10 +23,17 @@ #define BASIC_ERR_SYNTAX_TOKEN_LENGTH 2 #define BASIC_ERR_SYNTAX_GENERAL 3 #define BASIC_ERR_SYNTAX_MULTIPLE_RVALUES 4 +#define BASIC_ERR_INVALID_ARGUMENTS 5 +#define BASIC_ERR_INTERNAL_NULLPOINTER 6 +#define BASIC_ERR_INTERNAL_MEMORY 7 +#define BASIC_ERR_INTERNAL_UNDEFINED_BEHAVIOR 8 +#define BASIC_ERR_INTERNAL_UNIMPLEMENTED 9 +#define BASIC_ERR_MATH_DBZ 10 #define BASIC_TOKENIZER_MAX_LENGTH 512 +#define BASIC_VARNAME_MAX_LENGTH 16 -struct basic_math_expr { +struct basic_expr { char type; char lval_type; char rval_type; @@ -32,6 +42,19 @@ struct basic_math_expr { void *rval; }; +#define BASIC_VARFLAG_INIT 1 +#define BASIC_VARFLAG_TINT 2 +#define BASIC_VARFLAG_TSTR 4 + +struct basic_variable { + char *name; + char flags; + void *value; +}; + +#define BASIC_CONST_TRUE 1 +#define BASIC_CONST_FALSE 0 + extern int basic_errno; void run_basic(void);