From bdf69a5c1b4d95ea7c68cdcde48e40c80bb710d4 Mon Sep 17 00:00:00 2001 From: Tyler Perkins Date: Thu, 23 Sep 2021 21:25:42 -0400 Subject: [PATCH] Boilerplate forth --- .gitignore | 9 +++++++ Makefile | 13 +++++----- src/main.c | 65 +++++++++++++++++++++++++++++++++++++++++++++++++ src/parse.c | 69 +++++++++++++++++++++++++++++++++++++++++++++++++++++ src/parse.h | 23 ++++++++++++++++++ src/stack.c | 48 +++++++++++++++++++++++++++++++++++++ src/stack.h | 28 ++++++++++++++++++++++ 7 files changed, 248 insertions(+), 7 deletions(-) create mode 100644 .gitignore create mode 100644 src/main.c create mode 100644 src/parse.c create mode 100644 src/parse.h create mode 100644 src/stack.c create mode 100644 src/stack.h diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..e4febf2 --- /dev/null +++ b/.gitignore @@ -0,0 +1,9 @@ +#ignore all .o files +src/**/*.o + +#ignore all swp files +**/*.swp + +#ignore all executables, but still keep the bin folder +bin/* +!bin/.gitkeep diff --git a/Makefile b/Makefile index 1539b68..e9f1c92 100644 --- a/Makefile +++ b/Makefile @@ -4,26 +4,25 @@ # Makefile # -CC = g++ +CC = gcc FLAGS = -pipe CFLAGS = -Wall CFLAGS += -Ofast -CFLAGS += -std=c++17 -#CFLAGS += -g +CFLAGS += -g #CFLAGS += -pg LIBRARIES = -SRC = $(shell find ./src -name '*.cpp') -OBJ = $(subst .cpp,.o,$(SRC)) +SRC = $(shell find ./src -name '*.c') +OBJ = $(subst .c,.o,$(SRC)) BIN = ./bin PREFIX = /usr/local MANPREFIX = $(PREFIX)/share/man -TARGET = dashboard.out +TARGET = forth MAKEFLAGS += --jobs=4 @@ -31,7 +30,7 @@ all : $(OBJ) @echo LD $@ @$(CC) $(FLAGS) $(CFLAGS) -o $(BIN)/$(TARGET) $(OBJ) $(LIBRARIES) -.cpp.o : +.c.o : @echo CC $< @$(CC) $(FLAGS) $(CFLAGS) $(LIBRARIES) $(DEFINITIONS) -c $< -o $@ diff --git a/src/main.c b/src/main.c new file mode 100644 index 0000000..6e2cd04 --- /dev/null +++ b/src/main.c @@ -0,0 +1,65 @@ +/////////////////////////////////////////////////////////////////////////////// +// Tyler Perkins +// 9-23-21 +// Forth compiler/interpreter +// entry point +// + +#include +#include + +#include "parse.h" +#include "stack.h" + +#define BUFFER_SIZE 1024 + +void help(int argc, char** argv){ + printf("Incorrect usage!\n"); + printf("Usage:\n"); + printf(" %s [FILE]\n", argv[0]); + printf("File is an optional forth file containing code\n"); + printf("If no file is provided you will be dropped into an interactive shell\n"); + printf("All operators are using reverse Polish notation\n"); + printf("Max line input size is %i", BUFFER_SIZE); +} + +int main(int argc, char** argv){ + char input[BUFFER_SIZE] = {0}; + int retval = 0; + + + //check arg count + if(argc > 2){ + help(argc, argv); + return -1; + } else if(argc == 2){ + //TODO implement File parsing + } + + + printf("Entering shell...\n"); + + //get user input, with prompt + printf("> "); + fgets(input, BUFFER_SIZE, stdin); + + while(strcmp(input, "exit\n")){ + retval = parse(input); + if(retval > -1){ + printf(" "); + for(int i = 1; i != retval; ++i){ + printf(" "); + } + printf("^\n"); + printf("Error parsing character at position %d!\n", retval); + } else { + printf("%d\n", peek()); + } + + printf("> "); + fgets(input, BUFFER_SIZE, stdin); + } + + printf("Goodbye\n"); + return 0; +} diff --git a/src/parse.c b/src/parse.c new file mode 100644 index 0000000..c58f494 --- /dev/null +++ b/src/parse.c @@ -0,0 +1,69 @@ +/////////////////////////////////////////////////////////////////////////////// +// Tyler Perkins +// 9-23-21 +// parse implementations +// + +#include "parse.h" + +char ops[] = {'+','-','*','/','\0'}; + +int parse(const char* input){ + short int i = 0; + short int j = 0; + int ret = 0; + char buf[BUFFER_MAX_SIZE] = {'\0'}; + + while(input[i] != '\0'){ + //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]; + break; + case '-': + ret = operands[0] - operands[1]; + break; + case '*': + ret = operands[0] * operands[1]; + break; + case '/': + ret = operands[0] / operands[1]; + break; + default: + abort(); + } + + push(ret); + //TODO parse as token in dictionary + } else { //Is number + ret = atoi(buf); + push(ret); + } + + //clean up buf + memset(buf, '\0', j+1); + j = 0; + } else { //not whitespace + + buf[j] = input[i]; + ++j; + } + + ++i; + } + + return -1; +} diff --git a/src/parse.h b/src/parse.h new file mode 100644 index 0000000..e5d1320 --- /dev/null +++ b/src/parse.h @@ -0,0 +1,23 @@ +/////////////////////////////////////////////////////////////////////////////// +// Tyler Perkins +// 9-23-21 +// parse definitions +// + +#ifndef _PARSE_H_ +#define _PARSE_H_ + +#include +#include +#include + +#include "stack.h" + +extern char ops[]; + +//parse a line +int parse(const char*); + +#define BUFFER_MAX_SIZE 1024 + +#endif //!_PARSE_H_ diff --git a/src/stack.c b/src/stack.c new file mode 100644 index 0000000..b52b0cc --- /dev/null +++ b/src/stack.c @@ -0,0 +1,48 @@ +/////////////////////////////////////////////////////////////////////////////// +// Tyler Perkins +// 9-23-21 +// stack implementation +// + +#include "stack.h" + +struct s_node* head = NULL; +unsigned int _head_error = 0; + +void push(int val){ + struct s_node* temp; + + temp = head; + head = (struct s_node*)malloc(sizeof(struct s_node)); + + head->_val = val; + head->_next = temp; +} + +int pop(){ + struct s_node* temp; + int retval; + + if(head == NULL){ + _head_error = POP_EMPTY_STACK; + return 0; + } + + temp = head; + head = head->_next; + + retval = temp->_val; + + free(temp); + + return retval; +} + +int peek(){ + if(head == NULL){ + _head_error = PEEK_EMPTY_STACK; + return 0; + } + + return head->_val; +} diff --git a/src/stack.h b/src/stack.h new file mode 100644 index 0000000..5941c8d --- /dev/null +++ b/src/stack.h @@ -0,0 +1,28 @@ +/////////////////////////////////////////////////////////////////////////////// +// Tyler Perkins +// 9-23-21 +// stack definitions +// + +#ifndef _STACK_H_ +#define _STACK_H_ + +#include + +struct s_node { + int _val; + struct s_node* _next; +}; +extern struct s_node* head; +extern unsigned int _head_error; + +#define STACK_OK 0x00 +#define POP_EMPTY_STACK 0x01 +#define PEEK_EMPTY_STACK 0x02 + +void push(int); +int pop(); +int peek(); + + +#endif //!_STACK_H_