private static PainContext InvokeMethodGetContext( String Method, IList <Object> MethodParameters, IDictionary <String, Object> Values, IDictionary <String, Object> StaticValues) { PainContext newContext = CreateContext( new PainCodeLines(), Values, StaticValues, false, true); PainObject globalObject = newContext.GlobalObject; ExpressionGroup expressionGroup = new ExpressionGroup(false); expressionGroup.MainExpression = new Expression(); expressionGroup.MainExpression.IsOnpExecution = false; expressionGroup.MainExpression.Tokens = new ExpressionTokens(); expressionGroup.MainExpression.Tokens.Add( new ExpressionToken(Method, TokenType.VARIABLE)); expressionGroup.MainExpression.Tokens.Add( new ExpressionToken('@', TokenType.OPERATOR)); expressionGroup.MainExpression.Tokens.Add( new ExpressionToken('(', TokenType.BRACKET_BEGIN)); if (MethodParameters != null) { Int32 i = -1; foreach (Object parameter in MethodParameters) { i++; if (i > 0) { expressionGroup.MainExpression.Tokens.Add( new ExpressionToken(',', TokenType.SEPARATOR)); } String parameterName = IdGenerator.Generate(); globalObject.DynamicValues[parameterName] = parameter; // much faster //newContext[parameterName] = parameter; expressionGroup.MainExpression.Tokens.Add( new ExpressionToken(parameterName, TokenType.VARIABLE)); } } expressionGroup.MainExpression.Tokens.Add( new ExpressionToken(')', TokenType.BRACKET_END)); PainCodeLine lineOfCode = new PainCodeLine() { ExpressionGroup = expressionGroup, Depth = 0, IsLineEmpty = false, OperatorType = EOperatorType.RETURN }; newContext.GlobalState.Program.Lines.Add(lineOfCode); return(newContext); }
public PainCodeLine SetCodeLine(PainCodeLine compiledLine, CodeLine line) { IList <Char> lineTrimmed = line. TrimStart(). ToArray(); IList <Char> lineBody = line; EOperatorType operatorType = EOperatorType.NONE; // IF: wykrycie definicji IF'a if (lineTrimmed.Count > str_if.Length && StringHelper.StrEquals(lineTrimmed.TrimStart().ToArray(), str_if, true) && Char.IsWhiteSpace(lineTrimmed[str_if.Length])) { Int32 depth = GetDepth(line); operatorType = EOperatorType.IF; lineBody = lineTrimmed. Substring2(str_if.Length). TrimStart(). ToList(); for (int i = 0; i < depth; i++) { lineBody.Insert(0, ' '); } lineBody.TrimEnd(':'); } // WHILE: wykrycie definicji WHILE'a else if (lineTrimmed.Count > str_while.Length && StringHelper.StrEquals(lineTrimmed.TrimStart().ToArray(), str_while, true) && Char.IsWhiteSpace(lineTrimmed[str_while.Length])) { Int32 depth = GetDepth(line); operatorType = EOperatorType.WHILE; lineBody = lineTrimmed. Substring2(str_while.Length). TrimStart(). ToList(); for (int i = 0; i < depth; i++) { lineBody.Insert(0, ' '); } lineBody.TrimEnd(':'); } // ELSE: wykrycie definicji ELSE'a else if (lineTrimmed.Count >= str_else.Length && StringHelper.StrEquals(lineTrimmed.TrimStart().ToArray(), str_else, true)) { Int32 depth = GetDepth(line); operatorType = EOperatorType.ELSE; lineBody = lineTrimmed. Substring2(str_else.Length). TrimStart(). ToList(); for (int i = 0; i < depth; i++) { lineBody.Insert(0, ' '); } lineBody.TrimEnd(':'); } // ELIF: wykrycie definicji ELIF'a else if (lineTrimmed.Count > str_elif.Length && StringHelper.StrEquals(lineTrimmed.TrimStart().ToArray(), str_elif, true) && Char.IsWhiteSpace(lineTrimmed[str_elif.Length])) { Int32 depth = GetDepth(line); operatorType = EOperatorType.ELIF; lineBody = lineTrimmed. Substring2(str_elif.Length). TrimStart(). ToList(); for (int i = 0; i < depth; i++) { lineBody.Insert(0, ' '); } lineBody.TrimEnd(':'); } // RETURN: wykrycie definicji RETURN'a else if (lineTrimmed.Count > str_return.Length && StringHelper.StrEquals(lineTrimmed.TrimStart().ToArray(), str_return, true) && Char.IsWhiteSpace(lineTrimmed[str_return.Length])) { Int32 depth = GetDepth(line); operatorType = EOperatorType.RETURN; lineBody = lineTrimmed. Substring2(str_return.Length). TrimStart(). ToList(); for (int i = 0; i < depth; i++) { lineBody.Insert(0, ' '); } lineBody.TrimEnd(':'); } // TRY: wykrycie definicji TRY'a else if (lineTrimmed.Count > str_try.Length && StringHelper.StrEquals(lineTrimmed.TrimStart().ToArray(), str_try, true) /*&& * Char.IsWhiteSpace(lineTrimmed[str_try.Length])*/) { Int32 depth = GetDepth(line); operatorType = EOperatorType.TRY; lineBody = lineTrimmed. Substring2(str_try.Length). TrimStart(). ToList(); for (int i = 0; i < depth; i++) { lineBody.Insert(0, ' '); } lineBody.TrimEnd(':'); } // CATCH: wykrycie definicji CATCH'a else if (lineTrimmed.Count > str_catch.Length && StringHelper.StrEquals(lineTrimmed.TrimStart().ToArray(), str_catch, true) /*&& * Char.IsWhiteSpace(lineTrimmed[str_catch.Length])*/) { Int32 depth = GetDepth(line); operatorType = EOperatorType.CATCH; lineBody = lineTrimmed. Substring2(str_catch.Length). TrimStart(). ToList(); for (int i = 0; i < depth; i++) { lineBody.Insert(0, ' '); } lineBody.TrimEnd(':'); } // FINALLY: wykrycie definicji FINALLY'a else if (lineTrimmed.Count > str_finally.Length && StringHelper.StrEquals(lineTrimmed.TrimStart().ToArray(), str_finally, true) /*&& * Char.IsWhiteSpace(lineTrimmed[str_finally.Length])*/) { Int32 depth = GetDepth(line); operatorType = EOperatorType.FINALLY; lineBody = lineTrimmed. Substring2(str_finally.Length). TrimStart(). ToList(); for (int i = 0; i < depth; i++) { lineBody.Insert(0, ' '); } lineBody.TrimEnd(':'); } // THROW: wykrycie definicji THROW'a else if (lineTrimmed.Count > str_throw.Length && StringHelper.StrEquals(lineTrimmed.TrimStart().ToArray(), str_throw, true) /*&& * Char.IsWhiteSpace(lineTrimmed[str_THROW.Length])*/) { Int32 depth = GetDepth(line); operatorType = EOperatorType.THROW; lineBody = lineTrimmed. Substring2(str_throw.Length). TrimStart(). ToList(); for (int i = 0; i < depth; i++) { lineBody.Insert(0, ' '); } lineBody.TrimEnd(':'); } ExpressionGroup expressionGroup = TokenizerInvariant.I. Compile(lineBody); if (compiledLine == null) { compiledLine = new PainCodeLine(); } compiledLine.Code = line.ToString2(); compiledLine.ExpressionGroup = expressionGroup; compiledLine.OperatorType = operatorType; compiledLine.IsLineEmpty = lineTrimmed.Count == 0; compiledLine.Depth += GetDepth(lineBody); return(compiledLine); }
private static LinqExpression[] CompileGroup(ExpressionGroup group, CompilationData data) { switch (group) { case Persist p: foreach (var s in p.State) { if (!(s.InitialValue is Constant)) { throw new Exception("Persist initial value is not constant"); } data.StateValues.Add(((Constant)s.InitialValue).Value); } var assigns = new List <LinqExpression>(); // TODO: Resolve parent scopes data.ResolveState = s => LinqExpression.ArrayAccess(data.StateArray, LinqExpression.Constant(s.Id)); for (var i = 0; i < p.NewValue.Count; i++) { var newValueExpr = Compile(p.NewValue[i], data); assigns.Add(LinqExpression.Assign( LinqExpression.ArrayAccess(data.StateArray, LinqExpression.Constant(i)), newValueExpr)); } data.Statements.AddRange(assigns); return(Enumerable.Range(0, p.Size) .Select(i => LinqExpression.ArrayAccess(data.StateArray, LinqExpression.Constant(i))) .ToArray()); case Loop l: var stateList = new List <ParameterExpression>(); foreach (var s in l.State) { var initial = Compile(s.InitialValue, data); var variable = LinqExpression.Variable(initial.Type); data.Statements.Add(LinqExpression.Assign(variable, initial)); data.Variables.Add(variable); stateList.Add(variable); } // TODO: Resolve parent scopes data.ResolveState = s => stateList[s.Id]; var parentStatements = data.Statements; // Make a new cache that copies in the old one, but won't leak State expressions data.Cache = new Dictionary <CachedExpression, ParameterExpression>(data.Cache); // Create a new statements list to put in the loop body var s1 = data.Statements = new List <LinqExpression>(); var condition = Compile(l.Condition, data); var s2 = data.Statements = new List <LinqExpression>(); var newState = l.Body.Select(e => Compile(e, data)).ToArray(); // Ensure that the entire state is only set at the end of the loop for (var i = 0; i < newState.Length; i++) { var s = newState[i]; if (!(s is ParameterExpression)) { var tmpVar = LinqExpression.Variable(s.Type); data.Variables.Add(tmpVar); s2.Add(LinqExpression.Assign(tmpVar, s)); newState[i] = tmpVar; } } var breakLabel = LinqExpression.Label(); var body = LinqExpression.Block(s1 .Concat(new[] { LinqExpression.IfThen( LinqExpression.LessThan(condition, LinqExpression.Constant(1f)), LinqExpression.Break(breakLabel)) }) .Concat(s2) .Concat(newState.Select((e, i) => LinqExpression.Assign(stateList[i], e)))); parentStatements.Add(LinqExpression.Loop(body, breakLabel)); return(stateList.ToArray()); default: throw new NotSupportedException(); } }