Add new Type struct
This commit is contained in:
parent
6d608f00cd
commit
0759050fef
@ -17,12 +17,12 @@ void check_comparable(AnalysisResult res1, AnalysisResult res2, CodePosition pos
|
||||
Type type2 = get<Type>(res2);
|
||||
|
||||
|
||||
switch (type1) {
|
||||
case Type::Int:
|
||||
case Type::Double: {
|
||||
switch (type2) {
|
||||
case Type::Int:
|
||||
case Type::Double: {
|
||||
switch (type1.type) {
|
||||
case TypeType::Int:
|
||||
case TypeType::Double: {
|
||||
switch (type2.type) {
|
||||
case TypeType::Int:
|
||||
case TypeType::Double: {
|
||||
return;
|
||||
}
|
||||
default:
|
||||
@ -36,13 +36,13 @@ void check_comparable(AnalysisResult res1, AnalysisResult res2, CodePosition pos
|
||||
|
||||
Type get_cast(AnalysisResult type1, AnalysisResult type2, CodePosition pos) {
|
||||
(void)type1; (void)type2; (void)pos;
|
||||
return Type::Int;
|
||||
return type_type_to_type(TypeType::Int);
|
||||
}
|
||||
|
||||
bool is_arithmetic_type(Type type) {
|
||||
switch (type) {
|
||||
case Type::Int:
|
||||
case Type::Double:
|
||||
switch (type.type) {
|
||||
case TypeType::Int:
|
||||
case TypeType::Double:
|
||||
return true;
|
||||
default:
|
||||
return false;
|
||||
@ -64,9 +64,9 @@ AnalysisResult analyze(Node &ast, Memory &memory) {
|
||||
switch (token.type) {
|
||||
case TokenType::Litteral: {
|
||||
if (holds_alternative<int>(token.data)) {
|
||||
return Type::Int;
|
||||
return type_type_to_type(TypeType::Int);
|
||||
} else if (holds_alternative<double>(token.data)) {
|
||||
return Type::Double;
|
||||
return type_type_to_type(TypeType::Double);
|
||||
}
|
||||
throw exception();
|
||||
break;
|
||||
@ -149,14 +149,14 @@ AnalysisResult analyze(Node &ast, Memory &memory) {
|
||||
throw TypeError(ErrorType::TypeNotCastable, get_node_pos(node.children[1]), "bool");
|
||||
}
|
||||
|
||||
return Type::Int;
|
||||
return type_type_to_type(TypeType::Int);
|
||||
} break;
|
||||
case NodeType::Neg: {
|
||||
if (!bool_castable(analyze(node.children[0], memory))) {
|
||||
throw TypeError(ErrorType::TypeNotCastable, get_node_pos(node.children[0]), "bool");
|
||||
}
|
||||
|
||||
return Type::Int;
|
||||
return type_type_to_type(TypeType::Int);
|
||||
} break;
|
||||
case NodeType::Lt:
|
||||
case NodeType::Gt:
|
||||
@ -167,7 +167,7 @@ AnalysisResult analyze(Node &ast, Memory &memory) {
|
||||
|
||||
check_comparable(res1, res2, node.pos);
|
||||
|
||||
return Type::Int;
|
||||
return type_type_to_type(TypeType::Int);
|
||||
} break;
|
||||
case NodeType::Eq:
|
||||
case NodeType::Neq:
|
||||
@ -184,14 +184,14 @@ AnalysisResult analyze(Node &ast, Memory &memory) {
|
||||
AnalysisResult e1 = analyze(node.children[0], memory);
|
||||
AnalysisResult e2 = analyze(node.children[1], memory);
|
||||
|
||||
if (holds_alternative<monostate>(e1) || get<Type>(e1) != Type::Int) {
|
||||
if (holds_alternative<monostate>(e1) || get<Type>(e1).type != TypeType::Int) {
|
||||
throw TypeError(ErrorType::ExpectedIntegralType, get_node_pos(node.children[0]));
|
||||
}
|
||||
if (holds_alternative<monostate>(e2) || get<Type>(e2) != Type::Int) {
|
||||
if (holds_alternative<monostate>(e2) || get<Type>(e2).type != TypeType::Int) {
|
||||
throw TypeError(ErrorType::ExpectedIntegralType, get_node_pos(node.children[1]));
|
||||
}
|
||||
|
||||
return Type::Int;
|
||||
return type_type_to_type(TypeType::Int);
|
||||
} break;
|
||||
case NodeType::UnaryPlus:
|
||||
case NodeType::UnaryMinus: {
|
||||
|
@ -7,8 +7,26 @@
|
||||
#include <list>
|
||||
#include <vector>
|
||||
#include <stdexcept>
|
||||
#include <tuple>
|
||||
using namespace std;
|
||||
|
||||
/**
|
||||
* Types definition
|
||||
*/
|
||||
struct Type;
|
||||
|
||||
enum class TypeType {
|
||||
Int, Double, Void, Function
|
||||
};
|
||||
|
||||
using FunctionPrototype = vector<tuple<string, Type>>;
|
||||
using TypeData = variant<monostate, FunctionPrototype>;
|
||||
|
||||
struct Type {
|
||||
TypeType type;
|
||||
TypeData data { };
|
||||
};
|
||||
|
||||
/**
|
||||
* Tokens definition
|
||||
*/
|
||||
@ -19,11 +37,7 @@ enum class TokenType {
|
||||
Break, Continue, Return, Comma
|
||||
};
|
||||
|
||||
enum class Type {
|
||||
Int, Double, Void
|
||||
};
|
||||
|
||||
using TokenData = variant<int, double, string, Type>;
|
||||
using TokenData = variant<monostate, int, double, string, Type>;
|
||||
|
||||
struct CodePosition {
|
||||
int line;
|
||||
|
@ -9,6 +9,11 @@ using namespace std;
|
||||
*/
|
||||
CodePosition get_node_pos(Node node);
|
||||
|
||||
/**
|
||||
* Returns a Type object of the given TypeType
|
||||
*/
|
||||
Type type_type_to_type(TypeType type_type);
|
||||
|
||||
/**
|
||||
* Returns the Type associated with a type name
|
||||
*/
|
||||
@ -19,4 +24,9 @@ Type string_to_type(string type_name);
|
||||
*/
|
||||
vector<string> split_string(const string& input, char delimiter);
|
||||
|
||||
/**
|
||||
* Returns a human-readable name for a TypeType object
|
||||
*/
|
||||
string _debug_get_type_type_name(TypeType type);
|
||||
|
||||
#endif
|
@ -301,10 +301,10 @@ EvalResult eval(Node &ast, Memory &memory) {
|
||||
Type type = string_to_type(typeName);
|
||||
memory.declare(identifier, type);
|
||||
|
||||
if (type == Type::Int) {
|
||||
if (type.type == TypeType::Int) {
|
||||
memory.update(identifier, int_cast(value));
|
||||
}
|
||||
else if (type == Type::Double) {
|
||||
else if (type.type == TypeType::Double) {
|
||||
memory.update(identifier, double_cast(value));
|
||||
}
|
||||
|
||||
@ -317,10 +317,10 @@ EvalResult eval(Node &ast, Memory &memory) {
|
||||
|
||||
Type type = memory.get(identifier).type;
|
||||
|
||||
if (type == Type::Int) {
|
||||
if (type.type == TypeType::Int) {
|
||||
memory.update(identifier, int_cast(value));
|
||||
}
|
||||
else if (type == Type::Double) {
|
||||
else if (type.type == TypeType::Double) {
|
||||
memory.update(identifier, double_cast(value));
|
||||
}
|
||||
|
||||
@ -335,7 +335,7 @@ EvalResult eval(Node &ast, Memory &memory) {
|
||||
if (!var.initialized) {
|
||||
throw RuntimeError(ErrorType::UninitializedIdentifier, identifierTok.pos, identifier);
|
||||
}
|
||||
else if (var.type == Type::Int) {
|
||||
else if (var.type.type == TypeType::Int) {
|
||||
memory.update(identifier, get<int>(var.value) + 1);
|
||||
return var.value;
|
||||
}
|
||||
@ -352,7 +352,7 @@ EvalResult eval(Node &ast, Memory &memory) {
|
||||
if (!var.initialized) {
|
||||
throw RuntimeError(ErrorType::UninitializedIdentifier, identifierTok.pos, identifier);
|
||||
}
|
||||
else if (var.type == Type::Int) {
|
||||
else if (var.type.type == TypeType::Int) {
|
||||
int oldVal = get<int>(var.value);
|
||||
memory.update(identifier, oldVal + 1);
|
||||
return oldVal;
|
||||
@ -370,7 +370,7 @@ EvalResult eval(Node &ast, Memory &memory) {
|
||||
if (!var.initialized) {
|
||||
throw RuntimeError(ErrorType::UninitializedIdentifier, identifierTok.pos, identifier);
|
||||
}
|
||||
else if (var.type == Type::Int) {
|
||||
else if (var.type.type == TypeType::Int) {
|
||||
memory.update(identifier, get<int>(var.value) - 1);
|
||||
return var.value;
|
||||
}
|
||||
@ -387,7 +387,7 @@ EvalResult eval(Node &ast, Memory &memory) {
|
||||
if (!var.initialized) {
|
||||
throw RuntimeError(ErrorType::UninitializedIdentifier, identifierTok.pos, identifier);
|
||||
}
|
||||
else if (var.type == Type::Int) {
|
||||
else if (var.type.type == TypeType::Int) {
|
||||
int oldVal = get<int>(var.value);
|
||||
memory.update(identifier, oldVal - 1);
|
||||
return oldVal;
|
||||
|
@ -1,4 +1,5 @@
|
||||
#include "include/memory.h"
|
||||
#include "include/utils.h"
|
||||
using namespace std;
|
||||
|
||||
Memory::Memory(void) {
|
||||
@ -78,10 +79,6 @@ void _debug_print_memory_var(MemoryVar var) {
|
||||
}
|
||||
}
|
||||
|
||||
const char* _debug_type_names[] = {
|
||||
"Int", "Double"
|
||||
};
|
||||
|
||||
void _debug_print_scope(Scope scope) {
|
||||
for (auto it : scope.vars) {
|
||||
if (it.first.length() > 6) {
|
||||
@ -90,7 +87,7 @@ void _debug_print_scope(Scope scope) {
|
||||
cout << setw (6) << it.first << " ";
|
||||
}
|
||||
cout << "|";
|
||||
cout << setw (7) << _debug_type_names[int(it.second.type)] << " |";
|
||||
cout << setw (7) << _debug_get_type_type_name(it.second.type.type) << " |";
|
||||
|
||||
_debug_print_memory_var(it.second);
|
||||
cout << endl;
|
||||
|
@ -43,15 +43,6 @@ vector<tuple<string, TokenType>> simpleTokens = {
|
||||
{ ",", TokenType::Comma }
|
||||
};
|
||||
|
||||
string _debug_get_type_name(Type type) {
|
||||
switch (type) {
|
||||
case Type::Int: return "INT";
|
||||
case Type::Double: return "DOUBLE";
|
||||
case Type::Void: return "VOID";
|
||||
default: return "Unknown";
|
||||
}
|
||||
}
|
||||
|
||||
string _debug_get_token_type_name(TokenType type) {
|
||||
switch (type) {
|
||||
case TokenType::Identifier: return "Identifier";
|
||||
|
@ -11,11 +11,26 @@ CodePosition get_node_pos(Node node) {
|
||||
return get<Token>(node).pos;
|
||||
}
|
||||
|
||||
Type type_type_to_type(TypeType type_type) {
|
||||
switch (type_type) {
|
||||
case TypeType::Int:
|
||||
case TypeType::Double:
|
||||
case TypeType::Void: {
|
||||
Type type = { .type = type_type };
|
||||
return type;
|
||||
}
|
||||
default:
|
||||
throw exception();
|
||||
}
|
||||
}
|
||||
|
||||
Type string_to_type(string type_name) {
|
||||
if (type_name == "int")
|
||||
return Type::Int;
|
||||
return type_type_to_type(TypeType::Int);
|
||||
if (type_name == "double")
|
||||
return Type::Double;
|
||||
return type_type_to_type(TypeType::Double);
|
||||
if (type_name == "void")
|
||||
return type_type_to_type(TypeType::Void);
|
||||
|
||||
throw exception();
|
||||
}
|
||||
@ -30,4 +45,14 @@ vector<string> split_string(const string& input, char delimiter) {
|
||||
}
|
||||
|
||||
return tokens;
|
||||
}
|
||||
|
||||
string _debug_get_type_type_name(TypeType type) {
|
||||
switch (type) {
|
||||
case TypeType::Int: return "INT";
|
||||
case TypeType::Double: return "DOUBLE";
|
||||
case TypeType::Void: return "VOID";
|
||||
case TypeType::Function: return "FUNCTION";
|
||||
default: return "Unknown";
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue
Block a user