/// <summary> /// Parse /// </summary> /// <returns>Base block</returns> public Block Parse() { Block baseBlock = new Block(null), actualBlock = baseBlock; int level = 0; while (HasNextToken()) { #region Class Parsing if (Match(TokenType.CLASS)) { Token classToken = Pop(); if (Match(TokenType.IDENTIFIER)) { Token nameToken = Pop(); actualBlock.AddBlock(actualBlock = new Class(actualBlock, nameToken.Value)); level++; } else Logger.Error("You must specify a name for your class."); } #endregion #region Method declaration parsing else if (Match(TokenType.FUNCTION)) { Token methodToken = Pop(); if (Match(TokenType.IDENTIFIER)) { Token nameToken = Pop(); if (Match(TokenType.OPENPAREN)) { Pop(); // Pop the open parenthesis List<Parameter> parameters = new List<Parameter>(); while (true) { if (MatchOneOfThem(new TokenType[] { TokenType.BOOL, TokenType.INT, TokenType.STRING, TokenType.FLOAT, TokenType.IDENTIFIER })) { TokenType argType = Pop().Type; if (Match(TokenType.IDENTIFIER)) { string argName = Pop().Value; parameters.Add(new Parameter((VariableType)argType, argName)); if (Match(TokenType.COMMA)) { Pop(); // Pop the comma continue; } else break; } else Logger.Error("You need to set a name for your parameter"); } else break; } if (!Match(TokenType.CLOSEPAREN)) Logger.Error("You need to close parenthesis after put parameters"); else Pop(); // Pop the parenthesis TokenType returnType = TokenType.UNKNOWN; if (Match(TokenType.RETURN)) { Pop(); // Pop the return keyword if (!MatchOneOfThem(new TokenType[] { TokenType.BOOL, TokenType.IDENTIFIER, TokenType.INT, TokenType.STRING, TokenType.FLOAT, TokenType.VOID })) Logger.Error("Wrong return type for your function"); else returnType = Pop().Type; } else Logger.Error("You need to set return type"); actualBlock.AddBlock(actualBlock = new Method(actualBlock, nameToken.Value, (VariableType)returnType, parameters.ToArray())); level++; } else Logger.Error("You need to open parenthesis for function declaration."); } else Logger.Error("You must specify a name for your method."); } #endregion #region Constructor parsing else if (Match(TokenType.CONSTRUCTOR)) { Token constructorToken = Pop(); if (Match(TokenType.OPENPAREN)) { Pop(); List<Parameter> parameters = new List<Parameter>(); while (true) { if (MatchOneOfThem(new TokenType[] { TokenType.BOOL, TokenType.INT, TokenType.STRING, TokenType.FLOAT, TokenType.IDENTIFIER })) { Token argType = Pop(); if (Match(TokenType.IDENTIFIER)) { string argName = Pop().Value; if ((VariableType)argType.Type == VariableType.CUSTOM) parameters.Add(new Parameter((VariableType)argType.Type, argName, argType.Value)); else parameters.Add(new Parameter((VariableType)argType.Type, argName)); if (Match(TokenType.COMMA)) { Pop(); // Pop the comma continue; } else break; } else Logger.Error("You need to set a name for your parameter"); } else break; } if (!Match(TokenType.CLOSEPAREN)) Logger.Error("You need to close parenthesis after put parameters"); else Pop(); // Pop the parenthesis actualBlock.AddBlock(actualBlock = new Constructor(actualBlock, parameters.ToArray())); level++; } else Logger.Error("You need to open parenthesis after constructor."); } #endregion #region Variable declaration parsing else if (MatchOneOfThem(new TokenType[] { TokenType.BOOL, TokenType.STRING, TokenType.INT, TokenType.FLOAT })) { if (actualBlock.GetType() == typeof(Block)) Logger.Error("Variable can only be delcared inside a class, function..."); Token typeToken = Pop(); if (Match(TokenType.IDENTIFIER)) { Token nameToken = Pop(); actualBlock.AddBlock(new VariableDeclarationStatement(actualBlock, nameToken.Value, (VariableType)typeToken.Type)); if (Match(TokenType.ASSIGN)) { Pop(); // Pop the assign char actualBlock.AddBlock(new AssignStatement(actualBlock, nameToken.Value, AssignType.EQUAL, Exp(actualBlock))); } } else Logger.Error("You must specify a name for your variable."); } #endregion #region Identifier parsing -> Custom object declaration, method call ... else if (Match(TokenType.IDENTIFIER)) { Token identifierToken = Pop(); if (Match(TokenType.IDENTIFIER)) // Custom object declaration { Token nameToken = Pop(); actualBlock.AddBlock(new VariableDeclarationStatement(actualBlock, nameToken.Value, VariableType.CUSTOM, identifierToken.Value)); if (Match(TokenType.ASSIGN)) { Pop(); // Pop the assign char actualBlock.AddBlock(new AssignStatement(actualBlock, nameToken.Value, AssignType.EQUAL, Exp(actualBlock))); } } else if (Match(TokenType.ASSIGN)) { Pop(); // Pop the assign char actualBlock.AddBlock(new AssignStatement(actualBlock, identifierToken.Value, AssignType.EQUAL, Exp(actualBlock))); } } #endregion #region Condition parsing else if (Match(TokenType.IF)) { Pop(); // Pop the if keyword if (Match(TokenType.OPENPAREN)) { Pop(); // Pop the paren List<IExpression> leftExp = Exp(actualBlock); if (MatchOneOfThem(new TokenType[] { TokenType.DIFFERENT, TokenType.EQUAL, TokenType.GREATER, TokenType.GREATEREQUAL, TokenType.LESS, TokenType.LESSEQUAL })) { Token compToken = Pop(); List<IExpression> rightExp = Exp(actualBlock); if (Match(TokenType.CLOSEPAREN)) { Pop(); // Pop the paren actualBlock.AddBlock(actualBlock = new ConditionStatement(actualBlock, leftExp, rightExp, compToken.Type)); level++; } else Logger.Error("You need to close parenthesis after if condition"); } else Logger.Error("Wrong comparison operator for if"); } else Logger.Error("You must open parenthesis after if keyword"); } else if (Match(TokenType.ELSE)) { if (!(actualBlock is ConditionStatement) && !(actualBlock is ElseIfStatement)) Logger.Error("Cant declare else statement without if before."); Pop(); // Pop the else keyword if (Match(TokenType.IF)) { Pop(); // Pop the if keyword if (Match(TokenType.OPENPAREN)) { Pop(); // Pop the paren List<IExpression> leftExp = Exp(actualBlock); if (MatchOneOfThem(new TokenType[] { TokenType.DIFFERENT, TokenType.EQUAL, TokenType.GREATER, TokenType.GREATEREQUAL, TokenType.LESS, TokenType.LESSEQUAL })) { Token compToken = Pop(); List<IExpression> rightExp = Exp(actualBlock); if (Match(TokenType.CLOSEPAREN)) { Pop(); // Pop the paren if (actualBlock is ElseIfStatement) actualBlock = actualBlock.SuperBlock; actualBlock.AddBlock(actualBlock = new ElseIfStatement(actualBlock, leftExp, rightExp, compToken.Type)); } else Logger.Error("You need to close parenthesis after else if condition"); } else Logger.Error("Wrong comparison operator for else if"); } else Logger.Error("You must open parenthesis after else if keyword"); } else { if (actualBlock is ElseIfStatement) actualBlock = actualBlock.SuperBlock; actualBlock.AddBlock(actualBlock = new ElseStatement(actualBlock)); } } #endregion #region Print parsing else if (Match(TokenType.PRINT)) { Pop(); // Pop print if (Match(TokenType.OPENPAREN)) { Pop(); // Pop parenthesis actualBlock.AddBlock(new PrintStatement(actualBlock, Exp(actualBlock))); if (!Match(TokenType.CLOSEPAREN)) Logger.Error("You need to close parenthesis after function call"); else Pop(); // Pop parenthesis } } #endregion #region Return parsing else if (Match(TokenType.RETURN)) { Pop(); // Pop the return keyword actualBlock.AddBlock(new ReturnStatement(actualBlock, Exp(actualBlock))); } #endregion #region End parsing else if (Match(TokenType.END)) { Pop(); // Pop the end keyword if (actualBlock is ElseStatement || actualBlock is ElseIfStatement) actualBlock = actualBlock.SuperBlock; level--; if (level < 0) Logger.Error("Useful end"); actualBlock = actualBlock.SuperBlock; } #endregion else Pop(); //TODO FINISH PARSER } return baseBlock; }
/// <summary> /// Main constructor /// </summary> /// <param name="superBlock">Super block</param> /// <param name="parameters">Parameters</param> public Constructor(Block superBlock, Parameter[] parameters) : base(superBlock) { Parameters = parameters; if (superBlock is Class) ClassBlock = superBlock as Class; }