Statement ParseMemberAssignmentOrMethodCallStatement(string variable) { // assignment: // {variable} = {value} string dotType = fCurrentToken.Value; ReadNextToken(); // skip '.' MemberAccess ma = new MemberAccess(new Variable(variable, "var"), ParseDotExpression()); if (dotType == "[") SkipExpected(TokenType.Symbol, "]"); if (ma.RightChildExpression is MethodCall) return new MethodCallStatement(ma); else if(ma.RightChildExpression is FunctionCall) return new MethodCallStatement(ma); else return ParseMemberAssignment(ma, fCurrentToken.Value); }
Expression ParseDotExpression() { // DOT-expression: // {unary-expression} . {functionCallOrVariable} Expression lNode = ParseBaseExpression(); while (!AtEndOfSource && (fCurrentToken.Value == "." || fCurrentToken.Value == "[")) { string currToken = fCurrentToken.Value; if (currToken == ".") { ReadNextToken(); // skip '.' //if (fCurrentToken.Value == "$=") // return lNode; Expression exp = ParseVariableOrFunctionCall(); if (exp is FunctionCall) lNode = new MethodCall(lNode, exp); else lNode = new MemberAccess(lNode, exp); } else { ReadNextToken(); // skip '[' lNode = new IndexerAccess(lNode, ParseExpression()); SkipExpected(TokenType.Symbol, "]"); } } return lNode; }
MemberAssignment ParseMemberAssignment(MemberAccess variable, string op) { // assignment: // {variable} += {value} ReadNextToken(); // skip '+=' MemberAssignment a = null; if (op == "++" || op == "--") a = new MemberAssignment(variable, op, null); else a = new MemberAssignment(variable, op, ParseExpression()); return a; }
public override object Calculate(Context context, ParserNode parentNode) { object res = LeftChildExpression.Calculate(context, this); // eğer sonuç null ve LeftExp variable ise static call olabilir if (res == null && LeftChildExpression is Variable) { string className = (LeftChildExpression as Variable).Name; Type t = Context.GetType(className, context.Using); if (t != null) { if (RightChildExpression is Variable) { string propName = (RightChildExpression as Variable).Name; PropertyInfo pi = t.GetProperty(propName, BindingFlags.Static | BindingFlags.Public); if (pi != null) res = pi.GetValue(null, null); else { FieldInfo fi = t.GetField(propName); if (fi != null) res = fi.GetValue(null); else res = ""; } } else if (RightChildExpression is FunctionCall) { FunctionCall fc = (FunctionCall)RightChildExpression; object[] paramValues = new object[fc.Arguments.Length]; Type[] paramTypes = new Type[fc.Arguments.Length]; int i = 0; foreach (Expression exp in fc.Arguments) { paramValues[i] = exp.Calculate(context, this); paramTypes[i] = paramValues[i]==null ? null : paramValues[i].GetType(); i++; } //MethodInfo mi = t.GetMethod(fc.Name, BindingFlags.Static | BindingFlags.Public, null, paramTypes, null); MethodInfo mi = null; ParameterInfo[] arrPi; FindMethod(t, fc.Name, paramTypes, out mi, out arrPi, BindingFlags.Static | BindingFlags.Public); if (mi == null) throw new Exception("Undefined param types for static method: " + this); else res = mi.Invoke(null, paramValues); } else if (RightChildExpression is MemberAccess) { res = new MemberAccess(new MemberAccess(this.LeftChildExpression, (this.RightChildExpression as MemberAccess).LeftChildExpression), (this.RightChildExpression as MemberAccess).RightChildExpression).Calculate(context, this); } else res = null; } else throw new Exception("Undefined static method: " + this); } else if (RightChildExpression is MemberAccess) { res = new MemberAccess(new MemberAccess(this.LeftChildExpression, (this.RightChildExpression as MemberAccess).LeftChildExpression), (this.RightChildExpression as MemberAccess).RightChildExpression).Calculate(context, this); } else if (RightChildExpression is FunctionCall) { FunctionCall fc = (FunctionCall)RightChildExpression; List<object> paramValues = new List<object>(); List<Type> paramTypes = new List<Type>(); int i = 0; foreach (Expression exp in fc.Arguments) { paramValues.Add(exp.Calculate(context, this)); paramTypes.Add(paramValues[i] == null ? typeof(object) : paramValues[i].GetType()); i++; } if (res is string) { switch (fc.Name.ToLowerInvariant()) { case "split": return res.ToString().Split(new string[] { paramValues[0].ToString() }, StringSplitOptions.RemoveEmptyEntries); } } //MethodInfo mi = res.GetType().GetMethod(fc.Name, paramTypes); MethodInfo mi = null; ParameterInfo[] pinfo = null; FindMethod(res.GetType(), fc.Name, paramTypes.ToArray(), out mi, out pinfo); if (mi == null) throw new Exception("Undefined method: " + this); else { if (mi.GetParameters().Length > paramTypes.Count) { paramTypes.Add(typeof(object[])); paramValues.Add(new object[0]); } for (int j = 0; j < paramTypes.Count; j++) { try { if(!paramTypes[j].IsSubclassOf(pinfo[j].ParameterType)) paramValues[j] = paramValues[j].ChangeType(pinfo[j].ParameterType); } catch { throw new Exception("Cannot convert from " + paramValues[j].GetType().Name + " to " + pinfo[j].ParameterType.Name + " or undefined method: " + this); } } res = mi.Invoke(res, paramValues.ToArray()); } } else if (RightChildExpression is Variable) { Variable var = (Variable)RightChildExpression; PropertyInfo pi = res.GetType().GetProperty(var.Name); if (pi != null) { try { res = pi.GetValue(res, null); } catch(Exception ex) { throw new Exception("Property found but couldnt be read: " + this + " (" + (ex.InnerException != null ? ex.InnerException.Message : ex.Message) + ")"); } } else { FieldInfo fi = res.GetType().GetField(var.Name); if (fi != null) { try { res = fi.GetValue(res); } catch(Exception ex) { throw new Exception("Field found but couldnt be read: " + this + " (" + (ex.InnerException != null ? ex.InnerException.Message : ex.Message) + ")"); } } else { MethodInfo mi = res.GetType().GetMethod("get_Item", new Type[] { typeof(string) }); if (mi != null) { try { object paramObj = var.Name.ChangeType(mi.GetParameters()[0].ParameterType); res = mi.Invoke(res, new object[] { paramObj }); } catch(Exception ex) { throw new Exception("Indexer found but couldnt be read: " + this + " (" + (ex.InnerException != null ? ex.InnerException.Message : ex.Message) + ")"); } } else throw new Exception("Undefined property, field or indexer parameter: " + this); } } } else { object val = RightChildExpression.Calculate(context, this); if (val.IsNumeric() && res.GetType() == typeof(string)) res = res.ToString()[Convert.ToInt32(val)]; else res = res.GetIndexedValue(val); } return res; }