Skip to content

Commit a458a20

Browse files
committed
Merge branch 'master' of https://github.com/neolithos/neolua
2 parents fea1d62 + 9ee47ca commit a458a20

File tree

2 files changed

+85
-9
lines changed

2 files changed

+85
-9
lines changed

NeoLua.Test/Functions.cs

+58
Original file line numberDiff line numberDiff line change
@@ -360,6 +360,64 @@ public void TestFunctions62()
360360
}
361361
}
362362

363+
[TestMethod]
364+
public void TestForwardDeclaration()
365+
{
366+
TestCode(
367+
@"local f
368+
function f()
369+
return 'Hello'
370+
end
371+
372+
return f()",
373+
"Hello");
374+
}
375+
[TestMethod]
376+
public void TestDoubleLocalFunction()
377+
{
378+
TestCode(
379+
@"local function f()
380+
return 'Hello'
381+
end
382+
local function f()
383+
return 'World'
384+
end
385+
return f()",
386+
"World");
387+
}
388+
389+
[TestMethod]
390+
public void TestLocalMutualRecursiveFunction()
391+
{
392+
TestCode(
393+
@"
394+
local f1, f2
395+
function f2()
396+
return f1()
397+
end
398+
function f1()
399+
return 'Hello'
400+
end
401+
return _G['f2'] == nil",
402+
true);
403+
}
404+
405+
[TestMethod]
406+
public void TestAssignFunctionToParentLocal()
407+
{
408+
TestCode(@"
409+
local f
410+
function g()
411+
function f()
412+
return 'Hello'
413+
end
414+
end
415+
g()
416+
return f()
417+
",
418+
"Hello");
419+
}
420+
363421
[TestMethod]
364422
public void TestFunctionConvert01()
365423
{

NeoLua/Parser.cs

+27-9
Original file line numberDiff line numberDiff line change
@@ -2180,10 +2180,19 @@ private static void ParseFunction(Scope scope, ILuaLexer code, bool isLocal)
21802180
if (isLocal) // Local function, only one identifier is allowed
21812181
{
21822182
var t = FetchToken(LuaToken.Identifier, code);
2183-
ParameterExpression funcVar = null;
2184-
var exprFunction = ParseLamdaDefinition(scope, code, t.Value, false,
2185-
typeDelegate => funcVar = scope.RegisterVariable(typeDelegate, t.Value)
2186-
);
2183+
2184+
ParameterExpression funcVar = scope.LookupExpression(t.Value) as ParameterExpression;
2185+
Expression exprFunction;
2186+
if (funcVar == null)
2187+
{
2188+
exprFunction = ParseLamdaDefinition(scope, code, t.Value, false,
2189+
typeDelegate => funcVar = scope.RegisterVariable(typeDelegate, t.Value));
2190+
}
2191+
else
2192+
{
2193+
exprFunction = ParseLamdaDefinition(scope, code, t.Value, false, null);
2194+
}
2195+
21872196
scope.AddExpression(Expression.Assign(funcVar, exprFunction));
21882197
}
21892198
else // Function that is assigned to a table. A chain of identifiers is allowed.
@@ -2202,7 +2211,7 @@ private static void ParseFunction(Scope scope, ILuaLexer code, bool isLocal)
22022211
memberName = FetchToken(LuaToken.Identifier, code).Value;
22032212
}
22042213
// add a method to the table. methods get a hidden parameter and will bo marked
2205-
bool lMethodMember;
2214+
bool lMethodMember = false;
22062215
if (code.Current.Typ == LuaToken.Colon)
22072216
{
22082217
code.Next();
@@ -2216,8 +2225,17 @@ private static void ParseFunction(Scope scope, ILuaLexer code, bool isLocal)
22162225
else
22172226
{
22182227
if (assignee == null)
2228+
{
2229+
// there was no member access, so try to find a local to assign to
2230+
var local = scope.LookupExpression(memberName);
2231+
if (local is ParameterExpression)
2232+
{
2233+
scope.AddExpression(Expression.Assign(local, ParseLamdaDefinition(scope, code, memberName, false, null)));
2234+
return;
2235+
}
2236+
22192237
assignee = scope.LookupExpression(csEnv); // create a global function
2220-
lMethodMember = false;
2238+
}
22212239
}
22222240

22232241
// generate lambda
@@ -2295,7 +2313,7 @@ private static Expression ParseLamdaDefinition(Scope parent, ILuaLexer code, str
22952313
// register the delegate
22962314
if (functionTypeCollected != null)
22972315
{
2298-
var functionType = scope.ReturnType == typeof(void)
2316+
var functionType = scope.ReturnType == typeof(void)
22992317
? Expression.GetActionType((from p in parameters select p.Type).ToArray())
23002318
: Expression.GetFuncType((from p in parameters select p.Type).Concat(new Type[] { scope.ReturnType }).ToArray());
23012319
functionTypeCollected(functionType);
@@ -2428,7 +2446,7 @@ private static void ParseTableField(ParameterExpression tableVar, Scope scope, I
24282446

24292447
private static Expression CreateEmptyTableExpression()
24302448
=> Expression.New(typeof(LuaTable));
2431-
2449+
24322450
#endregion
24332451

24342452
#region -- FetchToken, ParseError ---------------------------------------------
@@ -2449,7 +2467,7 @@ public static Token FetchToken(LuaToken typ, ILuaLexer code, bool isOptional = f
24492467

24502468
public static LuaParseException ParseError(Token start, string message)
24512469
=> new LuaParseException(start.Start, message, null);
2452-
2470+
24532471
private static Exception ParseError(ILuaLexer code, string message = null)
24542472
{
24552473
switch (code.Current.Typ)

0 commit comments

Comments
 (0)