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
|
src/%.o: src/%.c
|
||||||
bcc -ansi -0 -c -o $@ $<
|
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
|
ld86 -d -M -o $@ $^ | tee ld86.out
|
||||||
|
|
||||||
asm/kernel_syms.S: kernel.bin
|
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:
|
_extern_c_main:
|
||||||
jmp 0x1000:0x0412
|
jmp 0x1000:0x0d90
|
||||||
_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
|
|
||||||
|
|||||||
146
src/basic.c
146
src/basic.c
@@ -4,7 +4,7 @@
|
|||||||
#include "string.h"
|
#include "string.h"
|
||||||
#include "stdlib.h"
|
#include "stdlib.h"
|
||||||
|
|
||||||
struct basic_math_expr math_expressions[8];
|
struct basic_expr math_expressions[32];
|
||||||
int basic_errno;
|
int basic_errno;
|
||||||
|
|
||||||
char _tokenizer_value[BASIC_TOKENIZER_MAX_LENGTH];
|
char _tokenizer_value[BASIC_TOKENIZER_MAX_LENGTH];
|
||||||
@@ -50,14 +50,98 @@ char *_tokenize(char *ptr, char token)
|
|||||||
return &_tokenizer_value;
|
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 flags = 0;
|
||||||
char *subptr = 0;
|
char *subptr = 0;
|
||||||
|
|
||||||
_tokenizer_init();
|
_tokenizer_init();
|
||||||
memset(ret, 0x0, sizeof(struct basic_math_expr));
|
memset(ret, 0x0, sizeof(struct basic_expr));
|
||||||
|
|
||||||
while ( *expbuf != '\0' ) {
|
while ( *expbuf != '\0' ) {
|
||||||
if ( *expbuf == ' ' ) {
|
if ( *expbuf == ' ' ) {
|
||||||
@@ -69,24 +153,26 @@ struct basic_math_expr *basic_parse_expr(char *expbuf)
|
|||||||
return NULL;
|
return NULL;
|
||||||
} else if ( ret->type == 0x0 ) {
|
} else if ( ret->type == 0x0 ) {
|
||||||
ret->lval = atoi(_tokenize(expbuf, ' '));
|
ret->lval = atoi(_tokenize(expbuf, ' '));
|
||||||
|
ret->lval_type = BASIC_LVAL_CONST;
|
||||||
flags = (flags + BASIC_FOUND_LVAL);
|
flags = (flags + BASIC_FOUND_LVAL);
|
||||||
} else if ( ret->type != 0x0 && ((flags & BASIC_FOUND_RVAL) == BASIC_FOUND_RVAL)) {
|
} else if ( ret->type != 0x0 && ((flags & BASIC_FOUND_RVAL) == BASIC_FOUND_RVAL)) {
|
||||||
basic_errno = BASIC_ERR_SYNTAX_MULTIPLE_RVALUES;
|
basic_errno = BASIC_ERR_SYNTAX_MULTIPLE_RVALUES;
|
||||||
return NULL;
|
return NULL;
|
||||||
} else if ( ret->type != 0x0 ) {
|
} else if ( ret->type != 0x0 ) {
|
||||||
ret->rval = atoi(_tokenize(expbuf, ' '));
|
ret->rval = atoi(_tokenize(expbuf, ' '));
|
||||||
|
ret->rval_type = BASIC_RVAL_CONST;
|
||||||
}
|
}
|
||||||
} else if ( ret->type == 0x0 ) {
|
} else if ( ret->type == 0x0 ) {
|
||||||
if ( *expbuf == '+' ) {
|
if ( *expbuf == '+' ) {
|
||||||
ret->type = BASIC_MATH_ADD;
|
ret->type = BASIC_OPTP_ADD;
|
||||||
} else if ( *expbuf == '*' ) {
|
} else if ( *expbuf == '*' ) {
|
||||||
ret->type = BASIC_MATH_MUL;
|
ret->type = BASIC_OPTP_MUL;
|
||||||
} else if ( *expbuf == '-' ) {
|
} else if ( *expbuf == '-' ) {
|
||||||
ret->type = BASIC_MATH_SUB;
|
ret->type = BASIC_OPTP_SUB;
|
||||||
} else if ( *expbuf == '/' ) {
|
} else if ( *expbuf == '/' ) {
|
||||||
ret->type = BASIC_MATH_DIV;
|
ret->type = BASIC_OPTP_DIV;
|
||||||
} else if ( *expbuf == '%' ) {
|
} else if ( *expbuf == '%' ) {
|
||||||
ret->type = BASIC_MATH_MOD;
|
ret->type = BASIC_OPTP_MOD;
|
||||||
} else {
|
} else {
|
||||||
basic_errno = BASIC_ERR_SYNTAX_GENERAL;
|
basic_errno = BASIC_ERR_SYNTAX_GENERAL;
|
||||||
return NULL;
|
return NULL;
|
||||||
@@ -104,16 +190,25 @@ void basic_run(void)
|
|||||||
{
|
{
|
||||||
char keybuff[512];
|
char keybuff[512];
|
||||||
char outbuff[128];
|
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();
|
blankScreen();
|
||||||
setCursorPosition(0, 0);
|
setCursorPosition(0, 0);
|
||||||
_cputs("Piquant Basic v0.1\n\n");
|
_cputs("Piquant Basic v0.1\n\n");
|
||||||
|
|
||||||
while ( 1 ) {
|
while ( 1 ) {
|
||||||
|
memset((void *)&result, 0x00, sizeof(struct basic_variable));
|
||||||
|
expr = NULL;
|
||||||
_cputs("> ");
|
_cputs("> ");
|
||||||
|
|
||||||
|
/* Read */
|
||||||
|
|
||||||
memset((void *)&keybuff, 0x00, 512);
|
memset((void *)&keybuff, 0x00, 512);
|
||||||
memset((void *)&outbuff, 0x00, 128);
|
memset((void *)&outbuff, 0x00, 128);
|
||||||
if ( _cgets((char *)&keybuff) != NULL ) {
|
if ( _cgets((char *)&keybuff) != NULL ) {
|
||||||
@@ -124,30 +219,49 @@ void basic_run(void)
|
|||||||
|
|
||||||
expr = basic_parse_expr((char *)&keybuff);
|
expr = basic_parse_expr((char *)&keybuff);
|
||||||
if ( expr == NULL ) {
|
if ( expr == NULL ) {
|
||||||
_cputs("Syntax Error: ");
|
_cputs("Error: ");
|
||||||
decimal = dtoa(basic_errno);
|
decimal[0] = dtoa(basic_errno);
|
||||||
_cputs(&decimal);
|
_cputs(&decimal);
|
||||||
_cputs("\n");
|
_cputs("\n");
|
||||||
|
basic_errno = 0;
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
decimal = dtoa(expr->type);
|
/* Debug */
|
||||||
|
|
||||||
|
decimal[0] = dtoa(expr->type);
|
||||||
memcpy(&outbuff, "Expression type: \0", strlen("Expression type: \0"));
|
memcpy(&outbuff, "Expression type: \0", strlen("Expression type: \0"));
|
||||||
strncat(&outbuff, &decimal, 1);
|
strncat(&outbuff, &decimal, 1);
|
||||||
_cputs(&outbuff);
|
_cputs(&outbuff);
|
||||||
_cputs("\n");
|
_cputs("\n");
|
||||||
|
|
||||||
decimal = dtoa(expr->lval);
|
decimal[0] = dtoa(expr->lval);
|
||||||
memcpy(&outbuff, "Expression lval: \0", strlen("Expression lval: \0"));
|
memcpy(&outbuff, "Expression lval: \0", strlen("Expression lval: \0"));
|
||||||
strncat(&outbuff, &decimal, 1);
|
strncat(&outbuff, &decimal, 1);
|
||||||
_cputs(&outbuff);
|
_cputs(&outbuff);
|
||||||
_cputs("\n");
|
_cputs("\n");
|
||||||
|
|
||||||
decimal = dtoa(expr->rval);
|
decimal[0] = dtoa(expr->rval);
|
||||||
memcpy(&outbuff, "Expression rval: \0", strlen("Expression rval: \0"));
|
memcpy(&outbuff, "Expression rval: \0", strlen("Expression rval: \0"));
|
||||||
strncat(&outbuff, &decimal, 1);
|
strncat(&outbuff, &decimal, 1);
|
||||||
_cputs(&outbuff);
|
_cputs(&outbuff);
|
||||||
_cputs("\n");
|
_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_
|
#ifndef _BASIC_H_
|
||||||
#define _BASIC_H_
|
#define _BASIC_H_
|
||||||
|
|
||||||
#define BASIC_MATH_ADD 1
|
#define BASIC_OPTP_ADD 1
|
||||||
#define BASIC_MATH_SUB 2
|
#define BASIC_OPTP_SUB 2
|
||||||
#define BASIC_MATH_MUL 3
|
#define BASIC_OPTP_MUL 3
|
||||||
#define BASIC_MATH_DIV 4
|
#define BASIC_OPTP_DIV 4
|
||||||
#define BASIC_MATH_MOD 5
|
#define BASIC_OPTP_MOD 5
|
||||||
|
#define BASIC_OPTP_EQL 6
|
||||||
|
#define BASIC_OPTP_ASN 7
|
||||||
|
|
||||||
#define BASIC_LVAL_EXPR 0
|
#define BASIC_LVAL_EXPR 0
|
||||||
#define BASIC_LVAL_VAR 1
|
#define BASIC_LVAL_VAR 1
|
||||||
#define BASIC_RVAL_EXPR 2
|
#define BASIC_LVAL_CONST 2
|
||||||
#define BASIC_RVAL_VAR 3
|
#define BASIC_RVAL_EXPR 3
|
||||||
#define BASIC_RVAL_CONST 4
|
#define BASIC_RVAL_VAR 4
|
||||||
|
#define BASIC_RVAL_CONST 5
|
||||||
|
|
||||||
#define BASIC_FOUND_LVAL 0x0001
|
#define BASIC_FOUND_LVAL 0x0001
|
||||||
#define BASIC_FOUND_RVAL 0x0002
|
#define BASIC_FOUND_RVAL 0x0002
|
||||||
@@ -20,10 +23,17 @@
|
|||||||
#define BASIC_ERR_SYNTAX_TOKEN_LENGTH 2
|
#define BASIC_ERR_SYNTAX_TOKEN_LENGTH 2
|
||||||
#define BASIC_ERR_SYNTAX_GENERAL 3
|
#define BASIC_ERR_SYNTAX_GENERAL 3
|
||||||
#define BASIC_ERR_SYNTAX_MULTIPLE_RVALUES 4
|
#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_TOKENIZER_MAX_LENGTH 512
|
||||||
|
#define BASIC_VARNAME_MAX_LENGTH 16
|
||||||
|
|
||||||
struct basic_math_expr {
|
struct basic_expr {
|
||||||
char type;
|
char type;
|
||||||
char lval_type;
|
char lval_type;
|
||||||
char rval_type;
|
char rval_type;
|
||||||
@@ -32,6 +42,19 @@ struct basic_math_expr {
|
|||||||
void *rval;
|
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;
|
extern int basic_errno;
|
||||||
|
|
||||||
void run_basic(void);
|
void run_basic(void);
|
||||||
|
|||||||
Reference in New Issue
Block a user