Woohoo we have math

This commit is contained in:
2015-01-26 21:55:55 -08:00
parent 208c831c79
commit cf5883d401
4 changed files with 164 additions and 51 deletions

View File

@@ -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");
}
}
}
}
}

View File

@@ -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);