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);
|
throw TypeError(ErrorType::AlreadyDeclaredIdentifier, 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);
|
||||||
|
if (type.type == TypeType::Void)
|
||||||
|
throw TypeError(ErrorType::IncompleteType, token.pos, {});
|
||||||
|
|
||||||
memory.declare(identifier, type);
|
memory.declare(identifier, type);
|
||||||
|
|
||||||
return {};
|
return {};
|
||||||
@ -229,6 +232,9 @@ AnalysisResult analyze(Node &ast, Memory &memory) {
|
|||||||
throw TypeError(ErrorType::AlreadyDeclaredIdentifier, token.pos, identifier);
|
throw TypeError(ErrorType::AlreadyDeclaredIdentifier, 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);
|
||||||
|
if (type.type == TypeType::Void)
|
||||||
|
throw TypeError(ErrorType::IncompleteType, token.pos, {});
|
||||||
|
|
||||||
memory.declare(identifier, type);
|
memory.declare(identifier, type);
|
||||||
|
|
||||||
get_cast(type, analyze(node.children[2], memory), get_node_pos(node));
|
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);
|
memory.declare(function_name, type);
|
||||||
|
|
||||||
return {};
|
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.declare(function_name, type);
|
||||||
|
|
||||||
memory.update(function_name, node.children[3]);
|
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::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::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::IncompatibleReturnValue: return "Return value type does not match the function type";
|
||||||
|
case ErrorType::IncompleteType: return "Incomplete type is not allowed";
|
||||||
|
|
||||||
// Runtime
|
// Runtime
|
||||||
case ErrorType::UnknownIdentifier: return "Unknown identifier '"+get<string>(this->data)+"'";
|
case ErrorType::UnknownIdentifier: return "Unknown identifier '"+get<string>(this->data)+"'";
|
||||||
|
@ -45,6 +45,7 @@ enum class ErrorType {
|
|||||||
IncompatibleDefinition, // function declaration incompatible with prototype
|
IncompatibleDefinition, // function declaration incompatible with prototype
|
||||||
UnexpectedArgumentCount,
|
UnexpectedArgumentCount,
|
||||||
IncompatibleReturnValue,
|
IncompatibleReturnValue,
|
||||||
|
IncompleteType, // void x
|
||||||
|
|
||||||
// Runtime
|
// Runtime
|
||||||
UnknownIdentifier,
|
UnknownIdentifier,
|
||||||
|
@ -98,5 +98,17 @@ int main() {
|
|||||||
true
|
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;
|
return 0;
|
||||||
}
|
}
|
@ -35,6 +35,12 @@ int main() {
|
|||||||
true
|
true
|
||||||
);
|
);
|
||||||
|
|
||||||
|
_TEST_ASSERT(
|
||||||
|
_TEST_IS_EXCEPTION(execute("void x;"), ErrorType::IncompleteType),
|
||||||
|
"Type void",
|
||||||
|
true
|
||||||
|
);
|
||||||
|
|
||||||
_TEST_ASSERT(
|
_TEST_ASSERT(
|
||||||
_TEST_NO_EXCEPTION(holds_alternative<monostate>(execute("int x; { int x; }"))),
|
_TEST_NO_EXCEPTION(holds_alternative<monostate>(execute("int x; { int x; }"))),
|
||||||
"Identifieur déjà défini dans une autre scope",
|
"Identifieur déjà défini dans une autre scope",
|
||||||
|
Loading…
Reference in New Issue
Block a user