uploaded current state of stacat

This commit is contained in:
2025-06-14 00:29:53 +02:00
parent e1824fc79c
commit 69bff131db
17 changed files with 643 additions and 0 deletions

7
src/config.h Normal file
View File

@@ -0,0 +1,7 @@
#ifndef CONFIG_H
#define CONFIG_H
#define DEBUG true
#define STACAT_VERSION "1.0.0"
#endif

View File

@@ -0,0 +1,89 @@
#include <iostream>
#include "interpreter.h"
#include "../output.h"
using namespace std;
using namespace debug;
using namespace error;
Interpreter::Interpreter(string data, string filename) {
// interpreter data
this->data = data;
this->stack = list<size_t>();
this->ostream = list<char>();
// interpreter states
this->comment = false;
this->filename = filename;
this->line = 1;
this->column = 1;
this->before_command = 0;
}
void Interpreter::run() {
// run interpreter
for (char command : this->data) {
this->interpret(command);
}
this->ostream.reverse();
// clear stack
this->stack.clear();
}
void Interpreter::interpret(char command) {
// evaluate command
switch (command) {
case '>':
this->push();
break;
case '^':
this->clone();
break;
case '+':
this->add();
break;
case '-':
this->sub();
break;
case '*':
this->mul();
break;
case '!':
if (!this->comment) {
this->print();
}
break;
case '?':
this->input();
break;
case ' ':
break;
case '\n':
this->line++;
this->column = 1;
this->comment = false;
break;
case '\t':
this->column += 4;
break;
case '_':
this->comment = !this->comment;
break;
default:
if (!this->comment) {
throwError(UNKNOWN_INSTRUCTION, this->filename, this->line, this->column, command, __LINE__, __FILE__);
exit(EXIT_FAILURE);
}
break;
}
}
string Interpreter::getostream() {
string output = "";
for (char c : this->ostream) {
output += c;
}
return output;
}

View File

@@ -0,0 +1,55 @@
#ifndef INTERPRETER_H
#define INTERPRETER_H
#include <iostream>
#include <list>
class Interpreter {
public:
// constructor
Interpreter(std::string data, std::string filename);
// methods
void run();
std::string getostream();
private:
// interpreter data
std::string data;
std::list<size_t> stack;
std::list<char> ostream;
// interpreter states
bool comment;
std::string filename;
int line;
int column;
char before_command;
// methods
void interpret(char command);
void push();
void clone();
void add();
void sub();
void mul();
void print();
void input();
};
class Function {
public:
// constructor
Function(std::string name, std::string data);
// methods
void run();
private:
// function data
std::string name;
std::string data;
};
#endif

View File

@@ -0,0 +1,46 @@
#include <iostream>
#include "interpreter.h"
#include "../output.h"
using namespace std;
using namespace debug;
using namespace error;
void Interpreter::push() {
this->stack.push_back(1);
this->column++;
}
void Interpreter::clone() {
this->stack.push_back(this->stack.back());
this->column++;
}
void Interpreter::add() {
long long value = this->stack.back();
this->stack.pop_back();
this->stack.back() += value;
}
void Interpreter::sub() {
long long value = this->stack.back();
this->stack.pop_back();
this->stack.back() -= value;
}
void Interpreter::mul() {
long long value = this->stack.back();
this->stack.pop_back();
this->stack.back() *= value;
}
void Interpreter::print() {
this->ostream.push_back(this->stack.back());
this->stack.pop_back();
this->column++;
}
void Interpreter::input() {
log("Inputting");
}

79
src/main.cpp Normal file
View File

@@ -0,0 +1,79 @@
#include <iostream>
#include "config.h"
#include "main.h"
#include "output.h"
#include "interpreter/interpreter.h"
#include "utils/utils.h"
using namespace std;
using namespace debug;
using namespace error;
int main(int argc, char* argv[]) {
// check arguments
program::checkargs(argc, argv);
// read arguments
ProgramMode mode = program::readargs(argc, argv);
// check interpreter mode
switch (mode) {
case FILE_INTERPRETER:
log("Running file interpreter");
program::run(argv[1]);
break;
case CONSOLE_INTERPRETER:
log("Running console interpreter");
program::run();
break;
case MANUAL:
log("Displaying manual");
program::man();
break;
}
exit(EXIT_SUCCESS);
}
namespace program {
void run(char* filename) {
// prepare interpreter
string data = utils::readfile(filename);
Interpreter interpreter(data, filename);
// run interpreter
interpreter.run();
// get output
string ostream = interpreter.getostream();
program::outputconsole(ostream);
}
void run() {
Interpreter interpreter("data", "console");
interpreter.run();
}
void checkargs(int argc, char* argv[]) {
if (argc < 2) {
throwError(WRONG_ARGUMENT_COUNT, "Not enough arguments", __LINE__, __FILE__);
}
else if (argc > 2) {
throwError(WRONG_ARGUMENT_COUNT, "Too many arguments", __LINE__, __FILE__);
}
return;
}
ProgramMode readargs(int argc, char* argv[]) {
log("Reading arguments");
return FILE_INTERPRETER;
}
void outputconsole(string ostream) {
cout << ostream << endl;
}
void man() {
log("Displaying manual");
cout << "Usage: stacat [filename]" << endl;
}
}

25
src/main.h Normal file
View File

@@ -0,0 +1,25 @@
#ifndef MAIN_H
#define MAIN_H
#include "config.h"
int main(int argc, char* argv[]);
typedef enum ProgramMode {
FILE_INTERPRETER,
CONSOLE_INTERPRETER,
MANUAL
} ProgramMode;
namespace program {
// main.cpp
void run(char* filename);
void run();
void checkargs(int argc, char* argv[]);
ProgramMode readargs(int argc, char* argv[]);
void outputconsole(std::string ostream);
void man();
}
#endif

76
src/output.cpp Normal file
View File

@@ -0,0 +1,76 @@
#include <iostream>
#include "config.h"
#include "output.h"
using namespace std;
namespace debug {
void log(string message) {
if (DEBUG) {
cerr << "(\033[1;33mDEBUG\033[0m)\033[1;34mLOG\033[0m: " << message << endl;
}
}
void log(string message, int line) {
if (DEBUG) {
cerr << "(\033[1;33mDEBUG\033[0m)\033[1;34mLOG\033[0m: " << message << " at line " << line << endl;
}
}
void log(string message, int line, int column, int codeLine) {
if (DEBUG) {
cerr << "(\033[1;33mDEBUG\033[0m)\033[1;34mLOG\033[0m: " << message << " at line " << line << " at column " << column << " at code line " << codeLine << endl;
}
}
}
namespace error {
void throwError(RuntimeError error, const string message, int line, const string file) {
string errorMessage = getRuntimeError(error);
if (DEBUG) {
cerr << "(\033[1;33mDEBUG\033[0m)\033[1;31mERROR\033[0m: " << errorMessage << " at file '" << file << "' at line " << line << endl;
}
else {
cerr << "\033[1;31mERROR\033[0m: " << errorMessage << endl;
}
}
string getRuntimeError(RuntimeError error) {
switch (error) {
case WRONG_ARGUMENT_COUNT:
return "Wrong argument count";
case WRONG_FILE_EXTENSION:
return "Wrong file extension";
case FILE_NOT_FOUND:
return "File not found";
case FILE_READ_ERROR:
return "File read error";
case FILE_EMPTY_ERROR:
return "File empty error";
}
}
void throwError(InterpreterError error, const string file, const int line, const int column, const char instruction, const int codeline, const string sourcefile) {
string errorMessage = getInterpreterError(error);
if (DEBUG) {
cerr << "\033[1;35m" << file << ":l" << line << ":c" << column << "\033[0m\033[1;35m '" << instruction << "':\033[0m \033[1;31mERROR\033[0m " << "I DOAN UNDERSTAND DIS! (at line " << codeline << " at file '" << sourcefile << "')" << endl;
}
else {
cerr << "\033[1;35m" << file << ":l" << line << ":c" << column << "\033[0m\033[1;35m '" << instruction << "':\033[0m \033[1;31mERROR\033[0m " << "I DOAN UNDERSTAND DIS! " << endl;
}
}
string getInterpreterError(InterpreterError error) {
switch (error) {
case UNKNOWN_INSTRUCTION:
return "Unknown instruction";
case POINTER_OUT_OF_BOUNDS:
return "Pointer out of bounds";
case INVALID_VALUE:
return "Invalid value";
}
}
}

31
src/output.h Normal file
View File

@@ -0,0 +1,31 @@
#ifndef ERROR_H
#define ERROR_H
typedef enum RuntimeError {
WRONG_ARGUMENT_COUNT,
WRONG_FILE_EXTENSION,
FILE_NOT_FOUND,
FILE_READ_ERROR,
FILE_EMPTY_ERROR
} RuntimeError;
typedef enum InterpreterError {
UNKNOWN_INSTRUCTION,
POINTER_OUT_OF_BOUNDS,
INVALID_VALUE
} InterpreterError;
namespace debug {
void log(std::string message);
void log(std::string message, int line);
void log(std::string message, int line, int column, int codeLine);
}
namespace error {
void throwError(RuntimeError error, const std::string message, int line, const std::string file);
std::string getRuntimeError(RuntimeError error);
void throwError(InterpreterError error, const std::string file, const int line, const int column, const char instruction, const int codeline, const std::string sourcefile);
std::string getInterpreterError(InterpreterError error);
}
#endif

36
src/utils/readfile.cpp Normal file
View File

@@ -0,0 +1,36 @@
#include <iostream>
#include <fstream>
#include "readfile.h"
#include "utils.h"
#include "../output.h"
using namespace std;
using namespace debug;
using namespace error;
namespace utils {
string readfile(const char* filename) {
ifstream file(filename);
if (!checkfile(file)) {
exit(EXIT_FAILURE);
}
string data, line;
while (getline(file, line)) {
data += line;
data += '\n';
}
data.pop_back();
file.close();
return data;
}
bool checkfile(ifstream& file) {
if (!file.is_open()) {
throwError(FILE_NOT_FOUND, "File not found", __LINE__, __FILE__);
return false;
}
return true;
}
}

9
src/utils/readfile.h Normal file
View File

@@ -0,0 +1,9 @@
#ifndef READFILE_H
#define READFILE_H
#define FILE_EXTENSION ".scat"
#define MAX_FILE_LENGTH 0x0FFFFFFFUL
#define MAX_FILE_NAME_LENGTH 256
#endif

12
src/utils/utils.h Normal file
View File

@@ -0,0 +1,12 @@
#ifndef UTILS_H
#define UTILS_H
#include <fstream>
namespace utils {
// readfile.cpp
std::string readfile(const char* filename);
bool checkfile(std::ifstream& file);
}
#endif