Boilerplate forth
This commit is contained in:
parent
c454468ffc
commit
bdf69a5c1b
9
.gitignore
vendored
Normal file
9
.gitignore
vendored
Normal file
@ -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
|
13
Makefile
13
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 $@
|
||||
|
||||
|
65
src/main.c
Normal file
65
src/main.c
Normal file
@ -0,0 +1,65 @@
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
// Tyler Perkins
|
||||
// 9-23-21
|
||||
// Forth compiler/interpreter
|
||||
// entry point
|
||||
//
|
||||
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
|
||||
#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;
|
||||
}
|
69
src/parse.c
Normal file
69
src/parse.c
Normal file
@ -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;
|
||||
}
|
23
src/parse.h
Normal file
23
src/parse.h
Normal file
@ -0,0 +1,23 @@
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
// Tyler Perkins
|
||||
// 9-23-21
|
||||
// parse definitions
|
||||
//
|
||||
|
||||
#ifndef _PARSE_H_
|
||||
#define _PARSE_H_
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <stdio.h>
|
||||
|
||||
#include "stack.h"
|
||||
|
||||
extern char ops[];
|
||||
|
||||
//parse a line
|
||||
int parse(const char*);
|
||||
|
||||
#define BUFFER_MAX_SIZE 1024
|
||||
|
||||
#endif //!_PARSE_H_
|
48
src/stack.c
Normal file
48
src/stack.c
Normal file
@ -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;
|
||||
}
|
28
src/stack.h
Normal file
28
src/stack.h
Normal file
@ -0,0 +1,28 @@
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
// Tyler Perkins
|
||||
// 9-23-21
|
||||
// stack definitions
|
||||
//
|
||||
|
||||
#ifndef _STACK_H_
|
||||
#define _STACK_H_
|
||||
|
||||
#include <stdlib.h>
|
||||
|
||||
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_
|
Loading…
Reference in New Issue
Block a user