diff --git a/Source/Integration/LuaCall.cpp b/Source/Integration/LuaCall.cpp index b0daed00..ff3b76e4 100644 --- a/Source/Integration/LuaCall.cpp +++ b/Source/Integration/LuaCall.cpp @@ -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; } ///////////////////////////////////////////////////////////////// diff --git a/Source/Integration/LuaCall.h b/Source/Integration/LuaCall.h index 01b7a852..0af07448 100644 --- a/Source/Integration/LuaCall.h +++ b/Source/Integration/LuaCall.h @@ -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(); } }; //////////////////////////////////////////////////////////// diff --git a/Source/Integration/LuaCallNode.cpp b/Source/Integration/LuaCallNode.cpp index 0cb2959d..899c872a 100644 --- a/Source/Integration/LuaCallNode.cpp +++ b/Source/Integration/LuaCallNode.cpp @@ -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); diff --git a/Source/Integration/ReadLuaValues.cpp b/Source/Integration/ReadLuaValues.cpp index a3ae55a6..6ac12c32 100644 --- a/Source/Integration/ReadLuaValues.cpp +++ b/Source/Integration/ReadLuaValues.cpp @@ -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);