FunctionDeclaration analysis: add arguments definitions

This commit is contained in:
augustin64 2024-01-03 15:27:13 +01:00
parent 8401d3d8b6
commit fc53bf3113
3 changed files with 23 additions and 2 deletions

View File

@ -292,22 +292,41 @@ AnalysisResult analyze(Node &ast, Memory &memory) {
Token token = get<Token>(node.children[1]); Token token = get<Token>(node.children[1]);
string function_name = get<string>(token.data); string function_name = get<string>(token.data);
// Déclarée dans une fonction
try { try {
memory.get_function_scope(); memory.get_function_scope();
throw RuntimeError(ErrorType::NestedFunction, token.pos, {}); throw RuntimeError(ErrorType::NestedFunction, token.pos, {});
} catch (const InternalError& _) {} } catch (const InternalError& _) {}
// Corps de la fonction déjà déclaré
if (memory.contains(function_name) && memory.get(function_name).initialized) if (memory.contains(function_name) && memory.get(function_name).initialized)
throw RuntimeError(ErrorType::FunctionRedefinition, token.pos, function_name); 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, { memory.declare(function_name, {
.type=TypeType::Function, .type=TypeType::Function,
.data = make_fn_prototype(node) .data=prototype
}, return_type_token.pos); }, return_type_token.pos);
memory.update(function_name, node.children[3]); memory.update(function_name, node.children[3]);
memory.add_scope(ScopeType::Function, token.pos, &memory.get(function_name)); memory.add_scope(ScopeType::Function, token.pos, &memory.get(function_name));
for (tuple<Type, string> variable : prototype) {
Type vtype = get<0>(variable);
string vname = get<1>(variable);
memory.declare(vname, vtype, token.pos);
}
analyze(node.children[3], memory); analyze(node.children[3], memory);
memory.remove_scope(); memory.remove_scope();

View File

@ -26,6 +26,7 @@ string UserError::get_message(void) const {
case ErrorType::ExpectedIntegralType: return "Expression must have integral type"; case ErrorType::ExpectedIntegralType: return "Expression must have integral type";
case ErrorType::NestedFunction: return "Function definition is not allowed here"; case ErrorType::NestedFunction: return "Function definition is not allowed here";
case ErrorType::FunctionRedefinition: return "Redefinition of '"+get<string>(this->data)+"'"; case ErrorType::FunctionRedefinition: return "Redefinition of '"+get<string>(this->data)+"'";
case ErrorType::IncompatibleRedefinition: return "Redefinition of '"+get<string>(this->data)+"' as different kind of symbol";
case ErrorType::ExpectedArithmeticType: return "Expression must have arithmetic type"; case ErrorType::ExpectedArithmeticType: return "Expression must have arithmetic type";
case ErrorType::UnknownIdentifier: return "Unknown identifier '"+get<string>(this->data)+"'"; case ErrorType::UnknownIdentifier: return "Unknown identifier '"+get<string>(this->data)+"'";
case ErrorType::AlreadyDeclaredIdentifier: return "Already declared identifier '"+get<string>(this->data)+"'"; case ErrorType::AlreadyDeclaredIdentifier: return "Already declared identifier '"+get<string>(this->data)+"'";

View File

@ -35,6 +35,7 @@ enum class ErrorType {
ExpectedArithmeticType, ExpectedArithmeticType,
NestedFunction, NestedFunction,
FunctionRedefinition, FunctionRedefinition,
IncompatibleRedefinition,
// Runtime // Runtime
UnknownIdentifier, UnknownIdentifier,