Add 'ParseReturnValuesOnly' to the lua prototype parser.

This commit is contained in:
2026-03-04 17:50:18 -05:00
parent 4dabb98d05
commit 78f0f318c5
4 changed files with 64 additions and 31 deletions

View File

@@ -91,10 +91,7 @@ void FlxParsedProto::Syntax() {
ErrorMessage = Message;
}
void FlxParsedProto::Parse(const FString &str) {
Empty();
// Step one: tokenize.
bool FlxParsedProto::Tokenize(const FString &str) {
int offset = 0;
while (offset < str.Len()) {
TCHAR c = str[offset];
@@ -113,12 +110,33 @@ void FlxParsedProto::Parse(const FString &str) {
} else {
Empty();
ErrorMessage = FString::Printf(TEXT("%s ? %s"), *str.Mid(0, offset), *str.Mid(offset));
return;
return false;
}
}
NextToken = 0;
return true;
}
// Step two: Parse.
void FlxParsedProto::ParseReturnValues() {
while (true) {
if (IsLiteral(TEXT("..."))) {
ExtraReturnValues = true;
NextToken++;
break;
} else if (IsIdent()) {
FString Type = Tokens[NextToken++];
if (!IsIdent()) return Syntax();
FString Name = Tokens[NextToken++];
ReturnValues.Add(Pin(Type, Name));
if (!IsLiteral(TEXT(","))) break;
NextToken++;
} else {
return Syntax();
}
}
}
void FlxParsedProto::Parse() {
if (!IsLiteral(TEXT("*")) && !IsIdent()) return Syntax();
ClassName = Tokens[NextToken++];
if (!IsLiteral(TEXT("."))) return Syntax();
@@ -142,24 +160,24 @@ void FlxParsedProto::Parse(const FString &str) {
NextToken++;
if (IsLiteral(TEXT(":"))) {
NextToken++;
while (true) {
if (IsLiteral(TEXT("..."))) {
ExtraReturnValues = true;
NextToken++;
break;
} else if (IsIdent()) {
FString Type = Tokens[NextToken++];
if (!IsIdent()) return Syntax();
FString Name = Tokens[NextToken++];
ReturnValues.Add(Pin(Type, Name));
if (!IsLiteral(TEXT(","))) break;
NextToken++;
} else {
return Syntax();
}
}
ParseReturnValues();
}
if (NextToken != Tokens.Num()) return Syntax();
}
FlxParsedProto FlxParsedProto::ParsePrototype(const FString &str) {
FlxParsedProto Result;
if (!Result.Tokenize(str)) return Result;
Result.Parse();
if (Result.NextToken != Result.Tokens.Num()) Result.Syntax();
return Result;
}
FlxParsedProto FlxParsedProto::ParseReturnValuesOnly(const FString &str) {
FlxParsedProto Result;
if (!Result.Tokenize(str)) return Result;
Result.ParseReturnValues();
if (Result.NextToken != Result.Tokens.Num()) Result.Syntax();
return Result;
}
/////////////////////////////////////////////////////////////////

View File

@@ -86,14 +86,29 @@ private:
//
void Empty();
// Parse a function prototype.
// Parse comma-separated "type name" pairs into ReturnValues.
//
void Parse(const FString &proto);
void ParseReturnValues();
// Parse a full function prototype (assumes already tokenized).
//
void Parse();
// Tokenize the input string.
//
bool Tokenize(const FString &str);
public:
// Construct with a prototype.
// Parse a full function prototype.
//
FlxParsedProto(const FString &str) { Parse(str); }
static FlxParsedProto ParsePrototype(const FString &str);
// Parse just a comma-separated list of "type name" pairs.
//
static FlxParsedProto ParseReturnValuesOnly(const FString &str);
private:
FlxParsedProto() { Empty(); }
};
////////////////////////////////////////////////////////////

View File

@@ -72,7 +72,7 @@ void UK2Node_LuaInvoke::AllocateDefaultPins()
// Note that we use the saved value of the function
// prototype, because the function prototype pin
// has been deleted at this point.
FlxParsedProto ParsedProto(LuaFunctionPrototype);
FlxParsedProto ParsedProto = FlxParsedProto::ParsePrototype(LuaFunctionPrototype);
if (!ParsedProto.ErrorMessage.IsEmpty())
{
SetErrorMsg(FString::Printf(TEXT("Syntax error in lua function prototype: %s"), *ParsedProto.ErrorMessage));
@@ -164,7 +164,7 @@ void UK2Node_LuaInvoke::ExpandNode(class FKismetCompilerContext& CompilerContext
{
Super::ExpandNode(CompilerContext, SourceGraph);
// The BeginNode function packs the class name and function name into the call buffer.
FlxParsedProto ParsedProto(LuaFunctionPrototype);
FlxParsedProto ParsedProto = FlxParsedProto::ParsePrototype(LuaFunctionPrototype);
const UEdGraphSchema_K2* CCSchema = CompilerContext.GetSchema();
UK2Node_CallFunction* BeginNode = MakeCallFunctionNode(CompilerContext, SourceGraph, LuaCallLibraryFunction(LuaCallBegin));
CCSchema->TrySetDefaultValue(*BeginNode->FindPinChecked(TEXT("ClassName")), ParsedProto.ClassName);

View File

@@ -72,7 +72,7 @@ void UK2Node_ReadLuaValues::AllocateDefaultPins()
// Note that we use the saved value of the function
// prototype, because the function prototype pin
// has been deleted at this point.
FlxParsedProto ParsedProto(LuaFunctionPrototype);
FlxParsedProto ParsedProto = FlxParsedProto::ParsePrototype(LuaFunctionPrototype);
if (!ParsedProto.ErrorMessage.IsEmpty())
{
SetErrorMsg(FString::Printf(TEXT("Syntax error in lua function prototype: %s"), *ParsedProto.ErrorMessage));
@@ -164,7 +164,7 @@ void UK2Node_ReadLuaValues::ExpandNode(class FKismetCompilerContext& CompilerCon
{
Super::ExpandNode(CompilerContext, SourceGraph);
// The BeginNode function packs the class name and function name into the call buffer.
FlxParsedProto ParsedProto(LuaFunctionPrototype);
FlxParsedProto ParsedProto = FlxParsedProto::ParsePrototype(LuaFunctionPrototype);
const UEdGraphSchema_K2* CCSchema = CompilerContext.GetSchema();
UK2Node_CallFunction* BeginNode = MakeCallFunctionNode(CompilerContext, SourceGraph, LuaCallLibraryFunction(LuaCallBegin));
CCSchema->TrySetDefaultValue(*BeginNode->FindPinChecked(TEXT("ClassName")), ParsedProto.ClassName);