private void ReplaceExpressionClassAccess(KecaknoahExpressionAstNode node, bool isStatic, string className, IList<string> instanceMethods, IList<string> staticMethods, IList<string> Locals) { Action<KecaknoahExpressionAstNode> curry = (p) => ReplaceExpressionClassAccess(p, isStatic, className, instanceMethods, staticMethods, Locals); if (node is KecaknoahBinaryExpressionAstNode) { var bn = (KecaknoahBinaryExpressionAstNode)node; curry(bn.FirstNode); curry(bn.SecondNode); } else if (node is KecaknoahFactorExpressionAstNode) { var f = (KecaknoahFactorExpressionAstNode)node; if (f.FactorType == KecaknoahFactorType.Identifer) { if (!isStatic && (instanceMethods.Contains(f.StringValue) || Locals.Contains(f.StringValue))) { var newfac = new KecaknoahMemberAccessExpressionAstNode(); newfac.MemberName = f.StringValue; newfac.Target = new KecaknoahFactorExpressionAstNode { FactorType = KecaknoahFactorType.Identifer, StringValue = "self" }; f.FactorType = KecaknoahFactorType.ParenExpression; f.ExpressionNode = newfac; } if (staticMethods.Contains(f.StringValue)) { //サブクラスも含む、そのうちね var newfac = new KecaknoahMemberAccessExpressionAstNode(); newfac.MemberName = f.StringValue; newfac.Target = new KecaknoahFactorExpressionAstNode { FactorType = KecaknoahFactorType.Identifer, StringValue = className }; f.FactorType = KecaknoahFactorType.ParenExpression; f.ExpressionNode = newfac; } } } else if (node is KecaknoahArgumentCallExpressionAstNode) { var ac = (KecaknoahArgumentCallExpressionAstNode)node; curry(ac.Target); foreach (var i in ac.Arguments) curry(i); } else if (node is KecaknoahPrimaryExpressionAstNode) { curry(((KecaknoahPrimaryExpressionAstNode)node).Target); } else if (node is KecaknoahUnaryExpressionAstNode) { curry(((KecaknoahUnaryExpressionAstNode)node).Target); } }
private bool CheckStatementExpression(KecaknoahExpressionAstNode node) { if (node is KecaknoahArgumentCallExpressionAstNode && (node as KecaknoahArgumentCallExpressionAstNode).ExpressionType == KecaknoahOperatorType.FunctionCall) return true; var bn = node as KecaknoahBinaryExpressionAstNode; if (bn == null) return false; switch (bn.ExpressionType) { case KecaknoahOperatorType.Assign: case KecaknoahOperatorType.PlusAssign: case KecaknoahOperatorType.MinusAssign: case KecaknoahOperatorType.MultiplyAssign: case KecaknoahOperatorType.DivideAssign: case KecaknoahOperatorType.AndAssign: case KecaknoahOperatorType.OrAssign: case KecaknoahOperatorType.XorAssign: case KecaknoahOperatorType.LeftBitShiftAssign: case KecaknoahOperatorType.RightBitShiftAssign: case KecaknoahOperatorType.NilAssign: return true; } return false; }
private int CheckLocalReference(KecaknoahExpressionAstNode exp, IList<string> args) { if (exp is KecaknoahFactorExpressionAstNode) { var fc = (KecaknoahFactorExpressionAstNode)exp; switch (fc.FactorType) { case KecaknoahFactorType.BooleanValue: case KecaknoahFactorType.DoubleValue: case KecaknoahFactorType.IntegerValue: case KecaknoahFactorType.Nil: case KecaknoahFactorType.StringValue: case KecaknoahFactorType.SingleValue: return 0; case KecaknoahFactorType.CoroutineResume: case KecaknoahFactorType.VariableArguments: throw new ArgumentException("ラムダ式はcoresume・VARGSを内包できません。"); case KecaknoahFactorType.Array: return fc.ElementNodes.Max(p => CheckLocalReference(p, args)); case KecaknoahFactorType.Identifer: if (args.Contains(fc.StringValue)) return 0; if (fc.StringValue == "self") return 1; return 2; case KecaknoahFactorType.Lambda: case KecaknoahFactorType.ParenExpression: return CheckLocalReference(fc.ExpressionNode, args); default: return 0; } } else if (exp is KecaknoahPrimaryExpressionAstNode) { return CheckLocalReference((exp as KecaknoahPrimaryExpressionAstNode).Target, args); } else if (exp is KecaknoahUnaryExpressionAstNode) { return CheckLocalReference((exp as KecaknoahUnaryExpressionAstNode).Target, args); } else if (exp is KecaknoahBinaryExpressionAstNode) { var be = (KecaknoahBinaryExpressionAstNode)exp; return Math.Max(CheckLocalReference(be.FirstNode, args), CheckLocalReference(be.SecondNode, args)); } else { return 0; } }