Comments, better errors, bug fixes

This commit is contained in:
Maxwell Jeffress 2025-01-08 15:09:14 +11:00
parent 7c93d76588
commit f1bcf6ff1e
2 changed files with 61 additions and 22 deletions

View File

@ -1,5 +1,24 @@
#!/home/max/code/okto/okto #!/home/max/code/okto/okto
int dingus = 5 // Hello! This is some example Okto code to help you get started.
log dingus // Log something to the console...
dingus ++ log "Hello Okto!"
log dingus log 3.14159
log 7
// Log a variable to the console
str myString = "Hello Okto String!"
log "${myString}"
// Do some stuff with integers
// All this stuff can be done with decimals too, using the "dec" keyword.
int myInt = 5
log $myInt
myInt ++
log $myInt
myInt = $myInt + 4
log $myInt
// Exit the program
exit

View File

@ -13,6 +13,7 @@ enum class VarType {
INTEGER, INTEGER,
DECIMAL, DECIMAL,
STRING, STRING,
BOOLEAN,
UNKNOWN UNKNOWN
}; };
@ -43,7 +44,7 @@ private:
map<string, Variable> variables; map<string, Variable> variables;
bool isVerbose = false; bool isVerbose = false;
const vector<string> builtInFunctions = { const vector<string> builtInFunctions = {
"exit", "log", "type", "run", "verbose", "str", "dec", "int" "exit", "log", "type", "run", "verbose", "str", "dec", "int", "bool"
}; };
const vector<string> operators = { const vector<string> operators = {
@ -78,8 +79,11 @@ private:
} }
} }
void error(const string& str) { void error(const string& str, int exitCode = 1) {
cout << "\u001b[31m Error running code: " << str << "\u001b[39m" << endl; cout << "\u001b[31m Error running code: " << str << "\u001b[39m" << endl;
if (exitCode != 0) {
exit(exitCode);
}
} }
void verbose(const string& str) { void verbose(const string& str) {
@ -251,12 +255,19 @@ public:
auto tokens = tokenize(input); auto tokens = tokenize(input);
if (tokens.empty()) return 0; if (tokens.empty()) return 0;
tokens = preProcessTokens(tokens); tokens = preProcessTokens(tokens);
verbose("Attempting to run function " + tokens[0].first);
if (tokens[0].first == "//") {
verbose("Comment detected. Skipping line...");
return 0;
}
if (tokens[0].first == "log") { if (tokens[0].first == "log") {
verbose("Log command run"); verbose("Log function run");
if (tokens.size() < 2) { if (tokens.size() < 2) {
error("log requires an argument"); error("Log requires an argument");
return 0; return 0;
} }
const auto& [token, type] = tokens[1]; const auto& [token, type] = tokens[1];
@ -264,12 +275,13 @@ public:
cout << token << endl; cout << token << endl;
} }
else { else {
error("that type cannot be logged"); error("Type " + type + " cannot be logged");
} }
return 0; return 0;
} }
else if (tokens[0].first == "exit") { else if (tokens[0].first == "exit") {
verbose("Exit function run");
if (tokens.size() < 2) { if (tokens.size() < 2) {
exit(0); exit(0);
} else if (tokens.size() > 1) { } else if (tokens.size() > 1) {
@ -284,8 +296,9 @@ public:
} }
else if (tokens[0].first == "type") { else if (tokens[0].first == "type") {
verbose("Type function run");
if (tokens.size() < 2) { if (tokens.size() < 2) {
error("type requires an argument"); error("Type requires an argument");
return 0; return 0;
} }
const auto& [token, type] = tokens[1]; const auto& [token, type] = tokens[1];
@ -294,8 +307,13 @@ public:
} }
else if (tokens[0].first == "run") { else if (tokens[0].first == "run") {
verbose("Run function run");
if (tokens.size() < 2) { if (tokens.size() < 2) {
error("run requires an argument"); error("Run requires an argument");
return 0;
}
if (tokens[1].second != "string") {
error("Run argument must be string");
return 0; return 0;
} }
string inputStr = tokens[1].first; string inputStr = tokens[1].first;
@ -305,7 +323,7 @@ public:
return 0; return 0;
} }
else if (tokens[0].first == "str") { else if (tokens[0].first == "str") {
verbose("String command run"); verbose("String function run");
if (tokens.size() < 2) { if (tokens.size() < 2) {
error("variable must have a name"); error("variable must have a name");
return 0; return 0;
@ -334,12 +352,12 @@ public:
value = value.substr(1, value.length() - 2); value = value.substr(1, value.length() - 2);
variables[varName] = Variable(VarType::STRING, value); variables[varName] = Variable(VarType::STRING, value);
verbose("String variable " + varName + "defined as " + value); verbose("String variable " + varName + " defined as " + value);
return 0; return 0;
} }
else if (tokens[0].first == "int") { else if (tokens[0].first == "int") {
verbose("Integer command run"); verbose("Integer function run");
if (tokens.size() < 2) { if (tokens.size() < 2) {
error("variable must have a name"); error("variable must have a name");
return 0; return 0;
@ -367,12 +385,12 @@ public:
int value = stoi(tokens[3].first); int value = stoi(tokens[3].first);
variables[varName] = Variable(VarType::INTEGER, value); variables[varName] = Variable(VarType::INTEGER, value);
verbose("Integer variable " + varName + "defined as " + to_string(value)); verbose("Integer variable " + varName + " defined as " + to_string(value));
return 0; return 0;
} }
else if (tokens[0].first == "dec") { else if (tokens[0].first == "dec") {
verbose("Decimal command run"); verbose("Decimal function run");
if (tokens.size() < 2) { if (tokens.size() < 2) {
error("variable must have a name"); error("variable must have a name");
return 0; return 0;
@ -400,12 +418,14 @@ public:
double value = stod(tokens[3].first); double value = stod(tokens[3].first);
variables[varName] = Variable(VarType::DECIMAL, value); variables[varName] = Variable(VarType::DECIMAL, value);
verbose("Decimal variable " + varName + "defined as " + to_string(value)); verbose("Decimal variable " + varName + " defined as " + to_string(value));
return 0; return 0;
} }
else if (tokens[0].first == "verbose") { else if (tokens[0].first == "verbose") {
verbose("Verbose mode disabled");
isVerbose = !isVerbose; isVerbose = !isVerbose;
verbose("Verbose mode enabled");
return 0; return 0;
} }
@ -578,7 +598,7 @@ public:
} }
if (!tokens[0].first.empty()) { if (!tokens[0].first.empty()) {
error("I don't know how that works"); error(tokens[0].first + " isn't a function or variable. Check that the function or variable exists prior to running this line of code?");
return 0; return 0;
} }
return 0; return 0;
@ -586,24 +606,24 @@ public:
}; };
int main(int argc, char *argv[]) { int main(int argc, char *argv[]) {
cout << "Oktolang interpreter\n";
Interpreter interpreter; Interpreter interpreter;
if (argc > 1) { if (argc > 1) {
ifstream inFile(argv[1]); ifstream inFile(argv[1]);
string line; string line;
while (getline(inFile, line)) { while (getline(inFile, line)) {
if (line[0] == '#') continue; if (line[0] == '#') continue;
if (interpreter.executeCommand(line) != 0) return 1; interpreter.executeCommand(line);
} }
} else { } else {
string input; string input;
cout << "Oktolang interpreter\n";
while (true) { while (true) {
cout << "> "; cout << "> ";
getline(cin, input); getline(cin, input);
if (interpreter.executeCommand(input) != 0) break; interpreter.executeCommand(input);
} }
} }
return 0; return 0;
} }