diff --git a/src/analysis.cpp b/src/analysis.cpp index 687991b..abb3f80 100644 --- a/src/analysis.cpp +++ b/src/analysis.cpp @@ -292,22 +292,41 @@ AnalysisResult analyze(Node &ast, Memory &memory) { Token token = get(node.children[1]); string function_name = get(token.data); + // Déclarée dans une fonction try { memory.get_function_scope(); throw RuntimeError(ErrorType::NestedFunction, token.pos, {}); } catch (const InternalError& _) {} + // Corps de la fonction déjà déclaré if (memory.contains(function_name) && memory.get(function_name).initialized) throw RuntimeError(ErrorType::FunctionRedefinition, token.pos, function_name); + FunctionPrototype prototype = make_fn_prototype(node); + + if (memory.contains(function_name)) { + // Il existe une variable non fonction à ce nom + if (memory.get(function_name).type.type != TypeType::Function) { + throw RuntimeError(ErrorType::IncompatibleRedefinition, token.pos, function_name); + } + + //TODO: Vérification de la cohérence des arguments avec ceux du prototype + } + memory.declare(function_name, { - .type = TypeType::Function, - .data = make_fn_prototype(node) + .type=TypeType::Function, + .data=prototype }, return_type_token.pos); memory.update(function_name, node.children[3]); memory.add_scope(ScopeType::Function, token.pos, &memory.get(function_name)); + for (tuple variable : prototype) { + Type vtype = get<0>(variable); + string vname = get<1>(variable); + + memory.declare(vname, vtype, token.pos); + } analyze(node.children[3], memory); memory.remove_scope(); diff --git a/src/errors.cpp b/src/errors.cpp index e0a1f22..139286c 100644 --- a/src/errors.cpp +++ b/src/errors.cpp @@ -26,6 +26,7 @@ string UserError::get_message(void) const { case ErrorType::ExpectedIntegralType: return "Expression must have integral type"; case ErrorType::NestedFunction: return "Function definition is not allowed here"; case ErrorType::FunctionRedefinition: return "Redefinition of '"+get(this->data)+"'"; + case ErrorType::IncompatibleRedefinition: return "Redefinition of '"+get(this->data)+"' as different kind of symbol"; case ErrorType::ExpectedArithmeticType: return "Expression must have arithmetic type"; case ErrorType::UnknownIdentifier: return "Unknown identifier '"+get(this->data)+"'"; case ErrorType::AlreadyDeclaredIdentifier: return "Already declared identifier '"+get(this->data)+"'"; diff --git a/src/include/errors.h b/src/include/errors.h index b30abdb..04c7c5a 100644 --- a/src/include/errors.h +++ b/src/include/errors.h @@ -35,6 +35,7 @@ enum class ErrorType { ExpectedArithmeticType, NestedFunction, FunctionRedefinition, + IncompatibleRedefinition, // Runtime UnknownIdentifier,