private void CalculateTypeForNodes(IAstNode exprNode) { if (exprNode.AstNodeType == AstNodeTypes.BinaryOperator) { var binOpNode = exprNode.AsBinaryOp(); CalculateTypeForNodes(binOpNode.LeftOperand); binOpNode.TypeName = binOpNode.LeftOperand.AsNodeWithType().TypeName; CalculateTypeForNodes(binOpNode.RightOperand); } else if (exprNode.AstNodeType == AstNodeTypes.UnaryOperator) { CalculateTypeForNodes(exprNode.AsUnaryOp().Operand); } else if (exprNode.AstNodeType == AstNodeTypes.VarReference) { var varRef = exprNode.AsVarReferene(); if (!_symbolTable.ContainsKey(varRef.Name)) { throw new SemanticErrorException($"Variable '{varRef.Name}' is not declared.", exprNode); } exprNode.AsVarReferene().TypeName = _symbolTable[varRef.Name]; } }
private void CheckNodeType(IAstNode exprNode) { if (exprNode.AstNodeType == AstNodeTypes.BinaryOperator) { var binOpNode = exprNode.AsBinaryOp(); CheckNodeType(binOpNode.LeftOperand); CheckNodeType(binOpNode.RightOperand); if (binOpNode.LeftOperand.AsNodeWithType().TypeName != binOpNode.RightOperand.AsNodeWithType().TypeName) { throw new SemanticErrorException("Type mismatch.", binOpNode); } } else if (exprNode.AstNodeType == AstNodeTypes.UnaryOperator) { var unaryOpNode = exprNode.AsUnaryOp(); CheckNodeType(unaryOpNode.Operand); if (unaryOpNode.TypeName != unaryOpNode.Operand.AsNodeWithType().TypeName) { throw new SemanticErrorException("Type mismatch.", unaryOpNode); } } }
public void Traverse(IAstNode astNode) { ProcessNode?.Invoke(astNode); switch (astNode.AstNodeType) { case AstNodeTypes.VarStatement: Traverse(astNode.AsVarStatement().Expression); break; case AstNodeTypes.PrintStatement: foreach (var printExpr in astNode.AsPrintStatement().PrintExpressions) { Traverse(printExpr); } break; case AstNodeTypes.PrintExpression: Traverse(astNode.AsPrintExpression().Expression); break; case AstNodeTypes.UnaryOperator: Traverse(astNode.AsUnaryOp().Operand); break; case AstNodeTypes.BinaryOperator: Traverse(astNode.AsBinaryOp().LeftOperand); Traverse(astNode.AsBinaryOp().RightOperand); break; case AstNodeTypes.NumberLiteral: break; case AstNodeTypes.StringLiteral: break; case AstNodeTypes.VarReference: break; } PostProcessNode?.Invoke(astNode.AstNodeType); }