Woohoo we have math
This commit is contained in:
2
Makefile
2
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
|
||||
|
||||
@@ -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
|
||||
|
||||
146
src/basic.c
146
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");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
41
src/basic.h
41
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);
|
||||
|
||||
Reference in New Issue
Block a user