Add analysis of function declaration & prototype

This commit is contained in:
augustin64 2024-01-03 14:09:17 +01:00
parent 4de0c57236
commit ca02c78673
3 changed files with 51 additions and 0 deletions

View File

@ -264,6 +264,55 @@ AnalysisResult analyze(Node &ast, Memory &memory) {
analyze(node.children[0], memory);
return analyze(node.children[1], memory);
}
case NodeType::FunctionPrototype: {
Token return_type_token = get<Token>(node.children[0]);
string return_type_string = get<string>(return_type_token.data);
Type return_type = try_string_to_type(return_type_string, return_type_token.pos);
Token token = get<Token>(node.children[1]);
string function_name = get<string>(token.data);
try {
memory.get_function_scope();
throw RuntimeError(ErrorType::NestedFunction, token.pos, {});
} catch (const InternalError& _) {}
memory.declare(function_name, {
.type = TypeType::Function,
.data = make_fn_prototype(node)
}, return_type_token.pos);
return {};
} break;
case NodeType::FunctionDeclaration: {
Token return_type_token = get<Token>(node.children[0]);
string return_type_string = get<string>(return_type_token.data);
Type return_type = try_string_to_type(return_type_string, return_type_token.pos);
Token token = get<Token>(node.children[1]);
string function_name = get<string>(token.data);
try {
memory.get_function_scope();
throw RuntimeError(ErrorType::NestedFunction, token.pos, {});
} catch (const InternalError& _) {}
if (memory.contains(function_name) && memory.get(function_name).initialized)
throw RuntimeError(ErrorType::FunctionRedefinition, token.pos, function_name);
memory.declare(function_name, {
.type = TypeType::Function,
.data = make_fn_prototype(node)
}, return_type_token.pos);
memory.update(function_name, node.children[3]);
memory.add_scope(ScopeType::Function, token.pos, &memory.get(function_name));
analyze(node.children[3], memory);
memory.remove_scope();
return {};
} break;
default:
return {};
}

View File

@ -25,6 +25,7 @@ string UserError::get_message(void) const {
case ErrorType::TypesNotComparable: return "Types not comparable";
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<string>(this->data)+"'";
case ErrorType::ExpectedArithmeticType: return "Expression must have arithmetic type";
case ErrorType::UnknownIdentifier: return "Unknown identifier '"+get<string>(this->data)+"'";
case ErrorType::AlreadyDeclaredIdentifier: return "Already declared identifier '"+get<string>(this->data)+"'";

View File

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