Support nested function pointer types

This commit is contained in:
Duncan Ogilvie 2023-02-09 02:03:56 +01:00
parent 3087b56e5b
commit c1c257ce7a
2 changed files with 54 additions and 11 deletions

View File

@ -602,6 +602,7 @@ static void loadFunctions(const JSON froot, std::vector<Function> & functions)
void LoadModel(const std::string & owner, Model & model) void LoadModel(const std::string & owner, Model & model)
{ {
//Add all base struct/union types first to avoid errors later //Add all base struct/union types first to avoid errors later
// TODO: handle forward declarations
for(auto & su : model.structUnions) for(auto & su : model.structUnions)
{ {
auto success = su.isunion ? typeManager.AddUnion(owner, su.name) : typeManager.AddStruct(owner, su.name); auto success = su.isunion ? typeManager.AddUnion(owner, su.name) : typeManager.AddStruct(owner, su.name);

View File

@ -174,7 +174,7 @@ struct Parser
} }
index++; index++;
if (!isToken(Lexer::tok_identifier)) if (!isToken(Lexer::tok_identifier)) // TODO: support unnamed function pointers
{ {
errLine(curToken(), "expected identifier in function pointer type"); errLine(curToken(), "expected identifier in function pointer type");
return false; return false;
@ -291,9 +291,34 @@ struct Parser
} }
else if (t.Is(Lexer::tok_paropen)) else if (t.Is(Lexer::tok_paropen))
{ {
errLine(curToken(), "function pointer arguments are not supported"); auto startToken = curToken();
// TODO: support function pointers (requires recursion) index++;
// Function pointer argument to a function
Function subfn;
if(!parseFunction(tlist, subfn, true))
return false; return false;
// TODO: store this somewhere
// Create fake tokens
// TODO: handle this properly somehow
auto typeToken = tlist.back();
typeToken.Token = Lexer::tok_identifier;
typeToken.IdentifierStr = fn.name + "_" + subfn.name + "_fnptr";
printf("TODO function pointer: %s %s\n", typeToken.IdentifierStr.c_str(), subfn.name.c_str());
auto nameToken = startToken;
nameToken.Token = Lexer::tok_identifier;
nameToken.IdentifierStr = subfn.name;
// Replace the return type with the fake tokens
tlist.clear();
tlist.push_back(typeToken);
tlist.push_back(nameToken);
} }
else else
{ {
@ -321,13 +346,6 @@ struct Parser
return false; return false;
} }
if (!isToken(Lexer::tok_semic))
{
errLine(curToken(), "expected ; after function type");
return false;
}
eatSemic();
return true; return true;
} }
@ -442,6 +460,14 @@ struct Parser
{ {
return false; return false;
} }
if (!isToken(Lexer::tok_semic))
{
errLine(curToken(), "expected ; after function type");
return false;
}
eatSemic();
// TODO: put the function somewhere // TODO: put the function somewhere
printf("TODO function pointer: %s\n", fn.name.c_str()); printf("TODO function pointer: %s\n", fn.name.c_str());
@ -718,6 +744,14 @@ struct Parser
{ {
return false; return false;
} }
if (!isToken(Lexer::tok_semic))
{
errLine(curToken(), "expected ; after function type");
return false;
}
eatSemic();
// TODO: put the function somewhere // TODO: put the function somewhere
printf("TODO function pointer: %s\n", fn.name.c_str()); printf("TODO function pointer: %s\n", fn.name.c_str());
@ -807,6 +841,14 @@ struct Parser
{ {
return false; return false;
} }
if (!isToken(Lexer::tok_semic))
{
errLine(curToken(), "expected ; after function type");
return false;
}
eatSemic();
// TODO: put the function somewhere // TODO: put the function somewhere
printf("TODO function: %s\n", fn.name.c_str()); printf("TODO function: %s\n", fn.name.c_str());