public FunctionCallConstruct(IdentifierConstruct callee, IList<IRvalueConstruct> parameters) {
            Contract.Requires(callee != null);
            Contract.Requires(parameters != null);

            Callee = callee;
            Parameters = parameters;
        }
        public FunctionConstruct(IdentifierConstruct name, ICollection<IdentifierConstruct> parameters, ExectuableBlockConstruct controlBlock) {
            Contract.Requires(name != null);
            Contract.Requires(parameters != null);
            Contract.Requires(controlBlock != null);

            Name = name;
            Parameters = parameters;
            ControlBlock = controlBlock;

        }
        private FunctionConstruct ProcessAsFunction() {

            GetNextTokenAsserted(Token.KW_FUNC);

            var name = new IdentifierConstruct(GetNextTokenAsserted(Token.IDENTIFIER).Capture);
            
            // parse parameters
            var parameters = new List<IdentifierConstruct>();

            GetNextTokenAsserted(Token.RE_L_PAREN);
            while (PeekNextToken() != Token.RE_R_PAREN) {
                switch (PeekNextToken()) {

                    case Token.IDENTIFIER:
                        if (PeekNextToken(1) != Token.RE_R_PAREN && PeekNextToken(1) != Token.RE_COMMA)
                            throw new LexerException(ErrorCode.ErrorForCode("LEX1"), Token.RE_R_PAREN, PeekNextToken(1));
                        parameters.Add(new IdentifierConstruct(GetNextToken().Capture));
                        break;

                    case Token.RE_COMMA:
                        if (PeekNextToken(1) != Token.IDENTIFIER)
                            throw new LexerException(ErrorCode.ErrorForCode("LEX1"), Token.IDENTIFIER, PeekNextToken(1));
                        GetNextToken();
                        break;

                    default:
                        throw new LexerException(ErrorCode.ErrorForCode("LEX1"), Token.IDENTIFIER, PeekNextToken());
                }

            }
            GetNextTokenAsserted(Token.RE_R_PAREN);
            GetNextTokenAsserted(Token.RE_COLON);
            SkipNewLines();
            
            return new FunctionConstruct(name, parameters, ProcessAsBlock());
        }
        private FunctionCallConstruct ProcessAsFunctionCall() {
            var identifier = new IdentifierConstruct(GetNextTokenAsserted(Token.IDENTIFIER).Capture);
            SkipTokensAsserted(Token.RE_L_PAREN);

            var parameters = new List<IRvalueConstruct>();

            var endOfExpression = true;
            while (PeekNextToken() != Token.RE_R_PAREN) {
                if (!endOfExpression)
                    SkipTokensAsserted(Token.RE_COMMA);
                else
                    endOfExpression = false;
                parameters.Add(ProcessAsRvalue());
            }

            SkipTokensAsserted(Token.RE_R_PAREN);
            return new FunctionCallConstruct(identifier, parameters);
        }
        public VariableConstruct(IdentifierConstruct name) {
            Contract.Requires(name != null);

            Name = name;
        }