This repository was archived by the owner on Apr 25, 2021. It is now read-only.
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathhmlog.cpp
More file actions
119 lines (99 loc) · 4.34 KB
/
hmlog.cpp
File metadata and controls
119 lines (99 loc) · 4.34 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
#include <algorithm>
#include <iostream>
#include <vector>
#include "hmlog.hpp"
using namespace std;
// reads command string and returns command name and command arguments
pair<string, vector<string>> readCommand(string command) {
string commandName;
vector<string> arguments;
// pushes characters to commandName, stops when reaches '('
int i;
for (i = 0; i < (int) command.size(); i++) {
if (command[i] == '(') break;
commandName.push_back(command[i]);
}
// pushes charachers to arguments, pushes arguments when reaches ',' or ')', stops wher reaches ')'
string currentArg;
for (i++; i < (int) command.size(); i++) {
if (command[i] == ',' || command[i] == ')') {
arguments.push_back(currentArg);
currentArg.clear();
} else {
currentArg.push_back(command[i]);
}
if (command[i] == ')') break;
}
return {commandName, arguments};
}
string compileCommand(string commandName, vector<string> arguments) {
if (commandPtr[commandName]) {
return commandPtr[commandName](arguments);
} else {
cerr << commandName << " not found. Terminating.";
return "";
}
}
int main(int argc, char *argv[]) {
// source file is in argv[1], output file is in argv[2]
// redirect input file to stdin and stdout to to output file
freopen(argv[1], "r", stdin);
freopen(argv[2], "w", stdout);
// reads file character by character and pushes each command (seperated by ';') into "commands" vector
vector<string> commands; // stores all commands from the source code
char currentCharacter;
string currentCommand; // holds currect command before pushing it to "commands"
bool qoute = false; // this indicates wheter currentCharacter is between qoutes or not (strings should only be in double qoutes.)
const vector<char> skipChars = {' ', '\n'};
cin >> noskipws; // do not skip whitespaces
while (cin >> currentCharacter) {
if (currentCharacter == ';') {
commands.push_back(currentCommand);
currentCommand.clear();
} else {
// only push current character if it is not a whitespace or is betweean qoutes
if (find(skipChars.begin(), skipChars.end(), currentCharacter) == skipChars.end()) {
currentCommand.push_back(currentCharacter);
} else if (qoute) {
currentCommand.push_back(currentCharacter);
}
if (currentCharacter == '"') qoute = !qoute;
}
}
string output;
// proccesses command one by one and calls apropriate function from "hmlogCommands.cpp"
for (string command : commands) {
// for each command, if the first '=' is before the first '(', compiles assignment, else compiles function call
for (int i = 0; i < (int) command.size(); i++) {
if (command[i] == '=') {
// compiles the right part of the assignment like a normall call
pair<string, vector<string>> commandPair = readCommand(command.substr(i + 1));
string compiled = compileCommand(commandPair.first, commandPair.second);
if (compiled.size()) output += compiled;
else return 1;
// gets the variable name on the left of the assignment
string assignName;
for (int j = 0; j < i; j++) {
if (command[j] != ' ') {
assignName.push_back(command[j]);
}
}
// compiles set operation of the assignment. sets assignName to "ASSIGNCON".
// "ASSIGNCON" is a temporary variable used for assignments.
compiled = compileCommand("set", {assignName, "ASSIGNCON"});
if (compiled.size()) output += compiled;
else return 1;
break;
} else if (command[i] == '(') {
// reads the command and compiles it. then prints the result to the output file
pair<string, vector<string>> commandPair = readCommand(command);
string compiled = compileCommand(commandPair.first, commandPair.second);
if (compiled.size()) output += compiled;
else return 1;
break;
}
}
}
cout << output;
return 0;
}