From c1c257ce7a28ea8c015786100cbec3dbd8fd7b11 Mon Sep 17 00:00:00 2001 From: Duncan Ogilvie Date: Thu, 9 Feb 2023 02:03:56 +0100 Subject: [PATCH] Support nested function pointer types --- btparser/types.cpp | 1 + btparser/typesparser.cpp | 64 +++++++++++++++++++++++++++++++++------- 2 files changed, 54 insertions(+), 11 deletions(-) diff --git a/btparser/types.cpp b/btparser/types.cpp index a327626..487007b 100644 --- a/btparser/types.cpp +++ b/btparser/types.cpp @@ -602,6 +602,7 @@ static void loadFunctions(const JSON froot, std::vector & functions) void LoadModel(const std::string & owner, Model & model) { //Add all base struct/union types first to avoid errors later + // TODO: handle forward declarations for(auto & su : model.structUnions) { auto success = su.isunion ? typeManager.AddUnion(owner, su.name) : typeManager.AddStruct(owner, su.name); diff --git a/btparser/typesparser.cpp b/btparser/typesparser.cpp index 4535319..cc17746 100644 --- a/btparser/typesparser.cpp +++ b/btparser/typesparser.cpp @@ -174,7 +174,7 @@ struct Parser } index++; - if (!isToken(Lexer::tok_identifier)) + if (!isToken(Lexer::tok_identifier)) // TODO: support unnamed function pointers { errLine(curToken(), "expected identifier in function pointer type"); return false; @@ -291,9 +291,34 @@ struct Parser } else if (t.Is(Lexer::tok_paropen)) { - errLine(curToken(), "function pointer arguments are not supported"); - // TODO: support function pointers (requires recursion) - return false; + auto startToken = curToken(); + index++; + + // Function pointer argument to a function + Function subfn; + if(!parseFunction(tlist, subfn, true)) + 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 { @@ -321,13 +346,6 @@ struct Parser return false; } - if (!isToken(Lexer::tok_semic)) - { - errLine(curToken(), "expected ; after function type"); - return false; - } - eatSemic(); - return true; } @@ -442,6 +460,14 @@ struct Parser { return false; } + + if (!isToken(Lexer::tok_semic)) + { + errLine(curToken(), "expected ; after function type"); + return false; + } + eatSemic(); + // TODO: put the function somewhere printf("TODO function pointer: %s\n", fn.name.c_str()); @@ -718,6 +744,14 @@ struct Parser { return false; } + + if (!isToken(Lexer::tok_semic)) + { + errLine(curToken(), "expected ; after function type"); + return false; + } + eatSemic(); + // TODO: put the function somewhere printf("TODO function pointer: %s\n", fn.name.c_str()); @@ -807,6 +841,14 @@ struct Parser { return false; } + + if (!isToken(Lexer::tok_semic)) + { + errLine(curToken(), "expected ; after function type"); + return false; + } + eatSemic(); + // TODO: put the function somewhere printf("TODO function: %s\n", fn.name.c_str());