public static PainCodeLine PrevLineWithLessDepth( this PainCodeLines Lines, PainCodeLine StartLine, Func <PainCodeLine, Boolean> Predicate) { Int32 depth = (StartLine == null ? 0 : StartLine.Depth); Int32 index = (StartLine == null ? 0 : Lines.IndexOf(StartLine)); if (index < 0) { return(null); } for (var i = index - 1; i >= 0; i--) { PainCodeLine line = Lines[i]; if (!line.IsLineEmpty && line.Depth < depth) { if (Predicate == null || Predicate(line)) { return(line); } } } return(null); }
public static PainCodeLine NextOnSameOrHigher( this PainCodeLines Lines, PainCodeLine StartLine) { Int32 depth = (StartLine == null ? 0 : StartLine.Depth); Int32 index = (StartLine == null ? 0 : Lines.IndexOf(StartLine)); if (index < 0) { return(null); } for (var i = index + 1; i < Lines.Count; i++) { PainCodeLine line = Lines[i]; if (!line.IsLineEmpty) { if (line.Depth > depth) { return(line); } else if (line.Depth == depth) { return(line); } } } return(null); }
public static PainCodeLine NextOnSameOrLower( this PainCodeLines Lines, PainCodeLine StartLine, Func <PainCodeLine, Boolean> Predicate = null) { Int32 depth = (StartLine == null ? 0 : StartLine.Depth); Int32 index = (StartLine == null ? 0 : Lines.IndexOf(StartLine)); if (index < 0) { return(null); } for (var i = index + 1; i < Lines.Count; i++) { PainCodeLine line = Lines[i]; if (!line.IsLineEmpty && line.Depth <= depth) { if (Predicate == null || Predicate(line)) { return(line); } } } return(null); }
private static Boolean?ExecuteCalculations( PainContext PainContext, PainState currentState, out Object Result) { Result = null; PainCodeLines lines = currentState.GetCurrentLines(); PainCodeLine currentLine = currentState.GetCurrentLine(); // wykonanie kalkulacji if (currentLine.ContainsAnyExpressions() && currentLine.OperatorType != EOperatorType.ELSE) { if (PainContext.CurrentState.ExpressionContext == null) { PainContext.CurrentState.ExpressionContext = new ExpressionContext(currentLine.ExpressionGroup); } if (PainContext.CurrentState.ExpressionContext != null && PainContext.CurrentState.ExpressionContext.IsFinished) { Result = PainContext.CurrentState.ExpressionContext.Result; PainContext.CurrentState.ExpressionContext = null; } else { try { Boolean result = ExpressionRunner.NextStep( PainContext); return(result); } catch { throw; } } } return(null); }
public static PainCodeLine ExitParentIf( this PainCodeLines Lines, PainCodeLine StartLine) { Int32 depth = (StartLine == null ? 0 : StartLine.Depth); Int32 index = (StartLine == null ? 0 : Lines.IndexOf(StartLine)); if (index < 0) { return(null); } PainCodeLine line = StartLine; while (true) { line = NextLine( Lines, line); if (line == null) { break; } if (line.Depth < StartLine.Depth) { return(line); } if (line.Depth == StartLine.Depth && line.OperatorType != EOperatorType.ELIF && line.OperatorType != EOperatorType.ELSE) { return(line); } } return(null); }
private static Boolean?CheckIfFinishedOrEmptyLine( PainContext PainContext, PainState currentState) { if (currentState == null || PainContext.IsFinished) { PainContext.IsFinished = true; return(true); } PainCodeLines lines = currentState.GetCurrentLines(); PainCodeLine currentLine = currentState.GetCurrentLine(); if (currentLine == null) { return(ExitCurrentContext( PainContext)); } // jeśli linia jest pusta to przechodzimy do nastepnej if (currentLine.IsLineEmpty) { PainCodeLine nextLine = lines.NextLine(currentLine); if (nextLine == null) { return(ExitCurrentContext( PainContext)); } else { currentState.CurrentLineID = nextLine.ID; } return(true); } return(null); }
private static Boolean GotoCatch( PainContext PainContext, Exception exception) { while (true) { PainState currentState = PainContext. CurrentState; // reset dla kontekstu obliczeń, ponieważ przechodzimy do catch'a currentState.ExpressionContext = null; PainCodeLines lines = currentState.GetCurrentLines(); PainCodeLine currentLine = currentState.GetCurrentLine(); // poszukanie poprzedniego catch'a PainCodeLine prevCatch = lines. PrevLineWithLessDepth(currentLine, l => l.OperatorType == EOperatorType.CATCH); // poszukanie poprzedniego try'a PainCodeLine prevTry = lines. PrevLineWithLessDepth(currentLine, l => l.OperatorType == EOperatorType.TRY); if (prevTry == null) { ExitCurrentContext( PainContext); if (PainContext.IsFinished) { break; } } // jeśli znalazł try'a i nie jesteśmy w catch'u else if (prevTry.Depth < currentLine.Depth && (prevCatch == null || lines.IndexOf(prevCatch) < lines.IndexOf(prevTry))) { PainCodeLine nextCatch = lines.NextOnSameOrLower( prevTry, i => i.OperatorType == EOperatorType.CATCH); if (nextCatch != null) { ExpressionToken variableForException = nextCatch.ExpressionGroup != null && nextCatch.ExpressionGroup.MainExpression != null && nextCatch.ExpressionGroup.MainExpression.Tokens != null && nextCatch.ExpressionGroup.MainExpression.Tokens.Count > 0 ? nextCatch. ExpressionGroup. MainExpression. Tokens. FirstOrDefault(i => i.TokenType != TokenType.BRACKET_BEGIN) : null; currentState.CurrentLineID = nextCatch.ID; if (variableForException != null && !String.IsNullOrEmpty(variableForException.TokenName)) { currentState.Object[variableForException.TokenName] = exception; } break; } else { ExitCurrentContext( PainContext); if (PainContext.IsFinished) { break; } } } else { ExitCurrentContext( PainContext); if (PainContext.IsFinished) { break; } } } return(false); }
////////////////////////////////////////////// private static Boolean GotoNextLine( PainContext PainContext, PainState currentState, Object currentValue) { try { PainCodeLines lines = currentState.GetCurrentLines(); PainCodeLine currentLine = currentState.GetCurrentLine(); // jesli return to konczymy if (currentLine.OperatorType == EOperatorType.RETURN) { return(ExitCurrentContext( PainContext, currentValue)); } // throw błędu else if (currentLine.OperatorType == EOperatorType.THROW) { if (currentValue is Exception) { throw (Exception)currentValue; } else { String message = UniConvert.ToString(currentValue ?? ""); throw String.IsNullOrEmpty(message) ? new Exception() : new Exception(message); } /*return ExitCurrentContext( * PainContext, * new Exception(message));*/ } if (currentLine.OperatorType == EOperatorType.WHILE || currentLine.OperatorType == EOperatorType.IF || currentLine.OperatorType == EOperatorType.ELIF) { Boolean conditionResult = currentValue.IfTrue(); if (conditionResult) { PainCodeLine nextLine = lines.NextOnSameOrHigher(currentLine); if (nextLine != null) { currentState.CurrentLineID = nextLine.ID; } else { throw new NotImplementedException(); } } else { PainCodeLine nextLine = lines.NextOnSameOrLower(currentLine); if (nextLine == null) { return(ExitCurrentContext( PainContext)); } else { if (nextLine.Depth < currentLine.Depth) { while ( nextLine != null & (nextLine.OperatorType == EOperatorType.ELSE || nextLine.OperatorType == EOperatorType.ELIF /*|| * nextLine.OperatorType == EOperatorType.FINALLY*/)) { nextLine = lines.ExitParentIf(nextLine); if (nextLine == null) { break; } } if (nextLine == null) { return(ExitCurrentContext( PainContext)); } if (nextLine.Depth < currentLine.Depth) { //PainCodeLine prevIf = lines. // PrevLineWithLessDepth(currentLine, l => l.OperatorType == EOperatorType.IF || l.OperatorType == EOperatorType.ELIF); while (true) { PainCodeLine prevConditionLine = lines. PrevLineWithLessDepth( currentLine, l => l.OperatorType == EOperatorType.IF || l.OperatorType == EOperatorType.ELIF || l.OperatorType == EOperatorType.ELSE || l.OperatorType == EOperatorType.WHILE); if (prevConditionLine != null && prevConditionLine.Depth >= nextLine.Depth && prevConditionLine.OperatorType == EOperatorType.WHILE) { currentState.CurrentLineID = prevConditionLine.ID; break; } else if (prevConditionLine != null) { currentLine = prevConditionLine; } else { currentState.CurrentLineID = nextLine.ID; break; } } } else { currentState.CurrentLineID = nextLine.ID; } } else { currentState.CurrentLineID = nextLine.ID; } } } } else if ( currentLine.OperatorType == EOperatorType.TRY || currentLine.OperatorType == EOperatorType.ELSE) { PainCodeLine nextLine = lines.NextOnSameOrHigher(currentLine); if (nextLine != null) { currentState.CurrentLineID = nextLine.ID; } else { throw new NotImplementedException(); } } else if ( (currentLine.OperatorType == EOperatorType.FINALLY)) { throw new NotImplementedException("FINALLY"); } else if ( (currentLine.OperatorType == EOperatorType.CATCH)) { if (PainContext.Error != null) { PainContext.Error = null; PainCodeLine nextLine = lines.NextOnSameOrHigher(currentLine); if (nextLine != null) { currentState.CurrentLineID = nextLine.ID; } else { throw new NotImplementedException(); } } else { PainCodeLine nextLine = lines.NextOnSameOrLower(currentLine); if (nextLine != null) { currentState.CurrentLineID = nextLine.ID; } else { return(ExitCurrentContext( PainContext)); } } } else if (currentLine.OperatorType == EOperatorType.NONE) { PainCodeLine nextLine = lines.NextLine(currentLine); if (nextLine != null) { while ( nextLine != null & (nextLine.OperatorType == EOperatorType.ELSE || nextLine.OperatorType == EOperatorType.ELIF /*|| * nextLine.OperatorType == EOperatorType.FINALLY*/)) { nextLine = lines.ExitParentIf(nextLine); if (nextLine == null) { return(ExitCurrentContext( PainContext)); } } if (nextLine == null) { return(ExitCurrentContext( PainContext)); } if (nextLine.Depth < currentLine.Depth) { //PainCodeLine prevIf = lines. // PrevLineWithLessDepth(currentLine, l => l.OperatorType == EOperatorType.IF || l.OperatorType == EOperatorType.ELIF); while (true) { PainCodeLine prevConditionLine = lines. PrevLineWithLessDepth( currentLine, l => l.OperatorType == EOperatorType.IF || l.OperatorType == EOperatorType.ELIF || l.OperatorType == EOperatorType.ELSE || l.OperatorType == EOperatorType.WHILE); if (prevConditionLine != null && prevConditionLine.Depth >= nextLine.Depth && prevConditionLine.OperatorType == EOperatorType.WHILE) { currentState.CurrentLineID = prevConditionLine.ID; break; } else if (prevConditionLine != null) { currentLine = prevConditionLine; } else { currentState.CurrentLineID = nextLine.ID; break; } } } else { currentState.CurrentLineID = nextLine.ID; } } // jeśli ostatnia linia i jesteśmy w while'u else { //PainCodeLine prevIf = lines. // PrevLineWithLessDepth(currentLine, l => l.OperatorType == EOperatorType.IF || l.OperatorType == EOperatorType.ELIF); while (true) { PainCodeLine prevConditionLine = lines. PrevLineWithLessDepth( currentLine, l => l.OperatorType == EOperatorType.IF || l.OperatorType == EOperatorType.ELIF || l.OperatorType == EOperatorType.ELSE || l.OperatorType == EOperatorType.WHILE); if (prevConditionLine != null && prevConditionLine.OperatorType == EOperatorType.WHILE) { currentState.CurrentLineID = prevConditionLine.ID; break; } else if (prevConditionLine != null) { currentLine = prevConditionLine; } else { return(ExitCurrentContext( PainContext)); } } } } return(false); } catch { throw; } }
public PainProgram Compile(IList <Char> Code) { CodeLines lines = GetLines(Code); PainProgram mainProgram = new PainProgram(); List <PainProgram> methodStack = new List <PainProgram>(); methodStack.Push(mainProgram); foreach (CodeLine line in lines) { Int32 currentDepth = -1; PainMethod method = null; method = GetMethodDefinition(line); if (method != null) { currentDepth = method.Depth; } PainClass classDefinition = null; if (method == null) { classDefinition = GetClassDefinition(line); if (classDefinition != null) { currentDepth = classDefinition.Depth; } } PainCodeLine codeLine = null; if (method == null && classDefinition == null) { codeLine = GetCodeLine(line); if (codeLine != null) { currentDepth = codeLine.Depth; } } PainProgram currentMethod = methodStack.Peek(); if (codeLine == null || !codeLine.IsLineEmpty) { while (currentDepth < currentMethod.Depth || (currentDepth == currentMethod.Depth && classDefinition != null && classDefinition != currentMethod) || (currentDepth == currentMethod.Depth && method != null && method != currentMethod)) { methodStack.Pop(); currentMethod = methodStack.Peek(); } } if (method != null) { currentMethod.Methods.Remove_by_Name(method.Name); currentMethod.Methods.Add(method); methodStack.Push(method); continue; } if (classDefinition != null) { currentMethod.Classes.Remove_by_Name(classDefinition.Name); currentMethod.Classes.Add(classDefinition); methodStack.Push(classDefinition); continue; } if (codeLine != null) { if (codeLine.IsLineEmpty == false) { currentMethod.Lines.Add(codeLine); } } } return(mainProgram); }
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); }
public PainCodeLine SetCodeLine(PainCodeLine compiledLine, String line) { return(SetCodeLine(compiledLine, new CodeLine(line))); }
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); }