public DynLanMethod GetMethodDefinition(CodeLine line, Int32 Depth) { CodeLine trimmedLine = new CodeLine(StringHelper.TrimStart(line)); // DEF: wykrycie definicji metody if (//trimmedLine.Count > str_method.Length && StringHelper.StartsWith(trimmedLine, str_method, true, true) /* && * Char.IsWhiteSpace(trimmedLine[str_method.Length])*/) { DynLanMethod method = new DynLanMethod(); method.ForceDecimals = ForceDecimals; #if !SPACES_FOR_DEPTH method.Depth = Depth + 1; // zwiekszamy poziom metody #else method.Depth = GetDepth(line) + 1; // zwiekszamy poziom metody #endif string codeLine = trimmedLine.ToString().Substring(str_method.Length + 1); if (codeLine.Trim().Length == 0) { throw new Exception("DEF method name cannot be empty !"); } IList <OnpMethodPart> methodParameters = MethodParser. ExtractNames(codeLine, true); foreach (OnpMethodPart methodParameter in methodParameters) { if (methodParameter.Part == EOnpMethodPart.METHOD_NAME) { #if CASE_INSENSITIVE method.Name = methodParameter.Code.ToUpper(); #else method.Name = methodParameter.Code; #endif } else if (methodParameter.Part == EOnpMethodPart.PARAMETER) { method.Parameters.Add(methodParameter.Code); } } return(method); } return(null); }
//////////////////////////////////////////// private DynLanProgram Compile(IList <Char> Code) { CodeLines lines = GetLines(Code); DynLanProgram mainProgram = new DynLanProgram() { ForceDecimals = ForceDecimals }; List <DynLanProgram> methodStack = new List <DynLanProgram>(); methodStack.Add(mainProgram); Int32 lineNr = 0; Int32 depth = 0; //foreach (CodeLine line in lines) for (var i = 0; i < lines.Count; i++) { CodeLine line = lines[i]; CodeLine nextLine = i < lines.Count - 1 ? lines[i + 1] : null; lineNr++; try { Int32 currentDepth = -1; #if !SPACES_FOR_DEPTH if (StringHelper.SequenceEqualInsensitive(line, DynLanuageSymbols.DepthBegin)) { depth++; continue; } else if (StringHelper.SequenceEqualInsensitive(line, DynLanuageSymbols.DepthEnd)) { depth--; continue; } currentDepth = depth; #endif DynLanMethod method = null; method = GetMethodDefinition(line, currentDepth); #if SPACES_FOR_DEPTH if (method != null) { currentDepth = method.Depth; } #else if (method != null) { if (!StringHelper.SequenceEqualInsensitive(nextLine, DynLanuageSymbols.DepthBegin)) { throw new Exception("Method body should begin with bracket { !"); } else { depth++; currentDepth++; i++; } } #endif DynLanClass classDefinition = null; if (method == null) { classDefinition = GetClassDefinition(line, currentDepth); #if SPACES_FOR_DEPTH if (classDefinition != null) { currentDepth = classDefinition.Depth; } #else if (classDefinition != null) { if (!StringHelper.SequenceEqualInsensitive(nextLine, DynLanuageSymbols.DepthBegin)) { throw new Exception("Class body should begin with bracket { !"); } else { depth++; currentDepth++; i++; } } #endif } DynLanCodeLine codeLine = null; if (method == null && classDefinition == null) { codeLine = SetCodeLine(null, line, nextLine, ref currentDepth, ref i); depth = currentDepth; #if SPACES_FOR_DEPTH if (codeLine != null) { currentDepth = codeLine.Depth; } #endif } DynLanProgram currentMethod = MyCollectionsExtenders.Peek(methodStack); if (codeLine == null || !codeLine.IsLineEmpty) { while (currentDepth < currentMethod.Depth || (currentDepth == currentMethod.Depth && classDefinition != null && classDefinition != currentMethod) || (currentDepth == currentMethod.Depth && method != null && method != currentMethod)) { MyCollectionsExtenders.Pop(methodStack); currentMethod = MyCollectionsExtenders.Peek(methodStack); } } if (method != null) { currentMethod.Methods.Remove_by_Name(method.Name); currentMethod.Methods.Add(method); methodStack.Add(method); continue; } if (classDefinition != null) { currentMethod.Classes.Remove_by_Name(classDefinition.Name); currentMethod.Classes.Add(classDefinition); methodStack.Add(classDefinition); continue; } if (codeLine != null) { if (codeLine.IsLineEmpty == false) { currentMethod.Lines.Add(codeLine); } } } catch (Exception ex) { throw new DynLanCompileException( "Line index: " + line.LineIndex + " (" + new string(line.ToArray()) + ")" + "; " + ex.Message, ex); } } for (var i = mainProgram.Lines.Count - 1; i >= 0; i--) { var line = mainProgram.Lines[i]; if (line.Depth > 0) { continue; } else if (line.OperatorType == EOperatorType.PASS) { continue; } else if (line.OperatorType == EOperatorType.RETURN) { break; } else if (line.OperatorType == EOperatorType.NONE) { line.OperatorType = EOperatorType.RETURN; break; } else { break; } } if (depth != 0) { throw new DynLanCompileException( "Incorect number of brackets. " + (depth > 0 ? ("Missing } x " + depth) : ("Too many } x " + Math.Abs(depth)))); } return(mainProgram); }
public static Boolean EvaluateMethod( Object Object, Object MethodObject, IList <Object> Parameters, DynLanContext DynLanContext) { if (MethodObject is DynLanMethod) { if (Parameters == null) { Parameters = new Object[0]; } DynLanMethod method = (DynLanMethod)MethodObject; DynLanContextType contextType = DynLanContextType.METHOD; // jesli tworzenie klasy (wolanie konstruktora) if (MethodObject is DynLanClass) { contextType = DynLanContextType.CLASS; } DynLanState newContext = DynLanContext. PushContext(method, contextType, Parameters); newContext.Object.ParentObject = method.ParentObject; return(true); } else if (MethodObject is DynLanProgram) { DynLanProgram program = (DynLanProgram)MethodObject; IDictionary <String, Object> currentValues = (DynLanContext == null || DynLanContext.CurrentState == null || DynLanContext.CurrentState.Object == null ? null : DynLanContext. CurrentState. Object. DynamicValues); DynLanState newState = DynLanContext.PushContext( program, DynLanContextType.METHOD, null); if (currentValues != null) { foreach (String key in currentValues.Keys) { newState.Object.DynamicValues[key] = currentValues[key]; } } return(true); } else { ExpressionMethodResult methodResult = EvaluateInlineMethod( Object, MethodObject, Parameters, DynLanContext); if (methodResult != null && methodResult.NewContextCreated) { return(true); } else { var v = methodResult == null ? null : methodResult.Value; DynLanContext.CurrentExpressionState.PushValue(v); return(false); } } }