public override void VisitFor(ASTFor n) { //define labels Label loop = _gen.DefineLabel(); Label exit = _gen.DefineLabel(); //evaluate initial expression n.InitialExpr.Visit(this); //loop label _gen.MarkLabel(loop); //check condition n.Conditional.Visit(this); //break on false _gen.Emit(OpCodes.Brfalse, exit); //emit body of loop n.Body.Visit(this); //evaluate looping expression n.LoopExpr.Visit(this); //unconditional loop branch _gen.Emit(OpCodes.Br, loop); //break label _gen.MarkLabel(exit); }
private VisitResult VisitForStatement(ASTFor node) { foreach (var assign in node.Assignments) { Visit(assign); } var condition = node.Condition != null?Visit(node.Condition).Value : true; while (condition) { var result = Visit(node.Body); if (result != null) { switch (result.ControlType) { case ControlType.Return: return(result); case ControlType.Break: return(null); } } foreach (var continueStatement in node.ContinueStatements) { Visit(continueStatement); } condition = node.Condition != null?Visit(node.Condition).Value : true; } return(null); }
private Symbol VisitForStatement(ASTFor node) { Logger.DebugScope($"Enter scope : for"); var whileScope = new ScopedSymbolTable("for", _currentScope.Level + 1, _currentScope); _currentScope = whileScope; foreach (var assign in node.Assignments) { Visit(assign); } if (node.Condition != null) { Visit(node.Condition); } foreach (var statement in node.ContinueStatements) { Visit(statement); } var returnType = Visit(node.Body); DebugPrintSymbolTable(); _currentScope = _currentScope.EnclosingScope; Logger.DebugScope($"Leave scope : for"); return(returnType); }
private static List <ASTNode> ParseCodeBlock() { List <ASTNode> codeBlock = new List <ASTNode>(); if (currentToken < currentTokens.Count) { if (currentTokens[currentToken].Token == "{") { currentToken++; while (currentToken < currentTokens.Count && currentTokens[currentToken].Token != "}") { if (currentTokens[currentToken] is ReservedWordToken && currentTokens[currentToken].Token == "if") { ASTIf ifNode = ParseIf(); codeBlock.Add(ifNode); } else if (currentTokens[currentToken] is ReservedWordToken && currentTokens[currentToken].Token == "for") { ASTFor forNode = ParseFor(); codeBlock.Add(forNode); } else if (currentTokens[currentToken] is ReservedWordToken && currentTokens[currentToken].Token == "while") { ASTWhile whileNode = ParseWhile(); codeBlock.Add(whileNode); } else { ASTStatement statement = ParseStatement(); if (statement != null) { codeBlock.Add(statement); } } } if (currentToken == currentTokens.Count) { throw new ParserException("SourceCode can't end in Code Block.", -1); } return(codeBlock); } // No '{' means just one line of code else { ASTStatement statement = ParseStatement(); if (statement != null) { codeBlock.Add(statement); } return(codeBlock); } } throw new ParserException("Expected Code Block found End of File.", -1); }
/// <summary> /// /// </summary> /// <param name="n"></param> public override void VisitFor(ASTFor n) { //define the block scope now to incapsulate the declared variable. BeginForLoopBlock(); CFlatType initType = CheckSubTree(n.InitialExpr); n.InitialExpr.CFlatType = initType; TypeBool condition = CheckSubTree(n.Conditional) as TypeBool; if (condition != null) { n.Conditional.CFlatType = condition; CFlatType loopType = CheckSubTree(n.LoopExpr); n.LoopExpr.CFlatType = loopType; CheckSubTree(n.Body); } else { ReportError(n.Location, "The condition of a for loop must be a boolean."); } }
private static void PrintNode(ASTNode node, int incident) { if (node == null) { return; } for (int i = 0; i < incident; i++) { sw.Write("\t"); } if (node is ASTString) { sw.WriteLine("ASTString: " + ((ASTString)node).String.Replace("\n", "\\n")); } else if (node is ASTNumber) { sw.WriteLine("ASTNumber: " + ((ASTNumber)node).Number); } else if (node is ASTIdentifier) { sw.WriteLine("ASTIdentifier: " + ((ASTIdentifier)node).Identifier); } else if (node is ASTOperator) { ASTOperator op = (ASTOperator)node; sw.WriteLine("ASTOperator: " + op.Operator); PrintNode(op.Left, incident + 1); PrintNode(op.Right, incident + 1); } else if (node is ASTStatement) { ASTStatement stm = (ASTStatement)node; sw.WriteLine("ASTStatement: "); PrintNode(stm.Statement, incident + 1); } else if (node is ASTFunctionCall) { ASTFunctionCall call = (ASTFunctionCall)node; sw.WriteLine("ASTFunctionCall: " + call.Scope + "." + call.FunctionName); foreach (ASTNode param in call.Parameter) { PrintNode(param, incident + 1); } } else if (node is ASTClassParameter) { ASTClassParameter classP = (ASTClassParameter)node; sw.WriteLine("ASTClassParameter: " + classP.Scope); PrintNode(classP.Parameter, incident + 1); } else if (node is ASTIf) { ASTIf ifNode = (ASTIf)node; sw.WriteLine("ASTIf:"); for (int i = 0; i < incident; i++) { sw.Write("\t"); } sw.WriteLine("\tCondition:"); PrintNode(ifNode.Condition, incident + 2); for (int i = 0; i < incident; i++) { sw.Write("\t"); } sw.WriteLine("\tCodeBlock:"); foreach (ASTNode codeBlock in ifNode.CodeBlock) { PrintNode(codeBlock, incident + 2); } if (ifNode.ElseCodeBlock != null) { for (int i = 0; i < incident; i++) { sw.Write("\t"); } sw.WriteLine("\tElse:"); foreach (ASTNode codeBlock in ifNode.ElseCodeBlock) { PrintNode(codeBlock, incident + 2); } } } else if (node is ASTFor) { ASTFor forNode = (ASTFor)node; sw.WriteLine("ASTFor:"); for (int i = 0; i < incident; i++) { sw.Write("\t"); } sw.WriteLine("\tInit:"); PrintNode(forNode.Initialise, incident + 2); for (int i = 0; i < incident; i++) { sw.Write("\t"); } sw.WriteLine("\tCondition:"); PrintNode(forNode.Condition, incident + 2); for (int i = 0; i < incident; i++) { sw.Write("\t"); } sw.WriteLine("\tCounter:"); PrintNode(forNode.Count, incident + 2); for (int i = 0; i < incident; i++) { sw.Write("\t"); } sw.WriteLine("\tCodeBlock:"); foreach (ASTNode codeBlock in forNode.CodeBlock) { PrintNode(codeBlock, incident + 2); } } else if (node is ASTWhile) { ASTWhile wNode = (ASTWhile)node; sw.WriteLine("ASTWhile:"); for (int i = 0; i < incident; i++) { sw.Write("\t"); } sw.WriteLine("\tCondition:"); PrintNode(wNode.Condition, incident + 2); for (int i = 0; i < incident; i++) { sw.Write("\t"); } sw.WriteLine("\tCodeBlock:"); foreach (ASTNode codeBlock in wNode.CodeBlock) { PrintNode(codeBlock, incident + 2); } } else if (node is ASTFunction) { ASTFunction func = (ASTFunction)node; if (node is ASTConstructor) { sw.WriteLine("ASTConstructor:"); } else { sw.WriteLine("ASTFunction: " + func.ReturnValue.ToString() + " " + func.Name); } for (int i = 0; i < incident; i++) { sw.Write("\t"); } sw.WriteLine("\tParameter:"); foreach (ASTNode n in func.Parameter) { PrintNode(n, incident + 2); } for (int i = 0; i < incident; i++) { sw.Write("\t"); } sw.WriteLine("\tCodeBlock:"); foreach (ASTNode codeBlock in func.CodeBlock) { PrintNode(codeBlock, incident + 2); } } else if (node is ASTFunctionParameter) { ASTFunctionParameter param = (ASTFunctionParameter)node; switch (param.Type) { case VMType.Object: sw.WriteLine("Object: " + param.Name); break; case VMType.String: sw.WriteLine("String: " + param.Name); break; case VMType.Number: sw.WriteLine("Number: " + param.Name); break; } } else if (node is ASTLocalVariable) { ASTLocalVariable param = (ASTLocalVariable)node; switch (param.Type) { case VMType.Object: sw.WriteLine("var Object: " + param.Name); break; case VMType.String: sw.WriteLine("var String: " + param.Name); break; case VMType.Number: sw.WriteLine("var Number: " + param.Name); break; } } else if (node is ASTReturn) { sw.WriteLine("ASTReturn:"); PrintNode(((ASTReturn)node).Return, incident + 1); } else if (node is ASTClass) { ASTClass cNode = (ASTClass)node; sw.WriteLine("ASTClass: " + cNode.Name); sw.WriteLine("\tAttributes:"); foreach (ASTNode n in cNode.Attributes) { PrintNode(n, incident + 2); } sw.WriteLine("\tConstructors:"); foreach (ASTNode n in cNode.Constructors) { PrintNode(n, incident + 2); } sw.WriteLine("\tFunctions:"); foreach (ASTNode n in cNode.Functions) { PrintNode(n, incident + 2); } } }