public bool Visit(DereferenceOperator node) { if (node.SymType != null) { return(true); } node.Expr.Accept(this); if (!node.Expr.IsLValue) { throw new Exception(string.Format( "({0}, {1}) semantic error: expression '{2}' is not lvalue", node.Expr.Token.Line, node.Expr.Token.Column, node.Expr.ToString())); } if (!(node.Expr.SymType is SymPointerType)) { throw new Exception(string.Format( "({0}, {1}) semantic error: expression '{2}' is not a pointer", node.Expr.Token.Line, node.Expr.Token.Column, node.Expr.ToString())); } node.SymType = ((SymPointerType)node.Expr.SymType).ReferencedSymType; return(true); }
public AstPrinterNode Visit(DereferenceOperator node) { var printer = new AstPrinterNode(node.ToString()); printer.AddChild(node.Expr.Accept(this)); return(printer); }
private Expression ParseVariableReference() { var token = PeekToken(); AstNode left = ParseIdent(); if (left == null) { return(null); // this is not variable ref } bool breakWhile = false; while (!breakWhile) { token = PeekToken(); switch (token.Type) { case TokenType.OpenSquareBracket: { NextToken(); var paramList = ParseParamList(); if (paramList == null || paramList.Count == 0) { throw new Exception(string.Format( "({0}, {1}) syntax error: indexes expected, but {2} found", PeekToken().Line, PeekToken().Column, PeekToken().Lexeme)); } token = PeekToken(); CheckToken(PeekToken().Type, new List <TokenType> { TokenType.CloseSquareBracket }, string.Format("({0}, {1}) syntax error: ']' expected, but {2} found", PeekToken().Line, PeekToken().Column, PeekAndNext().Lexeme)); if (!(left is Ident || left is RecordAccess || left is ArrayAccess)) { throw new Exception(string.Format( "({0}, {1}) syntax error: accessing array must be identifier", left.Token.Line, left.Token.Column, left.Token.Lexeme)); } left = new ArrayAccess(left as Expression, paramList); break; } case TokenType.Dot: { NextToken(); var field = ParseIdent(); if (field == null) { throw new Exception(string.Format( "({0}, {1}) syntax error: field ident expected, but {2} found", PeekToken().Line, PeekToken().Column, PeekToken().Lexeme)); } // if (!(field is Ident)) // { // throw new Exception(string.Format( // "{0}, {1} : syntax error, accessing field must be identifier", // field.Token.Line, field.Token.Column, field.Token.Lexeme)); // } left = new RecordAccess(left as Expression, field as Ident); break; } case TokenType.OpenBracket: { token = NextAndPeek(); var paramList = ParseParamList(); if (paramList == null) { throw new Exception(string.Format( "({0}, {1}) syntax error: parameters list expected, but {2} found", PeekToken().Line, PeekToken().Column, PeekToken().Lexeme)); } CheckToken(PeekToken().Type, new List <TokenType> { TokenType.CloseBracket }, string.Format("({0}, {1}) syntax error: ')' expected, but {2} found", PeekToken().Line, PeekToken().Column, PeekAndNext().Lexeme)); if (!(left is Ident)) { throw new Exception(string.Format( "({0}, {1}) syntax error: accessing field must be identifier", left.Token.Line, left.Token.Column, left.Token.Lexeme)); } left = left.Token.Type == TokenType.Write || left.Token.Type == TokenType.WriteLn ? (AstNode) new WriteFunctionCall((Ident)left, paramList, left.Token.Type == TokenType.WriteLn) : new UserFunctionCall((Ident)left, paramList); break; } case TokenType.Carriage: { if (left.NodeType == AstNodeType.DereferenceOperator) { throw new Exception(string.Format("({0}, {1}) syntax error: double carriage found", PeekToken().Line, PeekToken().Column, PeekToken().Lexeme)); } var carriageToken = PeekAndNext(); left = new DereferenceOperator(carriageToken, left as Expression); break; } default: { breakWhile = true; break; } } } return(left as Expression); }