protected void CopySimpleData(ScriptVar val) { data = val.data; intData = val.intData; doubleData = val.doubleData; flags = (flags & ~Flags.VarTypeMask) | (val.flags & Flags.VarTypeMask); }
public void ReplaceWith(ScriptVar newVar) { ScriptVar oldVar = Var; Var = newVar.Ref(); oldVar.UnRef(); }
public void AddNativeProperty(string propertyDesc, ScriptCallbackCB callbackCB, object userData) { var oldLex = currentLexer; currentLexer = new ScriptLex(propertyDesc); var baseVar = Root; var propName = currentLexer.TokenString; currentLexer.Match(ScriptLex.LexTypes.Id); while (currentLexer.TokenType == (ScriptLex.LexTypes) '.') { currentLexer.Match((ScriptLex.LexTypes) '.'); var link = baseVar.FindChild(propName); if (link == null) { link = baseVar.AddChild(propName, new ScriptVar(null, ScriptVar.Flags.Object)); } baseVar = link.Var; propName = currentLexer.TokenString; currentLexer.Match(ScriptLex.LexTypes.Id); } var propVar = new ScriptVar(); callbackCB.Invoke(propVar, null); currentLexer = oldLex; baseVar.AddChild(propName, propVar); }
public ScriptVarLink AddChild(string childName, ScriptVar child, bool readOnly = false) { if (IsUndefined) { flags = Flags.Object; } var c = child ?? new ScriptVar(); var link = new ScriptVarLink(c, childName, readOnly) { Owned = true }; if (LastChild != null) { LastChild.Next = link; link.Prev = LastChild; LastChild = link; } else { FirstChild = link; LastChild = link; } return(link); }
protected void CopySimpleData(ScriptVar val) { _data = val._data; _intData = val._intData; _doubleData = val._doubleData; _flags = (_flags & ~Flags.VarTypeMask) | (val._flags & Flags.VarTypeMask); }
public ScriptVarLink AddChild(String childName, ScriptVar child) { if (IsUndefined) { _flags = Flags.Object; } ScriptVar c = child ?? new ScriptVar(); ScriptVarLink link = new ScriptVarLink(c, childName) { Owned = true }; if (LastChild != null) { LastChild.Next = link; link.Prev = LastChild; LastChild = link; } else { FirstChild = link; LastChild = link; } return(link); }
public ScriptVarLink(ScriptVar var, String name) { Name = name; Var = var.Ref(); Next = null; Prev = null; Owned = false; }
public ScriptVarLink(ScriptVar var, string name, bool readOnly = false) { Name = name; Var = var.Ref(); Next = null; Prev = null; Owned = false; IsConst = readOnly; }
public bool Equal(ScriptVar v) { bool res; using (ScriptVar resV = MathsOp(v, ScriptLex.LexTypes.Equal)) { res = resV.GetBool(); } return(res); }
private void CreateLink(ref ScriptVarLink link, ScriptVar res) { if (link == null || link.Owned) { link = new ScriptVarLink(res, null); } else { link.ReplaceWith(res); } }
public void ReplaceWith(ScriptVar newVar) { if (IsConst && Var?.IsUndefined == false) { throw new JITException(string.Format("{0} is const, cannot assign a new value", Name)); } var oldVar = Var; Var = newVar.Ref(); oldVar.UnRef(); }
private void ParseFunctionArguments(ScriptVar funcVar) { _currentLexer.Match((ScriptLex.LexTypes) '('); while (_currentLexer.TokenType != (ScriptLex.LexTypes) ')') { funcVar.AddChildNoDup(_currentLexer.TokenString, null); _currentLexer.Match(ScriptLex.LexTypes.Id); if (_currentLexer.TokenType != (ScriptLex.LexTypes) ')') { _currentLexer.Match((ScriptLex.LexTypes) ','); } } _currentLexer.Match((ScriptLex.LexTypes) ')'); }
public void RemoveChild(ScriptVar child) { ScriptVarLink link = FirstChild; while (link != null) { if (link.Var == child) { break; } link = link.Next; } RemoveLink(link); }
public ScriptEngine() { currentLexer = null; scopes = new List <ScriptVar>(); callStack = new Stack <ScriptVarLink>(); Root = (new ScriptVar(null, ScriptVar.Flags.Object)).Ref(); objectClass = (new ScriptVar(null, ScriptVar.Flags.Object)).Ref(); stringClass = (new ScriptVar(null, ScriptVar.Flags.Object)).Ref(); arrayClass = (new ScriptVar(null, ScriptVar.Flags.Object)).Ref(); Root.AddChild("Object", objectClass); Root.AddChild("String", stringClass); Root.AddChild("Array", arrayClass); }
public void AddMethod(String funcName, String[] args, ScriptCallbackCB callback, Object userdata) { ScriptVar funcVar = new ScriptVar(null, ScriptVar.Flags.Function | ScriptVar.Flags.Native); funcVar.SetCallback(callback, userdata); //do we have any arguments to create? if (args != null) { foreach (string arg in args) { funcVar.AddChildNoDup(arg, null); } } Root.AddChild(funcName, funcVar); }
public ScriptVarLink AddChildNoDup(String childName, ScriptVar child) { ScriptVar c = child ?? new ScriptVar(); ScriptVarLink v = FindChild(childName); if (v != null) { v.ReplaceWith(c); } else { v = AddChild(childName, c); } return(v); }
public ScriptVar DeepCopy() { ScriptVar newVar = new ScriptVar(); newVar.CopySimpleData(this); ScriptVarLink link = FirstChild; while (link != null) { ScriptVar copied = link.Name != PrototypeClassName?link.Var.DeepCopy() : link.Var; newVar.AddChild(link.Name, copied); link = link.Next; } return(newVar); }
private ScriptVarLink FindInParentClasses(ScriptVar obj, String name) { ScriptVarLink implementation; ScriptVarLink parentClass = obj.FindChild(ScriptVar.PrototypeClassName); while (parentClass != null) { implementation = parentClass.Var.FindChild(name); if (implementation != null) { return(implementation); } parentClass = parentClass.Var.FindChild(ScriptVar.PrototypeClassName); } if (obj.IsString) { implementation = _stringClass.FindChild(name); if (implementation != null) { return(implementation); } } if (obj.IsArray) { implementation = _arrayClass.FindChild(name); if (implementation != null) { return(implementation); } } implementation = _objectClass.FindChild(name); if (implementation != null) { return(implementation); } return(null); }
public void AddObject(String[] ns, String objectName, ScriptVar val) { ScriptVar baseVar = Root; if (ns != null) { int x = 0; for (; x < ns.Length; x++) { ScriptVarLink link = baseVar.FindChild(ns[x]); if (link == null) { link = baseVar.AddChild(ns[x], new ScriptVar(null, ScriptVar.Flags.Object)); } baseVar = link.Var; } } baseVar.AddChild(objectName, val); }
public ScriptEngine(bool loadProviders = true) { _currentLexer = null; _scopes = new Stack <ScriptVar>(); _callStack = new Stack <string>(); Root = (new ScriptVar(null, ScriptVar.Flags.Object)).Ref(); _stringClass = (new ScriptVar(null, ScriptVar.Flags.Object)).Ref(); _objectClass = (new ScriptVar(null, ScriptVar.Flags.Object)).Ref(); _arrayClass = (new ScriptVar(null, ScriptVar.Flags.Object)).Ref(); Root.AddChild("String", _stringClass); Root.AddChild("Object", _objectClass); Root.AddChild("Array", _arrayClass); if (loadProviders) { LoadAllFunctionProviders(); } }
public void CopyValue(ScriptVar val) { if (val != null) { CopySimpleData(val); RemoveAllChildren(); ScriptVarLink link = val.FirstChild; while (link != null) { ScriptVar copied = link.Name != PrototypeClassName?link.Var.DeepCopy() : link.Var; AddChild(link.Name, copied); link = link.Next; } } else { SetUndefined(); } }
public void SetArrayIndex(Int32 idx, ScriptVar value) { ScriptVarLink link = FindChild(String.Format("{0}", idx)); if (link != null) { if (value.IsUndefined) { RemoveLink(link); } else { link.ReplaceWith(value); } } else { if (!value.IsUndefined) { AddChild(String.Format("{0}", idx), value); } } }
public void AddMethod(String funcProto, ScriptCallbackCB callback, Object userdata) { ScriptLex oldLex = _currentLexer; using (_currentLexer = new ScriptLex(funcProto)) { ScriptVar baseVar = Root; _currentLexer.Match(ScriptLex.LexTypes.RFunction); String funcName = _currentLexer.TokenString; _currentLexer.Match(ScriptLex.LexTypes.Id); while (_currentLexer.TokenType == (ScriptLex.LexTypes) '.') { _currentLexer.Match((ScriptLex.LexTypes) '.'); ScriptVarLink link = baseVar.FindChild(funcName); if (link == null) { link = baseVar.AddChild(funcName, new ScriptVar(null, ScriptVar.Flags.Object)); } baseVar = link.Var; funcName = _currentLexer.TokenString; _currentLexer.Match(ScriptLex.LexTypes.Id); } ScriptVar funcVar = new ScriptVar(null, ScriptVar.Flags.Function | ScriptVar.Flags.Native); funcVar.SetCallback(callback, userdata); ParseFunctionArguments(funcVar); baseVar.AddChild(funcName, funcVar); } _currentLexer = oldLex; }
public void AddMethod(String[] ns, String funcName, String[] args, ScriptCallbackCB callback, Object userdata) { String fName = funcName; ScriptVar baseVar = Root; if (ns != null) { int x = 0; for (; x < ns.Length; x++) { ScriptVarLink link = baseVar.FindChild(ns[x]); if (link == null) { link = baseVar.AddChild(ns[x], new ScriptVar(null, ScriptVar.Flags.Object)); } baseVar = link.Var; } } ScriptVar funcVar = new ScriptVar(null, ScriptVar.Flags.Function | ScriptVar.Flags.Native); funcVar.SetCallback(callback, userdata); //do we have any arguments to create? if (args != null) { foreach (string arg in args) { funcVar.AddChildNoDup(arg, null); } } baseVar.AddChild(fName, funcVar); }
public void AddNative(string funcDesc, ScriptCallbackCB callbackCB, object userData) { var oldLex = currentLexer; currentLexer = new ScriptLex(funcDesc); var baseVar = Root; currentLexer.Match(ScriptLex.LexTypes.RFunction); var funcName = currentLexer.TokenString; currentLexer.Match(ScriptLex.LexTypes.Id); while (currentLexer.TokenType == (ScriptLex.LexTypes) '.') { currentLexer.Match((ScriptLex.LexTypes) '.'); var link = baseVar.FindChild(funcName); if (link == null) { link = baseVar.AddChild(funcName, new ScriptVar(null, ScriptVar.Flags.Object)); } baseVar = link.Var; funcName = currentLexer.TokenString; currentLexer.Match(ScriptLex.LexTypes.Id); } var funcVar = new ScriptVar(null, ScriptVar.Flags.Function | ScriptVar.Flags.Native); funcVar.SetCallback(callbackCB, userData); ParseFunctionArguments(funcVar); currentLexer = oldLex; baseVar.AddChild(funcName, funcVar); }
public ScriptVar MathsOp(ScriptVar b, ScriptLex.LexTypes op) { ScriptVar a = this; char opc = (char)op; if (op == ScriptLex.LexTypes.TypeEqual || op == ScriptLex.LexTypes.NTypeEqual) { bool equal = ((a._flags & Flags.VarTypeMask) == (b._flags & Flags.VarTypeMask)); if (equal) { ScriptVar contents = a.MathsOp(b, ScriptLex.LexTypes.Equal); if (!contents.GetBool()) { equal = false; } } if (op == ScriptLex.LexTypes.TypeEqual) { return(new ScriptVar(equal)); } return(new ScriptVar(!equal)); } if (a.IsUndefined && b.IsUndefined) { if (op == ScriptLex.LexTypes.Equal) { return(new ScriptVar(true)); } if (op == ScriptLex.LexTypes.NEqual) { return(new ScriptVar(false)); } return(new ScriptVar()); } if ((a.IsNumeric || a.IsUndefined) && (b.IsNumeric || b.IsUndefined)) { if (!a.IsDouble && !b.IsDouble) { //ints int da = a.GetInt(); int db = b.GetInt(); switch (opc) { case '+': return(new ScriptVar(da + db)); case '-': return(new ScriptVar(da - db)); case '*': return(new ScriptVar(da * db)); case '/': return(new ScriptVar(da / db)); case '&': return(new ScriptVar(da & db)); case '|': return(new ScriptVar(da | db)); case '^': return(new ScriptVar(da ^ db)); case '%': return(new ScriptVar(da % db)); case (char)ScriptLex.LexTypes.Equal: return(new ScriptVar(da == db)); case (char)ScriptLex.LexTypes.NEqual: return(new ScriptVar(da != db)); case '<': return(new ScriptVar(da < db)); case (char)ScriptLex.LexTypes.LEqual: return(new ScriptVar(da <= db)); case '>': return(new ScriptVar(da > db)); case (char)ScriptLex.LexTypes.GEqual: return(new ScriptVar(da >= db)); default: throw new ScriptException("Operation not supported on the Int datatype"); } } else { //doubles double da = a.GetDouble(); double db = b.GetDouble(); switch (opc) { case '+': return(new ScriptVar(da + db)); case '-': return(new ScriptVar(da - db)); case '*': return(new ScriptVar(da * db)); case '/': return(new ScriptVar(da / db)); case (char)ScriptLex.LexTypes.Equal: return(new ScriptVar(da == db)); case (char)ScriptLex.LexTypes.NEqual: return(new ScriptVar(da != db)); case '<': return(new ScriptVar(da < db)); case (char)ScriptLex.LexTypes.LEqual: return(new ScriptVar(da <= db)); case '>': return(new ScriptVar(da > db)); case (char)ScriptLex.LexTypes.GEqual: return(new ScriptVar(da >= db)); default: throw new ScriptException("Operation not supported on the Int datatype"); } } } if (a.IsArray) { switch (op) { case ScriptLex.LexTypes.Equal: return(new ScriptVar(a == b)); case ScriptLex.LexTypes.NEqual: return(new ScriptVar(a != b)); default: throw new ScriptException("Operation not supported on the Array datatype"); } } if (a.IsObject) { switch (op) { case ScriptLex.LexTypes.Equal: return(new ScriptVar(a == b)); case ScriptLex.LexTypes.NEqual: return(new ScriptVar(a != b)); default: throw new ScriptException("Operation not supported on the Object datatype"); } } string sda = a.GetString(); string sdb = b.GetString(); switch (opc) { case '+': return(new ScriptVar(sda + sdb, Flags.String)); case (char)ScriptLex.LexTypes.Equal: return(new ScriptVar(sda == sdb)); case (char)ScriptLex.LexTypes.NEqual: return(new ScriptVar(sda != sdb)); case '<': return(new ScriptVar(String.CompareOrdinal(sda, sdb) < 0)); case (char)ScriptLex.LexTypes.LEqual: return(new ScriptVar((String.CompareOrdinal(sda, sdb) < 0) || sda == sdb)); case '>': return(new ScriptVar(String.CompareOrdinal(sda, sdb) > 0)); case (char)ScriptLex.LexTypes.GEqual: return(new ScriptVar((String.CompareOrdinal(sda, sdb) > 0) || sda == sdb)); default: throw new ScriptException("Operation not supported on the String datatype"); } }
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); }
private void Statement(ref bool execute) { if (_currentLexer.TokenType == ScriptLex.LexTypes.Id || _currentLexer.TokenType == ScriptLex.LexTypes.Int || _currentLexer.TokenType == ScriptLex.LexTypes.Float || _currentLexer.TokenType == ScriptLex.LexTypes.Str || _currentLexer.TokenType == (ScriptLex.LexTypes) '-') { //execite a basic statement Base(ref execute); _currentLexer.Match((ScriptLex.LexTypes) ';'); } else if (_currentLexer.TokenType == (ScriptLex.LexTypes) '{') { //code block Block(ref execute); } else if (_currentLexer.TokenType == (ScriptLex.LexTypes) ';') { //allow for multiple semi colon such as ;;; _currentLexer.Match((ScriptLex.LexTypes) ';'); } else if (_currentLexer.TokenType == ScriptLex.LexTypes.RVar) { //creating variables //TODO: make this less shit _currentLexer.Match(ScriptLex.LexTypes.RVar); while (_currentLexer.TokenType != (ScriptLex.LexTypes) ';') { ScriptVarLink a = null; if (execute) { a = _scopes.Peek().FindChildOrCreate(_currentLexer.TokenString); } _currentLexer.Match(ScriptLex.LexTypes.Id); //get through the dots while (_currentLexer.TokenType == (ScriptLex.LexTypes) '.') { _currentLexer.Match((ScriptLex.LexTypes) '.'); if (execute) { ScriptVarLink aLast = a; if (aLast != null) { a = aLast.Var.FindChildOrCreate(_currentLexer.TokenString); } } _currentLexer.Match(ScriptLex.LexTypes.Id); } //initialiser if (_currentLexer.TokenType == (ScriptLex.LexTypes) '=') { _currentLexer.Match((ScriptLex.LexTypes) '='); ScriptVarLink varLink = Base(ref execute); if (execute) { if (a != null) { a.ReplaceWith(varLink); } } } if (_currentLexer.TokenType != (ScriptLex.LexTypes) ';') { _currentLexer.Match((ScriptLex.LexTypes) ','); } } _currentLexer.Match((ScriptLex.LexTypes) ';'); } else if (_currentLexer.TokenType == ScriptLex.LexTypes.RIf) { //if condition _currentLexer.Match(ScriptLex.LexTypes.RIf); _currentLexer.Match((ScriptLex.LexTypes) '('); ScriptVarLink varLink = Base(ref execute); _currentLexer.Match((ScriptLex.LexTypes) ')'); bool condition = execute && varLink.Var.GetBool(); bool noExecute = false; if (condition) { Statement(ref execute); } else { Statement(ref noExecute); } if (_currentLexer.TokenType == ScriptLex.LexTypes.RElse) { //else part of an if _currentLexer.Match(ScriptLex.LexTypes.RElse); if (condition) { Statement(ref noExecute); } else { Statement(ref execute); } } } else if (_currentLexer.TokenType == ScriptLex.LexTypes.RWhile) { //while loop _currentLexer.Match(ScriptLex.LexTypes.RWhile); _currentLexer.Match((ScriptLex.LexTypes) '('); Int32 whileConditionStart = _currentLexer.TokenStart; ScriptVarLink condition = Base(ref execute); bool loopCondition = execute && condition.Var.GetBool(); ScriptLex whileCond = _currentLexer.GetSubLex(whileConditionStart); _currentLexer.Match((ScriptLex.LexTypes) ')'); Int32 whileBodyStart = _currentLexer.TokenStart; Statement(ref loopCondition); ScriptLex whileBody = _currentLexer.GetSubLex(whileBodyStart); ScriptLex oldLex = _currentLexer; //TODO: possible maximum itteration limit? while (loopCondition) { whileCond.Reset(); _currentLexer = whileCond; condition = Base(ref execute); loopCondition = condition.Var.GetBool(); if (loopCondition) { whileBody.Reset(); _currentLexer = whileBody; Statement(ref execute); } } _currentLexer = oldLex; } else if (_currentLexer.TokenType == ScriptLex.LexTypes.RFor) { //for loop _currentLexer.Match(ScriptLex.LexTypes.RFor); _currentLexer.Match((ScriptLex.LexTypes) '('); Statement(ref execute); //init int forConditionStart = _currentLexer.TokenStart; ScriptVarLink condition = Base(ref execute); bool noExecute = false; bool loopCondition = execute && condition.Var.GetBool(); ScriptLex forCondition = _currentLexer.GetSubLex(forConditionStart); _currentLexer.Match((ScriptLex.LexTypes) ';'); int forIterStart = _currentLexer.TokenStart; Base(ref noExecute); ScriptLex forIter = _currentLexer.GetSubLex(forIterStart); _currentLexer.Match((ScriptLex.LexTypes) ')'); int forBodyStart = _currentLexer.TokenStart; if (loopCondition) { Statement(ref execute); } else { Statement(ref noExecute); } ScriptLex forBody = _currentLexer.GetSubLex(forBodyStart); ScriptLex oldLex = _currentLexer; if (loopCondition) { forIter.Reset(); _currentLexer = forIter; Base(ref execute); } //TODO: limit number of iterations? while (execute && loopCondition) { forCondition.Reset(); _currentLexer = forCondition; condition = Base(ref execute); loopCondition = condition.Var.GetBool(); if (execute && loopCondition) { forBody.Reset(); _currentLexer = forBody; Statement(ref execute); } if (execute && loopCondition) { forIter.Reset(); _currentLexer = forIter; Base(ref execute); } } _currentLexer = oldLex; } else if (_currentLexer.TokenType == ScriptLex.LexTypes.RReturn) { _currentLexer.Match(ScriptLex.LexTypes.RReturn); ScriptVarLink res = null; if (_currentLexer.TokenType != (ScriptLex.LexTypes) ';') { res = Base(ref execute); } if (execute) { ScriptVarLink resultVar = _scopes.Peek().FindChild(ScriptVar.ReturnVarName); if (resultVar != null) { resultVar.ReplaceWith(res); } else { //return statement outside of function??? System.Diagnostics.Trace.TraceWarning("Return statement outside of a function, what is going on?"); } } execute = false; _currentLexer.Match((ScriptLex.LexTypes) ';'); } else if (_currentLexer.TokenType == ScriptLex.LexTypes.RFunction) { //function ScriptVarLink funcVar = ParseFunctionDefinition(); if (execute) { if (funcVar.Name == String.Empty) { //functions must have a name at statement level } else { ScriptVar v = _scopes.Peek(); v.AddChildNoDup(funcVar.Name, funcVar.Var); } } } else { _currentLexer.Match(ScriptLex.LexTypes.Eof); } }
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); } }
public void SetReturnVar(ScriptVar var) { FindChildOrCreate(ReturnVarName).ReplaceWith(var); }