Merge branch 'main' of gitlab.aliens-lyon.fr:alucas03/c-repl into main
This commit is contained in:
commit
a2da815832
@ -286,7 +286,7 @@ AnalysisResult analyze(Node &ast, Memory &memory) {
|
|||||||
if (memory.contains(function_name)) {
|
if (memory.contains(function_name)) {
|
||||||
// Il existe une variable non fonction à ce nom
|
// Il existe une variable non fonction à ce nom
|
||||||
if (memory.get(function_name).type.type != TypeType::Function) {
|
if (memory.get(function_name).type.type != TypeType::Function) {
|
||||||
throw RuntimeError(ErrorType::IncompatibleRedefinition, token.pos, function_name);
|
throw TypeError(ErrorType::IncompatibleRedefinition, token.pos, function_name);
|
||||||
}
|
}
|
||||||
|
|
||||||
Type old_type = memory.get(function_name).type;
|
Type old_type = memory.get(function_name).type;
|
||||||
@ -326,7 +326,7 @@ AnalysisResult analyze(Node &ast, Memory &memory) {
|
|||||||
if (memory.contains(function_name)) {
|
if (memory.contains(function_name)) {
|
||||||
// Il existe une variable non fonction à ce nom
|
// Il existe une variable non fonction à ce nom
|
||||||
if (memory.get(function_name).type.type != TypeType::Function) {
|
if (memory.get(function_name).type.type != TypeType::Function) {
|
||||||
throw RuntimeError(ErrorType::IncompatibleRedefinition, token.pos, function_name);
|
throw TypeError(ErrorType::IncompatibleRedefinition, token.pos, function_name);
|
||||||
}
|
}
|
||||||
|
|
||||||
Type old_type = memory.get(function_name).type;
|
Type old_type = memory.get(function_name).type;
|
||||||
@ -358,23 +358,37 @@ AnalysisResult analyze(Node &ast, Memory &memory) {
|
|||||||
if (!memory.contains(function_name))
|
if (!memory.contains(function_name))
|
||||||
throw RuntimeError(ErrorType::UnknownIdentifier, token.pos, function_name);
|
throw RuntimeError(ErrorType::UnknownIdentifier, token.pos, function_name);
|
||||||
|
|
||||||
|
|
||||||
if (memory.contains(function_name) && !memory.get(function_name).initialized)
|
|
||||||
throw RuntimeError(ErrorType::UninitializedIdentifier, token.pos, function_name);
|
|
||||||
|
|
||||||
MemoryVar function = memory.get(function_name);
|
MemoryVar function = memory.get(function_name);
|
||||||
|
|
||||||
if (get<InnerNode>(node.children[1]).children.size() != get<FunctionPrototype>(function.type.data).size()-1)
|
if (get<InnerNode>(node.children[1]).children.size() != get<FunctionPrototype>(function.type.data).size()-1)
|
||||||
throw RuntimeError(ErrorType::UnexpectedArgumentCount, token.pos, int(get<FunctionPrototype>(function.type.data).size())-1);
|
throw TypeError(ErrorType::UnexpectedArgumentCount, token.pos, int(get<FunctionPrototype>(function.type.data).size())-1);
|
||||||
|
|
||||||
return get<0>(get<FunctionPrototype>(function.type.data).at(0));
|
return get<0>(get<FunctionPrototype>(function.type.data).at(0));
|
||||||
} break;
|
} break;
|
||||||
case NodeType::Return: {
|
case NodeType::Return: {
|
||||||
|
MemoryVar function;
|
||||||
try {
|
try {
|
||||||
memory.get_function_scope();
|
function = *memory.get_function_scope().fn;
|
||||||
} catch (const InternalError& _) {
|
} catch (const InternalError& _) {
|
||||||
throw ControlError(ErrorType::UnexpectedReturn, node.pos, {});
|
throw ControlError(ErrorType::UnexpectedReturn, node.pos, {});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
FunctionPrototype prototype = get<FunctionPrototype>(function.type.data);
|
||||||
|
Type return_type = get<0>(prototype.at(0));
|
||||||
|
if (return_type.type == TypeType::Void) {
|
||||||
|
if (node.children.size() != 0)
|
||||||
|
throw TypeError(ErrorType::IncompatibleReturnValue, node.pos, {});
|
||||||
|
return {};
|
||||||
|
}
|
||||||
|
|
||||||
|
if (node.children.size() == 0)
|
||||||
|
throw TypeError(ErrorType::IncompatibleReturnValue, node.pos, {});
|
||||||
|
|
||||||
|
AnalysisResult res = analyze(node.children[0], memory);
|
||||||
|
AnalysisResult expected_type = return_type;
|
||||||
|
|
||||||
|
get_cast(res, expected_type, node.pos);
|
||||||
|
|
||||||
return {};
|
return {};
|
||||||
}
|
}
|
||||||
default:
|
default:
|
||||||
|
@ -43,6 +43,7 @@ string UserError::get_message(void) const {
|
|||||||
case ErrorType::IncompatibleRedefinition: return "Redefinition of '"+get<string>(this->data)+"' as different kind of symbol";
|
case ErrorType::IncompatibleRedefinition: return "Redefinition of '"+get<string>(this->data)+"' as different kind of symbol";
|
||||||
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";
|
||||||
|
|
||||||
// Runtime
|
// Runtime
|
||||||
case ErrorType::UnknownIdentifier: return "Unknown identifier '"+get<string>(this->data)+"'";
|
case ErrorType::UnknownIdentifier: return "Unknown identifier '"+get<string>(this->data)+"'";
|
||||||
|
@ -44,6 +44,7 @@ enum class ErrorType {
|
|||||||
IncompatibleRedefinition, // redefinition of a variable as a function
|
IncompatibleRedefinition, // redefinition of a variable as a function
|
||||||
IncompatibleDefinition, // function declaration incompatible with prototype
|
IncompatibleDefinition, // function declaration incompatible with prototype
|
||||||
UnexpectedArgumentCount,
|
UnexpectedArgumentCount,
|
||||||
|
IncompatibleReturnValue,
|
||||||
|
|
||||||
// Runtime
|
// Runtime
|
||||||
UnknownIdentifier,
|
UnknownIdentifier,
|
||||||
|
Loading…
Reference in New Issue
Block a user