Add incomplete type error
This commit is contained in:
parent
ac191716d9
commit
6a646ecec7
@ -214,6 +214,9 @@ AnalysisResult analyze(Node &ast, Memory &memory) {
|
||||
throw TypeError(ErrorType::AlreadyDeclaredIdentifier, token.pos, identifier);
|
||||
|
||||
Type type = try_string_to_type(type_string, type_token.pos);
|
||||
if (type.type == TypeType::Void)
|
||||
throw TypeError(ErrorType::IncompleteType, token.pos, {});
|
||||
|
||||
memory.declare(identifier, type);
|
||||
|
||||
return {};
|
||||
@ -229,6 +232,9 @@ AnalysisResult analyze(Node &ast, Memory &memory) {
|
||||
throw TypeError(ErrorType::AlreadyDeclaredIdentifier, token.pos, identifier);
|
||||
|
||||
Type type = try_string_to_type(type_string, type_token.pos);
|
||||
if (type.type == TypeType::Void)
|
||||
throw TypeError(ErrorType::IncompleteType, token.pos, {});
|
||||
|
||||
memory.declare(identifier, type);
|
||||
|
||||
get_cast(type, analyze(node.children[2], memory), get_node_pos(node));
|
||||
@ -295,6 +301,15 @@ AnalysisResult analyze(Node &ast, Memory &memory) {
|
||||
}
|
||||
}
|
||||
|
||||
for (int i=1; i < (int)prototype.size(); i++) {
|
||||
if (get<0>(prototype.at(i)).type == TypeType::Void) {
|
||||
InnerNode args_node = get<InnerNode>(node.children[2]);
|
||||
InnerNode declaration_node = get<InnerNode>(args_node.children[i-1]);
|
||||
CodePosition type_pos = get_node_pos(declaration_node.children[0]);
|
||||
throw TypeError(ErrorType::IncompleteType, type_pos, {});
|
||||
}
|
||||
}
|
||||
|
||||
memory.declare(function_name, type);
|
||||
|
||||
return {};
|
||||
@ -335,6 +350,15 @@ AnalysisResult analyze(Node &ast, Memory &memory) {
|
||||
}
|
||||
}
|
||||
|
||||
for (int i=1; i < (int)prototype.size(); i++) {
|
||||
if (get<0>(prototype.at(i)).type == TypeType::Void) {
|
||||
InnerNode args_node = get<InnerNode>(node.children[2]);
|
||||
InnerNode declaration_node = get<InnerNode>(args_node.children[i-1]);
|
||||
CodePosition type_pos = get_node_pos(declaration_node.children[0]);
|
||||
throw TypeError(ErrorType::IncompleteType, type_pos, {});
|
||||
}
|
||||
}
|
||||
|
||||
memory.declare(function_name, type);
|
||||
|
||||
memory.update(function_name, node.children[3]);
|
||||
|
@ -46,6 +46,7 @@ string UserError::get_message(void) const {
|
||||
case ErrorType::IncompatibleDefinition: return "Declaration of '"+get<string>(this->data)+"' is incompatible with previous prototype";
|
||||
case ErrorType::UnexpectedArgumentCount: return "Expected "+to_string(get<int>(this->data))+" arguments to function call";
|
||||
case ErrorType::IncompatibleReturnValue: return "Return value type does not match the function type";
|
||||
case ErrorType::IncompleteType: return "Incomplete type is not allowed";
|
||||
|
||||
// Runtime
|
||||
case ErrorType::UnknownIdentifier: return "Unknown identifier '"+get<string>(this->data)+"'";
|
||||
|
@ -45,6 +45,7 @@ enum class ErrorType {
|
||||
IncompatibleDefinition, // function declaration incompatible with prototype
|
||||
UnexpectedArgumentCount,
|
||||
IncompatibleReturnValue,
|
||||
IncompleteType, // void x
|
||||
|
||||
// Runtime
|
||||
UnknownIdentifier,
|
||||
|
@ -98,5 +98,17 @@ int main() {
|
||||
true
|
||||
);
|
||||
|
||||
_TEST_ASSERT(
|
||||
_TEST_IS_EXCEPTION(execute("int f(int x, void y);"), ErrorType::IncompleteType),
|
||||
"Argument void (prototype)",
|
||||
true
|
||||
);
|
||||
|
||||
_TEST_ASSERT(
|
||||
_TEST_IS_EXCEPTION(execute("int f(int x, void y) { return x+2; };"), ErrorType::IncompleteType),
|
||||
"Argument void (déclaration)",
|
||||
true
|
||||
);
|
||||
|
||||
return 0;
|
||||
}
|
@ -35,6 +35,12 @@ int main() {
|
||||
true
|
||||
);
|
||||
|
||||
_TEST_ASSERT(
|
||||
_TEST_IS_EXCEPTION(execute("void x;"), ErrorType::IncompleteType),
|
||||
"Type void",
|
||||
true
|
||||
);
|
||||
|
||||
_TEST_ASSERT(
|
||||
_TEST_NO_EXCEPTION(holds_alternative<monostate>(execute("int x; { int x; }"))),
|
||||
"Identifieur déjà défini dans une autre scope",
|
||||
|
Loading…
Reference in New Issue
Block a user