Skip to content

Instantly share code, notes, and snippets.

@aneury1
Created January 12, 2024 18:16
Show Gist options
  • Save aneury1/91c510abf604b8582c6e536a51d4a150 to your computer and use it in GitHub Desktop.
Save aneury1/91c510abf604b8582c6e536a51d4a150 to your computer and use it in GitHub Desktop.
#include <vector>
#include <string>
#include <map>
#include <functional>
#include <memory>
#include <cctype>
#include <iostream>
#include <fstream>
using namespace std;
///
std::vector<std::string> splitString(std::string string){
std::vector<std::string> ret;
std::string temp;
int iter=0;
while(iter!=string.size()){
if(std::isspace(string[iter])){
/// std::cout <<"space\n";
if(temp.size()>0)
ret.emplace_back(temp);
temp="";
if(string[iter]=='\t')
ret.emplace_back("$TAB");
else if(string[iter]=='\n')
ret.emplace_back("$NEWLINE");
else if(string[iter]=='\0')
ret.emplace_back("$EOF");
else
ret.emplace_back("$SPACE");
}else if(std::isalpha(string[iter])){
/// std::cout <<"letter\n";
temp += string[iter];
}else if(std::isalnum(string[iter])){
/// std::cout <<"number\n";
std::string number;
number += string[iter];
if(temp.size()<=0)
ret.emplace_back(number);
else
temp+=number;
}else if(std::ispunct(string[iter])){
///std::cout <<"punt\n";
std::string symbol;
symbol += string[iter];
if(temp.size()>0)
ret.emplace_back(temp);
temp ="";
ret.emplace_back(symbol);
}
iter++;
}
if(temp.size()>0)
ret.emplace_back(temp);
return ret;
}
std::map<std::string, int>generateTokenMap(std::vector<std::string>keywords){
std::map<std::string,int> ret;
int current_map = 1;
for(auto it : keywords){
std::string key = it.c_str();
if(ret[key]==0)
ret[key]= current_map++;
else
;
}
return ret;
}
void printKeyMap(std::map<std::string, int> map){
for(auto keymap : map){
std::cout <<"KEY: "<< keymap.first <<", Value: "<< keymap.second <<"\n";
}
}
std::vector<int> compileText(std::vector<std::string> parsedText, std::map<std::string, int> keymap)
{
std::vector<int> ret;
for(auto word : parsedText){
int val = keymap[word];
ret.push_back(val);
}
return ret;
}
std::string getPreviousStringFromKeymap(std::vector<int> compiledObject, std::map<std::string, int> keymap){
std::string ret;
for(auto index : compiledObject){
for(auto key : keymap){
if(key.second == index){
if(key.first[0]=='$'){
if(key.first[1]=='T')
ret+='\t';
else if(key.first[1]=='N')
ret+='\n';
else if(key.first[1]=='E')
ret+='\0';
else
ret+=' ';
}else{
ret+= key.first;
}
}
}
}
return ret;
}
void printCompiledObject(std::vector<int> obj){
int line =1;
for(auto i : obj)
std::cout <<"000"<<line++<<": "<<i<<"\n";
}
std::string readFile(std::string filename){
std::ifstream stream(filename.c_str(),
std::ios::binary);
if(!stream)
return "<EMPTY>";
stream.seekg (0, stream.end);
int length = stream.tellg();
stream.seekg (0, stream.beg);
char *fileBuffer = new char[length + 2];
memset(fileBuffer, 0x00, length);
stream.read(fileBuffer, length);
fileBuffer[stream.gcount()]=0;
std::string ret;
ret += fileBuffer;
delete[] fileBuffer;
stream.close();
return ret;
}
void PseudoMachine(std::string s){
auto keywords = splitString(s);
std::cout <<"Entry Original Source: \n"<<s <<"\n";
for(auto key : keywords)
std::cout <<"KEYWORD: "<< key <<"\n";
std::cout <<"\n\n";
auto keymap = generateTokenMap(keywords);
printKeyMap(keymap);
auto compiledObject = compileText(keywords, keymap);
printCompiledObject(compiledObject);
auto originalSource = getPreviousStringFromKeymap(compiledObject, keymap);
std::cout <<"decompiled-original Source: \n"<<originalSource;
}
int main(int argc, char *argv[])
{
std::cout <<"pseudo-compiler" << argc;
if(argc!=2)
{
std::cout <<"We only need one file at time pseudo-compiler <filename>";
}
else
{
std::string testProgram = readFile(argv[1]);
PseudoMachine(testProgram);
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment