Add bitshift and file support

This commit is contained in:
Tyler Perkins 2021-09-23 22:21:44 -04:00
parent bdf69a5c1b
commit dbf68f5da5
4 changed files with 161 additions and 23 deletions

View File

@ -3,10 +3,29 @@ Forth
A weekend implementation of the Forth programming language
Usage
Compile
=====
```
make all
make clean
```
How to use
==========
These are the currently accepted operators:
+ add
- substract
* multiply
/ divide
. print top of stack
< bit shift left
> bit shift right

View File

@ -23,30 +23,59 @@ void help(int argc, char** argv){
printf("Max line input size is %i", BUFFER_SIZE);
}
void process_file(FILE* in, char* input){
char* fg;
int retval;
while(!(fg = fgets(input, BUFFER_SIZE, in)) || feof(in)){
retval = parse(input);
if(retval > -1){
printf("%s\n ",input);
for(int i = 1; i != retval; ++i){
printf(" ");
}
printf("^\n");
printf("Error parsing character at position %d!\n", retval);
break;
}
}
}
int main(int argc, char** argv){
char input[BUFFER_SIZE] = {0};
int retval = 0;
FILE* in = stdin;
char* fg;
//check arg count
if(argc > 2){
help(argc, argv);
return -1;
} else if(argc == 2){
//TODO implement File parsing
in = fopen(argv[1], "r");
if(in == NULL){
printf("Couldn't open file %s\n", argv[1]);
in = stdin;
}
}
if(in != stdin){
process_file(in, input);
}
printf("Entering shell...\n");
//get user input, with prompt
printf("> ");
fgets(input, BUFFER_SIZE, stdin);
fg = fgets(input, BUFFER_SIZE, in);
while(strcmp(input, "exit\n")){
if(fg == NULL) //ctrl+d
break;
retval = parse(input);
if(retval > -1){
printf(" ");
printf(" ");
for(int i = 1; i != retval; ++i){
printf(" ");
}
@ -57,7 +86,7 @@ int main(int argc, char** argv){
}
printf("> ");
fgets(input, BUFFER_SIZE, stdin);
fg = fgets(input, BUFFER_SIZE, in);
}
printf("Goodbye\n");

View File

@ -6,7 +6,89 @@
#include "parse.h"
char ops[] = {'+','-','*','/','\0'};
char ops[] = {'+','-','*','/','.','<','>','\0'};
int op_add(){
int ret = 0;
for(int it = 0;it < 2; ++it){
ret += pop();
if(_head_error == POP_EMPTY_STACK){
return -1;
}
}
push(ret);
return 0;
}
int op_sub(){
int op[2];
for(int it = 0;it < 2; ++it){
op[it] = pop();
if(_head_error == POP_EMPTY_STACK){
return -1;
}
}
push(op[1] - op[0]);
return 0;
}
int op_mul(){
int ret = 1;
for(int it = 0;it < 2; ++it){
ret *= pop();
if(_head_error == POP_EMPTY_STACK){
return -1;
}
}
push(ret);
return 0;
}
int op_div(){
int op[2];
for(int it = 0;it < 2; ++it){
op[it] = pop();
if(_head_error == POP_EMPTY_STACK){
return -1;
}
}
push(op[1]/op[0]);
return 0;
}
int op_pri(){
printf("%d\n", peek());
if(_head_error == PEEK_EMPTY_STACK){
return -1;
}
return 0;
}
int op_right(){
int ret = pop();
if(_head_error == POP_EMPTY_STACK){
return -1;
}
ret = ret >> 1;
push(ret);
return 0;
}
int op_left(){
int ret = pop();
if(_head_error == POP_EMPTY_STACK){
return -1;
}
ret = ret << 1;
push(ret);
return 0;
}
int parse(const char* input){
short int i = 0;
@ -18,35 +100,35 @@ int parse(const char* input){
//collect it into a temporary buffer
if(input[i] == ' ' || input[i] == '\n' || input[i] == '\t'){
if(j == 1 && (strstr(ops,buf) != NULL)){ //if single operator
int operands[2] = {0};
for(int it = 0;it < 2; ++it){
operands[it] = pop();
if(_head_error == POP_EMPTY_STACK){
printf("Not enough elements on stack!\n");
return i;
}
}
//apply operator
switch(buf[0]){
case '+':
ret = operands[0] + operands[1];
ret = op_add();
break;
case '-':
ret = operands[0] - operands[1];
ret = op_sub();
break;
case '*':
ret = operands[0] * operands[1];
ret = op_mul();
break;
case '/':
ret = operands[0] / operands[1];
ret = op_div();
break;
case '.':
ret = op_pri();
break;
case '<':
ret = op_left();
break;
case '>':
ret = op_right();
break;
default:
abort();
}
push(ret);
if(ret == -1){
return i;
}
//TODO parse as token in dictionary
} else { //Is number
ret = atoi(buf);

View File

@ -18,6 +18,14 @@ extern char ops[];
//parse a line
int parse(const char*);
int op_add();
int op_sub();
int op_mul();
int op_div();
int op_pri();
int op_right();
int op_left();
#define BUFFER_MAX_SIZE 1024
#endif //!_PARSE_H_