Added the ability to parse commands as well as expressions.
Added basic PRINT and REM commands. Added solver tests which had been around for a while and not committed. All execution is still immediate mode.
This commit is contained in:
172
src/basic.c
172
src/basic.c
@@ -11,6 +11,62 @@ char _tokenizer_value[BASIC_TOKENIZER_MAX_LENGTH];
|
|||||||
char *_tokenizer_prev;
|
char *_tokenizer_prev;
|
||||||
char *_tokenizer_prev_next;
|
char *_tokenizer_prev_next;
|
||||||
|
|
||||||
|
void basic_report_error()
|
||||||
|
{
|
||||||
|
char decimal[2];
|
||||||
|
decimal[0] = 0;
|
||||||
|
decimal[1] = 0;
|
||||||
|
_cputs("Error: ");
|
||||||
|
decimal[0] = dtoa(basic_errno);
|
||||||
|
_cputs((char *)&decimal);
|
||||||
|
_cputs("\n");
|
||||||
|
}
|
||||||
|
|
||||||
|
/***************************************************************
|
||||||
|
*
|
||||||
|
* Basic Commands
|
||||||
|
*
|
||||||
|
***************************************************************/
|
||||||
|
|
||||||
|
void basic_cmd_rem(void *expr)
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
void basic_cmd_print(void *data)
|
||||||
|
{
|
||||||
|
struct basic_variable result;
|
||||||
|
basic_expr *expr;
|
||||||
|
if ( data == NULL ) {
|
||||||
|
basic_errno = BASIC_ERR_INTERNAL_NULLPOINTER;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
_cputs("PRINT(");
|
||||||
|
_cputs((char *)data);
|
||||||
|
_cputs(")\n");
|
||||||
|
|
||||||
|
expr = basic_parse_expr((char *)data);
|
||||||
|
if ( expr == NULL ) {
|
||||||
|
basic_errno = BASIC_ERR_INTERNAL_NULLPOINTER;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
memset((void *)&result, 0x00, sizeof(struct basic_variable));
|
||||||
|
basic_solve_expr(expr, &result);
|
||||||
|
if ( basic_errno != 0 ) {
|
||||||
|
return;
|
||||||
|
} else {
|
||||||
|
basic_print_var(&result);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/***************************************************************
|
||||||
|
*
|
||||||
|
* Basic Tokenizer
|
||||||
|
*
|
||||||
|
***************************************************************/
|
||||||
|
|
||||||
void _tokenizer_init(void)
|
void _tokenizer_init(void)
|
||||||
{
|
{
|
||||||
_tokenizer_prev = NULL;
|
_tokenizer_prev = NULL;
|
||||||
@@ -64,11 +120,17 @@ _tokenize_copy:
|
|||||||
return ptr;
|
return ptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
char *_token_get(void)
|
char *tokenizer_token(void)
|
||||||
{
|
{
|
||||||
return (char *)&_tokenizer_value;
|
return (char *)&_tokenizer_value;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/***************************************************************
|
||||||
|
*
|
||||||
|
* Basic Interpreter
|
||||||
|
*
|
||||||
|
***************************************************************/
|
||||||
|
|
||||||
int basic_solve_expr(struct basic_expr *expr, struct basic_variable *result)
|
int basic_solve_expr(struct basic_expr *expr, struct basic_variable *result)
|
||||||
{
|
{
|
||||||
if ( expr == NULL || result == NULL ) {
|
if ( expr == NULL || result == NULL ) {
|
||||||
@@ -77,9 +139,18 @@ int basic_solve_expr(struct basic_expr *expr, struct basic_variable *result)
|
|||||||
}
|
}
|
||||||
|
|
||||||
switch (expr->type) {
|
switch (expr->type) {
|
||||||
|
case BASIC_OPTP_NONE:
|
||||||
|
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 {
|
||||||
|
basic_errno = BASIC_ERR_INTERNAL_UNIMPLEMENTED;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
break;
|
||||||
case BASIC_OPTP_ADD:
|
case BASIC_OPTP_ADD:
|
||||||
if ( expr->lval_type != BASIC_LVAL_CONST ||
|
if ( expr->lval_type != BASIC_LVAL_CONST_INT ||
|
||||||
( expr->rval_type != BASIC_RVAL_CONST ) ) {
|
( expr->rval_type != BASIC_RVAL_CONST_INT ) ) {
|
||||||
basic_errno = BASIC_ERR_INVALID_ARGUMENTS;
|
basic_errno = BASIC_ERR_INVALID_ARGUMENTS;
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
@@ -87,8 +158,8 @@ int basic_solve_expr(struct basic_expr *expr, struct basic_variable *result)
|
|||||||
result->value.i = expr->lval.i + expr->rval.i;
|
result->value.i = expr->lval.i + expr->rval.i;
|
||||||
break;
|
break;
|
||||||
case BASIC_OPTP_SUB:
|
case BASIC_OPTP_SUB:
|
||||||
if ( expr->lval_type != BASIC_LVAL_CONST ||
|
if ( expr->lval_type != BASIC_LVAL_CONST_INT ||
|
||||||
( expr->rval_type != BASIC_RVAL_CONST ) ) {
|
( expr->rval_type != BASIC_RVAL_CONST_INT ) ) {
|
||||||
basic_errno = BASIC_ERR_INVALID_ARGUMENTS;
|
basic_errno = BASIC_ERR_INVALID_ARGUMENTS;
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
@@ -96,8 +167,8 @@ int basic_solve_expr(struct basic_expr *expr, struct basic_variable *result)
|
|||||||
result->value.i = expr->lval.i - expr->rval.i;
|
result->value.i = expr->lval.i - expr->rval.i;
|
||||||
break;
|
break;
|
||||||
case BASIC_OPTP_MUL:
|
case BASIC_OPTP_MUL:
|
||||||
if ( expr->lval_type != BASIC_LVAL_CONST ||
|
if ( expr->lval_type != BASIC_LVAL_CONST_INT ||
|
||||||
( expr->rval_type != BASIC_RVAL_CONST ) ) {
|
( expr->rval_type != BASIC_RVAL_CONST_INT ) ) {
|
||||||
basic_errno = BASIC_ERR_INVALID_ARGUMENTS;
|
basic_errno = BASIC_ERR_INVALID_ARGUMENTS;
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
@@ -105,8 +176,8 @@ int basic_solve_expr(struct basic_expr *expr, struct basic_variable *result)
|
|||||||
result->value.i = expr->lval.i * expr->rval.i;
|
result->value.i = expr->lval.i * expr->rval.i;
|
||||||
break;
|
break;
|
||||||
case BASIC_OPTP_DIV:
|
case BASIC_OPTP_DIV:
|
||||||
if ( expr->lval_type != BASIC_LVAL_CONST ||
|
if ( expr->lval_type != BASIC_LVAL_CONST_INT ||
|
||||||
( expr->rval_type != BASIC_RVAL_CONST ) ) {
|
( expr->rval_type != BASIC_RVAL_CONST_INT ) ) {
|
||||||
basic_errno = BASIC_ERR_INVALID_ARGUMENTS;
|
basic_errno = BASIC_ERR_INVALID_ARGUMENTS;
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
@@ -118,8 +189,8 @@ int basic_solve_expr(struct basic_expr *expr, struct basic_variable *result)
|
|||||||
result->value.i = expr->lval.i / expr->rval.i;
|
result->value.i = expr->lval.i / expr->rval.i;
|
||||||
break;
|
break;
|
||||||
case BASIC_OPTP_MOD:
|
case BASIC_OPTP_MOD:
|
||||||
if ( expr->lval_type != BASIC_LVAL_CONST ||
|
if ( expr->lval_type != BASIC_LVAL_CONST_INT ||
|
||||||
( expr->rval_type != BASIC_RVAL_CONST ) ) {
|
( expr->rval_type != BASIC_RVAL_CONST_INT ) ) {
|
||||||
basic_errno = BASIC_ERR_INVALID_ARGUMENTS;
|
basic_errno = BASIC_ERR_INVALID_ARGUMENTS;
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
@@ -131,8 +202,8 @@ int basic_solve_expr(struct basic_expr *expr, struct basic_variable *result)
|
|||||||
result->value.i = (expr->lval.i) - ((expr->lval.i / expr->rval.i)*expr->rval.i);
|
result->value.i = (expr->lval.i) - ((expr->lval.i / expr->rval.i)*expr->rval.i);
|
||||||
break;
|
break;
|
||||||
case BASIC_OPTP_EQL:
|
case BASIC_OPTP_EQL:
|
||||||
if ( expr->lval_type != BASIC_LVAL_CONST ||
|
if ( expr->lval_type != BASIC_LVAL_CONST_INT ||
|
||||||
( expr->rval_type != BASIC_RVAL_CONST ) ) {
|
( expr->rval_type != BASIC_RVAL_CONST_INT ) ) {
|
||||||
basic_errno = BASIC_ERR_INVALID_ARGUMENTS;
|
basic_errno = BASIC_ERR_INVALID_ARGUMENTS;
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
@@ -169,37 +240,60 @@ struct basic_expr *basic_parse_expr(char *expbuf)
|
|||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
expbuf = _tokenize(expbuf, BASIC_TOKENIZER_TOKENS);
|
expbuf = _tokenize(expbuf, " ");
|
||||||
token = _token_get();
|
token = tokenizer_token();
|
||||||
if ( isdigit(*token) == 1 ) {
|
if ( isdigit(*token) == 1 ) {
|
||||||
if ( (ret->type == 0) && (flags & BASIC_PARSE_FOUND_LVAL) == BASIC_PARSE_FOUND_LVAL ) {
|
if ( (ret->type == 0) && (flags & BASIC_PARSE_FOUND_LVAL) == BASIC_PARSE_FOUND_LVAL ) {
|
||||||
basic_errno = BASIC_ERR_SYNTAX_MULTIPLE_LVALUES;
|
basic_errno = BASIC_ERR_SYNTAX_MULTIPLE_LVALUES;
|
||||||
return NULL;
|
return NULL;
|
||||||
} else if ( ret->type == 0x0 ) {
|
} else if ( ret->type == 0x0 ) {
|
||||||
ret->lval.i = atoi(token);
|
ret->lval.i = atoi(token);
|
||||||
ret->lval_type = BASIC_LVAL_CONST;
|
ret->lval_type = BASIC_LVAL_CONST_INT;
|
||||||
flags = (flags | BASIC_PARSE_FOUND_LVAL);
|
flags = (flags | BASIC_PARSE_FOUND_LVAL);
|
||||||
} else if ( ret->type != 0x0 && ((flags & BASIC_PARSE_FOUND_RVAL) == BASIC_PARSE_FOUND_RVAL)) {
|
} else if ( ret->type != 0x0 && ((flags & BASIC_PARSE_FOUND_RVAL) == BASIC_PARSE_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.i = atoi(token);
|
ret->rval.i = atoi(token);
|
||||||
ret->rval_type = BASIC_RVAL_CONST;
|
ret->rval_type = BASIC_RVAL_CONST_INT;
|
||||||
}
|
}
|
||||||
} else if ( token != NULL && ret->type == 0x0 ) {
|
} else if ( token != NULL && ret->type == 0x0 ) {
|
||||||
if ( *token == '+' ) {
|
switch ( *token ) {
|
||||||
|
case '+':
|
||||||
ret->type = BASIC_OPTP_ADD;
|
ret->type = BASIC_OPTP_ADD;
|
||||||
} else if ( *token == '*' ) {
|
break;
|
||||||
|
case '*':
|
||||||
ret->type = BASIC_OPTP_MUL;
|
ret->type = BASIC_OPTP_MUL;
|
||||||
} else if ( *token == '-' ) {
|
break;
|
||||||
|
case '-':
|
||||||
ret->type = BASIC_OPTP_SUB;
|
ret->type = BASIC_OPTP_SUB;
|
||||||
} else if ( *token == '/' ) {
|
break;
|
||||||
|
case '/':
|
||||||
ret->type = BASIC_OPTP_DIV;
|
ret->type = BASIC_OPTP_DIV;
|
||||||
} else if ( *token == '%' ) {
|
break;
|
||||||
|
case '%':
|
||||||
ret->type = BASIC_OPTP_MOD;
|
ret->type = BASIC_OPTP_MOD;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
/* see if a command will claim this token */
|
||||||
|
if ( strcmp(token, "REM") == 0 ) {
|
||||||
|
ret->type = BASIC_OPTP_CMD;
|
||||||
|
ret->lval_type = BASIC_LVAL_CMDPTR;
|
||||||
|
ret->lval.cmd_ptr = basic_cmd_rem;
|
||||||
|
ret->rval_type = BASIC_RVAL_NONE;
|
||||||
|
return ret;
|
||||||
|
} else if ( strcmp(token, "PRINT") == 0 ) {
|
||||||
|
ret->type = BASIC_OPTP_CMD;
|
||||||
|
ret->lval_type = BASIC_LVAL_CMDPTR;
|
||||||
|
ret->lval.cmd_ptr = basic_cmd_print;
|
||||||
|
ret->rval_type = BASIC_RVAL_PTR;
|
||||||
|
ret->rval.ptr = expbuf;
|
||||||
|
return ret;
|
||||||
} else {
|
} else {
|
||||||
basic_errno = BASIC_ERR_SYNTAX_GENERAL;
|
basic_errno = BASIC_ERR_SYNTAX_GENERAL;
|
||||||
return NULL;
|
return NULL;
|
||||||
|
break;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
basic_errno = BASIC_ERR_SYNTAX_GENERAL;
|
basic_errno = BASIC_ERR_SYNTAX_GENERAL;
|
||||||
@@ -209,6 +303,12 @@ struct basic_expr *basic_parse_expr(char *expbuf)
|
|||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/***************************************************************
|
||||||
|
*
|
||||||
|
* Basic REPL
|
||||||
|
*
|
||||||
|
***************************************************************/
|
||||||
|
|
||||||
void basic_print_var(struct basic_variable *var)
|
void basic_print_var(struct basic_variable *var)
|
||||||
{
|
{
|
||||||
char decimal[32];
|
char decimal[32];
|
||||||
@@ -229,20 +329,14 @@ void basic_repl(basic_program *program)
|
|||||||
{
|
{
|
||||||
char keybuff[512];
|
char keybuff[512];
|
||||||
char outbuff[128];
|
char outbuff[128];
|
||||||
char decimal[2];
|
|
||||||
|
|
||||||
struct basic_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;
|
expr = NULL;
|
||||||
_cputs("> ");
|
_cputs("> ");
|
||||||
|
|
||||||
@@ -256,23 +350,17 @@ void basic_repl(basic_program *program)
|
|||||||
/* Evaluate */
|
/* Evaluate */
|
||||||
expr = basic_parse_expr((char *)&keybuff);
|
expr = basic_parse_expr((char *)&keybuff);
|
||||||
if ( expr == NULL ) {
|
if ( expr == NULL ) {
|
||||||
_cputs("Error: ");
|
basic_report_error();
|
||||||
decimal[0] = dtoa(basic_errno);
|
|
||||||
_cputs((char *)&decimal);
|
|
||||||
_cputs("\n");
|
|
||||||
basic_errno = 0;
|
basic_errno = 0;
|
||||||
continue;
|
|
||||||
}
|
}
|
||||||
|
if ( expr->lval_type == BASIC_LVAL_CMDPTR ) {
|
||||||
basic_solve_expr(expr, &result);
|
if ( expr->lval.cmd_ptr == NULL ) {
|
||||||
if ( basic_errno != 0 ) {
|
basic_errno = BASIC_ERR_INTERNAL_NULLPOINTER;
|
||||||
_cputs("Error: ");
|
basic_report_error();
|
||||||
decimal[0] = dtoa(basic_errno);
|
basic_errno = 0;
|
||||||
_cputs((char *)&decimal);
|
|
||||||
_cputs("\n");
|
|
||||||
} else {
|
} else {
|
||||||
/* Print */
|
(*expr->lval.cmd_ptr)(expr->rval.ptr);
|
||||||
basic_print_var(&result);
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
21
src/basic.h
21
src/basic.h
@@ -1,9 +1,11 @@
|
|||||||
#ifndef _BASIC_H_
|
#ifndef _BASIC_H_
|
||||||
#define _BASIC_H_
|
#define _BASIC_H_
|
||||||
|
|
||||||
#define BASIC_MAX_LINES 1000
|
/* Per MS BASIC-80 ref page 1-2 */
|
||||||
#define BASIC_MAX_LINE_LENGTH 256
|
#define BASIC_MAX_LINES sizeof(int)
|
||||||
|
#define BASIC_MAX_LINE_LENGTH 255
|
||||||
|
|
||||||
|
#define BASIC_OPTP_NONE 0 /* No operation (only valid when LVAL is CONST and no RVAL) */
|
||||||
#define BASIC_OPTP_ADD 1 /* Add */
|
#define BASIC_OPTP_ADD 1 /* Add */
|
||||||
#define BASIC_OPTP_SUB 2 /* Subtract */
|
#define BASIC_OPTP_SUB 2 /* Subtract */
|
||||||
#define BASIC_OPTP_MUL 3 /* Multiply */
|
#define BASIC_OPTP_MUL 3 /* Multiply */
|
||||||
@@ -12,14 +14,17 @@
|
|||||||
#define BASIC_OPTP_EQL 6 /* Equality test */
|
#define BASIC_OPTP_EQL 6 /* Equality test */
|
||||||
#define BASIC_OPTP_ASN 7 /* Assignment */
|
#define BASIC_OPTP_ASN 7 /* Assignment */
|
||||||
#define BASIC_OPTP_STOR 8 /* Store line for later */
|
#define BASIC_OPTP_STOR 8 /* Store line for later */
|
||||||
|
#define BASIC_OPTP_CMD 9 /* BASIC command (PRINT, FOR, REM, etc)*/
|
||||||
|
|
||||||
#define BASIC_LVAL_EXPR 0
|
#define BASIC_LVAL_EXPR 0
|
||||||
#define BASIC_LVAL_VAR 1
|
#define BASIC_LVAL_VAR 1
|
||||||
#define BASIC_LVAL_CONST 2
|
#define BASIC_LVAL_CONST_INT 2
|
||||||
|
#define BASIC_LVAL_CMDPTR 3
|
||||||
#define BASIC_RVAL_EXPR 3
|
#define BASIC_RVAL_EXPR 3
|
||||||
#define BASIC_RVAL_VAR 4
|
#define BASIC_RVAL_VAR 4
|
||||||
#define BASIC_RVAL_CONST 5
|
#define BASIC_RVAL_CONST_INT 5
|
||||||
#define BASIC_RVAL_PTR 6 /* Only used internally */
|
#define BASIC_RVAL_PTR 6 /* Only used internally */
|
||||||
|
#define BASIC_RVAL_NONE 7
|
||||||
|
|
||||||
#define BASIC_PARSE_FOUND_LVAL 1
|
#define BASIC_PARSE_FOUND_LVAL 1
|
||||||
#define BASIC_PARSE_FOUND_RVAL 2
|
#define BASIC_PARSE_FOUND_RVAL 2
|
||||||
@@ -62,6 +67,7 @@ union basic_value {
|
|||||||
*/
|
*/
|
||||||
char *str;
|
char *str;
|
||||||
void *ptr;
|
void *ptr;
|
||||||
|
void (*cmd_ptr)(void *data);
|
||||||
};
|
};
|
||||||
typedef union basic_value basic_value;
|
typedef union basic_value basic_value;
|
||||||
|
|
||||||
@@ -94,5 +100,12 @@ extern int basic_errno;
|
|||||||
void basic_repl(basic_program *program);
|
void basic_repl(basic_program *program);
|
||||||
basic_expr *basic_parse_expr(char *);
|
basic_expr *basic_parse_expr(char *);
|
||||||
int basic_solve_expr(struct basic_expr *expr, struct basic_variable *result);
|
int basic_solve_expr(struct basic_expr *expr, struct basic_variable *result);
|
||||||
|
char *tokenizer_token(void);
|
||||||
|
|
||||||
|
void basic_cmd_rem(void *data);
|
||||||
|
void basic_cmd_print(void *data);
|
||||||
|
|
||||||
|
void basic_print_var(basic_variable *var);
|
||||||
|
void basic_report_error();
|
||||||
|
|
||||||
#endif /* _BASIC_H_ */
|
#endif /* _BASIC_H_ */
|
||||||
|
|||||||
@@ -8,13 +8,14 @@
|
|||||||
int main(void)
|
int main(void)
|
||||||
{
|
{
|
||||||
struct basic_expr *expr;
|
struct basic_expr *expr;
|
||||||
|
char *line;
|
||||||
/*struct basic_line *retline;
|
/*struct basic_line *retline;
|
||||||
struct basic_line *arrayline;*/
|
struct basic_line *arrayline;*/
|
||||||
|
|
||||||
/* Store a line */
|
/* Store a line */
|
||||||
/* expr = basic_parse_expr("10 =1 + 1");
|
/* expr = basic_parse_expr("10 =1 + 1");
|
||||||
if ( expr == NULL ) return 1;
|
if ( expr == NULL ) return 1;
|
||||||
if ( expr->lval_type != BASIC_LVAL_CONST ) return 2;
|
if ( expr->lval_type != BASIC_LVAL_CONST_INT ) return 2;
|
||||||
if ( expr->rval_type != BASIC_RVAL_PTR ) return 3;
|
if ( expr->rval_type != BASIC_RVAL_PTR ) return 3;
|
||||||
if ( expr->lval.i != 10 ) return 4;
|
if ( expr->lval.i != 10 ) return 4;
|
||||||
if ( expr->rval.ptr == NULL ) return 5;
|
if ( expr->rval.ptr == NULL ) return 5;
|
||||||
@@ -25,12 +26,49 @@ int main(void)
|
|||||||
expr = basic_parse_expr(retline->content);*/
|
expr = basic_parse_expr(retline->content);*/
|
||||||
expr = basic_parse_expr("1 + 1");
|
expr = basic_parse_expr("1 + 1");
|
||||||
if ( expr == NULL ) return 7;
|
if ( expr == NULL ) return 7;
|
||||||
if ( expr->lval_type != BASIC_LVAL_CONST ) return 8;
|
if ( expr->lval_type != BASIC_LVAL_CONST_INT ) return 8;
|
||||||
if ( expr->rval_type != BASIC_RVAL_CONST ) return 9;
|
if ( expr->rval_type != BASIC_RVAL_CONST_INT ) return 9;
|
||||||
if ( expr->lval.i != 1 ) return 10;
|
if ( expr->lval.i != 1 ) return 10;
|
||||||
if ( expr->rval.i != 1 ) return 11;
|
if ( expr->rval.i != 1 ) return 11;
|
||||||
if ( expr->type != BASIC_OPTP_ADD ) return 12;
|
if ( expr->type != BASIC_OPTP_ADD ) return 12;
|
||||||
|
|
||||||
|
line = "REM This is a comment that gets ignored";
|
||||||
|
expr = basic_parse_expr(line);
|
||||||
|
printf("%s\n", line);
|
||||||
|
printf("token = %s\n", tokenizer_token());
|
||||||
|
printf("errno = %d\n", basic_errno);
|
||||||
|
if ( expr == NULL ) return 13;
|
||||||
|
if ( expr->type != BASIC_OPTP_CMD ) return 14;
|
||||||
|
if ( expr->lval_type != BASIC_LVAL_CMDPTR ) return 15;
|
||||||
|
if ( expr->lval.cmd_ptr != &basic_cmd_rem ) return 16;
|
||||||
|
|
||||||
|
line = "PRINT 10";
|
||||||
|
expr = basic_parse_expr(line);
|
||||||
|
printf("%s\n", line);
|
||||||
|
printf("token = %s\n", tokenizer_token());
|
||||||
|
printf("errno = %d\n", basic_errno);
|
||||||
|
printf("rval.ptr = '%s'\n", (char *)expr->rval.ptr);
|
||||||
|
if ( expr == NULL ) return 17;
|
||||||
|
if ( expr->type != BASIC_OPTP_CMD ) return 18;
|
||||||
|
if ( expr->lval_type != BASIC_LVAL_CMDPTR ) return 19;
|
||||||
|
if ( expr->lval.cmd_ptr != &basic_cmd_print ) return 20;
|
||||||
|
if ( expr->rval_type != BASIC_RVAL_PTR ) return 21;
|
||||||
|
if ( expr->rval.ptr == NULL ) return 22;
|
||||||
|
if ( strcmp((char *)expr->rval.ptr, " 10") != 0 ) return 23;
|
||||||
|
|
||||||
|
line = " 10"; /* ... continuing logic from the previous */
|
||||||
|
expr = basic_parse_expr(line);
|
||||||
|
printf("%s\n", line);
|
||||||
|
printf("token = %s\n", tokenizer_token());
|
||||||
|
printf("errno = %d\n", basic_errno);
|
||||||
|
printf("expr.type = %d\n", expr->type);
|
||||||
|
printf("expr->lval_type = %d\n", expr->lval_type);
|
||||||
|
if ( expr == NULL ) return 24;
|
||||||
|
if ( expr->type != BASIC_OPTP_NONE ) return 25;
|
||||||
|
if ( expr->lval_type != BASIC_LVAL_CONST_INT ) return 26;
|
||||||
|
if ( expr->lval.i != 10 ) return 27;
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
arrayline = &basic_memory_lines[0];
|
arrayline = &basic_memory_lines[0];
|
||||||
if ( retline != arrayline) return 13;
|
if ( retline != arrayline) return 13;
|
||||||
|
|||||||
36
tests/basic_solver.c
Normal file
36
tests/basic_solver.c
Normal file
@@ -0,0 +1,36 @@
|
|||||||
|
#include "types.h"
|
||||||
|
#include "basic.h"
|
||||||
|
#include "string.h"
|
||||||
|
#include <stdio.h>
|
||||||
|
|
||||||
|
int main(void)
|
||||||
|
{
|
||||||
|
basic_expr expr;
|
||||||
|
basic_variable result;
|
||||||
|
result.flags = 0;
|
||||||
|
|
||||||
|
expr.type = BASIC_OPTP_ADD;
|
||||||
|
expr.lval_type = BASIC_LVAL_CONST_INT;
|
||||||
|
expr.lval.i = 1;
|
||||||
|
expr.rval_type = BASIC_RVAL_CONST_INT;
|
||||||
|
expr.rval.i = 1;
|
||||||
|
|
||||||
|
basic_solve_expr(&expr, &result);
|
||||||
|
if ( basic_errno != 0 ) return 2;
|
||||||
|
if ( result.flags != (BASIC_VARFLAG_INIT | BASIC_VARFLAG_TINT) ) return 3;
|
||||||
|
if ( result.value.i != 2 ) return 4;
|
||||||
|
|
||||||
|
expr.type = BASIC_OPTP_NONE;
|
||||||
|
expr.lval_type = BASIC_LVAL_CONST_INT;
|
||||||
|
expr.lval.i = 1;
|
||||||
|
expr.rval_type = BASIC_RVAL_NONE;
|
||||||
|
memset(&result, 0x00, sizeof(basic_variable));
|
||||||
|
basic_solve_expr(&expr, &result);
|
||||||
|
if ( basic_errno != 0 ) return 5;
|
||||||
|
if ( result.flags != (BASIC_VARFLAG_INIT | BASIC_VARFLAG_TINT) ) return 6;
|
||||||
|
if ( result.value.i != 1 ) return 7;
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
5
tests/basic_solver.deps
Normal file
5
tests/basic_solver.deps
Normal file
@@ -0,0 +1,5 @@
|
|||||||
|
basic
|
||||||
|
stdlib
|
||||||
|
string
|
||||||
|
conio
|
||||||
|
screen
|
||||||
@@ -4,11 +4,10 @@
|
|||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
|
|
||||||
char *_tokenize(char *ptr, char *token);
|
char *_tokenize(char *ptr, char *token);
|
||||||
char *_token_get(void);
|
|
||||||
|
|
||||||
#define assert_token_value(str, val, ret_null, ret_neq) \
|
#define assert_token_value(str, val, ret_null, ret_neq) \
|
||||||
ptr = _tokenize(str, BASIC_TOKENIZER_TOKENS); \
|
ptr = _tokenize(str, BASIC_TOKENIZER_TOKENS); \
|
||||||
value = _token_get(); \
|
value = tokenizer_token(); \
|
||||||
if ( ptr == NULL ) return ret_null; \
|
if ( ptr == NULL ) return ret_null; \
|
||||||
rc = strcmp(value, val); \
|
rc = strcmp(value, val); \
|
||||||
printf("(%s) => (value) == (val) ? : (%s) == (%s) %d\n", str, value, val, rc); \
|
printf("(%s) => (value) == (val) ? : (%s) == (%s) %d\n", str, value, val, rc); \
|
||||||
|
|||||||
Reference in New Issue
Block a user