public void CheckInScope(Node node, Scope inner, Scope outer) { switch (node.GetNodeType()) { case NodeType.Block: Scope newOuter = new Scope(outer); newOuter.AddScope(inner); GoDeeperInScope(node as BlockNode, newOuter); break; case NodeType.If: IfNode ifNode = node as IfNode; ValType type = CheckValueType(ifNode.check, inner, outer); if (type == ValType.Bool) { CheckInScope(ifNode.ifBlock, inner, outer); if (!(ifNode.elseBlock is null)) { CheckInScope(ifNode.elseBlock, inner, outer); } } else { string typeString = Enum.GetName(typeof(ValType), type); throw new SemanticException(SemanticErrorCode.IllegalCast, "Expected Bool, but got " + typeString + ".", node.Line); } break; case NodeType.While: WhileNode whileNode = node as WhileNode; type = CheckValueType(whileNode.check, inner, outer); if (type == ValType.Bool) { CheckInScope(whileNode.block, inner, outer); } else { string typeString = Enum.GetName(typeof(ValType), type); throw new SemanticException(SemanticErrorCode.IllegalCast, "Expected Bool, but got " + typeString + ".", node.Line); } break; case NodeType.Read: ReadNode readNode = node as ReadNode; CheckInScope(readNode.target, inner, outer); break; case NodeType.Write: WriteNode writeNode = node as WriteNode; if (!(writeNode.content is StringNode)) { CheckInScope(writeNode.content, inner, outer); } break; case NodeType.Variable: VariableNode variableNode = node as VariableNode; CheckValueType(variableNode, inner, outer); break; case NodeType.Init: InitNode initNode = node as InitNode; if (inner.variables.ContainsKey(initNode.variable.name)) { throw new SemanticException(SemanticErrorCode.VariableAlreadyDeclared, "Variable \"" + initNode.variable.name + "\" already declared in scope", initNode.variable.Line); } else { inner.variables.Add(initNode.variable.name, initNode.variable); } initNode.variable.LocalIndex = locals.Count; locals.Add(new LocalVariable { Name = initNode.variable.name, Type = initNode.variable.ValType }); break; case NodeType.Assign: AssignNode assignNode = node as AssignNode; CheckValueType(assignNode, inner, outer); break; case NodeType.BinaryOp: BinaryOpNode binaryOpNode = node as BinaryOpNode; CheckValueType(binaryOpNode, inner, outer); break; case NodeType.Comparison: ComparisonNode comparisonNode = node as ComparisonNode; CheckValueType(comparisonNode, inner, outer); break; case NodeType.Parenthesis: ParenthesisNode parenthesisNode = node as ParenthesisNode; CheckInScope(parenthesisNode.content, inner, outer); break; case NodeType.Int: case NodeType.Double: case NodeType.Bool: case NodeType.String: break; case NodeType.LogicOp: LogicOpNode logicNode = node as LogicOpNode; CheckValueType(logicNode, inner, outer); break; case NodeType.IntCast: IntCastNode intCastNode = node as IntCastNode; CheckValueType(intCastNode, inner, outer); break; case NodeType.DoubleCast: DoubleCastNode doubleCastNode = node as DoubleCastNode; CheckValueType(doubleCastNode, inner, outer); break; case NodeType.Not: NotNode notNode = node as NotNode; CheckValueType(notNode, inner, outer); break; case NodeType.Minus: MinusNode minusNode = node as MinusNode; CheckValueType(minusNode, inner, outer); break; case NodeType.Neg: NegNode negNode = node as NegNode; CheckValueType(negNode, inner, outer); break; } }
protected override void DoAction(int action) { #pragma warning disable 162, 1522 switch (action) { case 2: // start -> Program, block, EOF #line 22 "D:\MINICompiler\kompilator.y" { if (syntaxErrorLines.Count != 0) { YYAbort(); } ProgramTree.block = ValueStack[ValueStack.Depth - 2] as BlockNode; ProgramTree.Line = ValueStack[ValueStack.Depth - 3].Line; } #line default break; case 3: // block -> OpenBracket, lines, CloseBracket #line 34 "D:\MINICompiler\kompilator.y" { BlockNode node; if (ValueStack[ValueStack.Depth - 2] is null) { node = new BlockNode(); } else { node = new BlockNode(ValueStack[ValueStack.Depth - 2] as BlockNode); } node.Line = ValueStack[ValueStack.Depth - 3].Line; CurrentSemanticValue = node; } #line default break; case 5: // lines -> lines, instruction #line 44 "D:\MINICompiler\kompilator.y" { BlockNode node; if (ValueStack[ValueStack.Depth - 2] is null) { node = new BlockNode(); } else { node = new BlockNode(ValueStack[ValueStack.Depth - 2] as BlockNode); } node.instructions.Add(ValueStack[ValueStack.Depth - 1]); CurrentSemanticValue = node; } #line default break; case 6: // lines -> EOF #line 52 "D:\MINICompiler\kompilator.y" { syntaxErrorLines.Add(ProgramTree.LineCount); YYAbort(); } #line default break; case 11: // instruction -> exp, Semicolon #line 62 "D:\MINICompiler\kompilator.y" { ExpressionNode node = ValueStack[ValueStack.Depth - 2] as ExpressionNode; node.ShouldReturnValue = false; } #line default break; case 15: // instruction -> Semicolon #line 70 "D:\MINICompiler\kompilator.y" { syntaxErrorLines.Add(ValueStack[ValueStack.Depth - 1].Line); } #line default break; case 16: // instruction -> error #line 74 "D:\MINICompiler\kompilator.y" { syntaxErrorLines.Add(ValueStack[ValueStack.Depth - 1].Line); } #line default break; case 17: // write -> Write, String #line 80 "D:\MINICompiler\kompilator.y" { WriteNode node = new WriteNode(ValueStack[ValueStack.Depth - 2].Line); node.content = ValueStack[ValueStack.Depth - 1]; CurrentSemanticValue = node; } #line default break; case 18: // write -> Write, exp #line 86 "D:\MINICompiler\kompilator.y" { WriteNode node = new WriteNode(ValueStack[ValueStack.Depth - 2].Line); node.content = ValueStack[ValueStack.Depth - 1] as ExpressionNode; CurrentSemanticValue = node; } #line default break; case 19: // read -> Read, Variable #line 93 "D:\MINICompiler\kompilator.y" { ReadNode node = new ReadNode(ValueStack[ValueStack.Depth - 2].Line); node.target = ValueStack[ValueStack.Depth - 1] as VariableNode; CurrentSemanticValue = node; } #line default break; case 20: // init -> Int, Variable #line 100 "D:\MINICompiler\kompilator.y" { InitNode node = new InitNode(ValueStack[ValueStack.Depth - 2].Line); node.variable = ValueStack[ValueStack.Depth - 1] as VariableNode; node.variable.ValType = ValType.Int; CurrentSemanticValue = node; } #line default break; case 21: // init -> Double, Variable #line 108 "D:\MINICompiler\kompilator.y" { InitNode node = new InitNode(ValueStack[ValueStack.Depth - 2].Line); node.variable = ValueStack[ValueStack.Depth - 1] as VariableNode; node.variable.ValType = ValType.Double; CurrentSemanticValue = node; } #line default break; case 22: // init -> Bool, Variable #line 115 "D:\MINICompiler\kompilator.y" { InitNode node = new InitNode(ValueStack[ValueStack.Depth - 2].Line); node.variable = ValueStack[ValueStack.Depth - 1] as VariableNode; node.variable.ValType = ValType.Bool; CurrentSemanticValue = node; } #line default break; case 23: // assign -> Variable, Assign, exp #line 123 "D:\MINICompiler\kompilator.y" { AssignNode node = new AssignNode(ValueStack[ValueStack.Depth - 3].Line); node.left = ValueStack[ValueStack.Depth - 3] as VariableNode; node.right = ValueStack[ValueStack.Depth - 1]; node.ShouldReturnValue = true; CurrentSemanticValue = node; } #line default break; case 24: // exp -> OpenPar, exp, ClosePar #line 133 "D:\MINICompiler\kompilator.y" { ParenthesisNode node = new ParenthesisNode(ValueStack[ValueStack.Depth - 3].Line); node.content = ValueStack[ValueStack.Depth - 2] as ExpressionNode; CurrentSemanticValue = node; } #line default break; case 25: // exp -> exp, Add, exp #line 139 "D:\MINICompiler\kompilator.y" { BinaryOpNode node = ValueStack[ValueStack.Depth - 2] as BinaryOpNode; CurrentSemanticValue = AssignToBinaryOp(node, ValueStack[ValueStack.Depth - 3] as ExpressionNode, ValueStack[ValueStack.Depth - 1] as ExpressionNode); } #line default break; case 26: // exp -> exp, Sub, exp #line 144 "D:\MINICompiler\kompilator.y" { BinaryOpNode node = ValueStack[ValueStack.Depth - 2] as BinaryOpNode; CurrentSemanticValue = AssignToBinaryOp(node, ValueStack[ValueStack.Depth - 3] as ExpressionNode, ValueStack[ValueStack.Depth - 1] as ExpressionNode); } #line default break; case 27: // exp -> exp, Mult, exp #line 149 "D:\MINICompiler\kompilator.y" { BinaryOpNode node = ValueStack[ValueStack.Depth - 2] as BinaryOpNode; CurrentSemanticValue = AssignToBinaryOp(node, ValueStack[ValueStack.Depth - 3] as ExpressionNode, ValueStack[ValueStack.Depth - 1] as ExpressionNode); } #line default break; case 28: // exp -> exp, Div, exp #line 154 "D:\MINICompiler\kompilator.y" { BinaryOpNode node = ValueStack[ValueStack.Depth - 2] as BinaryOpNode; CurrentSemanticValue = AssignToBinaryOp(node, ValueStack[ValueStack.Depth - 3] as ExpressionNode, ValueStack[ValueStack.Depth - 1] as ExpressionNode); } #line default break; case 29: // exp -> exp, BitAnd, exp #line 159 "D:\MINICompiler\kompilator.y" { BinaryOpNode node = ValueStack[ValueStack.Depth - 2] as BinaryOpNode; CurrentSemanticValue = AssignToBinaryOp(node, ValueStack[ValueStack.Depth - 3] as ExpressionNode, ValueStack[ValueStack.Depth - 1] as ExpressionNode); } #line default break; case 30: // exp -> exp, BitOr, exp #line 164 "D:\MINICompiler\kompilator.y" { BinaryOpNode node = ValueStack[ValueStack.Depth - 2] as BinaryOpNode; CurrentSemanticValue = AssignToBinaryOp(node, ValueStack[ValueStack.Depth - 3] as ExpressionNode, ValueStack[ValueStack.Depth - 1] as ExpressionNode); } #line default break; case 32: // exp -> IntCast, exp #line 170 "D:\MINICompiler\kompilator.y" { IntCastNode node = new IntCastNode(ValueStack[ValueStack.Depth - 2].Line); node.content = ValueStack[ValueStack.Depth - 1] as ExpressionNode; CurrentSemanticValue = node; } #line default break; case 33: // exp -> DoubleCast, exp #line 176 "D:\MINICompiler\kompilator.y" { DoubleCastNode node = new DoubleCastNode(ValueStack[ValueStack.Depth - 2].Line); node.content = ValueStack[ValueStack.Depth - 1] as ExpressionNode; CurrentSemanticValue = node; } #line default break; case 37: // exp -> Not, exp #line 185 "D:\MINICompiler\kompilator.y" { NotNode node = new NotNode(ValueStack[ValueStack.Depth - 2].Line); node.content = ValueStack[ValueStack.Depth - 1] as ExpressionNode; CurrentSemanticValue = node; } #line default break; case 38: // exp -> Tilde, exp #line 191 "D:\MINICompiler\kompilator.y" { NegNode node = new NegNode(ValueStack[ValueStack.Depth - 2].Line); node.content = ValueStack[ValueStack.Depth - 1] as ExpressionNode; CurrentSemanticValue = node; } #line default break; case 39: // exp -> Sub, exp #line 197 "D:\MINICompiler\kompilator.y" { MinusNode node = new MinusNode(ValueStack[ValueStack.Depth - 2].Line); node.content = ValueStack[ValueStack.Depth - 1] as ExpressionNode; CurrentSemanticValue = node; } #line default break; case 40: // exp -> exp, And, exp #line 203 "D:\MINICompiler\kompilator.y" { LogicOpNode node = ValueStack[ValueStack.Depth - 2] as LogicOpNode; node.left = ValueStack[ValueStack.Depth - 3] as ExpressionNode; node.right = ValueStack[ValueStack.Depth - 1] as ExpressionNode; CurrentSemanticValue = node; } #line default break; case 41: // exp -> exp, Or, exp #line 210 "D:\MINICompiler\kompilator.y" { LogicOpNode node = ValueStack[ValueStack.Depth - 2] as LogicOpNode; node.left = ValueStack[ValueStack.Depth - 3] as ExpressionNode; node.right = ValueStack[ValueStack.Depth - 1] as ExpressionNode; CurrentSemanticValue = node; } #line default break; case 42: // exp -> exp, Comparison, exp #line 217 "D:\MINICompiler\kompilator.y" { ComparisonNode node = ValueStack[ValueStack.Depth - 2] as ComparisonNode; CurrentSemanticValue = AssignToComparisonOp(node, ValueStack[ValueStack.Depth - 3] as ExpressionNode, ValueStack[ValueStack.Depth - 1] as ExpressionNode); } #line default break; case 44: // if -> If, OpenPar, exp, ClosePar, instruction #line 225 "D:\MINICompiler\kompilator.y" { IfNode node = new IfNode(ValueStack[ValueStack.Depth - 5].Line); node.check = ValueStack[ValueStack.Depth - 3] as ExpressionNode; node.ifBlock = ValueStack[ValueStack.Depth - 1]; CurrentSemanticValue = node; } #line default break; case 45: // if -> If, OpenPar, exp, ClosePar, instruction, Else, instruction #line 232 "D:\MINICompiler\kompilator.y" { IfNode node = new IfNode(ValueStack[ValueStack.Depth - 7].Line); node.check = ValueStack[ValueStack.Depth - 5] as ExpressionNode; node.elseBlock = ValueStack[ValueStack.Depth - 1]; node.ifBlock = ValueStack[ValueStack.Depth - 3]; CurrentSemanticValue = node; } #line default break; case 46: // while -> While, OpenPar, exp, ClosePar, instruction #line 241 "D:\MINICompiler\kompilator.y" { WhileNode node = new WhileNode(ValueStack[ValueStack.Depth - 5].Line); node.check = ValueStack[ValueStack.Depth - 3] as ExpressionNode; node.block = ValueStack[ValueStack.Depth - 1]; CurrentSemanticValue = node; } #line default break; } #pragma warning restore 162, 1522 }