コード例 #1
0
 LNode EliminateRunSeqFromInitializer(LNode retType, LNode fieldName, ref LNode expr)
 {
     expr = BubbleUpBlocks(expr);
     if (expr.CallsMin(__runSequence, 1))
     {
         var   statements  = expr.Args.WithoutLast(1);
         var   finalResult = expr.Args.Last;
         LNode methodName  = F.Id(KeyNameComponentOf(fieldName).Name + "_initializer");
         expr = LNode.Call(methodName);
         return(LNode.Call(LNode.List(LNode.Id(CodeSymbols.Static)), CodeSymbols.Fn, LNode.List(retType, methodName, LNode.Call(CodeSymbols.AltList), LNode.Call(CodeSymbols.Braces, LNode.List().AddRange(statements).Add(LNode.Call(CodeSymbols.Return, LNode.List(finalResult)))).SetStyle(NodeStyle.Statement))));
     }
     else
     {
         return(null);
     }
 }
コード例 #2
0
ファイル: ContractsMacro.out.cs プロジェクト: sizzles/ecsharp
            void ProcessAttribute(LNode attr, Symbol mode, LNode exceptionType, LNode variableName, bool isPropSetter)
            {
                var    conditions     = attr.Args;
                object haveCCRewriter = Context.ScopedProperties.TryGetValue(_haveContractRewriter, null);

                _haveCCRewriter = haveCCRewriter is bool?(bool)haveCCRewriter : false;

                // #notnull is equivalent to either requires(_ != null) or ensures(_ != null)
                if (mode == sy_notnull)
                {
                    if (attr.Args.Count != 0)
                    {
                        Context.Sink.Warning(attr, "'#notnull' does not expect arguments.");
                    }
                    if (variableName != null                            // argument
                        )
                    {
                        mode = sy_requires;
                    }
                    else
                    {
                        // return value
                        mode = sy_ensures;
                    }
                    conditions.Add(LNode.Call(CodeSymbols.Neq, LNode.List(LNode.Id((Symbol)"_"), LNode.Literal(null))).SetStyle(NodeStyle.Operator));
                }
                else if (!attr.IsCall)
                {
                    Context.Sink.Warning(attr, "'{0}' expects a list of conditions.", attr.Name);
                }

                if (mode == sy_requires || mode == sy_assert)
                {
                    ProcessRequiresAttribute(conditions, mode, variableName);
                }
                else                    // mode == @@ensures || mode == @@ensuresFinally || mode == @@ensuresOnThrow
                {
                    if (variableName != null && !isPropSetter)
                    {
                        Context.Sink.Error(attr, "The '{0}' attribute does not apply to method arguments.", mode);
                    }
                    else
                    {
                        ProcessEnsuresAttribute(conditions, mode, exceptionType, variableName);
                    }
                }
            }
コード例 #3
0
            public void GenerateOutput(ref VList <LNode> list)
            {
                bool isAbstract = _classAttrs.Any(a => a.IsIdNamed(S.Abstract));
                var  baseParts  = new List <AdtParam>();

                for (var type = ParentType; type != null; type = type.ParentType)
                {
                    baseParts.InsertRange(0, type.Parts);
                }
                var allParts       = baseParts.Concat(Parts);
                var initialization = Parts.Select(p => LNode.Call(CodeSymbols.Assign, LNode.List(LNode.Call(CodeSymbols.Dot, LNode.List(LNode.Id(CodeSymbols.This), p.NameId)), p.NameId)).SetStyle(NodeStyle.Operator)).ToList();

                if (baseParts.Count > 0)
                {
                    initialization.Insert(0, F.Call(S.Base, baseParts.Select(p => p.NameId)));
                }
                var args = new VList <LNode>(allParts.Select(p => p.OriginalDecl));

                if (!_constructorAttrs.Any(a => a.IsIdNamed(S.Public)))
                {
                    _constructorAttrs.Add(F.Id(S.Public));
                }
                LNode constructor = LNode.Call(LNode.List(_constructorAttrs), CodeSymbols.Constructor, LNode.List(LNode.Missing, _typeNameStem, LNode.Call(CodeSymbols.AltList, LNode.List(args)), LNode.Call(CodeSymbols.Braces, LNode.List().AddRange(initialization).AddRange(_extraConstrLogic)).SetStyle(NodeStyle.Statement)));
                var   outBody     = new VList <LNode>();

                outBody.Add(constructor);
                outBody.AddRange(Parts.Select(p => p.GetFieldDecl()));
                outBody.AddRange(baseParts.Select(p => GetWithFn(p, isAbstract, S.Override, allParts)));
                outBody.AddRange(Parts.Select(p => GetWithFn(p, isAbstract, _children.Count > 0 ? S.Virtual : null, allParts)));
                outBody.AddRange(Parts.WithIndexes().Where(kvp => kvp.Value.NameId.Name.Name != "Item" + (baseParts.Count + kvp.Key + 1)).Select(kvp => kvp.Value.GetItemDecl(baseParts.Count + kvp.Key + 1)));
                outBody.AddRange(_classBody);
                list.Add(LNode.Call(LNode.List(_classAttrs), CodeSymbols.Class, LNode.List(TypeName, LNode.Call(CodeSymbols.AltList, LNode.List(BaseTypes)), LNode.Call(CodeSymbols.Braces, LNode.List(outBody)).SetStyle(NodeStyle.Statement))));
                if (_genericArgs.Count > 0 && Parts.Count > 0)
                {
                    var argNames = allParts.Select(p => p.NameId);
                    list.Add(LNode.Call(LNode.List().AddRange(_classAttrs).Add(LNode.Id(CodeSymbols.Static)).Add(LNode.Id(LNode.List(LNode.Id(CodeSymbols.TriviaWordAttribute)), CodeSymbols.Partial)), CodeSymbols.Class, LNode.List(_typeNameStem, LNode.Call(CodeSymbols.AltList), LNode.Call(CodeSymbols.Braces, LNode.List(LNode.Call(LNode.List(LNode.Id(CodeSymbols.Public), LNode.Id(CodeSymbols.Static)), CodeSymbols.Fn, LNode.List(TypeNameWithoutAttrs, LNode.Call(CodeSymbols.Of, LNode.List().Add(LNode.Id((Symbol)"New")).AddRange(_genericArgs)), LNode.Call(CodeSymbols.AltList, LNode.List(args)), LNode.Call(CodeSymbols.Braces, LNode.List(LNode.Call(CodeSymbols.Return, LNode.List(LNode.Call(CodeSymbols.New, LNode.List(LNode.Call(TypeNameWithoutAttrs, LNode.List(argNames)))))))).SetStyle(NodeStyle.Statement))))).SetStyle(NodeStyle.Statement))));
                }
                foreach (var child in _children)
                {
                    child.GenerateOutput(ref list);
                }
            }
コード例 #4
0
ファイル: BuiltinMacros.cs プロジェクト: sizzles/ecsharp
        public static LNode printKnownMacros(LNode node, IMacroContext context)
        {
            // namespace LeMP {
            //     /* documentation */
            //     macroName;
            //     ...
            // }
            return(F.Call(S.Splice, context.AllKnownMacros.SelectMany(p => p.Value)
                          .GroupBy(mi => mi.Namespace).OrderBy(g => g.Key).Select(group =>
                                                                                  F.Attr(F.Trivia(S.TriviaSLComment, " printKnownMacros output "),
                                                                                         F.Call(S.Namespace, NamespaceSymbolToLNode(group.Key ?? GSymbol.Empty), LNode.Missing,
                                                                                                F.Braces(group.OrderBy(mi => mi.Macro.Method.Name).Select(mi =>
            {
                StringBuilder descr = new StringBuilder();
                descr.Append("\n### ").Append(mi.Names.FirstOrDefault("<no name>")).Append(" ###\n");
                if (!string.IsNullOrEmpty(mi.Syntax))
                {
                    descr.Append("\n\t").Append(mi.Syntax).Append("\n");
                }
                if (!string.IsNullOrEmpty(mi.Description))
                {
                    descr.Append("\n").Append(mi.Description).Append("\n");
                }
                descr.Replace("\n", "\n\t\t");
                descr.Append("\t");
                LNode line = mi.Names.Length == 1
                                                                ? (LNode)LNode.Id(mi.Names[0])
                                                                : LNode.Call(S.Tuple, LNode.List(mi.Names.Select(name => (LNode)LNode.Id(name))));

                string methodName = mi.Macro.Method.Name, @class = mi.Macro.Method.DeclaringType.Name;
                string postComment = " " + @class + "." + methodName;
                if (mi.Mode != MacroMode.Normal)
                {
                    postComment += string.Format(" (Mode = {0})", mi.Mode);
                }
                return F.Attr(
                    F.Trivia(S.TriviaMLComment, descr.ToString()),
                    F.TriviaNewline,
                    line).PlusTrailingTrivia(F.Trivia(S.TriviaSLComment, postComment));
            })))))));
        }
コード例 #5
0
ファイル: StandardMacros.cs プロジェクト: dadhi/ecsharp
        public static LNode concatId(LNode node, IMacroContext context)
        {
            StringBuilder sb = ConcatCore(node, out var attrs, context.Sink, allowLastToBeCall: true);

            if (sb == null)
            {
                return(null);
            }

            Symbol combined = GSymbol.Get(sb.ToString());
            LNode  result;

            if (node.Args.Last.IsCall)
            {
                result = node.Args.Last.WithTarget(combined);
            }
            else
            {
                result = LNode.Id(combined, node);
            }
            return(result.WithAttrs(attrs));
        }
コード例 #6
0
        public static LNode printKnownMacros(LNode node, IMacroContext context)
        {
            // namespace LeMP {
            //     /* documentation */
            //     #fn;
            //     ...
            // }
            return(F.Call(S.Splice, context.AllKnownMacros.SelectMany(p => p.Value)
                          .GroupBy(mi => mi.NamespaceSym).OrderBy(g => g.Key).Select(group =>
                                                                                     F.Attr(F.Trivia(S.TriviaSLCommentBefore, "#printKnownMacros"),
                                                                                            F.Call(S.Namespace, NamespaceSymbolToLNode(group.Key ?? GSymbol.Empty), LNode.Missing,
                                                                                                   F.Braces(group.Select(mi =>
            {
                StringBuilder descr = new StringBuilder(string.Format("\n\t\t### {0} ###\n",
                                                                      ParsingService.Current.Print(LNode.Id(mi.Name), null, ParsingService.Exprs)));
                if (!string.IsNullOrWhiteSpace(mi.Info.Syntax))
                {
                    descr.Append("\n\t\t\t").Append(mi.Info.Syntax.Replace("\n", "\n\t\t")).Append("\n");
                }
                if (!string.IsNullOrWhiteSpace(mi.Info.Description))
                {
                    descr.Append("\n\t\t").Append(mi.Info.Description.Replace("\n", "\n\t\t")).Append("\n");
                }
                descr.Append("\t");
                LNode line = LNode.Id(mi.Name ?? (Symbol)"<null>");

                string methodName = mi.Macro.Method.Name, @class = mi.Macro.Method.DeclaringType.Name;
                string postComment = " " + @class + "." + methodName;
                if (mi.Mode != MacroMode.Normal)
                {
                    postComment += string.Format(" (Mode = {0})", mi.Mode);
                }
                return F.Attr(
                    F.Trivia(S.TriviaMLCommentBefore, descr.ToString()),
                    F.Trivia(S.TriviaSpaceBefore, "\n"),
                    F.Trivia(S.TriviaSLCommentAfter, postComment),
                    line);
            })))))));
        }
コード例 #7
0
ファイル: Token.cs プロジェクト: modulexcite/ecsharp
        /// <summary>Converts a <see cref="Token"/> to a <see cref="LNode"/>.</summary>
        /// <param name="file">This becomes the <see cref="LNode.Source"/> property.</param>
        /// <remarks>If you really need to store tokens as LNodes, use this. Only
        /// the <see cref="Kind"/>, not the TypeInt, is preserved. Identifiers
        /// (where Kind==TokenKind.Id and Value is Symbol) are translated as Id
        /// nodes; everything else is translated as a call, using the TokenKind as
        /// the <see cref="LNode.Name"/> and the value, if any, as parameters. For
        /// example, if it has been treeified with <see cref="TokensToTree"/>, the
        /// token list for <c>"Nodes".Substring(1, 3)</c> as parsed by LES might
        /// translate to the LNode sequence <c>String("Nodes"), Dot(@@.),
        /// Substring, LParam(Number(1), Separator(@@,), Number(3)), RParen()</c>.
        /// The <see cref="LNode.Range"/> will match the range of the token.
        /// </remarks>
        public LNode ToLNode(ISourceFile file)
        {
            var    kind = Kind;
            Symbol kSym = GSymbol.Empty;
            Symbol id;

            if (kind != TokenKind.Id)
            {
                int k = (int)kind >> TokenKindShift;
                kSym = _kindAttrTable.TryGet(k, null);
            }

            var r = new SourceRange(file, StartIndex, Length);
            var c = Children;

            if (c != null)
            {
                if (c.Count != 0)
                {
                    r = new SourceRange(file, StartIndex, System.Math.Max(EndIndex, c.Last.EndIndex) - StartIndex);
                }
                return(LNode.Call(kSym, c.ToLNodes(), r, Style));
            }
            else if (IsOpenerOrCloser(kind) || Value == WhitespaceTag.Value)
            {
                return(LNode.Call(kSym, VList <LNode> .Empty, r, Style));
            }
            else if (kind == TokenKind.Id && (id = this.Value as Symbol) != null)
            {
                return(LNode.Id(id, r, Style));
            }
            else
            {
                return(LNode.Trivia(kSym, this.Value, r, Style));
            }
        }
コード例 #8
0
ファイル: ContractsMacro.out.cs プロジェクト: sizzles/ecsharp
            void ProcessEnsuresAttribute(VList <LNode> conditions, Symbol mode, LNode exceptionType, LNode variableName)
            {
                // Create a "Contract.Whatever()" check for each provided condition.
                bool haveCCRewriter = _haveCCRewriter && mode != sy_ensuresAssert && mode != sy_ensuresFinally;
                var  checks         = LNode.List();

                foreach (var condition_ in conditions)
                {
                    LNode condition = condition_;                       // make it writable so we can replace `_`
                    LNode conditionStr;

                    LNode  contractResult  = null;
                    string underscoreError = null;
                    if (mode == sy_ensuresOnThrow)
                    {
                        contractResult = Id__exception__;
                        if (haveCCRewriter)
                        {
                            underscoreError = "`ensuresOnThrow` does not support `_` in MS Code Contracts mode.";
                        }
                    }
                    else                                // @@ensures or @@ensuresAssert or @@ensuresFinally
                    {
                        contractResult = haveCCRewriter ? LNode.Call(LNode.Call(CodeSymbols.Dot, LNode.List(LNode.Id((Symbol)"Contract"), LNode.Call(CodeSymbols.Of, LNode.List(LNode.Id((Symbol)"Result"), ReturnType)).SetStyle(NodeStyle.Operator))).SetStyle(NodeStyle.Operator)) : Id_return_value;
                        if (mode == sy_ensuresFinally)
                        {
                            underscoreError = "The macro for `{0}` does not support `_` because the return value is not available in `finally`";
                        }
                        else if (haveCCRewriter && ReturnType.IsIdNamed(S.Missing))
                        {
                            underscoreError = "The macro for `{0}` does not support `_` in this context when MS Code Contracts are enabled, because the return type is unknown.";
                        }
                        bool changed = ReplaceContractUnderscore(ref condition, contractResult);
                    }
                    if (ReplaceContractUnderscore(ref condition, contractResult) && underscoreError != null)
                    {
                        Context.Sink.Error(condition, underscoreError, mode);
                    }

                    if (haveCCRewriter)
                    {
                        if (mode == sy_ensuresOnThrow)
                        {
                            checks.Add(exceptionType != null
                                                        ? LNode.Call(LNode.Call(CodeSymbols.Dot, LNode.List(LNode.Id((Symbol)"Contract"), LNode.Call(CodeSymbols.Of, LNode.List(LNode.Id((Symbol)"EnsuresOnThrow"), exceptionType)).SetStyle(NodeStyle.Operator))).SetStyle(NodeStyle.Operator), LNode.List(condition)) : LNode.Call(LNode.Call(CodeSymbols.Dot, LNode.List(LNode.Id((Symbol)"Contract"), LNode.Id((Symbol)"EnsuresOnThrow"))).SetStyle(NodeStyle.Operator), LNode.List(condition)));
                        }
                        else
                        {
                            checks.Add(LNode.Call(LNode.Call(CodeSymbols.Dot, LNode.List(LNode.Id((Symbol)"Contract"), LNode.Id((Symbol)"Ensures"))).SetStyle(NodeStyle.Operator), LNode.List(condition)));
                        }
                    }
                    else
                    {
                        conditionStr = ConditionToStringLit(condition,
                                                            mode == sy_ensuresOnThrow
                                                ? "Postcondition failed after throwing an exception: {1}" :
                                                            "Postcondition failed: {1}");


                        if (mode == sy_ensuresOnThrow)
                        {
                            var excType = GetExceptionTypeForEnsuresOnThrow();
                            checks.Add(LNode.Call(CodeSymbols.If, LNode.List(LNode.Call(CodeSymbols.Not, LNode.List(condition)).SetStyle(NodeStyle.Operator), LNode.Call(CodeSymbols.Throw, LNode.List(LNode.Call(CodeSymbols.New, LNode.List(LNode.Call(excType, LNode.List(conditionStr, Id__exception__)))))))));
                        }
                        else
                        {
                            LNode assertMethod;
                            if (mode == sy_ensuresAssert)
                            {
                                assertMethod = GetAssertMethod(Context);
                            }
                            else if (mode == sy_ensuresFinally)
                            {
                                assertMethod = GetAssertMethodForEnsuresFinally();
                            }
                            else
                            {
                                assertMethod = GetAssertMethodForEnsures();
                            }

                            checks.Add(LNode.Call(assertMethod, LNode.List(condition, conditionStr)));
                        }
                    }
                }

                // Request that the checks be added to the beginning of the method
                if (checks.Count > 0)
                {
                    if (_haveCCRewriter)
                    {
                        PrependStmts.AddRange(checks);
                    }
                    else if (mode == sy_ensuresOnThrow)
                    {
                        LNode excSpec = exceptionType == null ? Id__exception__ : LNode.Call(CodeSymbols.Var, LNode.List(exceptionType, Id__exception__));
                        PrependStmts.Add(LNode.Call((Symbol)"on_throw", LNode.List(excSpec, LNode.Call(CodeSymbols.Braces, LNode.List(checks)).SetStyle(NodeStyle.Statement))).SetStyle(NodeStyle.Special));
                    }
                    else if (mode == sy_ensuresFinally)
                    {
                        PrependStmts.Add(LNode.Call((Symbol)"on_finally", LNode.List(LNode.Call(CodeSymbols.Braces, LNode.List(checks)).SetStyle(NodeStyle.Statement))).SetStyle(NodeStyle.Special));
                    }
                    else                                // mode == @@ensures || mode == @@ensuresAssert
                    {
                        PrependStmts.Add(LNode.Call((Symbol)"on_return", LNode.List(Id_return_value, LNode.Call(CodeSymbols.Braces, LNode.List(checks)).SetStyle(NodeStyle.Statement))).SetStyle(NodeStyle.Special));
                    }
                }
            }
コード例 #9
0
ファイル: ContractsMacro.out.cs プロジェクト: sizzles/ecsharp
 LNode GetExceptionTypeForEnsuresOnThrow()
 {
     return((Context.ScopedProperties.TryGetValue(sy__numexceptionTypeForEnsuresOnThrow, null) as LNode)
            ?? LNode.Id((Symbol)"InvalidOperationException"));
 }
コード例 #10
0
 void ProcessRequiresAttribute(VList <LNode> conditions, Symbol mode, LNode variableName)
 {
     foreach (var condition_ in conditions)
     {
         LNode condition = condition_;
         LNode conditionStr;
         if (ReplaceContractUnderscore(ref condition, variableName))
         {
             if (variableName == null)
             {
                 Context.Write(Severity.Error, condition, "`{0}`: underscore has no meaning in this location.", mode);
             }
         }
         if (mode == sy_assert)
         {
             PrependStmts.Add(LNode.Call((Symbol)"assert", LNode.List(condition)));
         }
         else if (_haveCCRewriter)
         {
             PrependStmts.Add(LNode.Call(LNode.Call(CodeSymbols.Dot, LNode.List(LNode.Id((Symbol)"Contract"), LNode.Id((Symbol)"Requires"))), LNode.List(condition)));
         }
         else
         {
             conditionStr = ConditionToStringLit(condition, "Precondition failed: {1}");
             PrependStmts.Add(LNode.Call(GetAssertMethodForRequires(), LNode.List(condition, conditionStr)));
         }
     }
 }
コード例 #11
0
ファイル: ContractsMacro.out.cs プロジェクト: sizzles/ecsharp
            void ProcessRequiresAttribute(VList <LNode> conditions, Symbol mode, LNode variableName)
            {
                // Create a "Contract.Requires()" check for each provided condition.
                foreach (var condition_ in conditions)
                {
                    LNode condition = condition_;                       // make it writable so we can replace `_`
                    LNode conditionStr;

                    if (ReplaceContractUnderscore(ref condition, variableName))
                    {
                        if (variableName == null)
                        {
                            Context.Sink.Error(condition, "`{0}`: underscore has no meaning in this location.", mode);
                        }
                    }
                    if (mode == sy_assert)
                    {
                        PrependStmts.Add(LNode.Call((Symbol)"assert", LNode.List(condition)));                          // relies on assert() macro
                    }
                    else if (_haveCCRewriter)
                    {
                        PrependStmts.Add(LNode.Call(LNode.Call(CodeSymbols.Dot, LNode.List(LNode.Id((Symbol)"Contract"), LNode.Id((Symbol)"Requires"))).SetStyle(NodeStyle.Operator), LNode.List(condition)));
                    }
                    else
                    {
                        conditionStr = ConditionToStringLit(condition, "Precondition failed: {1}");
                        PrependStmts.Add(LNode.Call(GetAssertMethodForRequires(), LNode.List(condition, conditionStr)));
                    }
                }
            }
コード例 #12
0
ファイル: MatchCode.out.cs プロジェクト: dadhi/ecsharp
            private void MakeArgListTests(LNodeList patternArgs, ref LNode candidate)
            {
                // Note: at this point we can assume that the quantity of
                // arguments has already been checked and is not too small.
                Symbol varArgSym  = null;
                LNode  varArgCond = null;
                int    i;

                for (i = 0; i < patternArgs.Count; i++)
                {
                    MakeTestExpr(patternArgs[i], LNode.Call(CodeSymbols.IndexBracks, LNode.List(LNode.Call(CodeSymbols.Dot, LNode.List(candidate, LNode.Id((Symbol)"Args"))).SetStyle(NodeStyle.Operator), F.Literal(i))).SetStyle(NodeStyle.Operator), out varArgSym, out varArgCond);
                    if (varArgSym != null)
                    {
                        break;
                    }
                }
                int i2 = i + 1;

                for (int left = patternArgs.Count - i2; i2 < patternArgs.Count; i2++)
                {
                    Symbol varArgSym2  = null;
                    LNode  varArgCond2 = null;
                    MakeTestExpr(patternArgs[i2], LNode.Call(CodeSymbols.IndexBracks, LNode.List(LNode.Call(CodeSymbols.Dot, LNode.List(candidate, LNode.Id((Symbol)"Args"))).SetStyle(NodeStyle.Operator), LNode.Call(CodeSymbols.Sub, LNode.List(LNode.Call(CodeSymbols.Dot, LNode.List(LNode.Call(CodeSymbols.Dot, LNode.List(candidate, LNode.Id((Symbol)"Args"))).SetStyle(NodeStyle.Operator), LNode.Id((Symbol)"Count"))).SetStyle(NodeStyle.Operator), F.Literal(left))).SetStyle(NodeStyle.Operator))).SetStyle(NodeStyle.Operator), out varArgSym2, out varArgCond2);
                    if (varArgSym2 != null)
                    {
                        Context.Sink.Error(patternArgs[i2], "More than a single $(...varargs) variable is not supported in a single argument list.");
                        break;
                    }
                    left--;
                }
                if (varArgSym != null && (varArgSym != __ || varArgCond != null))
                {
                    // Extract variable arg list
                    LNode varArgSymId = F.Id(varArgSym);
                    LNode grabVarArgs;
                    if (i == 0 && patternArgs.Count == 1)
                    {
                        grabVarArgs = LNode.Call(CodeSymbols.Assign, LNode.List(varArgSymId, LNode.Call(CodeSymbols.Dot, LNode.List(candidate, LNode.Id((Symbol)"Args"))).SetStyle(NodeStyle.Operator))).SetStyle(NodeStyle.Operator);
                    }
                    else if (i == 0 && patternArgs.Count > 1)
                    {
                        var fixedArgsLit = F.Literal(patternArgs.Count - 1);
                        grabVarArgs = LNode.Call(CodeSymbols.Assign, LNode.List(varArgSymId, LNode.Call(LNode.Call(CodeSymbols.Dot, LNode.List(LNode.Call(CodeSymbols.Dot, LNode.List(candidate, LNode.Id((Symbol)"Args"))).SetStyle(NodeStyle.Operator), LNode.Id((Symbol)"WithoutLast"))).SetStyle(NodeStyle.Operator), LNode.List(fixedArgsLit)))).SetStyle(NodeStyle.Operator);
                    }
                    else
                    {
                        var varArgStartLit = F.Literal(i);
                        var fixedArgsLit   = F.Literal(patternArgs.Count - 1);
                        if (i + 1 == patternArgs.Count)
                        {
                            grabVarArgs = LNode.Call(CodeSymbols.Assign, LNode.List(varArgSymId, LNode.Call(CodeSymbols.New, LNode.List(LNode.Call((Symbol)"LNodeList", LNode.List(LNode.Call(LNode.Call(CodeSymbols.Dot, LNode.List(LNode.Call(CodeSymbols.Dot, LNode.List(candidate, LNode.Id((Symbol)"Args"))).SetStyle(NodeStyle.Operator), LNode.Id((Symbol)"Slice"))).SetStyle(NodeStyle.Operator), LNode.List(varArgStartLit)))))))).SetStyle(NodeStyle.Operator);
                        }
                        else
                        {
                            grabVarArgs = LNode.Call(CodeSymbols.Assign, LNode.List(varArgSymId, LNode.Call(CodeSymbols.New, LNode.List(LNode.Call((Symbol)"LNodeList", LNode.List(LNode.Call(LNode.Call(CodeSymbols.Dot, LNode.List(LNode.Call(CodeSymbols.Dot, LNode.List(candidate, LNode.Id((Symbol)"Args"))).SetStyle(NodeStyle.Operator), LNode.Id((Symbol)"Slice"))).SetStyle(NodeStyle.Operator), LNode.List(varArgStartLit, LNode.Call(CodeSymbols.Sub, LNode.List(LNode.Call(CodeSymbols.Dot, LNode.List(LNode.Call(CodeSymbols.Dot, LNode.List(candidate, LNode.Id((Symbol)"Args"))).SetStyle(NodeStyle.Operator), LNode.Id((Symbol)"Count"))).SetStyle(NodeStyle.Operator), fixedArgsLit)).SetStyle(NodeStyle.Operator))))))))).SetStyle(NodeStyle.Operator);
                        }
                    }

                    // Add an extra condition on the $(...list) if requested by user
                    if (varArgCond != null || IsMultiCase)
                    {
                        Tests.Add(LNode.Call(CodeSymbols.OrBits, LNode.List(LNode.Call(CodeSymbols.Dot, LNode.List(grabVarArgs.PlusAttrs(LNode.List(LNode.InParensTrivia)), LNode.Id((Symbol)"IsEmpty"))).SetStyle(NodeStyle.Operator), LNode.Literal(true))).SetStyle(NodeStyle.Operator));
                        Tests.Add(varArgCond);
                    }
                    else
                    {
                        ThenClause.Add(grabVarArgs);
                    }
                }
            }
コード例 #13
0
ファイル: ContractsMacro.out.cs プロジェクト: sizzles/ecsharp
        public static LNode ContractsOnProperty(LNode prop, IMacroContext context)
        {
            // Performance note: one should keep in mind that this macro usually
            // has no effect. It looks for contracts and usually finds none.
            LNode oldProp = prop;

            if (prop.ArgCount == 4)
            {
                LNode braces    = prop[3];
                var   oldBraces = braces;
                var   rw        = new CodeContractRewriter(prop.Args[0], prop.Args[1], context);

                // If this has an argument list (this[...]), process its contract attributes
                prop = ProcessArgContractAttributes(prop, 2, rw);

                // Remove contract attributes from the property and store in a list
                VList <LNode> cAttrs = LNode.List();
                prop = prop.WithArgChanged(0, GrabContractAttrs(prop.Args[0], ref cAttrs, ContractAppliesTo.Getter));
                prop = GrabContractAttrs(prop, ref cAttrs);

                // Find the getter and setter
                LNode         getter = null, setter = null;
                int           getterIndex = -1, setterIndex = -1;
                VList <LNode> getterAttrs = LNode.List(), setterAttrs = LNode.List();
                bool          isLambdaProperty = !braces.Calls(S.Braces);
                if (isLambdaProperty)
                {
                    if (cAttrs.Count == 0)
                    {
                        return(null);                           // lambda property has no contract attributes
                    }
                    // Transform into a normal property
                    getterAttrs = cAttrs;
                    getter      = LNode.Call(CodeSymbols.get, LNode.List(LNode.Call(CodeSymbols.Braces, LNode.List(LNode.Call(CodeSymbols.Return, LNode.List(braces)))).SetStyle(NodeStyle.Statement))).SetStyle(NodeStyle.Special);
                    braces      = LNode.Call(CodeSymbols.Braces, LNode.List(getter)).SetStyle(NodeStyle.Statement);
                    getterIndex = 0;
                }
                else
                {
                    for (int i = 0; i < braces.Args.Count; i++)
                    {
                        var part = braces.Args[i];
                        if (part.Calls(S.get))
                        {
                            getter = part; getterIndex = i;
                        }
                        if (part.Calls(S.set))
                        {
                            setter = part; setterIndex = i;
                        }
                    }

                    // Now create separate lists of contract attributes for the getter and the setter
                    if (cAttrs.Count != 0)
                    {
                        getterAttrs = cAttrs.SmartWhere(a => (PropertyContractInterpretation(a) & ContractAppliesTo.Getter) != 0);
                        setterAttrs = cAttrs.SmartWhere(a => (PropertyContractInterpretation(a) & ContractAppliesTo.Setter) != 0);
                    }
                }

                // Process the discovered attributes to produce prepended statements
                var sharedPrependStmts = rw.PrependStmts;
                if (getter != null)
                {
                    getter = GrabContractAttrs(getter, ref getterAttrs);
                    rw.Process(getterAttrs, null);
                    rw.PrependStmtsToGetterOrSetter(ref braces, getterIndex, getter);
                }
                if (setter != null)
                {
                    rw.PrependStmts = sharedPrependStmts;
                    setter          = GrabContractAttrs(setter, ref setterAttrs);
                    rw.Process(setterAttrs, LNode.Id(CodeSymbols.value), true);
                    rw.PrependStmtsToGetterOrSetter(ref braces, setterIndex, setter);
                }

                // Update the property
                if (braces == oldBraces)
                {
                    return(null);                       // this is the common case
                }
                else
                {
                    return(prop.WithArgChanged(3, braces));
                }
            }
            return(null);
        }
コード例 #14
0
 [LexicalMacro("x in lo..hi; x in lo...hi; x in ..hi; x in lo..._; x in range", "Converts an 'in' expression to a normal C# expression using the following rules " + "(keeping in mind that the EC# parser treats `..<` as an alias for `..`):\n" + "1. `x in _..hi` and `x in ..hi` become `x.IsInRangeExcl(hi)`\n" + "2. `x in _...hi` and `x in ...hi` become `x.IsInRangeIncl(hi)`\n" + "3. `x in lo.._` and `x in lo..._` become simply `x >= lo`\n" + "4. `x in lo..hi` becomes `x.IsInRangeExcludeHi(lo, hi)`\n" + "5. `x in lo...hi` becomes `x.IsInRange(lo, hi)`\n" + "6. `x in range` becomes `range.Contains(x)`\n" + "The first applicable rule is used.", "#in")] public static LNode In(LNode node, IMacroContext context)
 {
     {
         LNode range, x;
         if (node.Calls(CodeSymbols.In, 2) && (x = node.Args[0]) != null && (range = node.Args[1]) != null)
         {
             LNode parens;
             range = range.WithoutAttrNamed(S.TriviaInParens, out parens);
             if (parens == null)
             {
                 {
                     LNode hi, lo;
                     if (range.Calls(CodeSymbols.DotDot, 2) && (lo = range.Args[0]) != null && (hi = range.Args[1]) != null)
                     {
                         if (lo.IsIdNamed(__))
                         {
                             return(LNode.Call(CodeSymbols.LT, LNode.List(x, hi)).SetStyle(NodeStyle.Operator));
                         }
                         else if (hi.IsIdNamed(__))
                         {
                             return(LNode.Call(CodeSymbols.GE, LNode.List(x, lo)).SetStyle(NodeStyle.Operator));
                         }
                         else
                         {
                             return(LNode.Call(LNode.Call(CodeSymbols.Dot, LNode.List(x, LNode.Id((Symbol)"IsInRangeExcludeHi"))), LNode.List(lo, hi)));
                         }
                     }
                     else if (range.Calls(CodeSymbols.DotDot, 1) && (hi = range.Args[0]) != null)
                     {
                         return(LNode.Call(CodeSymbols.LT, LNode.List(x, hi)).SetStyle(NodeStyle.Operator));
                     }
                     else if (range.Calls(CodeSymbols.DotDotDot, 2) && (lo = range.Args[0]) != null && (hi = range.Args[1]) != null)
                     {
                         if (lo.IsIdNamed(__))
                         {
                             return(LNode.Call(CodeSymbols.LE, LNode.List(x, hi)).SetStyle(NodeStyle.Operator));
                         }
                         else if (hi.IsIdNamed(__))
                         {
                             return(LNode.Call(CodeSymbols.GE, LNode.List(x, lo)).SetStyle(NodeStyle.Operator));
                         }
                         else
                         {
                             return(LNode.Call(LNode.Call(CodeSymbols.Dot, LNode.List(x, LNode.Id((Symbol)"IsInRange"))), LNode.List(lo, hi)));
                         }
                     }
                     else if (range.Calls(CodeSymbols.DotDotDot, 1) && (hi = range.Args[0]) != null)
                     {
                         return(LNode.Call(CodeSymbols.LE, LNode.List(x, hi)).SetStyle(NodeStyle.Operator));
                     }
                 }
             }
             return(LNode.Call(LNode.Call(CodeSymbols.Dot, LNode.List(range, LNode.Id((Symbol)"Contains"))), LNode.List(x)));
         }
     }
     return(null);
 }
コード例 #15
0
ファイル: StandardMacros.cs プロジェクト: dadhi/ecsharp
 internal static LNode TempVarDecl(IMacroContext ctx, LNode value, out LNode tmpVarName, string prefix)
 {
     tmpVarName = LNode.Id(NextTempName(ctx, prefix), value);
     return(F.Var(F.Missing, tmpVarName, value));
 }
コード例 #16
0
            public LNode GetWithFn(AdtParam part, bool isAbstract, Symbol virtualOverride, IEnumerable <AdtParam> allParts)
            {
                int totalParts = allParts.Count();
                var withField  = F.Id("With" + part.NameId.Name);

                var args = LNode.List();

                foreach (AdtParam otherPart in allParts)
                {
                    if (part == otherPart)
                    {
                        args.Add(F.Id("newValue"));
                    }
                    else
                    {
                        args.Add(otherPart.NameId);
                    }
                }

                var attrs = new VList <LNode>(F.Id(S.Public));

                if (isAbstract)
                {
                    attrs.Add(F.Id(S.Abstract));
                }
                if (virtualOverride != null && (!isAbstract || virtualOverride == S.Override))
                {
                    attrs.Add(F.Id(virtualOverride));
                }

                LNode method;
                LNode type    = part.Type;
                LNode retType = part.ContainingType.TypeNameWithoutAttrs;

                if (isAbstract)
                {
                    method = LNode.Call(LNode.List(attrs), CodeSymbols.Fn, LNode.List(retType, withField, LNode.Call(CodeSymbols.AltList, LNode.List(LNode.Call(LNode.List(part.OriginalDecl.Attrs), CodeSymbols.Var, LNode.List(type, LNode.Id((Symbol)"newValue")))))));
                }
                else
                {
                    method = LNode.Call(LNode.List(attrs), CodeSymbols.Fn, LNode.List(retType, withField, LNode.Call(CodeSymbols.AltList, LNode.List(LNode.Call(LNode.List(part.OriginalDecl.Attrs), CodeSymbols.Var, LNode.List(type, LNode.Id((Symbol)"newValue"))))), LNode.Call(CodeSymbols.Braces, LNode.List(LNode.Call(CodeSymbols.Return, LNode.List(LNode.Call(CodeSymbols.New, LNode.List(LNode.Call(TypeNameWithoutAttrs, LNode.List(args)))))))).SetStyle(NodeStyle.Statement)));
                }
                return(method);
            }
コード例 #17
0
            public LNode GetItemDecl(int itemNum)
            {
                LNode ItemN = F.Id("Item" + itemNum);

                // ItemN properties are used by the code generated for pattern matching
                return(LNode.Call(LNode.List(LNode.Call(LNode.Call(CodeSymbols.Dot, LNode.List(LNode.Call(CodeSymbols.Dot, LNode.List(LNode.Id((Symbol)"System"), LNode.Id((Symbol)"ComponentModel"))).SetStyle(NodeStyle.Operator), LNode.Id((Symbol)"EditorBrowsable"))).SetStyle(NodeStyle.Operator), LNode.List(LNode.Call(CodeSymbols.Dot, LNode.List(LNode.Call(CodeSymbols.Dot, LNode.List(LNode.Call(CodeSymbols.Dot, LNode.List(LNode.Id((Symbol)"System"), LNode.Id((Symbol)"ComponentModel"))).SetStyle(NodeStyle.Operator), LNode.Id((Symbol)"EditorBrowsableState"))).SetStyle(NodeStyle.Operator), LNode.Id((Symbol)"Never"))).SetStyle(NodeStyle.Operator))), LNode.Id(CodeSymbols.Public)), CodeSymbols.Property, LNode.List(Type, ItemN, LNode.Missing, LNode.Call(CodeSymbols.Braces, LNode.List(LNode.Call(CodeSymbols.get, LNode.List(LNode.Call(CodeSymbols.Braces, LNode.List(LNode.Call(CodeSymbols.Return, LNode.List(NameId)))).SetStyle(NodeStyle.Statement))).SetStyle(NodeStyle.Special))).SetStyle(NodeStyle.Statement))));
            }
コード例 #18
0
ファイル: MatchCode.out.cs プロジェクト: jonathanvdc/Loyc
            private void MakeArgListTests(VList <LNode> patternArgs, ref LNode candidate)
            {
                Symbol varArgSym  = null;
                LNode  varArgCond = null;
                int    i;

                for (i = 0; i < patternArgs.Count; i++)
                {
                    MakeTestExpr(patternArgs[i], LNode.Call(CodeSymbols.IndexBracks, LNode.List(LNode.Call(CodeSymbols.Dot, LNode.List(candidate, LNode.Id((Symbol)"Args"))), F.Literal(i))), out varArgSym, out varArgCond);
                    if (varArgSym != null)
                    {
                        break;
                    }
                }
                int i2 = i + 1;

                for (int left = patternArgs.Count - i2; i2 < patternArgs.Count; i2++)
                {
                    Symbol varArgSym2  = null;
                    LNode  varArgCond2 = null;
                    MakeTestExpr(patternArgs[i2], LNode.Call(CodeSymbols.IndexBracks, LNode.List(LNode.Call(CodeSymbols.Dot, LNode.List(candidate, LNode.Id((Symbol)"Args"))), LNode.Call(CodeSymbols.Sub, LNode.List(LNode.Call(CodeSymbols.Dot, LNode.List(LNode.Call(CodeSymbols.Dot, LNode.List(candidate, LNode.Id((Symbol)"Args"))), LNode.Id((Symbol)"Count"))), F.Literal(left))).SetStyle(NodeStyle.Operator))), out varArgSym2, out varArgCond2);
                    if (varArgSym2 != null)
                    {
                        Context.Sink.Write(Severity.Error, patternArgs[i2], "More than a single $(...varargs) variable is not supported in a single argument list.");
                        break;
                    }
                    left--;
                }
                if (varArgSym != null && (varArgSym != __ || varArgCond != null))
                {
                    LNode varArgSymId = F.Id(varArgSym);
                    LNode grabVarArgs;
                    if (i == 0 && patternArgs.Count == 1)
                    {
                        grabVarArgs = LNode.Call(CodeSymbols.Assign, LNode.List(varArgSymId, LNode.Call(CodeSymbols.Dot, LNode.List(candidate, LNode.Id((Symbol)"Args"))))).SetStyle(NodeStyle.Operator);
                    }
                    else if (i == 0 && patternArgs.Count > 1)
                    {
                        var fixedArgsLit = F.Literal(patternArgs.Count - 1);
                        grabVarArgs = LNode.Call(CodeSymbols.Assign, LNode.List(varArgSymId, LNode.Call(LNode.Call(CodeSymbols.Dot, LNode.List(LNode.Call(CodeSymbols.Dot, LNode.List(candidate, LNode.Id((Symbol)"Args"))), LNode.Id((Symbol)"WithoutLast"))), LNode.List(fixedArgsLit)))).SetStyle(NodeStyle.Operator);
                    }
                    else
                    {
                        var varArgStartLit = F.Literal(i);
                        var fixedArgsLit   = F.Literal(patternArgs.Count - 1);
                        if (i + 1 == patternArgs.Count)
                        {
                            grabVarArgs = LNode.Call(CodeSymbols.Assign, LNode.List(varArgSymId, LNode.Call(CodeSymbols.New, LNode.List(LNode.Call(LNode.Call(CodeSymbols.Of, LNode.List(LNode.Id((Symbol)"VList"), LNode.Id((Symbol)"LNode"))), LNode.List(LNode.Call(LNode.Call(CodeSymbols.Dot, LNode.List(LNode.Call(CodeSymbols.Dot, LNode.List(candidate, LNode.Id((Symbol)"Args"))), LNode.Id((Symbol)"Slice"))), LNode.List(varArgStartLit)))))))).SetStyle(NodeStyle.Operator);
                        }
                        else
                        {
                            grabVarArgs = LNode.Call(CodeSymbols.Assign, LNode.List(varArgSymId, LNode.Call(CodeSymbols.New, LNode.List(LNode.Call(LNode.Call(CodeSymbols.Of, LNode.List(LNode.Id((Symbol)"VList"), LNode.Id((Symbol)"LNode"))), LNode.List(LNode.Call(LNode.Call(CodeSymbols.Dot, LNode.List(LNode.Call(CodeSymbols.Dot, LNode.List(candidate, LNode.Id((Symbol)"Args"))), LNode.Id((Symbol)"Slice"))), LNode.List(varArgStartLit, LNode.Call(CodeSymbols.Sub, LNode.List(LNode.Call(CodeSymbols.Dot, LNode.List(LNode.Call(CodeSymbols.Dot, LNode.List(candidate, LNode.Id((Symbol)"Args"))), LNode.Id((Symbol)"Count"))), fixedArgsLit)).SetStyle(NodeStyle.Operator))))))))).SetStyle(NodeStyle.Operator);
                        }
                    }
                    if (varArgCond != null || IsMultiCase)
                    {
                        Tests.Add(LNode.Call(CodeSymbols.OrBits, LNode.List(LNode.Call(CodeSymbols.Dot, LNode.List(grabVarArgs.PlusAttrs(LNode.List(LNode.InParensTrivia)), LNode.Id((Symbol)"IsEmpty"))), LNode.Literal(true))).SetStyle(NodeStyle.Operator));
                        Tests.Add(varArgCond);
                    }
                    else
                    {
                        ThenClause.Add(grabVarArgs);
                    }
                }
            }
コード例 #19
0
ファイル: MatchCode.out.cs プロジェクト: jonathanvdc/Loyc
        [LexicalMacro("matchCode (var) { case ...: ... }; // In LES, use a => b instead of case a: b", "Attempts to match and deconstruct a Loyc tree against a series of cases with patterns, e.g. " + "`case $a + $b:` expects a tree that calls `+` with two parameters, placed in new variables called a and b. " + "`break` is not required or recognized at the end of each case's handler (code block). " + "Use `$(...x)` to gather zero or more parameters into a list `x`. " + "Use `case pattern1, pattern2:` in EC# to handle multiple cases with the same handler.")] public static LNode matchCode(LNode node, IMacroContext context)
        {
            var           args_body = context.GetArgsAndBody(true);
            VList <LNode> args = args_body.Item1, body = args_body.Item2;

            if (args.Count != 1 || body.Count < 1)
            {
                return(null);
            }
            var cases  = GetCases(body, context.Sink);

            if (cases.IsEmpty)
            {
                return(null);
            }
            var output = new WList <LNode>();
            var @var   = MaybeAddTempVarDecl(args[0], output);
            var ifClauses = new List <Pair <LNode, LNode> >();
            var cmc    = new CodeMatchContext {
                Context = context
            };

            foreach (var @case in cases)
            {
                cmc.ThenClause.Clear();
                LNode testExpr = null;
                if (@case.Key.Count > 0)
                {
                    if (cmc.IsMultiCase = @case.Key.Count > 1)
                    {
                        cmc.UsageCounters.Clear();
                        testExpr = @case.Key.Aggregate((LNode)null, (test, pattern) => {
                            test = LNode.MergeBinary(test, cmc.MakeTopTestExpr(pattern, @var), S.Or);
                            return(test);
                        });
                        foreach (var pair in cmc.UsageCounters.Where(p => p.Value < @case.Key.Count))
                        {
                            if (cmc.NodeVars.ContainsKey(pair.Key))
                            {
                                cmc.NodeVars[pair.Key] = true;
                            }
                            if (cmc.ListVars.ContainsKey(pair.Key))
                            {
                                cmc.ListVars[pair.Key] = true;
                            }
                        }
                    }
                    else
                    {
                        testExpr = cmc.MakeTopTestExpr(@case.Key[0], @var);
                    }
                }
                var handler = @case.Value;
                if (cmc.ThenClause.Count > 0)
                {
                    handler = LNode.MergeLists(F.Braces(cmc.ThenClause), handler, S.Braces);
                }
                ifClauses.Add(Pair.Create(testExpr, handler));
            }
            LNode ifStmt = null;

            for (int i = ifClauses.Count - 1; i >= 0; i--)
            {
                if (ifClauses[i].Item1 == null)
                {
                    if (ifStmt == null)
                    {
                        ifStmt = ifClauses[i].Item2;
                    }
                    else
                    {
                        context.Sink.Write(Severity.Error, node, "The default case must appear last, and there can be only one.");
                    }
                }
                else
                {
                    if (ifStmt == null)
                    {
                        ifStmt = F.Call(S.If, ifClauses[i].Item1, ifClauses[i].Item2);
                    }
                    else
                    {
                        ifStmt = F.Call(S.If, ifClauses[i].Item1, ifClauses[i].Item2, ifStmt);
                    }
                }
            }
            if (cmc.NodeVars.Count > 0)
            {
                output.Add(F.Call(S.Var, ListExt.Single(F.Id("LNode")).Concat(cmc.NodeVars.OrderBy(v => v.Key.Name).Select(kvp => kvp.Value ? F.Call(S.Assign, F.Id(kvp.Key), F.Null) : F.Id(kvp.Key)))));
            }
            if (cmc.ListVars.Count > 0)
            {
                LNode type = LNode.Call(CodeSymbols.Of, LNode.List(LNode.Id((Symbol)"VList"), LNode.Id((Symbol)"LNode")));
                output.Add(F.Call(S.Var, ListExt.Single(type).Concat(cmc.ListVars.OrderBy(v => v.Key.Name).Select(kvp => kvp.Value ? LNode.Call(CodeSymbols.Assign, LNode.List(F.Id(kvp.Key), LNode.Call(CodeSymbols.Default, LNode.List(type)))).SetStyle(NodeStyle.Operator) : F.Id(kvp.Key)))));
            }
            if (output.Count == 0)
            {
                return(ifStmt);
            }
            else
            {
                output.Add(ifStmt);
                return(F.Braces(output.ToVList()));
            }
        }
コード例 #20
0
ファイル: MatchMacro.out.cs プロジェクト: jonathanvdc/Loyc
            void GenCodeForPattern(LNode input, LNode pattern)
            {
                bool          refExistingVar;
                LNode         varBinding, cmpExpr, isType, inRange;
                VList <LNode> subPatterns, conditions;

                GetPatternComponents(pattern, out varBinding, out refExistingVar, out cmpExpr, out isType, out inRange, out subPatterns, out conditions);
                if (isType != null)
                {
                    if ((cmpExpr ?? inRange ?? varBinding) != null)
                    {
                        if (!LooksLikeSimpleValue(input))
                        {
                            PutStmt(TempVarDecl(input, out input));
                        }
                    }
                    PutCond(LNode.Call(CodeSymbols.Is, LNode.List(input, isType)).SetStyle(NodeStyle.Operator));
                    if (varBinding == null && ((cmpExpr ?? inRange) != null || subPatterns.Count > 0))
                    {
                        varBinding = LNode.Id(NextTempName(), isType);
                    }
                }
                if (varBinding != null)
                {
                    if (isType != null)
                    {
                        if (refExistingVar)
                        {
                            PutStmt(LNode.Call(CodeSymbols.Assign, LNode.List(varBinding, LNode.Call(CodeSymbols.Cast, LNode.List(input, isType)).SetStyle(NodeStyle.Operator))).SetStyle(NodeStyle.Operator));
                        }
                        else
                        {
                            PutStmt(LNode.Call(CodeSymbols.Var, LNode.List(isType, LNode.Call(CodeSymbols.Assign, LNode.List(varBinding, LNode.Call(CodeSymbols.Cast, LNode.List(input, isType)).SetStyle(NodeStyle.Operator))))));
                        }
                    }
                    else
                    {
                        if (refExistingVar)
                        {
                            PutStmt(LNode.Call(CodeSymbols.Assign, LNode.List(varBinding, input)).SetStyle(NodeStyle.Operator));
                        }
                        else
                        {
                            PutStmt(LNode.Call(CodeSymbols.Var, LNode.List(LNode.Missing, LNode.Call(CodeSymbols.Assign, LNode.List(varBinding, input)))));
                        }
                    }
                    input = varBinding;
                }
                if (cmpExpr != null)
                {
                    if (cmpExpr.Value == null)
                    {
                        PutCond(LNode.Call(CodeSymbols.Eq, LNode.List(input, LNode.Literal(null))).SetStyle(NodeStyle.Operator));
                    }
                    else
                    {
                        PutCond(LNode.Call(LNode.Call(CodeSymbols.Dot, LNode.List(cmpExpr, LNode.Id((Symbol)"Equals"))), LNode.List(input)));
                    }
                }
                for (int itemIndex = 0; itemIndex < subPatterns.Count; itemIndex++)
                {
                    var   subPattern = subPatterns[itemIndex];
                    LNode propName;
                    if (subPattern.Calls(S.NamedArg, 2) || subPattern.Calls(S.Colon, 2))
                    {
                        propName   = subPattern[0];
                        subPattern = subPattern[1];
                    }
                    else
                    {
                        propName = LNode.Id("Item" + (itemIndex + 1), subPattern);
                    }
                    GenCodeForPattern(LNode.Call(CodeSymbols.Dot, LNode.List(input, propName)), subPattern);
                }
                if (inRange != null)
                {
                    PutCond(LNode.Call(CodeSymbols.In, LNode.List(input, inRange)).SetStyle(NodeStyle.Operator));
                }
                foreach (var cond in conditions)
                {
                    PutCond(cond);
                }
            }
コード例 #21
0
        public static LNode ContractsOnProperty(LNode prop, IMacroContext context)
        {
            LNode oldProp = prop;

            if (prop.ArgCount == 4)
            {
                LNode braces    = prop[3];
                var   oldBraces = braces;
                var   rw        = new CodeContractRewriter(prop.Args[0], prop.Args[1], context);
                prop = ProcessArgContractAttributes(prop, 2, rw);
                VList <LNode> cAttrs = LNode.List();
                prop = prop.WithArgChanged(0, GrabContractAttrs(prop.Args[0], ref cAttrs, ContractAppliesTo.Getter));
                prop = GrabContractAttrs(prop, ref cAttrs);
                LNode         getter = null, setter = null;
                int           getterIndex = -1, setterIndex = -1;
                VList <LNode> getterAttrs = LNode.List(), setterAttrs = LNode.List();
                bool          isLambdaProperty = !braces.Calls(S.Braces);
                if (isLambdaProperty)
                {
                    if (cAttrs.Count == 0)
                    {
                        return(null);
                    }
                    getterAttrs = cAttrs;
                    getter      = LNode.Call(CodeSymbols.get, LNode.List(LNode.Call(CodeSymbols.Braces, LNode.List(LNode.Call(CodeSymbols.Return, LNode.List(braces)))).SetStyle(NodeStyle.Statement))).SetStyle(NodeStyle.Special);
                    braces      = LNode.Call(CodeSymbols.Braces, LNode.List(getter)).SetStyle(NodeStyle.Statement);
                    getterIndex = 0;
                }
                else
                {
                    for (int i = 0; i < braces.Args.Count; i++)
                    {
                        var part = braces.Args[i];
                        if (part.Calls(S.get))
                        {
                            getter      = part;
                            getterIndex = i;
                        }
                        if (part.Calls(S.set))
                        {
                            setter      = part;
                            setterIndex = i;
                        }
                    }
                    if (cAttrs.Count != 0)
                    {
                        getterAttrs = cAttrs.SmartWhere(a => (PropertyContractInterpretation(a) & ContractAppliesTo.Getter) != 0);
                        setterAttrs = cAttrs.SmartWhere(a => (PropertyContractInterpretation(a) & ContractAppliesTo.Setter) != 0);
                    }
                }
                var sharedPrependStmts = rw.PrependStmts;
                if (getter != null)
                {
                    getter = GrabContractAttrs(getter, ref getterAttrs);
                    rw.Process(getterAttrs, null);
                    rw.PrependStmtsToGetterOrSetter(ref braces, getterIndex, getter);
                }
                if (setter != null)
                {
                    rw.PrependStmts = sharedPrependStmts;
                    setter          = GrabContractAttrs(setter, ref setterAttrs);
                    rw.Process(setterAttrs, LNode.Id(CodeSymbols.value), true);
                    rw.PrependStmtsToGetterOrSetter(ref braces, setterIndex, setter);
                }
                if (braces == oldBraces)
                {
                    return(null);
                }
                else
                {
                    return(prop.WithArgChanged(3, braces));
                }
            }
            return(null);
        }
コード例 #22
0
 /// <summary>Returns the same node with a parentheses attribute added.</summary>
 public static LNode InParens(this LNode node)
 {
     return(node.PlusAttrBefore(LNode.Id(CodeSymbols.TriviaInParens)));
 }
コード例 #23
0
            public LNode GetItemDecl(int itemNum)
            {
                LNode ItemN = F.Id("Item" + itemNum);

                return(LNode.Call(LNode.List(LNode.Call(LNode.Call(CodeSymbols.Dot, LNode.List(LNode.Call(CodeSymbols.Dot, LNode.List(LNode.Id((Symbol)"System"), LNode.Id((Symbol)"ComponentModel"))), LNode.Id((Symbol)"EditorBrowsable"))), LNode.List(LNode.Call(CodeSymbols.Dot, LNode.List(LNode.Call(CodeSymbols.Dot, LNode.List(LNode.Call(CodeSymbols.Dot, LNode.List(LNode.Id((Symbol)"System"), LNode.Id((Symbol)"ComponentModel"))), LNode.Id((Symbol)"EditorBrowsableState"))), LNode.Id((Symbol)"Never"))))), LNode.Id(CodeSymbols.Public)), CodeSymbols.Property, LNode.List(Type, ItemN, LNode.Missing, LNode.Call(CodeSymbols.Braces, LNode.List(LNode.Call(CodeSymbols.get, LNode.List(LNode.Call(CodeSymbols.Braces, LNode.List(LNode.Call(CodeSymbols.Return, LNode.List(NameId)))).SetStyle(NodeStyle.Statement))).SetStyle(NodeStyle.Special))).SetStyle(NodeStyle.Statement))));
            }
コード例 #24
0
 /// <summary>Returns the same node with a parentheses attribute added.</summary>
 /// <remarks>The node's range is changed to the provided <see cref="SourceRange"/>.</remarks>
 public static LNode InParens(this LNode node, SourceRange range)
 {
     return(node.WithRange(range).PlusAttrBefore(LNode.Id(CodeSymbols.TriviaInParens)));
 }
コード例 #25
0
 public LNode GetFieldDecl()
 {
     return(LNode.Call(LNode.List(LNode.Id(CodeSymbols.Public)), CodeSymbols.Property, LNode.List(Type, NameId, LNode.Missing, LNode.Call(CodeSymbols.Braces, LNode.List(LNode.Id(CodeSymbols.get), LNode.Id(LNode.List(LNode.Id(CodeSymbols.Private)), CodeSymbols.set))).SetStyle(NodeStyle.Statement))));
 }
コード例 #26
0
ファイル: MatchCode.out.cs プロジェクト: dadhi/ecsharp
            private void MakeTestExpr(LNode pattern, LNode candidate, out Symbol varArgSym, out LNode varArgCond)
            {
                varArgSym = null; varArgCond = null;

                // is this a $substitutionVar?
                LNode condition;
                bool  isParams, refExistingVar;
                var   nodeVar = DecodeSubstitutionExpr(pattern, out condition, out isParams, out refExistingVar);

                // Unless the candidate is a simple variable name, avoid repeating
                // it by creating a temporary variable to hold its value
                int predictedTests = pattern.Attrs.Count +
                                     (nodeVar != null ? 0 : pattern.Args.Count) +
                                     (!pattern.HasSimpleHeadWithoutPAttrs() ? 1 : 0);

                if (predictedTests > 1)
                {
                    candidate = MaybePutCandidateInTempVar(candidate.IsCall, candidate);
                }

                MatchAttributes(pattern, candidate);                    // Look for @[$(...var)]
                // case $_
                if (nodeVar != null)
                {
                    if (nodeVar != __ || condition != null)
                    {
                        if (!refExistingVar)
                        {
                            AddVar(nodeVar, isParams, errAt: pattern);
                        }
                        if (!isParams)
                        {
                            var assignment = LNode.Call(CodeSymbols.Assign, LNode.List(F.Id(nodeVar), candidate)).SetStyle(NodeStyle.Operator);
                            Tests.Add(LNode.Call(CodeSymbols.NotEq, LNode.List(assignment.PlusAttrs(LNode.List(LNode.InParensTrivia)), LNode.Literal(null))).SetStyle(NodeStyle.Operator));
                            Tests.Add(condition);
                        }
                    }
                    if (isParams)
                    {
                        varArgSym  = nodeVar;
                        varArgCond = condition;
                        return;
                    }
                }
                else if (pattern.IsId)
                {
                    Tests.Add(LNode.Call(LNode.Call(CodeSymbols.Dot, LNode.List(candidate, LNode.Id((Symbol)"IsIdNamed"))).SetStyle(NodeStyle.Operator), LNode.List(LNode.Call(CodeSymbols.Cast, LNode.List(F.Literal(pattern.Name.Name), LNode.Id((Symbol)"Symbol"))).SetStyle(NodeStyle.Operator))));
                }
                else if (pattern.IsLiteral)
                {
                    if (pattern.Value == null)
                    {
                        Tests.Add(LNode.Call(CodeSymbols.Eq, LNode.List(LNode.Call(CodeSymbols.Dot, LNode.List(candidate, LNode.Id((Symbol)"Value"))).SetStyle(NodeStyle.Operator), LNode.Literal(null))).SetStyle(NodeStyle.Operator));
                    }
                    else
                    {
                        Tests.Add(LNode.Call(LNode.Call(CodeSymbols.Dot, LNode.List(pattern, LNode.Id((Symbol)"Equals"))).SetStyle(NodeStyle.Operator), LNode.List(LNode.Call(CodeSymbols.Dot, LNode.List(candidate, LNode.Id((Symbol)"Value"))).SetStyle(NodeStyle.Operator))));
                    }
                }
                else                            // call(...)
                {
                    int?varArgAt;
                    int fixedArgC = GetFixedArgCount(pattern.Args, out varArgAt);

                    // Test if the call target matches
                    var pTarget = pattern.Target;
                    if (pTarget.IsId && !pTarget.HasPAttrs())
                    {
                        var   quoteTarget = QuoteSymbol(pTarget.Name);
                        LNode targetTest;
                        if (varArgAt.HasValue && fixedArgC == 0)
                        {
                            targetTest = LNode.Call(LNode.Call(CodeSymbols.Dot, LNode.List(candidate, LNode.Id((Symbol)"Calls"))).SetStyle(NodeStyle.Operator), LNode.List(quoteTarget));
                        }
                        else if (varArgAt.HasValue)
                        {
                            targetTest = LNode.Call(LNode.Call(CodeSymbols.Dot, LNode.List(candidate, LNode.Id((Symbol)"CallsMin"))).SetStyle(NodeStyle.Operator), LNode.List(quoteTarget, F.Literal(fixedArgC)));
                        }
                        else
                        {
                            targetTest = LNode.Call(LNode.Call(CodeSymbols.Dot, LNode.List(candidate, LNode.Id((Symbol)"Calls"))).SetStyle(NodeStyle.Operator), LNode.List(quoteTarget, F.Literal(fixedArgC)));
                        }
                        Tests.Add(targetTest);
                    }
                    else
                    {
                        if (fixedArgC == 0)
                        {
                            Tests.Add(LNode.Call(CodeSymbols.Dot, LNode.List(candidate, LNode.Id((Symbol)"IsCall"))).SetStyle(NodeStyle.Operator));
                            if (!varArgAt.HasValue)
                            {
                                Tests.Add(LNode.Call(CodeSymbols.Eq, LNode.List(LNode.Call(CodeSymbols.Dot, LNode.List(LNode.Call(CodeSymbols.Dot, LNode.List(candidate, LNode.Id((Symbol)"Args"))).SetStyle(NodeStyle.Operator), LNode.Id((Symbol)"Count"))).SetStyle(NodeStyle.Operator), LNode.Literal(0))).SetStyle(NodeStyle.Operator));
                            }
                        }
                        else
                        {
                            var op = varArgAt.HasValue ? S.GE : S.Eq;
                            Tests.Add(LNode.Call(op, LNode.List(LNode.Call(CodeSymbols.Dot, LNode.List(LNode.Call(CodeSymbols.Dot, LNode.List(candidate, LNode.Id((Symbol)"Args"))).SetStyle(NodeStyle.Operator), LNode.Id((Symbol)"Count"))).SetStyle(NodeStyle.Operator), F.Literal(fixedArgC))));
                        }
                        int i = Tests.Count;
                        MakeTestExpr(pTarget, LNode.Call(CodeSymbols.Dot, LNode.List(candidate, LNode.Id((Symbol)"Target"))).SetStyle(NodeStyle.Operator));
                    }

                    MakeArgListTests(pattern.Args, ref candidate);
                }
            }
コード例 #27
0
            void GenCodeForPattern(LNode input, LNode pattern, string defaultPropName = null)
            {
                // Get the parts of the pattern, e.g. `$x is T(sp)` => varBinding=x, isType=T, sp is returned
                bool          refExistingVar;
                LNode         varBinding, cmpExpr, isType, inRange, propName;
                VList <LNode> subPatterns, conditions;

                GetPatternComponents(pattern, out propName, out varBinding, out refExistingVar, out cmpExpr, out isType, out inRange, out subPatterns, out conditions);

                if (defaultPropName == null)                    // Outermost pattern
                {
                    if (propName != null)
                    {
                        _context.Sink.Error(propName, "match: property name not allowed on outermost pattern");
                    }
                }
                else
                {
                    if ((propName = propName ?? LNode.Id(defaultPropName, pattern)) != null)
                    {
                        input = LNode.Call(CodeSymbols.Dot, LNode.List(input, propName)).SetStyle(NodeStyle.Operator);
                    }
                }

                // For a pattern like `is Type varBinding(subPatterns) in A...B && conds`,
                // our goal is to generate code like this:
                //
                //   var tmp_1 = $input; // temp var created unless $input looks simple
                //   if (tmp_1 is Type) {
                //     Type varBinding = (Type)tmp_1;
                //     if (varBinding >= A && varBinding <= B && /* code for matching subPatterns */)
                //         if (conds)
                //             $handler;
                //   }
                if (isType != null)
                {
                    if ((cmpExpr ?? inRange ?? varBinding) != null)
                    {
                        // input will be used multiple times, so consider making a tmp var.
                        if (!LooksLikeSimpleValue(input))
                        {
                            PutStmt(TempVarDecl(_context, input, out input));
                        }
                    }

                    PutCond(LNode.Call(CodeSymbols.Is, LNode.List(input, isType)).SetStyle(NodeStyle.Operator));

                    if (varBinding == null && ((cmpExpr ?? inRange) != null || subPatterns.Count > 0))
                    {
                        // we'll need another temp variable to hold the same value, casted.
                        varBinding = LNode.Id(NextTempName(_context), isType);
                    }
                }

                if (varBinding != null)
                {
                    if (isType != null)
                    {
                        if (refExistingVar)
                        {
                            PutStmt(LNode.Call(CodeSymbols.Assign, LNode.List(varBinding, LNode.Call(CodeSymbols.Cast, LNode.List(input, isType)).SetStyle(NodeStyle.Operator))).SetStyle(NodeStyle.Operator));
                        }
                        else
                        {
                            PutStmt(LNode.Call(CodeSymbols.Var, LNode.List(isType, LNode.Call(CodeSymbols.Assign, LNode.List(varBinding, LNode.Call(CodeSymbols.Cast, LNode.List(input, isType)).SetStyle(NodeStyle.Operator))))));
                        }
                    }
                    else
                    {
                        if (refExistingVar)
                        {
                            PutStmt(LNode.Call(CodeSymbols.Assign, LNode.List(varBinding, input)).SetStyle(NodeStyle.Operator));
                        }
                        else
                        {
                            PutStmt(LNode.Call(CodeSymbols.Var, LNode.List(LNode.Missing, LNode.Call(CodeSymbols.Assign, LNode.List(varBinding, input)))));
                        }
                    }
                    input = varBinding;
                }

                if (cmpExpr != null)                    // do equality test
                {
                    if (cmpExpr.Value == null)
                    {
                        PutCond(LNode.Call(CodeSymbols.Eq, LNode.List(input, LNode.Literal(null))).SetStyle(NodeStyle.Operator));
                    }
                    else
                    {
                        PutCond(LNode.Call(LNode.Call(CodeSymbols.Dot, LNode.List(cmpExpr, LNode.Id((Symbol)"Equals"))).SetStyle(NodeStyle.Operator), LNode.List(input)));
                    }
                }

                // Generate code for subpatterns
                for (int itemIndex = 0; itemIndex < subPatterns.Count; itemIndex++)
                {
                    var subPattern = subPatterns[itemIndex];
                    GenCodeForPattern(input, subPattern, "Item" + (itemIndex + 1));
                }

                if (inRange != null)
                {
                    PutCond(LNode.Call(CodeSymbols.In, LNode.List(input, inRange)).SetStyle(NodeStyle.Operator));
                }

                foreach (var cond in conditions)
                {
                    PutCond(cond);
                }
            }
コード例 #28
0
ファイル: MatchCode.out.cs プロジェクト: dadhi/ecsharp
        public static LNode matchCode(LNode node, IMacroContext context)
        {
            if (node.AttrNamed(S.Static) != null)
            {
                return(null);                   // this case is handled by static_matchCode macro
            }
            var       args_body = context.GetArgsAndBody(false);
            LNodeList args = args_body.Item1, body = args_body.Item2;

            if (args.Count != 1 || body.Count < 1)
            {
                return(null);
            }
            var cases = GetCases(body, context.Sink);

            if (cases.IsEmpty)
            {
                return(null);
            }

            var output = new WList <LNode>();
            var var    = MaybeAddTempVarDecl(context, args[0], output);

            var ifClauses = new List <Pair <LNode, LNode> >();
            var cmc       = new CodeMatchContext {
                Context = context
            };

            foreach (var @case in cases)
            {
                cmc.ThenClause.Clear();
                // e.g. case [$(..._)] Foo($x + 1, $y) =>
                //      LNode x, y, tmp9;
                //      if (var.Calls((Symbol) "Foo", 2) && (tmp9 = var.Args[0]).Calls(CodeSymbols.Plus, 2)
                //          && (x = tmp9.Args[0]) != null // this will never be null, but we want to put it the assignment in the 'if' statement
                //          && 1.Equals(tmp9.Args[1].Value) && (y = var.Args[1]) != null) { ... }
                LNode testExpr = null;
                if (@case.Key.Count > 0)
                {
                    if (cmc.IsMultiCase = @case.Key.Count > 1)
                    {
                        cmc.UsageCounters.Clear();
                        testExpr = @case.Key.Aggregate((LNode)null, (test, pattern) => {
                            test = LNode.MergeBinary(test, cmc.MakeTopTestExpr(pattern, var), S.Or);
                            return(test);
                        });
                        foreach (var pair in cmc.UsageCounters.Where(p => p.Value < @case.Key.Count))
                        {
                            if (cmc.NodeVars.ContainsKey(pair.Key))
                            {
                                cmc.NodeVars[pair.Key] = true;
                            }
                            if (cmc.ListVars.ContainsKey(pair.Key))
                            {
                                cmc.ListVars[pair.Key] = true;
                            }
                        }
                    }
                    else
                    {
                        testExpr = cmc.MakeTopTestExpr(@case.Key[0], var);
                    }
                }
                var handler = F.Braces(@case.Value);
                if (cmc.ThenClause.Count > 0)
                {
                    handler = LNode.MergeLists(F.Braces(cmc.ThenClause), handler, S.Braces);
                }
                ifClauses.Add(Pair.Create(testExpr, handler));
            }

            LNode ifStmt = null;

            for (int i = ifClauses.Count - 1; i >= 0; i--)
            {
                if (ifClauses[i].Item1 == null)
                {
                    if (ifStmt == null)
                    {
                        ifStmt = ifClauses[i].Item2;
                    }
                    else
                    {
                        context.Sink.Error(node, "The default case must appear last, and there can be only one.");
                    }
                }
                else
                {
                    if (ifStmt == null)
                    {
                        ifStmt = F.Call(S.If, ifClauses[i].Item1, ifClauses[i].Item2);
                    }
                    else
                    {
                        ifStmt = F.Call(S.If, ifClauses[i].Item1, ifClauses[i].Item2, ifStmt);
                    }
                }
            }

            if (cmc.NodeVars.Count > 0)
            {
                output.Add(F.Call(S.Var, ListExt.Single(F.Id("LNode")).Concat(
                                      cmc.NodeVars.OrderBy(v => v.Key.Name).Select(kvp => kvp.Value ? F.Call(S.Assign, F.Id(kvp.Key), F.Null) : F.Id(kvp.Key)))));
            }
            if (cmc.ListVars.Count > 0)
            {
                LNode type = LNode.Id((Symbol)"LNodeList");
                output.Add(F.Call(S.Var, ListExt.Single(type).Concat(
                                      cmc.ListVars.OrderBy(v => v.Key.Name).Select(kvp => kvp.Value ? LNode.Call(CodeSymbols.Assign, LNode.List(F.Id(kvp.Key), LNode.Call(CodeSymbols.Default, LNode.List(type)))).SetStyle(NodeStyle.Operator) : F.Id(kvp.Key)))));
            }
            if (output.Count == 0)
            {
                return(ifStmt.IncludingTriviaFrom(node));
            }
            else
            {
                output.Add(ifStmt);
                return(F.Braces(output.ToVList()).IncludingTriviaFrom(node));
            }
        }
コード例 #29
0
ファイル: Literals.out.cs プロジェクト: dadhi/ecsharp
        public static LNode ArrayLiteral(LNode node, IMacroContext context)
        {
            var value = node.Value;

            if (value is Array array)
            {
                Type   elementType     = value.GetType().GetElementType();
                string elementTypeName = elementType.NameWithGenericArgs();
                LNode  elementTypeN    = LNode.Call(S.CsRawText, LNode.List(LNode.Literal(elementTypeName)));

                Func <object, LNode, LNode> newLiteral = (el, pnode) => LNode.Literal(el, pnode);
                // Reduce output text size by preventing the printer from using casts
                // e.g. print `23` instead of `(byte) 23` or `(short) 23`. Also, unbox
                // ints to save memory (ideally we'd do this for all Value Types)
                if (elementType == typeof(byte))
                {
                    newLiteral = (el, pnode) => LNode.Literal((int)(byte)el, pnode);
                }
                if (elementType == typeof(sbyte))
                {
                    newLiteral = (el, pnode) => LNode.Literal((int)(sbyte)el, pnode);
                }
                if (elementType == typeof(short))
                {
                    newLiteral = (el, pnode) => LNode.Literal((int)(short)el, pnode);
                }
                if (elementType == typeof(ushort))
                {
                    newLiteral = (el, pnode) => LNode.Literal((int)(ushort)el, pnode);
                }
                if (elementType == typeof(int))
                {
                    newLiteral = (el, pnode) => LNode.Literal((int)(int)el, pnode);
                }

                if (array.Rank == 1)
                {
                    var initializers = new List <LNode>();
                    int count        = 0;
                    foreach (object element in array)
                    {
                        LNode elemNode = newLiteral(element, node);
                        if ((count++ & 7) == 0 && array.Length > 8)
                        {
                            elemNode = elemNode.PlusAttr(LNode.Id(S.TriviaNewline));
                        }
                        initializers.Add(elemNode);
                    }
                    return(LNode.Call(CodeSymbols.New, LNode.List().Add(LNode.Call(LNode.Call(CodeSymbols.Of, LNode.List(LNode.Id(CodeSymbols.Array), elementTypeN)))).AddRange(initializers)));
                }
                else
                {
                    return(null);                       // TODO
                    //Stmt("int[,] Foo = new[,] { {\n 0 }, {\n 1,\n 2, }, };", F.Call(S.Var, F.Of(S.TwoDimensionalArray, S.Int32),
                    //	F.Call(S.Assign, Foo, F.Call(S.New, F.Call(S.TwoDimensionalArray), F.Braces(zero), F.Braces(one, two)))));
                }
            }
            return(null);
        }
コード例 #30
0
ファイル: MatchCode.out.cs プロジェクト: dadhi/ecsharp
            private void MatchAttributes(LNode pattern, LNode candidate)
            {
                LNode  condition;
                bool   isParams, refExistingVar;
                Symbol listVar;
                var    pAttrs = pattern.PAttrs();

                if (pAttrs.Count == 1 && (listVar = DecodeSubstitutionExpr(pAttrs[0], out condition, out isParams, out refExistingVar)) != null && isParams)
                {
                    if (listVar != __ || condition != null)
                    {
                        if (!refExistingVar)
                        {
                            AddVar(listVar, true, errAt: pattern);
                        }
                        Tests.Add(LNode.Call(CodeSymbols.OrBits, LNode.List(LNode.Call(CodeSymbols.Dot, LNode.List(LNode.Call(LNode.List(LNode.InParensTrivia), CodeSymbols.Assign, LNode.List(F.Id(listVar), LNode.Call(CodeSymbols.Dot, LNode.List(candidate, LNode.Id((Symbol)"Attrs"))).SetStyle(NodeStyle.Operator))).SetStyle(NodeStyle.Operator), LNode.Id((Symbol)"IsEmpty"))).SetStyle(NodeStyle.Operator), LNode.Literal(true))).SetStyle(NodeStyle.Operator));
                        if (condition != null)
                        {
                            Tests.Add(condition);
                        }
                    }
                }
                else if (pAttrs.Count != 0)
                {
                    Context.Sink.Error(pAttrs[0], "Currently, Attribute matching is very limited; you can only use `[$(...varName)]`");
                }
            }