else if(resolve<FunctionResolver>(stage, flags, RESOLVE_FUNCTIONS))
flags |= RESOLVE_EXPRESSIONS;
else if(resolve<ExpressionResolver>(stage, flags, RESOLVE_EXPRESSIONS))
- flags |= RESOLVE_VARIABLES;
+ flags |= RESOLVE_VARIABLES|RESOLVE_FUNCTIONS;
}
}
void DumpTree::visit(FunctionDeclaration &func)
{
- string text = format("%%%d %s %s", get_label(func), func.return_type, func.name);
+ string text = format("%%%d %s %s%s", get_label(func), func.return_type, func.name, (func.signature.empty() ? "(?)" : func.signature));
if(func.source==BUILTIN_SOURCE)
text += " (builtin)";
else if(!func.definition)
append(text);
begin_sub();
+ if(func.return_type_declaration)
+ append(format("Return type: %%%d %s", get_label(*func.return_type_declaration), func.return_type_declaration->name));
for(NodeArray<VariableDeclaration>::const_iterator i=func.parameters.begin(); i!=func.parameters.end(); ++i)
(*i)->visit(*this);
last_branch();
#include <msp/core/hash.h>
#include <msp/core/raii.h>
#include <msp/strings/lexicalcast.h>
+#include <msp/strings/utils.h>
#include "builtin.h"
#include "generate.h"
void FunctionResolver::visit(FunctionCall &call)
{
- map<string, FunctionDeclaration *>::iterator i = stage->functions.find(call.name);
- FunctionDeclaration *declaration = (i!=stage->functions.end() ? i->second : 0);
+ string arg_types;
+ bool has_signature = true;
+ for(NodeArray<Expression>::const_iterator i=call.arguments.begin(); (has_signature && i!=call.arguments.end()); ++i)
+ {
+ if((*i)->type)
+ append(arg_types, ",", (*i)->type->name);
+ else
+ has_signature = false;
+ }
+
+ FunctionDeclaration *declaration = 0;
+ if(has_signature)
+ {
+ map<string, FunctionDeclaration *>::iterator i = stage->functions.find(format("%s(%s)", call.name, arg_types));
+ declaration = (i!=stage->functions.end() ? i->second : 0);
+ }
r_any_resolved |= (declaration!=call.declaration);
call.declaration = declaration;
void FunctionResolver::visit(FunctionDeclaration &func)
{
- FunctionDeclaration *&stage_decl = stage->functions[func.name];
- vector<FunctionDeclaration *> &decls = declarations[func.name];
+ if(func.signature.empty())
+ {
+ string param_types;
+ for(NodeArray<VariableDeclaration>::const_iterator i=func.parameters.begin(); i!=func.parameters.end(); ++i)
+ {
+ if((*i)->type_declaration)
+ append(param_types, ",", (*i)->type_declaration->name);
+ else
+ return;
+ }
+ func.signature = format("(%s)", param_types);
+ r_any_resolved = true;
+ }
+
+ string key = func.name+func.signature;
+ FunctionDeclaration *&stage_decl = stage->functions[key];
+ vector<FunctionDeclaration *> &decls = declarations[key];
if(func.definition==&func)
{
stage_decl = &func;
name(other.name),
parameters(other.parameters),
body(other.body),
+ signature(other.signature),
definition(other.definition==&other ? this : 0),
return_type_declaration(0)
{ }
NodeArray<VariableDeclaration> parameters;
Block body;
+ std::string signature;
FunctionDeclaration *definition;
TypeDeclaration *return_type_declaration;
{
if(Statement *previous = find_definition(func.name))
{
- FunctionDeclaration *prev_func = dynamic_cast<FunctionDeclaration *>(previous);
- if(prev_func && prev_func->definition==&func)
- declarations[current_block][func.name] = &func;
- else
+ if(!dynamic_cast<FunctionDeclaration *>(previous))
multiple_definition(format("'%s'", func.name), func, *previous);
}
else
record_definition(func.name, func);
+ if(func.definition==&func)
+ check_definition(func.name+func.signature, func);
+
TraversingVisitor::visit(func);
}
void NodeRemover::visit(FunctionDeclaration &func)
{
if(to_remove->count(&func))
+ {
remove_from_map(stage->functions, func.name, func);
+ if(!func.signature.empty())
+ remove_from_map(stage->functions, func.name+func.signature, func);
+ }
TraversingVisitor::visit(func);
}