private static string GetMemberPathCore(Exp exp) { var sb = new StringBuilder(); var curExp = exp; while (true) { switch (curExp.Type) { case ExpType.IdentifierExpression: sb.Append(curExp.ToIdentifier().Identifier); return(sb.ToString()); case ExpType.BinaryOperatorExpression: var binOpExp = curExp.ToBinaryOperator(); if (binOpExp.Operator != MemberOperator || binOpExp.LeftOperand.Type != ExpType.IdentifierExpression) { return(null); } sb.Append($".{binOpExp.LeftOperand.ToIdentifier().Identifier}"); curExp = binOpExp.RightOperand; break; default: return(null); } } }
protected override List <AphidExpression> MutateCore(AphidExpression expression, out bool hasChanged) { LoadScriptExpression loadExp; AphidExpression scriptExp; if (expression.Type != AphidExpressionType.LoadScriptExpression) { hasChanged = false; return(null); } else if ((loadExp = (LoadScriptExpression)expression).FileExpression.Type != AphidExpressionType.StringExpression) { var constantFolder = new ConstantFoldingMutator(); var mutated = constantFolder.Mutate(new List <AphidExpression> { loadExp.FileExpression }); if (mutated.Count != 1 || (scriptExp = mutated[0]).Type != AphidExpressionType.StringExpression) { hasChanged = false; return(null); //throw new AphidParserException("Invalid load script operand", loadExp); } } else { scriptExp = loadExp.FileExpression; } var scriptStr = StringParser.Parse(((StringExpression)scriptExp).Value); var script = Loader.FindScriptFile(_applicationDirectory, scriptStr); if (!File.Exists(script)) { throw new AphidParserException( string.Format( "Could not find script {0}", scriptStr), scriptExp); } Included.Add(script); List <AphidExpression> ast; if (AphidConfig.Current.ScriptCaching && !DisableCaching) { AphidByteCodeCache cache; if (UseImplicitReturns) { cache = new AphidByteCodeCache(Loader.SearchPaths.ToArray()); } else { cache = new AphidByteCodeCache(Loader.SearchPaths.ToArray(), 0x1); } ast = cache.Read(script, out var cacheSources); for (var i = 0; i < cacheSources.Length; i++) { Included.Add(cacheSources[i].Name); } } else { var code = AphidScript.Read(script); ast = AphidParser.Parse(code, script, useImplicitReturns: UseImplicitReturns); } if (PerformCommonTransformations) { var mutatedAst = new PartialOperatorMutator().Mutate(ast); mutatedAst = new AphidMacroMutator().Mutate(mutatedAst); mutatedAst = new AphidPreprocessorDirectiveMutator().Mutate(mutatedAst); mutatedAst = new ConstantFoldingMutator().Mutate(mutatedAst); hasChanged = true; return(mutatedAst); } hasChanged = true; return(ast); }
protected override List <AphidExpression> MutateCore(AphidExpression expression, out bool hasChanged) { LoadScriptExpression loadExp; AphidExpression scriptExp; if (expression.Type != AphidExpressionType.LoadScriptExpression) { hasChanged = false; return(null); } else if ((loadExp = (LoadScriptExpression)expression).FileExpression.Type != AphidExpressionType.StringExpression) { var mutated = new ConstantFoldingMutator() .MutateSingle(loadExp.FileExpression); if ((scriptExp = mutated).Type != AphidExpressionType.StringExpression) { hasChanged = false; return(null); //throw new AphidParserException("Invalid load script operand", loadExp); } } else { scriptExp = loadExp.FileExpression; } var scriptStr = StringParser.Parse(((StringExpression)scriptExp).Value); if (!EnvironmentHelper.IsWindows) { scriptStr = scriptStr.ToLower(); } var script = Loader.FindScriptFile(_applicationDirectory, scriptStr); if (script == null && scriptExp.Filename != null) { script = Loader.FindScriptFile(Path.GetDirectoryName(scriptExp.Filename), scriptStr); } if (!File.Exists(script)) { throw new AphidParserException( string.Format( "Could not find script {0}", scriptStr), scriptExp); } AddIncluded(script); List <AphidExpression> ast; if (AphidConfig.Current.ScriptCaching && !DisableCaching) { AphidByteCodeCache cache = UseImplicitReturns ? new AphidByteCodeCache(Loader.SearchPaths.ToArray()) { DisableConstantFolding = false, InlineScripts = true, } : new AphidByteCodeCache(Loader.SearchPaths.ToArray(), 0x1); ast = cache.Read(script, out var cacheSources); for (var i = 0; i < cacheSources.Length; i++) { AddIncluded(cacheSources[i].Name); } } else { var code = AphidScript.Read(script); ast = AphidParser.Parse(code, script, useImplicitReturns: UseImplicitReturns); } if (PerformCommonTransformations) { var mut = MutatorGroups.GetStandard().Mutate(ast); hasChanged = true; return(mut); } hasChanged = true; return(ast); }
protected override List <AphidExpression> MutateCore(AphidExpression expression, out bool hasChanged) { if (expression.Type != AphidExpressionType.BinaryOperatorExpression) { hasChanged = false; return(null); } var binOp = (BinaryOperatorExpression)expression; if (OperandsAre(binOp, AphidExpressionType.StringExpression) && binOp.Operator == AphidTokenType.AdditionOperator) { hasChanged = true; var left = GetString(binOp.LeftOperand); var right = GetString(binOp.RightOperand); return(new List <AphidExpression> { new StringExpression( "'" + left.Substring(1, left.Length - 2).Replace("\\\"", "\"") + right.Substring(1, right.Length - 2).Replace("\\\"", "\"") + "'") }); } else if (OperandsAre(binOp, AphidExpressionType.NumberExpression)) { var left = GetNumber(binOp.LeftOperand); var right = GetNumber(binOp.RightOperand); switch (binOp.Operator) { case AphidTokenType.AdditionOperator: hasChanged = true; return(new List <AphidExpression> { new NumberExpression(left + right) }); case AphidTokenType.MinusOperator: hasChanged = true; return(new List <AphidExpression> { new NumberExpression(left - right) }); case AphidTokenType.MultiplicationOperator: hasChanged = true; return(new List <AphidExpression> { new NumberExpression(left * right) }); case AphidTokenType.DivisionOperator: if (right != 0) { hasChanged = true; return(new List <AphidExpression> { new NumberExpression(left / right) }); } hasChanged = false; return(null); default: hasChanged = false; return(null); } } else { hasChanged = false; return(null); } }
private static string GetString(AphidExpression exp) => ((StringExpression)exp).Value;
private static decimal GetNumber(AphidExpression exp) => ((NumberExpression)exp).Value;
public static AphidExpression FirstComplete(AphidExpression expression) => FirstComplete(new[] { expression });
public static AphidExpression FirstRange(AphidExpression expression) => FirstRange(new[] { expression });
public static AphidExpression FirstFilename(AphidExpression expression) => FirstFilename(new[] { expression });
public CallExpression(AphidExpression functionExpression, AphidExpression expression) : this(functionExpression, new List <AphidExpression> { expression }) { }
protected abstract void Visit(AphidExpression expression);
protected virtual void EndVisitNode(AphidExpression expression) { }
public void VisitExpression(AphidExpression node) => Visit(new List <AphidExpression> { node });
public static string GetMemberPath(Exp exp) => _memoizer.Call(GetMemberPathCore, exp);
public static bool IsMemberPath(Exp exp) => GetMemberPath(exp) != null;
//private string _code; //private string _filename; //public AphidCodeVisitor(string code) // : this(code, null) //{ //} //public AphidCodeVisitor(string code, string filename) //{ // _code = code; // _filename = filename; //} protected override void EndVisit(List <AphidExpression> ast) { if (ast.Count < 2) { return; } AphidExpression prev = null, next = ast[1]; for (var i = 0; i < ast.Count; i++) { var node = ast[i]; if (node.Index == -1) { if (prev == null) { if (node.Code == null) { node.Code = next.Code; } if (node.Filename == null && next.Filename != null) { node.Filename = next.Filename; } node.Index = 0; node.Length = next.Index; } else if (next == null) { if (node.Code == null) { node.Code = prev.Code; } if (node.Filename == null && prev.Filename != null) { node.Filename = prev.Filename; } node.Index = prev.Index + prev.Length; node.Length = node.Code.Length - node.Index; } else { if (node.Code == null) { node.Code = prev.Code; } if (node.Filename == null && prev.Filename != null) { node.Filename = prev.Filename; } node.Index = prev.Index + prev.Length; node.Length = next.Index - node.Index; } } prev = ast[i]; next = i + 2 < ast.Count ? ast[i + 2] : null; } base.EndVisit(ast); }