New error system
This commit is contained in:
parent
8e853aaaf2
commit
eb29c03359
@ -9,7 +9,7 @@ bool bool_castable(AnalysisResult type) {
|
|||||||
|
|
||||||
void check_comparable(AnalysisResult res1, AnalysisResult res2, CodePosition pos) {
|
void check_comparable(AnalysisResult res1, AnalysisResult res2, CodePosition pos) {
|
||||||
if (holds_alternative<monostate>(res1) || holds_alternative<monostate>(res2)) {
|
if (holds_alternative<monostate>(res1) || holds_alternative<monostate>(res2)) {
|
||||||
throw TypeError("Incomparable values", pos);
|
throw TypeError(ErrorType::TypesNotComparable, pos);
|
||||||
}
|
}
|
||||||
|
|
||||||
Type type1 = get<Type>(res1);
|
Type type1 = get<Type>(res1);
|
||||||
@ -25,11 +25,11 @@ void check_comparable(AnalysisResult res1, AnalysisResult res2, CodePosition pos
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
default:
|
default:
|
||||||
throw TypeError("Incomparable values", pos);
|
throw TypeError(ErrorType::TypesNotComparable, pos);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
default:
|
default:
|
||||||
throw TypeError("Incomparable values", pos);
|
throw TypeError(ErrorType::TypesNotComparable, pos);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -53,7 +53,7 @@ Type try_string_to_type(string type_name, CodePosition pos) {
|
|||||||
Type type = string_to_type(type_name);
|
Type type = string_to_type(type_name);
|
||||||
return type;
|
return type;
|
||||||
} catch (...) {
|
} catch (...) {
|
||||||
throw TypeError("Unknown type '"+type_name+"'", pos);
|
throw TypeError(ErrorType::UnknownType, pos, type_name);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -74,7 +74,7 @@ AnalysisResult analyze(Node &ast, Memory &memory) {
|
|||||||
string identifier = get<string>(token.data);
|
string identifier = get<string>(token.data);
|
||||||
|
|
||||||
if (!memory.contains(identifier))
|
if (!memory.contains(identifier))
|
||||||
throw RuntimeError("Unknown identifier \""+identifier+"\"", token.pos);
|
throw RuntimeError(ErrorType::UnknownIdentifier, token.pos, identifier);
|
||||||
|
|
||||||
return memory.get(identifier).type;
|
return memory.get(identifier).type;
|
||||||
throw exception();
|
throw exception();
|
||||||
@ -100,7 +100,7 @@ AnalysisResult analyze(Node &ast, Memory &memory) {
|
|||||||
case NodeType::If:
|
case NodeType::If:
|
||||||
case NodeType::IfElse: {
|
case NodeType::IfElse: {
|
||||||
if (!bool_castable(analyze(node.children[0], memory))) {
|
if (!bool_castable(analyze(node.children[0], memory))) {
|
||||||
throw TypeError("Can't find an explicit cast to bool", get_node_pos(node.children[0]));
|
throw TypeError(ErrorType::TypeNotCastable, get_node_pos(node.children[0]), "bool");
|
||||||
}
|
}
|
||||||
|
|
||||||
analyze(node.children[1], memory);
|
analyze(node.children[1], memory);
|
||||||
@ -111,7 +111,7 @@ AnalysisResult analyze(Node &ast, Memory &memory) {
|
|||||||
} break;
|
} break;
|
||||||
case NodeType::While: {
|
case NodeType::While: {
|
||||||
if (!bool_castable(analyze(node.children[0], memory))) {
|
if (!bool_castable(analyze(node.children[0], memory))) {
|
||||||
throw TypeError("Can't find a cast to bool", get_node_pos(node.children[0]));
|
throw TypeError(ErrorType::TypeNotCastable, get_node_pos(node.children[0]), "bool");
|
||||||
}
|
}
|
||||||
analyze(node.children[1], memory);
|
analyze(node.children[1], memory);
|
||||||
|
|
||||||
@ -123,7 +123,7 @@ AnalysisResult analyze(Node &ast, Memory &memory) {
|
|||||||
analyze(node.children[0], memory);
|
analyze(node.children[0], memory);
|
||||||
|
|
||||||
if (!bool_castable(analyze(node.children[1], memory))) {
|
if (!bool_castable(analyze(node.children[1], memory))) {
|
||||||
throw TypeError("Can't find an explicit cast to bool", get_node_pos(node.children[1]));
|
throw TypeError(ErrorType::TypeNotCastable, get_node_pos(node.children[1]), "bool");
|
||||||
}
|
}
|
||||||
|
|
||||||
analyze(node.children[2], memory);
|
analyze(node.children[2], memory);
|
||||||
@ -142,17 +142,17 @@ AnalysisResult analyze(Node &ast, Memory &memory) {
|
|||||||
case NodeType::Lor:
|
case NodeType::Lor:
|
||||||
case NodeType::Land: {
|
case NodeType::Land: {
|
||||||
if (!bool_castable(analyze(node.children[0], memory))) {
|
if (!bool_castable(analyze(node.children[0], memory))) {
|
||||||
throw TypeError("Can't find an explicit cast to bool", get_node_pos(node.children[0]));
|
throw TypeError(ErrorType::TypeNotCastable, get_node_pos(node.children[0]), "bool");
|
||||||
}
|
}
|
||||||
if (!bool_castable(analyze(node.children[1], memory))) {
|
if (!bool_castable(analyze(node.children[1], memory))) {
|
||||||
throw TypeError("Can't find an explicit cast to bool", get_node_pos(node.children[1]));
|
throw TypeError(ErrorType::TypeNotCastable, get_node_pos(node.children[1]), "bool");
|
||||||
}
|
}
|
||||||
|
|
||||||
return Type::Int;
|
return Type::Int;
|
||||||
} break;
|
} break;
|
||||||
case NodeType::Neg: {
|
case NodeType::Neg: {
|
||||||
if (!bool_castable(analyze(node.children[0], memory))) {
|
if (!bool_castable(analyze(node.children[0], memory))) {
|
||||||
throw TypeError("Can't find an explicit cast to bool", get_node_pos(node.children[0]));
|
throw TypeError(ErrorType::TypeNotCastable, get_node_pos(node.children[0]), "bool");
|
||||||
}
|
}
|
||||||
|
|
||||||
return Type::Int;
|
return Type::Int;
|
||||||
@ -184,10 +184,10 @@ AnalysisResult analyze(Node &ast, Memory &memory) {
|
|||||||
AnalysisResult e2 = analyze(node.children[1], 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::Int) {
|
||||||
throw TypeError("Expression must have integral type", get_node_pos(node.children[0]));
|
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::Int) {
|
||||||
throw TypeError("Expression must have integral type", get_node_pos(node.children[1]));
|
throw TypeError(ErrorType::ExpectedIntegralType, get_node_pos(node.children[1]));
|
||||||
}
|
}
|
||||||
|
|
||||||
return Type::Int;
|
return Type::Int;
|
||||||
@ -197,7 +197,7 @@ AnalysisResult analyze(Node &ast, Memory &memory) {
|
|||||||
AnalysisResult res = analyze(node.children[0], memory);
|
AnalysisResult res = analyze(node.children[0], memory);
|
||||||
|
|
||||||
if (holds_alternative<monostate>(res) || !is_arithmetic_type(get<Type>(res))) {
|
if (holds_alternative<monostate>(res) || !is_arithmetic_type(get<Type>(res))) {
|
||||||
throw TypeError("Expressions must have arithmetic type", get_node_pos(node.children[1]));
|
throw TypeError(ErrorType::ExpectedArithmeticType, get_node_pos(node.children[0]));
|
||||||
}
|
}
|
||||||
|
|
||||||
return get<Type>(res);
|
return get<Type>(res);
|
||||||
@ -210,7 +210,7 @@ AnalysisResult analyze(Node &ast, Memory &memory) {
|
|||||||
string identifier = get<string>(token.data);
|
string identifier = get<string>(token.data);
|
||||||
|
|
||||||
if (memory.contains_top(identifier))
|
if (memory.contains_top(identifier))
|
||||||
throw RuntimeError("Already defined identifier \""+identifier+"\"", token.pos);
|
throw RuntimeError(ErrorType::AlreadyDefinedIdentifier, token.pos, identifier);
|
||||||
|
|
||||||
Type type = try_string_to_type(type_string, type_token.pos);
|
Type type = try_string_to_type(type_string, type_token.pos);
|
||||||
memory.declare(identifier, type);
|
memory.declare(identifier, type);
|
||||||
@ -225,7 +225,7 @@ AnalysisResult analyze(Node &ast, Memory &memory) {
|
|||||||
string identifier = get<string>(token.data);
|
string identifier = get<string>(token.data);
|
||||||
|
|
||||||
if (memory.contains_top(identifier))
|
if (memory.contains_top(identifier))
|
||||||
throw TypeError("Already defined identifier \""+identifier+"\"", token.pos);
|
throw RuntimeError(ErrorType::AlreadyDefinedIdentifier, token.pos, identifier);
|
||||||
|
|
||||||
Type type = try_string_to_type(type_string, type_token.pos);
|
Type type = try_string_to_type(type_string, type_token.pos);
|
||||||
memory.declare(identifier, type);
|
memory.declare(identifier, type);
|
||||||
@ -238,7 +238,7 @@ AnalysisResult analyze(Node &ast, Memory &memory) {
|
|||||||
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);
|
||||||
if (!memory.contains(identifier))
|
if (!memory.contains(identifier))
|
||||||
throw RuntimeError("Unknown identifier \""+identifier+"\"", identifierTok.pos);
|
throw RuntimeError(ErrorType::UnknownIdentifier, identifierTok.pos, identifier);
|
||||||
|
|
||||||
Type type = memory.get(identifier).type;
|
Type type = memory.get(identifier).type;
|
||||||
AnalysisResult res = analyze(node.children[1], memory);
|
AnalysisResult res = analyze(node.children[1], memory);
|
||||||
@ -255,7 +255,7 @@ AnalysisResult analyze(Node &ast, Memory &memory) {
|
|||||||
string identifier = get<string>(identifierTok.data);
|
string identifier = get<string>(identifierTok.data);
|
||||||
|
|
||||||
if (!memory.contains(identifier))
|
if (!memory.contains(identifier))
|
||||||
throw RuntimeError("Unknown identifier \""+identifier+"\"", identifierTok.pos);
|
throw RuntimeError(ErrorType::UnknownIdentifier, identifierTok.pos, identifier);
|
||||||
|
|
||||||
return memory.get(identifier).type;
|
return memory.get(identifier).type;
|
||||||
}
|
}
|
||||||
|
@ -12,20 +12,16 @@ using namespace std;
|
|||||||
*/
|
*/
|
||||||
EvalResult eval(Node &ast, Memory& memory);
|
EvalResult eval(Node &ast, Memory& memory);
|
||||||
|
|
||||||
class BreakException : public runtime_error {
|
class BreakException : public InternalError {
|
||||||
public:
|
public:
|
||||||
explicit BreakException(const string& message, CodePosition pos)
|
explicit BreakException(CodePosition pos)
|
||||||
: runtime_error(message), pos(pos) {}
|
: InternalError(pos) {}
|
||||||
|
|
||||||
const CodePosition pos;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
class ContinueException : public runtime_error {
|
class ContinueException : public InternalError {
|
||||||
public:
|
public:
|
||||||
explicit ContinueException(const string& message, CodePosition pos)
|
explicit ContinueException(CodePosition pos)
|
||||||
: runtime_error(message), pos(pos) {}
|
: InternalError(pos) {}
|
||||||
|
|
||||||
const CodePosition pos;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif
|
#endif
|
@ -10,10 +10,10 @@ using namespace std;
|
|||||||
/**
|
/**
|
||||||
* Utilisé pour revenir en arrière quand quelque chose n'est pas reconnu
|
* Utilisé pour revenir en arrière quand quelque chose n'est pas reconnu
|
||||||
*/
|
*/
|
||||||
class ParseException : public std::exception {
|
class ParseException : public InternalError {
|
||||||
const char* what() const noexcept override {
|
public:
|
||||||
return "Parse Exception";
|
explicit ParseException(CodePosition pos = {})
|
||||||
}
|
: InternalError(pos) {}
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -183,26 +183,50 @@ struct Scope {
|
|||||||
/**
|
/**
|
||||||
* Errors
|
* Errors
|
||||||
*/
|
*/
|
||||||
class SyntaxError : public runtime_error {
|
enum class ErrorType { DivisionByZero, ModuloByZero, ExpectedIntegralType, ExpectedArithmeticType, UninitializedIdentifier, UnknownIdentifier, AlreadyDefinedIdentifier, EmptyInput, UnknownToken, InvalidSyntax, ExceptedLParen, ExpectedRParen, ExpectedRCurlyBracket, ExpectedSemicolon, DependentDeclaration, TypesNotComparable, TypeNotCastable, UnknownType };
|
||||||
|
|
||||||
|
using ErrorData = variant<monostate, string>;
|
||||||
|
|
||||||
|
class UserError : public exception {
|
||||||
public:
|
public:
|
||||||
explicit SyntaxError(const string& message, CodePosition pos)
|
explicit UserError(ErrorType type, CodePosition pos, ErrorData data = {})
|
||||||
: runtime_error(message), pos(pos) {}
|
: pos(pos), type(type), data(data) {}
|
||||||
|
|
||||||
|
const char* what() const noexcept override {
|
||||||
|
return "User error occurred.";
|
||||||
|
}
|
||||||
|
|
||||||
const CodePosition pos;
|
const CodePosition pos;
|
||||||
|
const ErrorType type;
|
||||||
|
const ErrorData data;
|
||||||
};
|
};
|
||||||
|
|
||||||
class TypeError : public runtime_error {
|
class SyntaxError : public UserError {
|
||||||
public:
|
public:
|
||||||
explicit TypeError(const string& message, CodePosition pos)
|
explicit SyntaxError(ErrorType type, CodePosition pos, ErrorData data = {})
|
||||||
: runtime_error(message), pos(pos) {}
|
: UserError(type, pos, data) {}
|
||||||
|
|
||||||
const CodePosition pos;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
class RuntimeError : public runtime_error {
|
class TypeError : public UserError {
|
||||||
public:
|
public:
|
||||||
explicit RuntimeError(const string& message, CodePosition pos)
|
explicit TypeError(ErrorType type, CodePosition pos, ErrorData data = {})
|
||||||
: runtime_error(message), pos(pos) {}
|
: UserError(type, pos, data) {}
|
||||||
|
};
|
||||||
|
|
||||||
|
class RuntimeError : public UserError {
|
||||||
|
public:
|
||||||
|
explicit RuntimeError(ErrorType type, CodePosition pos, ErrorData data = {})
|
||||||
|
: UserError(type, pos, data) {}
|
||||||
|
};
|
||||||
|
|
||||||
|
class InternalError : public exception {
|
||||||
|
public:
|
||||||
|
explicit InternalError(CodePosition pos = {})
|
||||||
|
: pos(pos) {}
|
||||||
|
|
||||||
|
const char* what() const noexcept override {
|
||||||
|
return "Internal error occurred.";
|
||||||
|
}
|
||||||
|
|
||||||
const CodePosition pos;
|
const CodePosition pos;
|
||||||
};
|
};
|
||||||
|
@ -241,13 +241,13 @@ EvalResult eval(Node &ast, Memory &memory) {
|
|||||||
if (holds_alternative<double>(e1) || holds_alternative<double>(e2)) {
|
if (holds_alternative<double>(e1) || holds_alternative<double>(e2)) {
|
||||||
double d1 = double_cast(e1);
|
double d1 = double_cast(e1);
|
||||||
double d2 = double_cast(e2);
|
double d2 = double_cast(e2);
|
||||||
if (d2 == 0) throw RuntimeError("Division by 0", node.pos);
|
if (d2 == 0) throw RuntimeError(ErrorType::DivisionByZero, node.pos);
|
||||||
return d1 / d2;
|
return d1 / d2;
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
int i1 = get<int>(e1);
|
int i1 = get<int>(e1);
|
||||||
int i2 = get<int>(e2);
|
int i2 = get<int>(e2);
|
||||||
if (i2 == 0) throw RuntimeError("Division by 0", node.pos);
|
if (i2 == 0) throw RuntimeError(ErrorType::DivisionByZero, node.pos);
|
||||||
return i1 / i2;
|
return i1 / i2;
|
||||||
}
|
}
|
||||||
} break;
|
} break;
|
||||||
@ -257,7 +257,7 @@ EvalResult eval(Node &ast, Memory &memory) {
|
|||||||
|
|
||||||
int i1 = get<int>(e1);
|
int i1 = get<int>(e1);
|
||||||
int i2 = get<int>(e2);
|
int i2 = get<int>(e2);
|
||||||
if (i2 == 0) throw RuntimeError("Modulo by 0", node.pos);
|
if (i2 == 0) throw RuntimeError(ErrorType::ModuloByZero, node.pos);
|
||||||
return i1 % i2;
|
return i1 % i2;
|
||||||
} break;
|
} break;
|
||||||
case NodeType::UnaryPlus: {
|
case NodeType::UnaryPlus: {
|
||||||
@ -332,7 +332,7 @@ EvalResult eval(Node &ast, Memory &memory) {
|
|||||||
MemoryVar& var = memory.get(identifier);
|
MemoryVar& var = memory.get(identifier);
|
||||||
|
|
||||||
if (!var.initialized) {
|
if (!var.initialized) {
|
||||||
throw RuntimeError("Accessing uninitialized identifier \""+identifier+"\"", identifierTok.pos);
|
throw RuntimeError(ErrorType::UninitializedIdentifier, identifierTok.pos, identifier);
|
||||||
}
|
}
|
||||||
else if (var.type == Type::Int) {
|
else if (var.type == Type::Int) {
|
||||||
memory.update(identifier, get<int>(var.value) + 1);
|
memory.update(identifier, get<int>(var.value) + 1);
|
||||||
@ -349,7 +349,7 @@ EvalResult eval(Node &ast, Memory &memory) {
|
|||||||
MemoryVar& var = memory.get(identifier);
|
MemoryVar& var = memory.get(identifier);
|
||||||
|
|
||||||
if (!var.initialized) {
|
if (!var.initialized) {
|
||||||
throw RuntimeError("Accessing uninitialized identifier \""+identifier+"\"", identifierTok.pos);
|
throw RuntimeError(ErrorType::UninitializedIdentifier, identifierTok.pos, identifier);
|
||||||
}
|
}
|
||||||
else if (var.type == Type::Int) {
|
else if (var.type == Type::Int) {
|
||||||
int oldVal = get<int>(var.value);
|
int oldVal = get<int>(var.value);
|
||||||
@ -367,7 +367,7 @@ EvalResult eval(Node &ast, Memory &memory) {
|
|||||||
MemoryVar& var = memory.get(identifier);
|
MemoryVar& var = memory.get(identifier);
|
||||||
|
|
||||||
if (!var.initialized) {
|
if (!var.initialized) {
|
||||||
throw RuntimeError("Accessing uninitialized identifier \""+identifier+"\"", identifierTok.pos);
|
throw RuntimeError(ErrorType::UninitializedIdentifier, identifierTok.pos, identifier);
|
||||||
}
|
}
|
||||||
else if (var.type == Type::Int) {
|
else if (var.type == Type::Int) {
|
||||||
memory.update(identifier, get<int>(var.value) - 1);
|
memory.update(identifier, get<int>(var.value) - 1);
|
||||||
@ -384,7 +384,7 @@ EvalResult eval(Node &ast, Memory &memory) {
|
|||||||
MemoryVar& var = memory.get(identifier);
|
MemoryVar& var = memory.get(identifier);
|
||||||
|
|
||||||
if (!var.initialized) {
|
if (!var.initialized) {
|
||||||
throw RuntimeError("Accessing uninitialized identifier \""+identifier+"\"", identifierTok.pos);
|
throw RuntimeError(ErrorType::UninitializedIdentifier, identifierTok.pos, identifier);
|
||||||
}
|
}
|
||||||
else if (var.type == Type::Int) {
|
else if (var.type == Type::Int) {
|
||||||
int oldVal = get<int>(var.value);
|
int oldVal = get<int>(var.value);
|
||||||
@ -396,7 +396,7 @@ EvalResult eval(Node &ast, Memory &memory) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
default: {
|
default: {
|
||||||
throw RuntimeError("Not Implemented", node.pos);
|
throw exception();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -419,15 +419,15 @@ EvalResult eval(Node &ast, Memory &memory) {
|
|||||||
MemoryVar& var = memory.get(identifier);
|
MemoryVar& var = memory.get(identifier);
|
||||||
|
|
||||||
if (!var.initialized)
|
if (!var.initialized)
|
||||||
throw RuntimeError("Accessing uninitialized identifier \""+identifier+"\"", token.pos);
|
throw RuntimeError(ErrorType::UninitializedIdentifier, token.pos, identifier);
|
||||||
|
|
||||||
return var.value;
|
return var.value;
|
||||||
} break;
|
} break;
|
||||||
case TokenType::Break: {
|
case TokenType::Break: {
|
||||||
throw BreakException("", token.pos);
|
throw BreakException(token.pos);
|
||||||
} break;
|
} break;
|
||||||
case TokenType::Continue: {
|
case TokenType::Continue: {
|
||||||
throw ContinueException("", token.pos);
|
throw ContinueException(token.pos);
|
||||||
} break;
|
} break;
|
||||||
default:
|
default:
|
||||||
throw exception();
|
throw exception();
|
||||||
|
@ -55,14 +55,14 @@ Node parse(vector<Token> tokens) {
|
|||||||
reverse(tokens.begin(), tokens.end());
|
reverse(tokens.begin(), tokens.end());
|
||||||
|
|
||||||
if (tokens.size() == 0) {
|
if (tokens.size() == 0) {
|
||||||
throw SyntaxError("Input must not be empty", null_pos);
|
throw SyntaxError(ErrorType::EmptyInput, null_pos);
|
||||||
}
|
}
|
||||||
|
|
||||||
ParseReturn ret = parse_prog(tokens);
|
ParseReturn ret = parse_prog(tokens);
|
||||||
|
|
||||||
if (ret.tokens.size() != 0) {
|
if (ret.tokens.size() != 0) {
|
||||||
CodePosition pos = ret.tokens.back().pos;
|
CodePosition pos = ret.tokens.back().pos;
|
||||||
throw SyntaxError("Unable to parse", pos);
|
throw SyntaxError(ErrorType::InvalidSyntax, pos);
|
||||||
}
|
}
|
||||||
|
|
||||||
return ret.node;
|
return ret.node;
|
||||||
@ -169,7 +169,7 @@ ParseReturn parse_statement(vector<Token> tokens) {
|
|||||||
tokens.pop_back();
|
tokens.pop_back();
|
||||||
|
|
||||||
if (tokens.back().type != TokenType::Semicolon)
|
if (tokens.back().type != TokenType::Semicolon)
|
||||||
throw SyntaxError("Expected ';'", tokens.back().pos);
|
throw SyntaxError(ErrorType::ExpectedSemicolon, tokens.back().pos);
|
||||||
|
|
||||||
tokens.pop_back();
|
tokens.pop_back();
|
||||||
return {
|
return {
|
||||||
@ -195,7 +195,7 @@ ParseReturn parse_statement(vector<Token> tokens) {
|
|||||||
|
|
||||||
tokens.pop_back();
|
tokens.pop_back();
|
||||||
if (tokens.back().type != TokenType::LParenthese) // Opening (
|
if (tokens.back().type != TokenType::LParenthese) // Opening (
|
||||||
throw SyntaxError("Missing '('", tokens.back().pos);
|
throw SyntaxError(ErrorType::ExceptedLParen, tokens.back().pos);
|
||||||
|
|
||||||
tokens.pop_back();
|
tokens.pop_back();
|
||||||
ParseReturn ret = parse_expr(tokens); // Expr
|
ParseReturn ret = parse_expr(tokens); // Expr
|
||||||
@ -203,7 +203,7 @@ ParseReturn parse_statement(vector<Token> tokens) {
|
|||||||
int nb_tok = ret.tokens.size(); // Closing )
|
int nb_tok = ret.tokens.size(); // Closing )
|
||||||
if (nb_tok == 0 || ret.tokens.back().type != TokenType::RParenthese)
|
if (nb_tok == 0 || ret.tokens.back().type != TokenType::RParenthese)
|
||||||
throw SyntaxError(
|
throw SyntaxError(
|
||||||
"Missing ')'",
|
ErrorType::ExpectedRParen,
|
||||||
nb_tok == 0 ? tokens.back().pos : ret.tokens.back().pos
|
nb_tok == 0 ? tokens.back().pos : ret.tokens.back().pos
|
||||||
);
|
);
|
||||||
|
|
||||||
@ -215,7 +215,7 @@ ParseReturn parse_statement(vector<Token> tokens) {
|
|||||||
ret = parse_instruction(tokens); // Instruction1
|
ret = parse_instruction(tokens); // Instruction1
|
||||||
} catch (const ParseException& pex) {
|
} catch (const ParseException& pex) {
|
||||||
throw SyntaxError(
|
throw SyntaxError(
|
||||||
"Invalid Syntax",
|
ErrorType::InvalidSyntax,
|
||||||
pos=tokens.back().pos
|
pos=tokens.back().pos
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
@ -224,7 +224,7 @@ ParseReturn parse_statement(vector<Token> tokens) {
|
|||||||
( get<InnerNode>(ret.node).type == NodeType::AssignedDeclaration ||
|
( get<InnerNode>(ret.node).type == NodeType::AssignedDeclaration ||
|
||||||
get<InnerNode>(ret.node).type == NodeType::Declaration ) )
|
get<InnerNode>(ret.node).type == NodeType::Declaration ) )
|
||||||
throw SyntaxError(
|
throw SyntaxError(
|
||||||
"a dependent statement may not be a declaration",
|
ErrorType::DependentDeclaration,
|
||||||
pos=tokens.back().pos
|
pos=tokens.back().pos
|
||||||
);
|
);
|
||||||
|
|
||||||
@ -263,7 +263,7 @@ ParseReturn parse_statement(vector<Token> tokens) {
|
|||||||
tokens.pop_back();
|
tokens.pop_back();
|
||||||
|
|
||||||
if (tokens.back().type != TokenType::LParenthese) // Opening (
|
if (tokens.back().type != TokenType::LParenthese) // Opening (
|
||||||
throw SyntaxError("Missing '('", tokens.back().pos);
|
throw SyntaxError(ErrorType::ExceptedLParen, tokens.back().pos);
|
||||||
tokens.pop_back();
|
tokens.pop_back();
|
||||||
|
|
||||||
ParseReturn ret1;
|
ParseReturn ret1;
|
||||||
@ -283,7 +283,7 @@ ParseReturn parse_statement(vector<Token> tokens) {
|
|||||||
int nb_tok = ret1.tokens.size(); // First ;
|
int nb_tok = ret1.tokens.size(); // First ;
|
||||||
if (nb_tok == 0 || ret1.tokens.back().type != TokenType::Semicolon)
|
if (nb_tok == 0 || ret1.tokens.back().type != TokenType::Semicolon)
|
||||||
throw SyntaxError(
|
throw SyntaxError(
|
||||||
"Expected ';'",
|
ErrorType::ExpectedSemicolon,
|
||||||
nb_tok == 0 ? tokens.back().pos : ret1.tokens.back().pos
|
nb_tok == 0 ? tokens.back().pos : ret1.tokens.back().pos
|
||||||
);
|
);
|
||||||
tokens = ret1.tokens;
|
tokens = ret1.tokens;
|
||||||
@ -302,7 +302,7 @@ ParseReturn parse_statement(vector<Token> tokens) {
|
|||||||
nb_tok = ret2.tokens.size(); // Second ;
|
nb_tok = ret2.tokens.size(); // Second ;
|
||||||
if (nb_tok == 0 || ret2.tokens.back().type != TokenType::Semicolon)
|
if (nb_tok == 0 || ret2.tokens.back().type != TokenType::Semicolon)
|
||||||
throw SyntaxError(
|
throw SyntaxError(
|
||||||
"Expected ';'",
|
ErrorType::ExpectedSemicolon,
|
||||||
nb_tok == 0 ? tokens.back().pos : ret2.tokens.back().pos
|
nb_tok == 0 ? tokens.back().pos : ret2.tokens.back().pos
|
||||||
);
|
);
|
||||||
tokens = ret2.tokens;
|
tokens = ret2.tokens;
|
||||||
@ -321,7 +321,7 @@ ParseReturn parse_statement(vector<Token> tokens) {
|
|||||||
nb_tok = ret3.tokens.size(); // Closing )
|
nb_tok = ret3.tokens.size(); // Closing )
|
||||||
if (nb_tok == 0 || ret3.tokens.back().type != TokenType::RParenthese)
|
if (nb_tok == 0 || ret3.tokens.back().type != TokenType::RParenthese)
|
||||||
throw SyntaxError(
|
throw SyntaxError(
|
||||||
"Missing ')'",
|
ErrorType::ExpectedRParen,
|
||||||
nb_tok == 0 ? tokens.back().pos : ret3.tokens.back().pos
|
nb_tok == 0 ? tokens.back().pos : ret3.tokens.back().pos
|
||||||
);
|
);
|
||||||
tokens = ret3.tokens;
|
tokens = ret3.tokens;
|
||||||
@ -351,14 +351,14 @@ ParseReturn parse_statement(vector<Token> tokens) {
|
|||||||
tokens.back().type != TokenType::RCurlyBracket
|
tokens.back().type != TokenType::RCurlyBracket
|
||||||
)
|
)
|
||||||
throw SyntaxError(
|
throw SyntaxError(
|
||||||
"Invalid Syntax. Missing ';' ?",
|
ErrorType::InvalidSyntax,
|
||||||
tokens.back().pos
|
tokens.back().pos
|
||||||
);
|
);
|
||||||
|
|
||||||
int nb_tok = ret.tokens.size();
|
int nb_tok = ret.tokens.size();
|
||||||
if (nb_tok == 0 || ret.tokens.back().type != TokenType::RCurlyBracket)
|
if (nb_tok == 0 || ret.tokens.back().type != TokenType::RCurlyBracket)
|
||||||
throw SyntaxError(
|
throw SyntaxError(
|
||||||
"Missing '}'",
|
ErrorType::ExpectedRCurlyBracket,
|
||||||
nb_tok == 0 ? tokens.back().pos : ret.tokens.back().pos
|
nb_tok == 0 ? tokens.back().pos : ret.tokens.back().pos
|
||||||
);
|
);
|
||||||
|
|
||||||
@ -800,7 +800,7 @@ ParseReturn parse_val(vector<Token> tokens) {
|
|||||||
tokens=ret.tokens;
|
tokens=ret.tokens;
|
||||||
|
|
||||||
if (tokens.size() < 1 || tokens.back().type != TokenType::RParenthese)
|
if (tokens.size() < 1 || tokens.back().type != TokenType::RParenthese)
|
||||||
throw SyntaxError("Missing ')'", tokens.back().pos);
|
throw SyntaxError(ErrorType::ExpectedRParen, tokens.back().pos);
|
||||||
|
|
||||||
tokens.pop_back();
|
tokens.pop_back();
|
||||||
|
|
||||||
|
@ -259,7 +259,7 @@ vector<Token> tokenize(vector<string> input, int initial_line) {
|
|||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
throw SyntaxError("Unknown token", pos);
|
throw SyntaxError(ErrorType::UnknownToken, pos);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user