コード例 #1
0
 public IAstNode CreateIAstNode(IAstNode beforeNode, string token)
 {
     if ((token[0] == '@' || token[0] == ':') && token.Length > 1)
     {
         // If the variable name is quoted
         if (token[1] == '"' || token[1] == '\'')
         {
             //_regex r2 = new _regex(@"^(((""[^""\\]*(?:\\.[^""\\]*)*(""|$))+)|(('[^'\\]*(?:\\.[^'\\]*)*('|$))+))\s");
             //TODO Valiable Node
             //return new ASTNode(   TokenType.VARIABLE
             //                ,   token[0] + r2.Match(token.Substring(1)).OriginalValue);
         }
         else
         {
             Match match = _regex.Match(token);
             if (match.Success)
             {
                 //TODO ValiableNode
                 //return new ASTNode(   TokenType.VARIABLE
                 //                ,   m3.OriginalValue
                 //                );
             }
         }
     }
     return null;
 }
コード例 #2
0
ファイル: NullExpression.cs プロジェクト: Microsoft/RTVS
        public override bool Parse(ParseContext context, IAstNode parent) {
            if (context.Tokens.CurrentToken.TokenType == RTokenType.OpenBrace) {
                context.AddError(new ParseError(ParseErrorType.UnexpectedToken, ErrorLocation.Token, context.Tokens.CurrentToken));
            }

            return false;
        }
コード例 #3
0
ファイル: FunctionDefinition.cs プロジェクト: Microsoft/RTVS
        public override bool Parse(ParseContext context, IAstNode parent) {
            TokenStream<RToken> tokens = context.Tokens;

            Debug.Assert(tokens.CurrentToken.TokenType == RTokenType.Keyword);
            this.Keyword = RParser.ParseKeyword(context, this);
            this.Text = context.TextProvider.GetText(this.Keyword);

            if (tokens.CurrentToken.TokenType == RTokenType.OpenBrace) {
                this.OpenBrace = RParser.ParseToken(context, this);

                this.Arguments = new ArgumentList(RTokenType.CloseBrace);
                this.Arguments.Parse(context, this);

                if (tokens.CurrentToken.TokenType == RTokenType.CloseBrace) {
                    this.CloseBrace = RParser.ParseToken(context, this);
                    this.Scope = RParser.ParseScope(context, this, allowsSimpleScope: true, terminatingKeyword: null);
                    if (this.Scope != null) {
                        return base.Parse(context, parent);
                    } else {
                        context.AddError(new ParseError(ParseErrorType.FunctionBodyExpected, ErrorLocation.Token, tokens.PreviousToken));
                    }
                } else {
                    context.AddError(new ParseError(ParseErrorType.CloseBraceExpected, ErrorLocation.Token, tokens.CurrentToken));
                }
            } else {
                context.AddError(new ParseError(ParseErrorType.OpenBraceExpected, ErrorLocation.Token, tokens.CurrentToken));
            }

            return false;
        }
コード例 #4
0
        protected override CommaSeparatedItem CreateItem(IAstNode parent, ParseContext context) {
            RToken currentToken = context.Tokens.CurrentToken;
            RToken nextToken = context.Tokens.NextToken;

            switch (currentToken.TokenType) {
                case RTokenType.Ellipsis:
                    return new EllipsisArgument();

                case RTokenType.Comma:
                    return new MissingArgument();

                case RTokenType.Identifier:
                case RTokenType.String:
                case RTokenType.Logical:
                case RTokenType.Complex:
                case RTokenType.NaN:
                case RTokenType.Null:
                case RTokenType.Number:
                case RTokenType.Infinity:
                    if (nextToken.TokenType == RTokenType.Operator && context.TextProvider.GetText(nextToken) == "=") {
                        return new NamedArgument();
                    }
                    break;

                case RTokenType.CloseBrace:
                    return null; // no arguments supplied
            }

            return new ExpressionArgument();
        }
コード例 #5
0
ファイル: AstRoot.cs プロジェクト: Microsoft/RTVS
        public override bool Parse(ParseContext context, IAstNode parent) {
            // Remove comments from the token stream
            this.Comments = new CommentsCollection(context.Comments);

            GlobalScope globalScope = new GlobalScope();
            return globalScope.Parse(context, this);
        }
コード例 #6
0
ファイル: Expression.cs プロジェクト: Microsoft/RTVS
        public override bool Parse(ParseContext context, IAstNode parent) {
            if (ParseExpression(context) && this.Children.Count > 0) {
                return base.Parse(context, parent);
            }

            return false;
        }
コード例 #7
0
 public StatementIndent(IAstNode node)
 {
     BeforeNode = node.BeforeNode;
     AfterNode = node;
     node.BeforeNode = this;
     ParentNode = (Statement)node.ParentNode;
 }
コード例 #8
0
ファイル: JumpAstVisitor.cs プロジェクト: scemino/nscumm
 protected override void DefaultVisit(IAstNode node)
 {
     foreach (var child in node.Children)
     {
         child.Accept(this);
     }
 }
コード例 #9
0
        private void BuildAddIndexNode(IIndexDefinition index, IAstNode parent)
        {
            IAddIndexNode addIndexNode = new AddIndexNode(parent, index.Name);
            parent.ChildNodes.Add(addIndexNode);

            SemanticModelUtil.Copy(index, addIndexNode);
        }
コード例 #10
0
ファイル: If.cs プロジェクト: Microsoft/RTVS
        public override bool Parse(ParseContext context, IAstNode parent) {
            // First parse base which should pick up keyword, braces, inner
            // expression and either full or simple (single statement) scope
            if (!base.Parse(context, parent)) {
                return false;
            }

            // At this point we should be either at 'else' token or 
            // at the next statement. In the latter case we are done.
            TokenStream<RToken> tokens = context.Tokens;

            if (tokens.CurrentToken.IsKeywordText(context.TextProvider, "else")) {
                bool allowLineBreak = AllowLineBreakBeforeElse(context);
                if (!allowLineBreak) {
                    // Verify that there is no line break before the 'else'
                    if (context.Tokens.IsLineBreakAfter(context.TextProvider, tokens.Position - 1)) {
                        context.AddError(new ParseError(ParseErrorType.UnexpectedToken, ErrorLocation.Token, tokens.CurrentToken));
                        return true;
                    }
                }
                this.Else = new KeywordScopeStatement(allowsSimpleScope: true);
                return this.Else.Parse(context, this);
            }

            // Not at 'else' so we are done here
            return true;
        }
コード例 #11
0
        public override bool Parse(ParseContext context, IAstNode parent) {
            TokenStream<RToken> tokens = context.Tokens;

            if (tokens.CurrentToken.IsVariableKind()) {
                var v = new Variable();
                v.Parse(context, this);

                // Variables don't set parent since during complex
                // exression parsing parent is determined by the
                // expression parser based on precedence and grouping.
                v.Parent = this; 
                this.Variable = v;

                if (tokens.CurrentToken.IsKeywordText(context.TextProvider, "in")) {
                    this.InOperator = new TokenNode();
                    this.InOperator.Parse(context, this);

                    this.Expression = new Expression(inGroup: true);
                    if (this.Expression.Parse(context, this)) {
                        return base.Parse(context, parent);
                    }
                } else {
                    context.AddError(new MissingItemParseError(ParseErrorType.InKeywordExpected, tokens.CurrentToken));
                }
            } else {
                context.AddError(new MissingItemParseError(ParseErrorType.IndentifierExpected, tokens.PreviousToken));
            }

            return false;
        }
コード例 #12
0
ファイル: Debug.cs プロジェクト: AlexanderSher/RTVS-Old
        public static void CompareNodes(EditorTree editorTree, IAstNode node1, IAstNode node2)
        {
#if ___DEBUG
            Debug.Assert(node1 is RootNode || editorTree.ParseTree.ContainsElement(node1.Key));

            if (!node1.ChildrenInvalidated)
                Debug.Assert(node1.Children.Count == node2.Children.Count);

            Debug.Assert(TextRange.AreEqual(node1.NameRange, node2.NameRange));
            Debug.Assert(node1.Attributes.Count == node2.Attributes.Count);

            Debug.Assert(TextRange.AreEqual(node1.OuterRange, node2.OuterRange));
            Debug.Assert(TextRange.AreEqual(node1.InnerRange, node2.InnerRange));

            Debug.Assert(node1.Start == node2.Start);
            Debug.Assert(node1.End == node2.End);

            if (!node1.ChildrenInvalidated)
            {
                if (node1.Children.Count == node2.Children.Count)
                {
                    for (int i = 0; i < node1.Children.Count; i++)
                    {
                        CompareNodes(editorTree, node1.Children[i], node2.Children[i]);
                    }
                }
            }
#endif
        }
コード例 #13
0
        public override bool Parse(ParseContext context, IAstNode parent) {
            if (context.Tokens.CurrentToken.TokenType == RTokenType.Comma) {
                this.Comma = RParser.ParseToken(context, this);
            }

            return base.Parse(context, parent);
        }
コード例 #14
0
ファイル: ParserHelpers.cs プロジェクト: Microsoft/RTVS
        public static TokenNode ParseToken(ParseContext context, IAstNode parent) {
            TokenStream<RToken> tokens = context.Tokens;
            TokenNode node = new TokenNode();

            node.Parse(context, parent);
            return node;
        }
コード例 #15
0
ファイル: NamedArgument.cs プロジェクト: int19h/RTVS-OLD
        public override bool Parse(ParseContext context, IAstNode parent) {
            TokenStream<RToken> tokens = context.Tokens;

            Debug.Assert(context.Tokens.CurrentToken.TokenType == RTokenType.Identifier || 
                         context.Tokens.CurrentToken.TokenType == RTokenType.String);

            this.Identifier = RParser.ParseToken(context, this);
            this.EqualsSign = RParser.ParseToken(context, this);

            if (context.Tokens.CurrentToken.TokenType != RTokenType.Comma && context.Tokens.CurrentToken.TokenType != RTokenType.CloseBrace) {
                Expression exp = new Expression(inGroup: true);
                if (exp.Parse(context, this)) {
                    this.DefaultValue = exp;
                }
            } else {
                this.DefaultValue = new NullExpression();
                if (context.Tokens.IsEndOfStream()) {
                    context.AddError(new ParseError(ParseErrorType.ExpressionExpected, ErrorLocation.Token, context.Tokens.CurrentToken));
                } else {
                    context.AddError(new ParseError(ParseErrorType.ExpressionExpected, ErrorLocation.Token, EqualsSign));
                }
            }

            return base.Parse(context, parent);
        }
コード例 #16
0
        public IEnumerable<SuggestedActionSet> GetSuggestedActions(ISuggestedActionCategorySet requestedActionCategories, SnapshotSpan range, CancellationToken cancellationToken) {
            if (cancellationToken.IsCancellationRequested ||
                !range.Snapshot.TextBuffer.ContentType.TypeName.EqualsOrdinal(RContentTypeDefinition.ContentType)) {
                return Enumerable.Empty<SuggestedActionSet>();
            }

            List<SuggestedActionSet> actionSets = new List<SuggestedActionSet>();
            var caretPosition = _textView.Caret.Position.BufferPosition;
            SnapshotPoint? bufferPoint = _textView.MapDownToR(caretPosition);
            if (bufferPoint.HasValue) {
                AstRoot ast = _document?.EditorTree.AstRoot;
                int bufferPosition = bufferPoint.Value.Position;
                _lastNode = ast?.GetNodeOfTypeFromPosition<TokenNode>(bufferPosition);
                if (_lastNode != null) {
                    foreach (IRSuggestedActionProvider actionProvider in _suggestedActionProviders) {
                        if (actionProvider.HasSuggestedActions(_textView, _textBuffer, bufferPosition)) {
                            IEnumerable<ISuggestedAction> actions = actionProvider.GetSuggestedActions(_textView, _textBuffer, bufferPosition);
                            Span applicableSpan = new Span(_lastNode.Start, _lastNode.Length);
                            SuggestedActionSet actionSet = new SuggestedActionSet(actions, applicableToSpan: applicableSpan);
                            actionSets.Add(actionSet);
                        }
                    }
                }
            }
            return actionSets;
        }
コード例 #17
0
ファイル: AstNode.cs プロジェクト: AlexanderSher/RTVS-Old
        public void RemoveChildren(int start, int count) {
            if (count == 0)
                return;

            if (start < 0 || start >= Children.Count)
                throw new ArgumentOutOfRangeException("start");

            if (count < 0 || count > Children.Count || start + count > Children.Count)
                throw new ArgumentOutOfRangeException("count");

            if (Children.Count == count) {
                _children = new TextRangeCollection<IAstNode>();
            } else {
                var newChildren = new IAstNode[Children.Count - count];

                int j = 0;

                for (int i = 0; i < start; i++, j++)
                    newChildren[j] = Children[i];

                for (int i = start; i < start + count; i++)
                    Children[i].Parent = null;

                for (int i = start + count; i < Children.Count; i++, j++)
                    newChildren[j] = Children[i];

                _children = new TextRangeCollection<IAstNode>(newChildren);
            }
        }
コード例 #18
0
        public TableOrColumnName(IAstNode preNode, string originalValue)
            : base(preNode, originalValue)
        {
            // SQLが成立していないとき
            if (ParentNode == null || ParentNode.ParentNode == null)
            {
                Order = OrderType.Unknown;
                throw new Exception("SQLが成立していません");
            }

            // 定義の親がStatementでその親が予約語
            if (ParentNode.ParentNode.GetType() == typeof (ReservedTopLevel))
            {
                string reservedWord = ParentNode.ParentNode.OriginalValue;
                Match m = _regex.Match(reservedWord);
                if (m.Success)
                {
                    // FROMやUPDATEなど、カラム名称が定義されない予約語ならテーブル名
                    Order = OrderType.Table;
                }
                else
                {
                    // SELECT句やWHERE区ででてきたカラム定義
                    Order = OrderType.Column;
                }
            }
            else
            {
                // JOIN句など、予約語とは違うネスト階層により出現する定義
                Order = OrderType.Column;
            }
        }
コード例 #19
0
ファイル: Statement.cs プロジェクト: Microsoft/RTVS
        /// <summary>
        /// Abstract factory creating statements depending on current
        /// token and the following token sequence
        /// </summary>
        /// <returns></returns>
        public static IStatement Create(ParseContext context, IAstNode parent, string terminatingKeyword) {
            TokenStream<RToken> tokens = context.Tokens;
            RToken currentToken = tokens.CurrentToken;

            IStatement statement = null;

            switch (currentToken.TokenType) {
                case RTokenType.Keyword:
                    // If statement starts with a keyword, it is not an assignment
                    // hence we should always try keyword based statements first.
                    // Some of the statements may be R-values like typeof() but
                    // in case of the statement appearing on its own return value
                    // will be simply ignored. IDE may choose to show a warning.
                    if (currentToken.SubType == RTokenSubType.BuiltinFunction && tokens.NextToken.TokenType != RTokenType.OpenBrace) {
                        // 'return <- x + y' is allowed
                        statement = new ExpressionStatement(terminatingKeyword);
                    } else {
                        statement = KeywordStatement.CreateStatement(context, parent);
                    }
                    break;

                case RTokenType.Semicolon:
                    statement = new EmptyStatement();
                    break;

                default:
                    // Possible L-value in a left-hand assignment, 
                    // a function call or R-value in a right hand assignment.
                    statement = new ExpressionStatement(terminatingKeyword);
                    break;
            }

            return statement;
        }
コード例 #20
0
ファイル: TokenNode.cs プロジェクト: Microsoft/RTVS
        public override bool Parse(ParseContext context, IAstNode parent) {
            RToken currentToken = context.Tokens.CurrentToken;

            this.Token = currentToken;
            context.Tokens.MoveToNextToken();

            return base.Parse(context, parent);
        }
コード例 #21
0
ファイル: ExpressionArgument.cs プロジェクト: Microsoft/RTVS
        public override bool Parse(ParseContext context, IAstNode parent) {
            this.ArgumentValue = new Expression(inGroup: true);
            if (this.ArgumentValue.Parse(context, this)) {
                return base.Parse(context, parent);
            }

            return false;
        }
コード例 #22
0
ファイル: ErrorArgument.cs プロジェクト: Microsoft/RTVS
        public override bool Parse(ParseContext context, IAstNode parent) {
            foreach (RToken t in Tokens) {
                TokenNode n = new TokenNode(t);
                n.Parent = this;
            }

            return base.Parse(context, parent);
        }
コード例 #23
0
ファイル: ParseResult.cs プロジェクト: parsnips/Expressions
        public ParseResult(IAstNode rootNode, IdentifierCollection identifiers)
        {
            Require.NotNull(rootNode, "rootNode");
            Require.NotNull(identifiers, "identifiers");

            RootNode = rootNode;
            Identifiers = identifiers;
        }
コード例 #24
0
ファイル: Evaluator.cs プロジェクト: AlexanderSher/RTVS-Old
        public RObject Evaluate(IAstNode node) {
            IRValueNode rValue = node as IRValueNode;
            if (rValue == null) {
                return RNull.Null;
            }

            return RNull.Null;
        }
コード例 #25
0
 public IAstNode CreateIAstNode(IAstNode beforeNode, string token)
 {
     if (token[0] == '(' || token[0] == ')')
     {
         return new Bracket(beforeNode, token[0].ToString());
     }
     return null;
 }
コード例 #26
0
 public IAstNode CreateIAstNode(IAstNode beforeNode, string token)
 {
     Match match = _regex.Match(token);
     if (match.Success)
     {
         return new Boundaries(beforeNode, match.Value);
     }
     return null;
 }
コード例 #27
0
ファイル: Bracket.cs プロジェクト: NaoyaOura/SqlFormatter
 public override void SetParentInChildNode(IAstNode node)
 {
     if (node.GetType() == typeof (ReservedTopLevel))
     {
         // SELECTなどの予約語をもつことからネスト構造のSQLをもつ
         HasQuery = true;
     }
     base.SetParentInChildNode(node);
 }
コード例 #28
0
 public IAstNode CreateIAstNode(IAstNode beforeNode, string token)
 {
     Match match = _regex.Match(token);
     if (match.Success)
     {
         return new FunctionWord(beforeNode, match.Groups["target"].Value);
     }
     return null;
 }
コード例 #29
0
        public override bool Parse(ParseContext context, IAstNode parent) {
            if (ParseKeyword(context, this)) {
                if (ParseSemicolon(context, this)) {
                    return base.Parse(context, parent);
                }
            }

            return false;
        }
コード例 #30
0
ファイル: FormatOperations.cs プロジェクト: Microsoft/RTVS
 /// <summary>
 /// Formats specific AST node 
 /// </summary>
 public static void FormatNode(ITextView textView, ITextBuffer textBuffer, IEditorShell editorShell, IAstNode node, int limit = -1) {
     if (node != null) {
         if (limit >= 0 && limit < node.Start) {
             throw new ArgumentException(nameof(limit));
         }
         ITextRange range = limit < 0 ? node as ITextRange : TextRange.FromBounds(node.Start, limit);
         UndoableFormatRange(textView, textBuffer, range, editorShell);
     }
 }
コード例 #31
0
 public void EndVisit(IAstNode element, object parameter)
 {
 }
コード例 #32
0
ファイル: Util.cs プロジェクト: cybrown/MeeShell
 public static void DumpAst(IAstNode ast)
 {
     ast.Accept(new DumpAstVisitor());
 }
コード例 #33
0
 public virtual bool Transform(IAstNode node)
 {
     return(true);
 }
コード例 #34
0
 public EvaluationString(IAstNode beforeNode, string value)
     : base(beforeNode, value)
 {
 }
コード例 #35
0
        /// <summary>
        /// Leave the scope. Must corespond to <see cref="EnterScope"/>
        /// </summary>
        public virtual void LeaveScope(IAstNode node)
        {
            var pop = _scope.Pop();

            Debug.Assert(pop == node);
        }
コード例 #36
0
 private IAstNode Process_SourceFilter(IReadWriteOperation op, int operationId, IAstNode result)
 {
     return(Process_ValuesFilter(
                op,
                operationId,
                result,
                AstBuildHelper.ReadMembersChain(
                    AstBuildHelper.ReadLocalRA(locFrom),
                    op.Source.MembersChain
                    ),
                "SourceFilter",
                op.SourceFilter
                ));
 }
コード例 #37
0
 public GreaterThanNode(IAstNode value1, IAstNode value2)
 {
     Value1 = value1;
     Value2 = value2;
 }
コード例 #38
0
ファイル: MissingValue.cs プロジェクト: zachwieja/RTVS
 public override bool Parse(ParseContext context, IAstNode parent)
 {
     Value = new RMissing();
     return(base.Parse(context, parent));
 }
コード例 #39
0
ファイル: Scope.cs プロジェクト: fpcMotif/RTVS
        public override bool Parse(ParseContext context, IAstNode parent)
        {
            TokenStream <RToken> tokens = context.Tokens;
            RToken currentToken         = tokens.CurrentToken;

            context.Scopes.Push(this);

            if (!(this is GlobalScope) && currentToken.TokenType == RTokenType.OpenCurlyBrace)
            {
                this.OpenCurlyBrace = RParser.ParseToken(context, this);
            }

            while (!tokens.IsEndOfStream())
            {
                currentToken = context.Tokens.CurrentToken;

                switch (currentToken.TokenType)
                {
                case RTokenType.CloseCurlyBrace:
                    if (this.OpenCurlyBrace != null)
                    {
                        this.CloseCurlyBrace = RParser.ParseToken(context, this);
                    }
                    else
                    {
                        context.AddError(new ParseError(ParseErrorType.UnexpectedToken, ErrorLocation.Token, currentToken));
                        context.Tokens.MoveToNextToken();
                    }
                    break;

                case RTokenType.OpenCurlyBrace:
                    IScope scope = new Scope(string.Empty);
                    scope.Parse(context, this);
                    break;

                default:
                    IStatement statement = Statement.Create(context, this, null);
                    if (statement != null)
                    {
                        if (statement.Parse(context, this))
                        {
                            this.statements.Add(statement);
                        }
                        else
                        {
                            statement = null;
                        }
                    }

                    if (statement == null)
                    {
                        if (!context.TextProvider.IsNewLineBeforePosition(context.Tokens.CurrentToken.Start))
                        {
                            // try recovering at the next line or past nearest
                            // semicolon or closing curly brace
                            tokens.MoveToNextLine(context.TextProvider,
                                                  (TokenStream <RToken> ts) => {
                                return(ts.CurrentToken.TokenType == RTokenType.Semicolon ||
                                       ts.NextToken.TokenType == RTokenType.CloseCurlyBrace);
                            });
                        }
                        else
                        {
                            tokens.MoveToNextToken();
                        }
                    }
                    break;
                }

                if (this.CloseCurlyBrace != null)
                {
                    break;
                }
            }

            context.Scopes.Pop();

            if (this.OpenCurlyBrace != null && this.CloseCurlyBrace == null)
            {
                context.AddError(new MissingItemParseError(ParseErrorType.CloseCurlyBraceExpected, context.Tokens.PreviousToken));
            }

            // TODO: process content and fill out declared variables
            // and functions and get data to the classifier for colorization.
            return(base.Parse(context, parent));
        }
コード例 #40
0
 public DeclarationSemanticException(IAstNode node, string message) : base(node, message)
 {
 }
コード例 #41
0
 public ReservedWord(IAstNode preNode, string originalValue)
     : base(preNode, originalValue)
 {
 }
コード例 #42
0
 public void Declare(string name, SymbolKind kind, IAstNode ctx, params (string, object)[] properties)
コード例 #43
0
        private static void AddOperation(StructuredProgramContext context, LinkedListNode <INode> opNode)
        {
            Operation operation = (Operation)opNode.Value;

            Instruction inst = operation.Inst;

            bool isCall = inst == Instruction.Call;

            int sourcesCount = operation.SourcesCount;

            List <Operand> callOutOperands = new List <Operand>();

            if (isCall)
            {
                LinkedListNode <INode> scan = opNode.Next;

                while (scan != null && scan.Value is Operation nextOp && nextOp.Inst == Instruction.CallOutArgument)
                {
                    callOutOperands.Add(nextOp.Dest);
                    scan = scan.Next;
                }

                sourcesCount += callOutOperands.Count;
            }

            IAstNode[] sources = new IAstNode[sourcesCount];

            for (int index = 0; index < operation.SourcesCount; index++)
            {
                sources[index] = context.GetOperandUse(operation.GetSource(index));
            }

            if (isCall)
            {
                for (int index = 0; index < callOutOperands.Count; index++)
                {
                    sources[operation.SourcesCount + index] = context.GetOperandDef(callOutOperands[index]);
                }

                callOutOperands.Clear();
            }

            AstTextureOperation GetAstTextureOperation(TextureOperation texOp)
            {
                return(new AstTextureOperation(
                           inst,
                           texOp.Type,
                           texOp.Format,
                           texOp.Flags,
                           texOp.CbufSlot,
                           texOp.Handle,
                           4, // TODO: Non-hardcoded array size.
                           texOp.Index,
                           sources));
            }

            if (operation.Dest != null)
            {
                AstOperand dest = context.GetOperandDef(operation.Dest);

                if (inst == Instruction.LoadConstant)
                {
                    Operand slot = operation.GetSource(0);

                    if (slot.Type == OperandType.Constant)
                    {
                        context.Info.CBuffers.Add(slot.Value);
                    }
                    else
                    {
                        // If the value is not constant, then we don't know
                        // how many constant buffers are used, so we assume
                        // all of them are used.
                        int cbCount = 32 - BitOperations.LeadingZeroCount(context.Config.GpuAccessor.QueryConstantBufferUse());

                        for (int index = 0; index < cbCount; index++)
                        {
                            context.Info.CBuffers.Add(index);
                        }

                        context.Info.UsesCbIndexing = true;
                    }
                }
                else if (UsesStorage(inst))
                {
                    AddSBufferUse(context.Info.SBuffers, operation);
                }

                // If all the sources are bool, it's better to use short-circuiting
                // logical operations, rather than forcing a cast to int and doing
                // a bitwise operation with the value, as it is likely to be used as
                // a bool in the end.
                if (IsBitwiseInst(inst) && AreAllSourceTypesEqual(sources, VariableType.Bool))
                {
                    inst = GetLogicalFromBitwiseInst(inst);
                }

                bool isCondSel = inst == Instruction.ConditionalSelect;
                bool isCopy    = inst == Instruction.Copy;

                if (isCondSel || isCopy)
                {
                    VariableType type = GetVarTypeFromUses(operation.Dest);

                    if (isCondSel && type == VariableType.F32)
                    {
                        inst |= Instruction.FP32;
                    }

                    dest.VarType = type;
                }
                else
                {
                    dest.VarType = InstructionInfo.GetDestVarType(inst);
                }

                IAstNode source;

                if (operation is TextureOperation texOp)
                {
                    if (texOp.Inst == Instruction.ImageLoad || texOp.Inst == Instruction.ImageStore)
                    {
                        dest.VarType = texOp.Format.GetComponentType();
                    }

                    AstTextureOperation astTexOp = GetAstTextureOperation(texOp);

                    if (texOp.Inst == Instruction.ImageLoad)
                    {
                        context.Info.Images.Add(astTexOp);
                    }
                    else
                    {
                        context.Info.Samplers.Add(astTexOp);
                    }

                    source = astTexOp;
                }
                else if (!isCopy)
                {
                    source = new AstOperation(inst, operation.Index, sources, operation.SourcesCount);
                }
                else
                {
                    source = sources[0];
                }

                context.AddNode(new AstAssignment(dest, source));
            }
            else if (operation.Inst == Instruction.Comment)
            {
                context.AddNode(new AstComment(((CommentNode)operation).Comment));
            }
            else if (operation is TextureOperation texOp)
            {
                AstTextureOperation astTexOp = GetAstTextureOperation(texOp);

                context.Info.Images.Add(astTexOp);

                context.AddNode(astTexOp);
            }
            else
            {
                if (UsesStorage(inst))
                {
                    AddSBufferUse(context.Info.SBuffers, operation);
                }

                context.AddNode(new AstOperation(inst, operation.Index, sources, operation.SourcesCount));
            }

            // Those instructions needs to be emulated by using helper functions,
            // because they are NVIDIA specific. Those flags helps the backend to
            // decide which helper functions are needed on the final generated code.
            switch (operation.Inst)
            {
            case Instruction.MultiplyHighS32:
                context.Info.HelperFunctionsMask |= HelperFunctionsMask.MultiplyHighS32;
                break;

            case Instruction.MultiplyHighU32:
                context.Info.HelperFunctionsMask |= HelperFunctionsMask.MultiplyHighU32;
                break;

            case Instruction.Shuffle:
                context.Info.HelperFunctionsMask |= HelperFunctionsMask.Shuffle;
                break;

            case Instruction.ShuffleDown:
                context.Info.HelperFunctionsMask |= HelperFunctionsMask.ShuffleDown;
                break;

            case Instruction.ShuffleUp:
                context.Info.HelperFunctionsMask |= HelperFunctionsMask.ShuffleUp;
                break;

            case Instruction.ShuffleXor:
                context.Info.HelperFunctionsMask |= HelperFunctionsMask.ShuffleXor;
                break;

            case Instruction.SwizzleAdd:
                context.Info.HelperFunctionsMask |= HelperFunctionsMask.SwizzleAdd;
                break;
            }
        }
コード例 #44
0
 /// <summary>
 /// Enter the scope.
 /// </summary>
 public virtual void EnterScope(IAstNode node)
 {
     _scope.Push(node);
 }
コード例 #45
0
        private static void FindSpecificNode(IAstNode node, int position, Func <IAstNode, bool> match, ref IAstNode deepestNode, bool includeEnd = false)
        {
            if (position == node.Start || (!node.Contains(position) && !(includeEnd && node.End == position)))
            {
                return; // not this element
            }

            if (match(node))
            {
                deepestNode = node;
            }

            for (var i = 0; i < node.Children.Count && node.Children[i].Start <= position; i++)
            {
                FindSpecificNode(node.Children[i], position, match, ref deepestNode, includeEnd);
            }
        }
コード例 #46
0
        private static void AddOperation(StructuredProgramContext context, Operation operation)
        {
            Instruction inst = operation.Inst;

            IAstNode[] sources = new IAstNode[operation.SourcesCount];

            for (int index = 0; index < sources.Length; index++)
            {
                sources[index] = context.GetOperandUse(operation.GetSource(index));
            }

            AstTextureOperation GetAstTextureOperation(TextureOperation texOp)
            {
                return(new AstTextureOperation(
                           inst,
                           texOp.Type,
                           texOp.Flags,
                           texOp.Handle,
                           4, // TODO: Non-hardcoded array size.
                           texOp.Index,
                           sources));
            }

            if (operation.Dest != null)
            {
                AstOperand dest = context.GetOperandDef(operation.Dest);

                if (inst == Instruction.LoadConstant)
                {
                    Operand slot = operation.GetSource(0);

                    if (slot.Type != OperandType.Constant)
                    {
                        throw new InvalidOperationException("Found load with non-constant constant buffer slot.");
                    }

                    context.Info.CBuffers.Add(slot.Value);
                }
                else if (UsesStorage(inst))
                {
                    AddSBufferUse(context.Info.SBuffers, operation);
                }

                AstAssignment assignment;

                // If all the sources are bool, it's better to use short-circuiting
                // logical operations, rather than forcing a cast to int and doing
                // a bitwise operation with the value, as it is likely to be used as
                // a bool in the end.
                if (IsBitwiseInst(inst) && AreAllSourceTypesEqual(sources, VariableType.Bool))
                {
                    inst = GetLogicalFromBitwiseInst(inst);
                }

                bool isCondSel = inst == Instruction.ConditionalSelect;
                bool isCopy    = inst == Instruction.Copy;

                if (isCondSel || isCopy)
                {
                    VariableType type = GetVarTypeFromUses(operation.Dest);

                    if (isCondSel && type == VariableType.F32)
                    {
                        inst |= Instruction.FP;
                    }

                    dest.VarType = type;
                }
                else
                {
                    dest.VarType = InstructionInfo.GetDestVarType(inst);
                }

                IAstNode source;

                if (operation is TextureOperation texOp)
                {
                    AstTextureOperation astTexOp = GetAstTextureOperation(texOp);

                    if (texOp.Inst == Instruction.ImageLoad)
                    {
                        context.Info.Images.Add(astTexOp);
                    }
                    else
                    {
                        context.Info.Samplers.Add(astTexOp);
                    }

                    source = astTexOp;
                }
                else if (!isCopy)
                {
                    source = new AstOperation(inst, operation.Index, sources);
                }
                else
                {
                    source = sources[0];
                }

                assignment = new AstAssignment(dest, source);

                context.AddNode(assignment);
            }
            else if (operation.Inst == Instruction.Comment)
            {
                context.AddNode(new AstComment(((CommentNode)operation).Comment));
            }
            else if (operation is TextureOperation texOp)
            {
                AstTextureOperation astTexOp = GetAstTextureOperation(texOp);

                context.Info.Images.Add(astTexOp);

                context.AddNode(astTexOp);
            }
            else
            {
                if (UsesStorage(inst))
                {
                    AddSBufferUse(context.Info.SBuffers, operation);
                }

                context.AddNode(new AstOperation(inst, operation.Index, sources));
            }

            // Those instructions needs to be emulated by using helper functions,
            // because they are NVIDIA specific. Those flags helps the backend to
            // decide which helper functions are needed on the final generated code.
            switch (operation.Inst)
            {
            case Instruction.MultiplyHighS32:
                context.Info.HelperFunctionsMask |= HelperFunctionsMask.MultiplyHighS32;
                break;

            case Instruction.MultiplyHighU32:
                context.Info.HelperFunctionsMask |= HelperFunctionsMask.MultiplyHighU32;
                break;

            case Instruction.Shuffle:
                context.Info.HelperFunctionsMask |= HelperFunctionsMask.Shuffle;
                break;

            case Instruction.ShuffleDown:
                context.Info.HelperFunctionsMask |= HelperFunctionsMask.ShuffleDown;
                break;

            case Instruction.ShuffleUp:
                context.Info.HelperFunctionsMask |= HelperFunctionsMask.ShuffleUp;
                break;

            case Instruction.ShuffleXor:
                context.Info.HelperFunctionsMask |= HelperFunctionsMask.ShuffleXor;
                break;

            case Instruction.SwizzleAdd:
                context.Info.HelperFunctionsMask |= HelperFunctionsMask.SwizzleAdd;
                break;
            }
        }
コード例 #47
0
 private IAstNode Process_DestinationFilter(IReadWriteOperation op, int operationId, IAstNode result)
 {
     return(Process_ValuesFilter(
                op,
                operationId,
                result,
                AstBuildHelper.ReadMembersChain(
                    AstBuildHelper.ReadLocalRA(locTo),
                    op.Destination.MembersChain
                    ),
                "DestinationFilter",
                op.DestinationFilter
                ));
 }
コード例 #48
0
 public LessThanNode(IAstNode value1, IAstNode value2)
 {
     Value1 = value1;
     Value2 = value2;
 }
コード例 #49
0
ファイル: AstHelper.cs プロジェクト: ianuub/Ryujinxxx
 public static IAstNode Next(IAstNode node)
 {
     return(node.LLNode.Next?.Value);
 }
コード例 #50
0
        private static string GetExpression(CodeGenContext context, AstOperation operation)
        {
            Instruction inst = operation.Inst;

            InstInfo info = GetInstructionInfo(inst);

            if ((info.Type & InstType.Call) != 0)
            {
                bool atomic = (info.Type & InstType.Atomic) != 0;

                int arity = (int)(info.Type & InstType.ArityMask);

                string args = string.Empty;

                for (int argIndex = 0; argIndex < arity; argIndex++)
                {
                    // For shared memory access, the second argument is unused and should be ignored.
                    // It is there to make both storage and shared access have the same number of arguments.
                    // For storage, both inputs are consumed when the argument index is 0, so we should skip it here.
                    if (argIndex == 1 && (atomic || (inst & Instruction.MrMask) == Instruction.MrShared))
                    {
                        continue;
                    }

                    if (argIndex != 0)
                    {
                        args += ", ";
                    }

                    if (argIndex == 0 && atomic)
                    {
                        Instruction memRegion = inst & Instruction.MrMask;

                        switch (memRegion)
                        {
                        case Instruction.MrShared: args += LoadShared(context, operation); break;

                        case Instruction.MrStorage: args += LoadStorage(context, operation, forAtomic: true); break;

                        default: throw new InvalidOperationException($"Invalid memory region \"{memRegion}\".");
                        }
                    }
                    else
                    {
                        VariableType dstType = GetSrcVarType(inst, argIndex);

                        args += GetSoureExpr(context, operation.GetSource(argIndex), dstType);
                    }
                }

                if (inst == Instruction.Ballot)
                {
                    return($"unpackUint2x32({info.OpName}({args})).x");
                }
                else
                {
                    return(info.OpName + "(" + args + ")");
                }
            }
            else if ((info.Type & InstType.Op) != 0)
            {
                string op = info.OpName;

                // Return may optionally have a return value (and in this case it is unary).
                if (inst == Instruction.Return && operation.SourcesCount != 0)
                {
                    return($"{op} {GetSoureExpr(context, operation.GetSource(0), context.CurrentFunction.ReturnType)}");
                }

                int arity = (int)(info.Type & InstType.ArityMask);

                string[] expr = new string[arity];

                for (int index = 0; index < arity; index++)
                {
                    IAstNode src = operation.GetSource(index);

                    string srcExpr = GetSoureExpr(context, src, GetSrcVarType(inst, index));

                    bool isLhs = arity == 2 && index == 0;

                    expr[index] = Enclose(srcExpr, src, inst, info, isLhs);
                }

                switch (arity)
                {
                case 0:
                    return(op);

                case 1:
                    return(op + expr[0]);

                case 2:
                    return($"{expr[0]} {op} {expr[1]}");

                case 3:
                    return($"{expr[0]} {op[0]} {expr[1]} {op[1]} {expr[2]}");
                }
            }
            else if ((info.Type & InstType.Special) != 0)
            {
                switch (inst)
                {
                case Instruction.Call:
                    return(Call(context, operation));

                case Instruction.ImageLoad:
                    return(ImageLoadOrStore(context, operation));

                case Instruction.ImageStore:
                    return(ImageLoadOrStore(context, operation));

                case Instruction.LoadAttribute:
                    return(LoadAttribute(context, operation));

                case Instruction.LoadConstant:
                    return(LoadConstant(context, operation));

                case Instruction.LoadLocal:
                    return(LoadLocal(context, operation));

                case Instruction.LoadShared:
                    return(LoadShared(context, operation));

                case Instruction.LoadStorage:
                    return(LoadStorage(context, operation));

                case Instruction.Lod:
                    return(Lod(context, operation));

                case Instruction.PackDouble2x32:
                    return(PackDouble2x32(context, operation));

                case Instruction.PackHalf2x16:
                    return(PackHalf2x16(context, operation));

                case Instruction.StoreLocal:
                    return(StoreLocal(context, operation));

                case Instruction.StoreShared:
                    return(StoreShared(context, operation));

                case Instruction.StoreStorage:
                    return(StoreStorage(context, operation));

                case Instruction.TextureSample:
                    return(TextureSample(context, operation));

                case Instruction.TextureSize:
                    return(TextureSize(context, operation));

                case Instruction.UnpackDouble2x32:
                    return(UnpackDouble2x32(context, operation));

                case Instruction.UnpackHalf2x16:
                    return(UnpackHalf2x16(context, operation));
                }
            }

            throw new InvalidOperationException($"Unexpected instruction type \"{info.Type}\".");
        }
コード例 #51
0
ファイル: AstHelper.cs プロジェクト: ianuub/Ryujinxxx
 public static IAstNode InverseCond(IAstNode cond)
 {
     return(new AstOperation(Instruction.LogicalNot, cond));
 }
コード例 #52
0
ファイル: InstGen.cs プロジェクト: zpoo32/Ryujinx
        private static string GetExpression(CodeGenContext context, AstOperation operation)
        {
            Instruction inst = operation.Inst;

            InstInfo info = GetInstructionInfo(inst);

            if ((info.Type & InstType.Call) != 0)
            {
                int arity = (int)(info.Type & InstType.ArityMask);

                string args = string.Empty;

                for (int argIndex = 0; argIndex < arity; argIndex++)
                {
                    if (argIndex != 0)
                    {
                        args += ", ";
                    }

                    VariableType dstType = GetSrcVarType(inst, argIndex);

                    args += GetSoureExpr(context, operation.GetSource(argIndex), dstType);
                }

                return(info.OpName + "(" + args + ")");
            }
            else if ((info.Type & InstType.Op) != 0)
            {
                string op = info.OpName;

                int arity = (int)(info.Type & InstType.ArityMask);

                string[] expr = new string[arity];

                for (int index = 0; index < arity; index++)
                {
                    IAstNode src = operation.GetSource(index);

                    string srcExpr = GetSoureExpr(context, src, GetSrcVarType(inst, index));

                    bool isLhs = arity == 2 && index == 0;

                    expr[index] = Enclose(srcExpr, src, inst, info, isLhs);
                }

                switch (arity)
                {
                case 0:
                    return(op);

                case 1:
                    return(op + expr[0]);

                case 2:
                    return($"{expr[0]} {op} {expr[1]}");

                case 3:
                    return($"{expr[0]} {op[0]} {expr[1]} {op[1]} {expr[2]}");
                }
            }
            else if ((info.Type & InstType.Special) != 0)
            {
                switch (inst)
                {
                case Instruction.LoadConstant:
                    return(InstGenMemory.LoadConstant(context, operation));

                case Instruction.PackHalf2x16:
                    return(InstGenPacking.PackHalf2x16(context, operation));

                case Instruction.TextureSample:
                    return(InstGenMemory.TextureSample(context, operation));

                case Instruction.TextureSize:
                    return(InstGenMemory.TextureSize(context, operation));

                case Instruction.UnpackHalf2x16:
                    return(InstGenPacking.UnpackHalf2x16(context, operation));
                }
            }

            throw new InvalidOperationException($"Unexpected instruction type \"{info.Type}\".");
        }
コード例 #53
0
 public virtual bool Parse(ParseContext context, IAstNode parent = null)
 {
     Parent = parent;
     return(true);
 }
コード例 #54
0
ファイル: AstHelper.cs プロジェクト: ianuub/Ryujinxxx
 public static IAstNode Previous(IAstNode node)
 {
     return(node.LLNode.Previous?.Value);
 }
コード例 #55
0
        private static void AddOperation(StructuredProgramContext context, Operation operation)
        {
            Instruction inst = operation.Inst;

            int sourcesCount  = operation.SourcesCount;
            int outDestsCount = operation.DestsCount != 0 ? operation.DestsCount - 1 : 0;

            IAstNode[] sources = new IAstNode[sourcesCount + outDestsCount];

            for (int index = 0; index < operation.SourcesCount; index++)
            {
                sources[index] = context.GetOperandUse(operation.GetSource(index));
            }

            for (int index = 0; index < outDestsCount; index++)
            {
                AstOperand oper = context.GetOperandDef(operation.GetDest(1 + index));

                oper.VarType = InstructionInfo.GetSrcVarType(inst, sourcesCount + index);

                sources[sourcesCount + index] = oper;
            }

            AstTextureOperation GetAstTextureOperation(TextureOperation texOp)
            {
                return(new AstTextureOperation(
                           inst,
                           texOp.Type,
                           texOp.Format,
                           texOp.Flags,
                           texOp.CbufSlot,
                           texOp.Handle,
                           texOp.Index,
                           sources));
            }

            if (operation.Dest != null)
            {
                AstOperand dest = context.GetOperandDef(operation.Dest);

                // If all the sources are bool, it's better to use short-circuiting
                // logical operations, rather than forcing a cast to int and doing
                // a bitwise operation with the value, as it is likely to be used as
                // a bool in the end.
                if (IsBitwiseInst(inst) && AreAllSourceTypesEqual(sources, VariableType.Bool))
                {
                    inst = GetLogicalFromBitwiseInst(inst);
                }

                bool isCondSel = inst == Instruction.ConditionalSelect;
                bool isCopy    = inst == Instruction.Copy;

                if (isCondSel || isCopy)
                {
                    VariableType type = GetVarTypeFromUses(operation.Dest);

                    if (isCondSel && type == VariableType.F32)
                    {
                        inst |= Instruction.FP32;
                    }

                    dest.VarType = type;
                }
                else
                {
                    dest.VarType = InstructionInfo.GetDestVarType(inst);
                }

                IAstNode source;

                if (operation is TextureOperation texOp)
                {
                    if (texOp.Inst == Instruction.ImageLoad)
                    {
                        dest.VarType = texOp.Format.GetComponentType();
                    }

                    source = GetAstTextureOperation(texOp);
                }
                else if (!isCopy)
                {
                    source = new AstOperation(inst, operation.Index, sources, operation.SourcesCount);
                }
                else
                {
                    source = sources[0];
                }

                context.AddNode(new AstAssignment(dest, source));
            }
            else if (operation.Inst == Instruction.Comment)
            {
                context.AddNode(new AstComment(((CommentNode)operation).Comment));
            }
            else if (operation is TextureOperation texOp)
            {
                AstTextureOperation astTexOp = GetAstTextureOperation(texOp);

                context.AddNode(astTexOp);
            }
            else
            {
                context.AddNode(new AstOperation(inst, operation.Index, sources, operation.SourcesCount));
            }

            // Those instructions needs to be emulated by using helper functions,
            // because they are NVIDIA specific. Those flags helps the backend to
            // decide which helper functions are needed on the final generated code.
            switch (operation.Inst)
            {
            case Instruction.AtomicMaxS32 | Instruction.MrShared:
            case Instruction.AtomicMinS32 | Instruction.MrShared:
                context.Info.HelperFunctionsMask |= HelperFunctionsMask.AtomicMinMaxS32Shared;
                break;

            case Instruction.AtomicMaxS32 | Instruction.MrStorage:
            case Instruction.AtomicMinS32 | Instruction.MrStorage:
                context.Info.HelperFunctionsMask |= HelperFunctionsMask.AtomicMinMaxS32Storage;
                break;

            case Instruction.MultiplyHighS32:
                context.Info.HelperFunctionsMask |= HelperFunctionsMask.MultiplyHighS32;
                break;

            case Instruction.MultiplyHighU32:
                context.Info.HelperFunctionsMask |= HelperFunctionsMask.MultiplyHighU32;
                break;

            case Instruction.Shuffle:
                context.Info.HelperFunctionsMask |= HelperFunctionsMask.Shuffle;
                break;

            case Instruction.ShuffleDown:
                context.Info.HelperFunctionsMask |= HelperFunctionsMask.ShuffleDown;
                break;

            case Instruction.ShuffleUp:
                context.Info.HelperFunctionsMask |= HelperFunctionsMask.ShuffleUp;
                break;

            case Instruction.ShuffleXor:
                context.Info.HelperFunctionsMask |= HelperFunctionsMask.ShuffleXor;
                break;

            case Instruction.SwizzleAdd:
                context.Info.HelperFunctionsMask |= HelperFunctionsMask.SwizzleAdd;
                break;
            }
        }
コード例 #56
0
ファイル: InstGenHelper.cs プロジェクト: neozumm/Ryujinx
 public static string GetSoureExpr(CodeGenContext context, IAstNode node, VariableType dstType)
 {
     return(ReinterpretCast(context, node, OperandManager.GetNodeDestType(context, node), dstType));
 }
コード例 #57
0
ファイル: UserDefinedPeekItem.cs プロジェクト: xoriath/RTVS
 public UserDefinedPeekItem(string fileName, IAstNode definitionNode, string name, IPeekResultFactory peekResultFactory) :
     base(name, peekResultFactory)
 {
     DefinitionNode = definitionNode;
     FileName       = fileName;
 }
コード例 #58
0
ファイル: InstGenHelper.cs プロジェクト: neozumm/Ryujinx
        public static string Enclose(string expr, IAstNode node, Instruction pInst, bool isLhs)
        {
            InstInfo pInfo = GetInstructionInfo(pInst);

            return(Enclose(expr, node, pInst, pInfo, isLhs));
        }
コード例 #59
0
ファイル: AstHelper.cs プロジェクト: ianuub/Ryujinxxx
 public static AstAssignment Assign(IAstNode destination, IAstNode source)
 {
     return(new AstAssignment(destination, source));
 }