Refactored the C files out into libraries, started work on the BASIC repl (it can sorta do math!)

This commit is contained in:
2015-01-25 22:05:28 -08:00
parent 977285b8aa
commit 208c831c79
13 changed files with 560 additions and 234 deletions

1
.gitignore vendored Normal file
View File

@@ -0,0 +1 @@
src/*o

153
src/basic.c Normal file
View File

@@ -0,0 +1,153 @@
#include "basic.h"
#include "screen.h"
#include "conio.h"
#include "string.h"
#include "stdlib.h"
struct basic_math_expr math_expressions[8];
int basic_errno;
char _tokenizer_value[BASIC_TOKENIZER_MAX_LENGTH];
char *_tokenizer_prev;
char *_tokenizer_prev_next;
void _tokenizer_init(void)
{
_tokenizer_prev = NULL;
_tokenizer_prev_next = NULL;
}
char *_tokenize(char *ptr, char token)
{
char *orig = NULL;
int len = 0;
if ( ptr == NULL ) {
return NULL;
}
if ( _tokenizer_prev == ptr ) {
ptr = _tokenizer_prev_next;
}
orig = ptr;
memset(&_tokenizer_value, 0x00, BASIC_TOKENIZER_MAX_LENGTH);
while ( *ptr != token ) {
if ( *ptr == '\0' ) {
ptr -= sizeof(char);
break;
}
ptr += sizeof(char);
len += 1;
}
if ( len > BASIC_TOKENIZER_MAX_LENGTH ) {
basic_errno = BASIC_ERR_SYNTAX_TOKEN_LENGTH;
return NULL;
} else if ( len == 0 ) {
return NULL;
}
memcpy((void *)&_tokenizer_value, (void *)orig, len);
_tokenizer_prev_next = (ptr + 1);
return &_tokenizer_value;
}
struct basic_math_expr *basic_parse_expr(char *expbuf)
{
struct basic_math_expr *ret = &math_expressions[0];
char flags = 0;
char *subptr = 0;
_tokenizer_init();
memset(ret, 0x0, sizeof(struct basic_math_expr));
while ( *expbuf != '\0' ) {
if ( *expbuf == ' ' ) {
expbuf += sizeof(char);
continue;
} else if ( isdigit(*expbuf) == 1 ) {
if ( (ret->type == 0) && (flags & BASIC_FOUND_LVAL) == BASIC_FOUND_LVAL ) {
basic_errno = BASIC_ERR_SYNTAX_MULTIPLE_LVALUES;
return NULL;
} else if ( ret->type == 0x0 ) {
ret->lval = atoi(_tokenize(expbuf, ' '));
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, ' '));
}
} else if ( ret->type == 0x0 ) {
if ( *expbuf == '+' ) {
ret->type = BASIC_MATH_ADD;
} else if ( *expbuf == '*' ) {
ret->type = BASIC_MATH_MUL;
} else if ( *expbuf == '-' ) {
ret->type = BASIC_MATH_SUB;
} else if ( *expbuf == '/' ) {
ret->type = BASIC_MATH_DIV;
} else if ( *expbuf == '%' ) {
ret->type = BASIC_MATH_MOD;
} else {
basic_errno = BASIC_ERR_SYNTAX_GENERAL;
return NULL;
}
} else {
basic_errno = BASIC_ERR_SYNTAX_GENERAL;
return NULL;
}
expbuf += sizeof(char);
}
return ret;
}
void basic_run(void)
{
char keybuff[512];
char outbuff[128];
char decimal;
struct basic_math_expr *expr;
blankScreen();
setCursorPosition(0, 0);
_cputs("Piquant Basic v0.1\n\n");
while ( 1 ) {
_cputs("> ");
memset((void *)&keybuff, 0x00, 512);
memset((void *)&outbuff, 0x00, 128);
if ( _cgets((char *)&keybuff) != NULL ) {
_cputs("\n");
_cputs("Analyzing ");
_cputs((char *)&keybuff);
_cputs("\n");
expr = basic_parse_expr((char *)&keybuff);
if ( expr == NULL ) {
_cputs("Syntax Error: ");
decimal = dtoa(basic_errno);
_cputs(&decimal);
_cputs("\n");
continue;
}
decimal = dtoa(expr->type);
memcpy(&outbuff, "Expression type: \0", strlen("Expression type: \0"));
strncat(&outbuff, &decimal, 1);
_cputs(&outbuff);
_cputs("\n");
decimal = dtoa(expr->lval);
memcpy(&outbuff, "Expression lval: \0", strlen("Expression lval: \0"));
strncat(&outbuff, &decimal, 1);
_cputs(&outbuff);
_cputs("\n");
decimal = dtoa(expr->rval);
memcpy(&outbuff, "Expression rval: \0", strlen("Expression rval: \0"));
strncat(&outbuff, &decimal, 1);
_cputs(&outbuff);
_cputs("\n");
}
}
}

39
src/basic.h Normal file
View File

@@ -0,0 +1,39 @@
#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_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_FOUND_LVAL 0x0001
#define BASIC_FOUND_RVAL 0x0002
#define BASIC_ERR_SYNTAX_MULTIPLE_LVALUES 1
#define BASIC_ERR_SYNTAX_TOKEN_LENGTH 2
#define BASIC_ERR_SYNTAX_GENERAL 3
#define BASIC_ERR_SYNTAX_MULTIPLE_RVALUES 4
#define BASIC_TOKENIZER_MAX_LENGTH 512
struct basic_math_expr {
char type;
char lval_type;
char rval_type;
char pad;
void *lval;
void *rval;
};
extern int basic_errno;
void run_basic(void);
#endif /* _BASIC_H_ */

90
src/conio.c Normal file
View File

@@ -0,0 +1,90 @@
#include "types.h"
#include "conio.h"
#include "screen.h"
void _putch(char c)
{
#asm
push bx;
push ax;
mov bx, sp;
mov al, [bx+6];
mov ah, #0x0e;
mov bh, #0x00;
mov bl, #0x07;
int 0x10;
pop ax;
pop bx;
#endasm
return;
}
void _cputs(char *ptr)
{
if ( ptr == NULL ) {
return;
}
while ((char)*ptr != 0x0) {
_putch((char)*ptr);
if (*ptr == '\n') {
_cursor_y += 1;
_cursor_x = 0;
setCursorPosition(_cursor_x, _cursor_y);
} else {
advanceCursor();
}
ptr += 1;
}
return;
}
char _getkey(char *dest)
{
char echo;
char scancode;
#asm
push ax;
mov ah, #0x10;
int 0x16;
mov [bp-6], ah;
mov [bp-5], al;
pop ax;
#endasm
*dest = echo;
return scancode;
}
char *_cgets(char *d)
{
char *orig = d;
char scancode;
char printable;
if ( d == NULL ) {
return NULL;
}
scancode = _getkey(&printable);
while ( scancode != NULL ) {
if ( scancode == 0x0e ) {
if ( d > orig ) {
backupCursor();
setCursorPosition(_cursor_x, _cursor_y);
d -= 1;
_putch(0x0);
}
} else if ( scancode == 0x1c ) {
break;
} else {
*(d++) = printable;
_putch(printable);
advanceCursor();
}
scancode = _getkey(&printable);
}
__cgets_finish_loop:
*d = NULL;
return orig;
}

8
src/conio.h Normal file
View File

@@ -0,0 +1,8 @@
#ifndef _CONIO_H_
#define _CONIO_H_
void _putch(char _c);
char *_cgets(void);
char _getkey(char *dest);
#endif /* _CONIO_H_ */

View File

@@ -1,238 +1,8 @@
char _cursor_x = 0;
char _cursor_y = 0;
#define NULL 0x0
typedef int size_t;
void setCursorPosition(char x, char y)
{
#asm
push bx;
mov bx, sp;
mov dl, [bx+4];
mov dh, [bx+6];
pop bx;
push ax;
push bx;
mov ah, #0x02;
mov bx, #0x0;
int 0x10;
pop bx;
pop ax;
#endasm
return;
}
void backupCursor()
{
if ( _cursor_x == 0 && _cursor_y > 0 ) {
_cursor_x = 80;
_cursor_y -= 1;
} else if ( _cursor_x > 0 ) {
_cursor_x -= 1;
}
setCursorPosition(_cursor_x, _cursor_y);
}
void advanceCursor()
{
_cursor_x += 1;
if ( _cursor_x > 79 ) {
_cursor_x = 0;
_cursor_y += 1;
}
setCursorPosition(_cursor_x, _cursor_y);
}
void putc(char c)
{
#asm
push bx;
push ax;
mov bx, sp;
mov al, [bx+6];
mov ah, #0x0e;
mov bh, #0x00;
mov bl, #0x07;
int 0x10;
pop ax;
pop bx;
#endasm
return;
}
int strlen(char *ptr)
{
char *ptr2 = ptr;
if ( ptr == NULL ) {
return 0;
}
while (*ptr2 != 0x0 ) {
ptr2 += 1;
}
return ptr2 - ptr;
}
void puts(char *ptr, char x, char y)
{
if ( ptr == NULL ) {
return;
}
while ((char)*ptr != 0x0) {
putc((char)*ptr);
if (*ptr == '\n') {
_cursor_y += 1;
_cursor_x = 0;
setCursorPosition(_cursor_x, _cursor_y);
} else {
advanceCursor();
}
ptr += 1;
}
return;
}
char getkey(char *dest)
{
char echo;
char scancode;
#asm
push ax;
mov ah, 0x10;
int 0x16;
mov [bp-6], ah;
mov [bp-5], al;
pop ax;
#endasm
*dest = echo;
return scancode;
}
char *gets(char *d)
{
char *orig = d;
char scancode;
char printable;
if ( d == NULL ) {
return NULL;
}
scancode = getkey(&printable);
while ( scancode != NULL ) {
if ( scancode == 0x0e ) {
if ( d > orig ) {
backupCursor();
setCursorPosition(_cursor_x, _cursor_y);
d -= 1;
putc(0x0);
}
} else if ( scancode == 0x1c ) {
break;
} else {
*(d++) = printable;
putc(printable);
advanceCursor();
}
scancode = getkey(&printable);
}
_gets_finish_loop:
*d = NULL;
return orig;
}
void memset(void *s, int c, size_t n)
{
int *d = (int *)s;
if ( s == NULL ) {
return;
}
while ( ((int)d - (int)s) <= n ) {
*d = c;
d += sizeof(int);
}
}
signed int strcmp(char *s1, char *s2)
{
int d = 0;
int s1len = 0;
if ( s1 == NULL || s2 == NULL ) {
return 1;
}
s1len = strlen(s1);
if ( s1len != strlen(s2) ) {
return 1;
}
while ( *s1 != '\0' ) {
if ( *s1 != *s2 ) {
return 1;
}
s1 += sizeof(char);
s2 += sizeof(char);
}
return 0;
}
void repl(void)
{
char keybuff[512];
while ( 1 ) {
puts("> ");
memset((void *)&keybuff, 0x00, 512);
if ( gets((char *)&keybuff) != NULL ) {
puts("\n");
if ( strcmp(&keybuff, "quit") == 0 ) {
puts("You asked for it\n");
#asm
hlt;
#endasm
} else if ( strcmp(&keybuff, "reset") == 0 ) {
puts("Resetting PC ... ");
#asm
jmp 0xf000:0xfff0;
#endasm
} else if ( strcmp(&keybuff, "help") == 0 ) {
puts("help : Show this help message\n");
puts("quit : Halt the computer\n");
puts("reset : Reset the PC\n");
puts("\n");
} else {
puts("Wat?\n");
}
}
}
}
void blankScreen(void)
{
char i = 0;
char j = 0;
for ( i = 0 ; i < 26 ; i++ ) {
for ( j = 0; j < 81 ; j++ ) {
setCursorPosition(j, i);
putc(' ');
}
}
}
#include "screen.h"
#include "string.h"
#include "conio.h"
void main(void)
{
blankScreen();
setCursorPosition(0, 0);
puts("Piquant Kernel v0.1\n");
puts("\n");
repl();
basic_run();
}

58
src/screen.c Normal file
View File

@@ -0,0 +1,58 @@
#include "types.h"
#include "screen.h"
char _cursor_x = 0;
char _cursor_y = 0;
void blankScreen(void)
{
char i = 0;
char j = 0;
for ( i = 0 ; i < 26 ; i++ ) {
for ( j = 0; j < 81 ; j++ ) {
setCursorPosition(j, i);
_putch(0x0);
}
}
}
void setCursorPosition(char x, char y)
{
#asm
push bx;
mov bx, sp;
mov dl, [bx+4];
mov dh, [bx+6];
pop bx;
push ax;
push bx;
mov ah, #0x02;
mov bx, #0x0;
int 0x10;
pop bx;
pop ax;
#endasm
return;
}
void backupCursor()
{
if ( _cursor_x == 0 && _cursor_y > 0 ) {
_cursor_x = 80;
_cursor_y -= 1;
} else if ( _cursor_x > 0 ) {
_cursor_x -= 1;
}
setCursorPosition(_cursor_x, _cursor_y);
}
void advanceCursor()
{
_cursor_x += 1;
if ( _cursor_x > 79 ) {
_cursor_x = 0;
_cursor_y += 1;
}
setCursorPosition(_cursor_x, _cursor_y);
}

12
src/screen.h Normal file
View File

@@ -0,0 +1,12 @@
#ifndef _SCREEN_H_
#define _SCREEN_H_
extern char _cursor_x;
extern char _cursor_y;
void setCursorPosition(char x, char y);
void backupCursor();
void advanceCursor();
void blankScreen();
#endif /* _SCREEN_H_ */

81
src/stdlib.c Normal file
View File

@@ -0,0 +1,81 @@
#include "types.h"
#include "stdlib.h"
char dtoa(int d)
{
switch (d) {
case 0: return '0'; break;
case 1: return '1'; break;
case 2: return '2'; break;
case 3: return '3'; break;
case 4: return '4'; break;
case 5: return '5'; break;
case 6: return '6'; break;
case 7: return '7'; break;
case 8: return '8'; break;
case 9: return '9'; break;
}
}
int atoi(char *nptr)
{
int value = 0;
char *ptr = nptr;
int multiplier = 1;
if ( nptr == NULL ) {
return 0;
}
while ( isdigit(*ptr) == 1 ) {
ptr += 1;
}
ptr -= 1;
while ( ptr >= nptr) {
value += (((int)(*ptr--) - 0x30) * multiplier);
multiplier *= 10;
}
return value;
}
int isdigit(int c)
{
if (c >= 0x30 && c <= 0x39) {
return 1;
}
return 0;
}
int isupper(int c)
{
if (c >= 0x41 && c <= 0x5A) {
return 1;
}
return 0;
}
int islower(int c)
{
if (c >= 0x61 && c <= 0x7A) {
return 1;
}
return 0;
}
int isalnum(int c)
{
if ( isupper(c) || islower(c) || isdigit(c) ) {
return 1;
}
return 0;
}
int isxdigit(int c)
{
if ( isdigit(c) ||
(c >= 0x41 && c <= 0x46) ||
(c >= 0x61 && c <= 0x66)
) {
return 1;
}
return 0;
}

12
src/stdlib.h Normal file
View File

@@ -0,0 +1,12 @@
#ifndef _STDLIB_H_
#define _STDLIB_H_
char dtoa(int d);
int atoi(char *nptr);
int isdigit(int c);
int isupper(int c);
int islower(int c);
int isalnum(int c);
int isxdigit(int c);
#endif /* _STDLIB_H_ */

83
src/string.c Normal file
View File

@@ -0,0 +1,83 @@
#include "types.h"
#include "string.h"
size_t strlen(char *ptr)
{
char *ptr2 = ptr;
if ( ptr == NULL ) {
return 0;
}
while (*ptr2 != 0x0 ) {
ptr2 += 1;
}
return ptr2 - ptr;
}
void *memset(void *s, int c, size_t n)
{
int *d = (int *)s;
if ( s == NULL ) {
return NULL;
}
while ( ((int)d - (int)s) <= n ) {
*d = c;
d += sizeof(int);
}
return s;
}
void *memcpy(void *dest, void *src, size_t n)
{
int i = 0;
char *d = dest;
char *s = src;
if ( d == NULL || s == NULL ) {
return NULL;
}
for ( i = 0 ; i < n ; i++ ) {
*d++ = *s++;
}
*d = '\0';
return dest;
}
int strncat(char *dest, char *src, size_t n)
{
int c = 0;
if ( dest == NULL || src == NULL ) {
return 0;
}
dest = (dest + strlen(dest));
while ( c++ < n ) {
*dest++ = *src++;
}
return c;
}
int strcmp(char *s1, char *s2)
{
int d = 0;
int s1len = 0;
if ( s1 == NULL || s2 == NULL ) {
return 1;
}
s1len = strlen(s1);
if ( s1len != strlen(s2) ) {
return 1;
}
while ( *s1 != '\0' ) {
if ( *s1 != *s2 ) {
return 1;
}
s1 += sizeof(char);
s2 += sizeof(char);
}
return 0;
}

12
src/string.h Normal file
View File

@@ -0,0 +1,12 @@
#ifndef _STRING_H_
#define _STRING_H_
#include "types.h"
size_t strlen(char *ptr);
int strncat(char *dest, char *src, size_t n);
void *memset(void *s, int c, size_t n);
void *memcpy(void *dest, void *src, size_t n);
int strcmp(const char *s1, const char *s2);
#endif /* _STRING_H_ */

7
src/types.h Normal file
View File

@@ -0,0 +1,7 @@
#ifndef _TYPES_H_
#define _TYPES_H_
#define NULL 0x0
typedef int size_t;
#endif /* _TYPES_H_ */