private ScriptVarLink FunctionCall(ref bool execute, ScriptVarLink function, ScriptVar parent) { if (execute) { if (!function.Var.IsFunction) { throw new ScriptException(String.Format("{0} is not a function", function.Name)); } currentLexer.Match((ScriptLex.LexTypes) '('); var functionRoot = new ScriptVar(null, ScriptVar.Flags.Function); if (parent != null) { functionRoot.AddChildNoDup("this", parent); } var v = function.Var.FirstChild; while (v != null) { var value = Base(ref execute); if (execute) { if (value.Var.IsBasic) { //pass by val functionRoot.AddChild(v.Name, value.Var.DeepCopy()); } else { //pass by ref functionRoot.AddChild(v.Name, value.Var); } } if (currentLexer.TokenType != (ScriptLex.LexTypes) ')') { currentLexer.Match((ScriptLex.LexTypes) ','); } v = v.Next; } currentLexer.Match((ScriptLex.LexTypes) ')'); var returnVarLink = functionRoot.AddChild(ScriptVar.ReturnVarName, null); scopes.PushBack(functionRoot); //callStack.PushBack(string.Format("{0} from line {1}", function.Name, currentLexer.LineNumber)); callStack.Push(function); if (function.Var.IsNative) { var func = function.Var.GetCallback(); func?.Invoke(functionRoot, function.Var.GetCallbackUserData()); } else { var oldLex = currentLexer; var newLex = new ScriptLex(function.Var.String); currentLexer = newLex; try { Block(ref execute); execute = true; } catch { throw; } finally { currentLexer = oldLex; } } callStack.Pop(); scopes.PopBack(); var returnVar = new ScriptVarLink(returnVarLink.Var, null); functionRoot.RemoveLink(returnVarLink); return(returnVar); } else { //not executing the function, just parsing it out currentLexer.Match((ScriptLex.LexTypes) '('); while (currentLexer.TokenType != (ScriptLex.LexTypes) ')') { Base(ref execute); if (currentLexer.TokenType != (ScriptLex.LexTypes) ')') { currentLexer.Match((ScriptLex.LexTypes) ','); } } currentLexer.Match((ScriptLex.LexTypes) ')'); if (currentLexer.TokenType == (ScriptLex.LexTypes) '{') //WTF? { Block(ref execute); } return(function); } }
private ScriptVarLink FunctionCall(ref bool execute, ScriptVarLink function, ScriptVar parent) { if (execute) { if (!function.Var.IsFunction) { throw new ScriptException(String.Format("{0} is not a function", function.Name)); } _currentLexer.Match((ScriptLex.LexTypes) '('); ScriptVar functionRoot = new ScriptVar(null, ScriptVar.Flags.Function); if (parent != null) { functionRoot.AddChildNoDup("this", parent); } ScriptVarLink v = function.Var.FirstChild; while (v != null) { ScriptVarLink value = Base(ref execute); if (value.Var.IsBasic) { //pass by val functionRoot.AddChild(v.Name, value.Var.DeepCopy()); } else { //pass by ref functionRoot.AddChild(v.Name, value.Var); } if (_currentLexer.TokenType != (ScriptLex.LexTypes) ')') { _currentLexer.Match((ScriptLex.LexTypes) ','); } v = v.Next; } _currentLexer.Match((ScriptLex.LexTypes) ')'); ScriptVarLink returnVarLink = functionRoot.AddChild(ScriptVar.ReturnVarName, null); _scopes.Push(functionRoot); _callStack.Push(String.Format("{0} from line {1}", function.Name, _currentLexer.LineNumber)); if (function.Var.IsNative) { ScriptCallbackCB func = function.Var.GetCallback(); if (func != null) { func(functionRoot, function.Var.GetCallbackUserData(), parent); } } else { ScriptException ex = null; ScriptLex oldLex = _currentLexer; ScriptLex newLex = new ScriptLex(function.Var.GetString()); _currentLexer = newLex; try { Block(ref execute); execute = true; } catch (ScriptException e) { ex = e; } _currentLexer = oldLex; if (ex != null) { throw ex; } } _callStack.Pop(); _scopes.Pop(); ScriptVarLink returnVar = new ScriptVarLink(returnVarLink.Var, null); functionRoot.RemoveLink(returnVarLink); return(returnVar); } //not executing the function, just parsing it out _currentLexer.Match((ScriptLex.LexTypes) '('); while (_currentLexer.TokenType != (ScriptLex.LexTypes) ')') { Base(ref execute); if (_currentLexer.TokenType != (ScriptLex.LexTypes) ')') { _currentLexer.Match((ScriptLex.LexTypes) ','); } } _currentLexer.Match((ScriptLex.LexTypes) ')'); if (_currentLexer.TokenType == (ScriptLex.LexTypes) '{') //WTF? { Block(ref execute); } return(function); }