private void CheckVariableAssignmentUsedInStartEndExpression(IdentifierNode loopVariable, Node startExpression, Node endExpression, Node loopBody) { var stack = new Stack<Node>(); stack.Push(endExpression); stack.Push(startExpression); var loopExpressionVariables = new Dictionary<IdentifierNode, IdentifierNode>(); while (stack.Count != 0) { var current = stack.Pop(); if (current is IdentifierNode && ((IdentifierNode)current).Name != loopVariable.Name) { var id = (IdentifierNode)current; if (!loopExpressionVariables.ContainsKey(id)) { loopExpressionVariables.Add(id, id); } } foreach (var child in current.Children) { stack.Push(child); } } stack.Push(loopBody); while (stack.Count != 0) { var current = stack.Pop(); if (current is VariableAssignmentNode && loopExpressionVariables.ContainsKey(new IdentifierNode(0, 0, ((VariableAssignmentNode)current).Name))) { reporter.ReportError( Error.WARNING, "Possibly incorrect or confusing assignment to a variable '" + ((VariableAssignmentNode)current).Name + "', used in loop expression,", current.Line, current.Column); var id = loopExpressionVariables[new IdentifierNode(0, 0, ((VariableAssignmentNode)current).Name)]; reporter.ReportError( Error.NOTE, "Previous usage here", id.Line, id.Column); reporter.ReportError( Error.NOTE_GENERIC, "Loop start and end expressions are evaluated only once before entering the loop", 0, 0); break; } foreach (var child in current.Children) { stack.Push(child); } } }
private void ReportUndeclaredVariable(IdentifierNode node) { ReportUndeclaredVariable(node, node.Name); }
private void CheckLoopControlVariableUsageInStartEndExpression(ForNode node, IdentifierNode loopVariable, Node startExpression, Node endExpression) { var stack = new Stack<Node>(); stack.Push(endExpression); stack.Push(startExpression); while (stack.Count != 0) { var current = stack.Pop(); if (current is IdentifierNode && ((IdentifierNode)current).Name == loopVariable.Name) { reporter.ReportError( Error.WARNING, "Possibly incorrect or confusing usage of loop control variable '" + loopVariable.Name + "' in loop expression", current.Line, current.Column); reporter.ReportError( Error.NOTE, "Loop is here", node.Line, node.Column); reporter.ReportError( Error.NOTE_GENERIC, "Loop start and end expressions are evaluated only once before entering the loop", 0, 0); break; } foreach (var child in current.Children) { stack.Push(child); } } }
private void CheckLoopControlVariableAssignmentInBody(ForNode node, IdentifierNode loopVariable, Node loopBody) { var stack = new Stack<Node>(); stack.Push(loopBody); while (stack.Count != 0) { var current = stack.Pop(); if (current is VariableAssignmentNode && ((VariableAssignmentNode)current).Name == loopVariable.Name) { reporter.ReportError( Error.SEMANTIC_ERROR, "Cannot reassign control variable '" + loopVariable.Name + "'", current.Line, current.Column); reporter.ReportError( Error.NOTE, "Loop is here", node.Line, node.Column); break; } foreach (var child in current.Children) { stack.Push(child); } } }
public void Visit(IdentifierNode node) { if (SymbolTable.ContainsKey(node.Name)) { node.SetType(SymbolTable[node.Name].node.NodeType()); } else { node.SetType(VariableType.ERROR_TYPE); ReportUndeclaredVariable(node); } }
public ReadNode(int line, int column, IdentifierNode identifier) : base(line, column) { Children.Add(identifier); }
public void Visit(IdentifierNode node) { var data = symbolTable[node.Name]; switch (data.node.Type) { case VariableType.INTEGER: Emit(Bytecode.PUSH_INT_VAR); break; case VariableType.STRING: Emit(Bytecode.PUSH_STRING_VAR); break; case VariableType.BOOLEAN: Emit(Bytecode.PUSH_BOOLEAN_VAR); break; default: throw new InternalCompilerError("Invalid variable type"); } Emit(data.id); }