Memory types
This commit is contained in:
parent
b407b21cde
commit
7b89fcbf1f
@ -6,12 +6,22 @@
|
|||||||
#include <stdexcept>
|
#include <stdexcept>
|
||||||
using namespace std;
|
using namespace std;
|
||||||
|
|
||||||
using EvalResult = variant<int, monostate>;
|
#include "tokenize.h"
|
||||||
|
|
||||||
|
using EvalResult = variant<monostate, int, double>;
|
||||||
|
|
||||||
|
struct MemoryEntry {
|
||||||
|
EvalResult value { };
|
||||||
|
bool assigned { false };
|
||||||
|
Type type;
|
||||||
|
};
|
||||||
|
|
||||||
class RuntimeError : public runtime_error {
|
class RuntimeError : public runtime_error {
|
||||||
public:
|
public:
|
||||||
explicit RuntimeError(const string& message)
|
explicit RuntimeError(const string& message, CodePosition pos)
|
||||||
: runtime_error(message) {}
|
: runtime_error(message), pos(pos) {}
|
||||||
|
|
||||||
|
const CodePosition pos;
|
||||||
};
|
};
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -25,8 +25,10 @@ struct Token {
|
|||||||
|
|
||||||
class TokenError : public runtime_error {
|
class TokenError : public runtime_error {
|
||||||
public:
|
public:
|
||||||
explicit TokenError(const string& message)
|
explicit TokenError(const string& message, CodePosition pos)
|
||||||
: runtime_error(message) {}
|
: runtime_error(message), pos(pos) {}
|
||||||
|
|
||||||
|
const CodePosition pos;
|
||||||
};
|
};
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -6,7 +6,7 @@
|
|||||||
#include "include/interpreter.h"
|
#include "include/interpreter.h"
|
||||||
using namespace std;
|
using namespace std;
|
||||||
|
|
||||||
unordered_map<string, int> memory;
|
unordered_map<string, MemoryEntry> memory;
|
||||||
|
|
||||||
EvalResult eval(Node &ast) {
|
EvalResult eval(Node &ast) {
|
||||||
if (ast.index() == 0) {
|
if (ast.index() == 0) {
|
||||||
@ -37,13 +37,13 @@ EvalResult eval(Node &ast) {
|
|||||||
case NodeType::Div: {
|
case NodeType::Div: {
|
||||||
int e1 = get<int>(eval(node.children[0]));
|
int e1 = get<int>(eval(node.children[0]));
|
||||||
int e2 = get<int>(eval(node.children[1]));
|
int e2 = get<int>(eval(node.children[1]));
|
||||||
if (e2 == 0) throw RuntimeError("Division by 0");
|
if (e2 == 0) throw RuntimeError("Division by 0", node.pos);
|
||||||
return e1 / e2;
|
return e1 / e2;
|
||||||
} break;
|
} break;
|
||||||
case NodeType::Mod: {
|
case NodeType::Mod: {
|
||||||
int e1 = get<int>(eval(node.children[0]));
|
int e1 = get<int>(eval(node.children[0]));
|
||||||
int e2 = get<int>(eval(node.children[1]));
|
int e2 = get<int>(eval(node.children[1]));
|
||||||
if (e2 == 0) throw RuntimeError("Modulo by 0");
|
if (e2 == 0) throw RuntimeError("Modulo by 0", node.pos);
|
||||||
return e1 % e2;
|
return e1 % e2;
|
||||||
} break;
|
} break;
|
||||||
case NodeType::UnaryPlus: {
|
case NodeType::UnaryPlus: {
|
||||||
@ -57,44 +57,92 @@ EvalResult eval(Node &ast) {
|
|||||||
case NodeType::Declaration: {
|
case NodeType::Declaration: {
|
||||||
Token typeTok = get<Token>(node.children[0]);
|
Token typeTok = get<Token>(node.children[0]);
|
||||||
Token identifierTok = get<Token>(node.children[1]);
|
Token identifierTok = get<Token>(node.children[1]);
|
||||||
|
Type type = get<Type>(typeTok.data);
|
||||||
string identifier = get<string>(identifierTok.data);
|
string identifier = get<string>(identifierTok.data);
|
||||||
|
|
||||||
memory[identifier] = 0;
|
memory[identifier] = {
|
||||||
|
.type = type
|
||||||
|
};
|
||||||
|
|
||||||
return {};
|
return {};
|
||||||
} break;
|
} break;
|
||||||
case NodeType::AssignedDeclaration: {
|
case NodeType::AssignedDeclaration: {
|
||||||
Token typeTok = get<Token>(node.children[0]);
|
Token typeTok = get<Token>(node.children[0]);
|
||||||
Token identifierTok = get<Token>(node.children[1]);
|
Token identifierTok = get<Token>(node.children[1]);
|
||||||
|
Type type = get<Type>(typeTok.data);
|
||||||
string identifier = get<string>(identifierTok.data);
|
string identifier = get<string>(identifierTok.data);
|
||||||
int expr = get<int>(eval(node.children[2]));
|
EvalResult expr = eval(node.children[2]);
|
||||||
|
|
||||||
memory[identifier] = expr;
|
memory[identifier] = {
|
||||||
|
.value = expr,
|
||||||
|
.assigned = true,
|
||||||
|
.type = type,
|
||||||
|
};
|
||||||
|
|
||||||
return expr;
|
return expr;
|
||||||
} break;
|
} break;
|
||||||
case NodeType::Assignment: {
|
case NodeType::Assignment: {
|
||||||
Token identifierTok = get<Token>(node.children[0]);
|
Token identifierTok = get<Token>(node.children[0]);
|
||||||
string identifier = get<string>(identifierTok.data);
|
string identifier = get<string>(identifierTok.data);
|
||||||
int expr = get<int>(eval(node.children[1]));
|
EvalResult expr = eval(node.children[1]);
|
||||||
|
|
||||||
memory[identifier] = expr;
|
if (!memory.contains(identifier)) throw RuntimeError("Unknown identifier \""+identifier+"\"", identifierTok.pos);
|
||||||
|
|
||||||
|
memory[identifier].value = expr;
|
||||||
|
|
||||||
return expr;
|
return expr;
|
||||||
} break;
|
} break;
|
||||||
case NodeType::LIncr:
|
case NodeType::LIncr: {
|
||||||
|
Token identifierTok = get<Token>(node.children[0]);
|
||||||
|
string identifier = get<string>(identifierTok.data);
|
||||||
|
|
||||||
|
if (!memory.contains(identifier)) throw RuntimeError("Unknown identifier \""+identifier+"\"", identifierTok.pos);
|
||||||
|
|
||||||
|
if (memory[identifier].type == Type::Int) {
|
||||||
|
memory[identifier].value = get<int>(memory[identifier].value) + 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
return memory[identifier].value;
|
||||||
|
}
|
||||||
case NodeType::RIncr: {
|
case NodeType::RIncr: {
|
||||||
Token identifierTok = get<Token>(node.children[0]);
|
Token identifierTok = get<Token>(node.children[0]);
|
||||||
string identifier = get<string>(identifierTok.data);
|
string identifier = get<string>(identifierTok.data);
|
||||||
|
|
||||||
return node.type == NodeType::LIncr ? ++memory[identifier] : memory[identifier]++;
|
if (!memory.contains(identifier)) throw RuntimeError("Unknown identifier \""+identifier+"\"", identifierTok.pos);
|
||||||
|
|
||||||
|
if (memory[identifier].type == Type::Int) {
|
||||||
|
EvalResult res = memory[identifier].value;
|
||||||
|
memory[identifier].value = get<int>(memory[identifier].value) + 1;
|
||||||
|
return res;
|
||||||
|
}
|
||||||
|
|
||||||
|
return memory[identifier].value;
|
||||||
|
}
|
||||||
|
case NodeType::LDecr: {
|
||||||
|
Token identifierTok = get<Token>(node.children[0]);
|
||||||
|
string identifier = get<string>(identifierTok.data);
|
||||||
|
|
||||||
|
if (!memory.contains(identifier)) throw RuntimeError("Unknown identifier \""+identifier+"\"", identifierTok.pos);
|
||||||
|
|
||||||
|
if (memory[identifier].type == Type::Int) {
|
||||||
|
memory[identifier].value = get<int>(memory[identifier].value) - 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
return memory[identifier].value;
|
||||||
}
|
}
|
||||||
case NodeType::LDecr:
|
|
||||||
case NodeType::RDecr: {
|
case NodeType::RDecr: {
|
||||||
Token identifierTok = get<Token>(node.children[0]);
|
Token identifierTok = get<Token>(node.children[0]);
|
||||||
string identifier = get<string>(identifierTok.data);
|
string identifier = get<string>(identifierTok.data);
|
||||||
|
|
||||||
return node.type == NodeType::LDecr ? --memory[identifier] : memory[identifier]--;
|
if (!memory.contains(identifier)) throw RuntimeError("Unknown identifier \""+identifier+"\"", identifierTok.pos);
|
||||||
|
|
||||||
|
if (memory[identifier].type == Type::Int) {
|
||||||
|
EvalResult res = memory[identifier].value;
|
||||||
|
memory[identifier].value = get<int>(memory[identifier].value) - 1;
|
||||||
|
return res;
|
||||||
|
}
|
||||||
|
|
||||||
|
return memory[identifier].value;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -106,8 +154,10 @@ EvalResult eval(Node &ast) {
|
|||||||
} break;
|
} break;
|
||||||
case TokenType::Identifier: {
|
case TokenType::Identifier: {
|
||||||
string identifier = get<string>(token.data);
|
string identifier = get<string>(token.data);
|
||||||
if (!memory.contains(identifier)) throw RuntimeError("Unknown identifier");
|
|
||||||
return memory[identifier];
|
if (!memory.contains(identifier)) throw RuntimeError("Unknown identifier \""+identifier+"\"", token.pos);
|
||||||
|
|
||||||
|
return memory[identifier].value;
|
||||||
} break;
|
} break;
|
||||||
default:
|
default:
|
||||||
throw;
|
throw;
|
||||||
|
@ -162,7 +162,7 @@ vector<Token> tokenize(vector<string> input) {
|
|||||||
j += 1;
|
j += 1;
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
throw TokenError("Unknown token {}");
|
throw TokenError("Unknown token {}", pos);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user