Beispiel #1
0
 public Cursor(ast.Node parent = default, @string name = default, ref ptr <iterator> iter = default, ast.Node node = default)
 {
     this.parent = parent;
     this.name   = name;
     this.iter   = iter;
     this.node   = node;
 }
Beispiel #2
0
 // updateDead puts unreachable "if" and "case" nodes into dead.
 private static void updateDead(ptr <types.Info> _addr_info, map <ast.Node, bool> dead, ast.Node node)
 {
     ref types.Info info = ref _addr_info.val;
Beispiel #3
0
 // Apply traverses a syntax tree recursively, starting with root,
 // and calling pre and post for each node as described below.
 // Apply returns the syntax tree, possibly modified.
 //
 // If pre is not nil, it is called for each node before the node's
 // children are traversed (pre-order). If pre returns false, no
 // children are traversed, and post is not called for that node.
 //
 // If post is not nil, and a prior call of pre didn't return false,
 // post is called for each node after its children are traversed
 // (post-order). If post returns false, traversal is terminated and
 // Apply returns immediately.
 //
 // Only fields that refer to AST nodes are considered children;
 // i.e., token.Pos, Scopes, Objects, and fields of basic types
 // (strings, etc.) are ignored.
 //
 // Children are traversed in the order in which they appear in the
 // respective node's struct definition. A package's files are
 // traversed in the filenames' alphabetical order.
 //
 public static ast.Node Apply(ast.Node root, ApplyFunc pre, ApplyFunc post) => func((defer, panic, _) =>
Beispiel #4
0
 // Both F1 and G1 should appear as functions.
 public static void F1(ast.Node _p0)
 {
 }
Beispiel #5
0
 public @event(ast.Node node = default, ulong typ = default, long index = default)
 {
     this.node  = node;
     this.typ   = typ;
     this.index = index;
 }
Beispiel #6
0
 public Function(@string name = default, types.Object @object = default, ref ptr <types.Selection> method = default, ref ptr <types.Signature> Signature = default, token.Pos pos = default, @string Synthetic = default, ast.Node syntax = default, ref ptr <Function> parent = default, ref ptr <Package> Pkg = default, ref ptr <Program> Prog = default, slice <ptr <Parameter> > Params = default, slice <ptr <FreeVar> > FreeVars = default, slice <ptr <Alloc> > Locals = default, slice <ptr <BasicBlock> > Blocks = default, ref ptr <BasicBlock> Recover = default, slice <ptr <Function> > AnonFuncs = default, slice <Instruction> referrers = default, ref ptr <BasicBlock> currentBlock = default, map <types.Object, Value> objects = default, slice <ptr <Alloc> > namedResults = default, ref ptr <targets> targets = default, map <ptr <ast.Object>, ptr <lblock> > lblocks = default)
 {
     this.name         = name;
     this.@object      = @object;
     this.method       = method;
     this.Signature    = Signature;
     this.pos          = pos;
     this.Synthetic    = Synthetic;
     this.syntax       = syntax;
     this.parent       = parent;
     this.Pkg          = Pkg;
     this.Prog         = Prog;
     this.Params       = Params;
     this.FreeVars     = FreeVars;
     this.Locals       = Locals;
     this.Blocks       = Blocks;
     this.Recover      = Recover;
     this.AnonFuncs    = AnonFuncs;
     this.referrers    = referrers;
     this.currentBlock = currentBlock;
     this.objects      = objects;
     this.namedResults = namedResults;
     this.targets      = targets;
     this.lblocks      = lblocks;
 }
Beispiel #7
0
 private static long sourceLine(ast.Node n)
 {
     return(fset.Position(n.Pos()).Line);
 }
Beispiel #8
0
 public SelectState(types.ChanDir Dir = default, Value Chan = default, Value Send = default, token.Pos Pos = default, ast.Node DebugNode = default)
 {
     this.Dir       = Dir;
     this.Chan      = Chan;
     this.Send      = Send;
     this.Pos       = Pos;
     this.DebugNode = DebugNode;
 }
Beispiel #9
0
                                    // typeOf returns a distinct single-bit value that represents the type of n.
                                    //
                                    // Various implementations were benchmarked with BenchmarkNewInspector:
                                    //                                GOGC=off
                                    // - type switch                4.9-5.5ms    2.1ms
                                    // - binary search over a sorted list of types  5.5-5.9ms    2.5ms
                                    // - linear scan, frequency-ordered list     5.9-6.1ms    2.7ms
                                    // - linear scan, unordered list        6.4ms        2.7ms
                                    // - hash table                    6.5ms        3.1ms
                                    // A perfect hash seemed like overkill.
                                    //
                                    // The compiler's switch statement is the clear winner
                                    // as it produces a binary tree in code,
                                    // with constant conditions and good branch prediction.
                                    // (Sadly it is the most verbose in source code.)
                                    // Binary search suffered from poor branch prediction.
                                    //
                                    private static ulong typeOf(ast.Node n)
                                    {
                                        // Fast path: nearly half of all nodes are identifiers.
                                        {
                                            ptr <ast.Ident> (_, ok) = n._ <ptr <ast.Ident> >();

                                            if (ok)
                                            {
                                                return(1L << (int)(nIdent));
                                            }

                                            // These cases include all nodes encountered by ast.Inspect.
                                        }

                                        // These cases include all nodes encountered by ast.Inspect.
                                        switch (n.type())
                                        {
                                        case ptr <ast.ArrayType> _:
                                            return(1L << (int)(nArrayType));

                                            break;

                                        case ptr <ast.AssignStmt> _:
                                            return(1L << (int)(nAssignStmt));

                                            break;

                                        case ptr <ast.BadDecl> _:
                                            return(1L << (int)(nBadDecl));

                                            break;

                                        case ptr <ast.BadExpr> _:
                                            return(1L << (int)(nBadExpr));

                                            break;

                                        case ptr <ast.BadStmt> _:
                                            return(1L << (int)(nBadStmt));

                                            break;

                                        case ptr <ast.BasicLit> _:
                                            return(1L << (int)(nBasicLit));

                                            break;

                                        case ptr <ast.BinaryExpr> _:
                                            return(1L << (int)(nBinaryExpr));

                                            break;

                                        case ptr <ast.BlockStmt> _:
                                            return(1L << (int)(nBlockStmt));

                                            break;

                                        case ptr <ast.BranchStmt> _:
                                            return(1L << (int)(nBranchStmt));

                                            break;

                                        case ptr <ast.CallExpr> _:
                                            return(1L << (int)(nCallExpr));

                                            break;

                                        case ptr <ast.CaseClause> _:
                                            return(1L << (int)(nCaseClause));

                                            break;

                                        case ptr <ast.ChanType> _:
                                            return(1L << (int)(nChanType));

                                            break;

                                        case ptr <ast.CommClause> _:
                                            return(1L << (int)(nCommClause));

                                            break;

                                        case ptr <ast.Comment> _:
                                            return(1L << (int)(nComment));

                                            break;

                                        case ptr <ast.CommentGroup> _:
                                            return(1L << (int)(nCommentGroup));

                                            break;

                                        case ptr <ast.CompositeLit> _:
                                            return(1L << (int)(nCompositeLit));

                                            break;

                                        case ptr <ast.DeclStmt> _:
                                            return(1L << (int)(nDeclStmt));

                                            break;

                                        case ptr <ast.DeferStmt> _:
                                            return(1L << (int)(nDeferStmt));

                                            break;

                                        case ptr <ast.Ellipsis> _:
                                            return(1L << (int)(nEllipsis));

                                            break;

                                        case ptr <ast.EmptyStmt> _:
                                            return(1L << (int)(nEmptyStmt));

                                            break;

                                        case ptr <ast.ExprStmt> _:
                                            return(1L << (int)(nExprStmt));

                                            break;

                                        case ptr <ast.Field> _:
                                            return(1L << (int)(nField));

                                            break;

                                        case ptr <ast.FieldList> _:
                                            return(1L << (int)(nFieldList));

                                            break;

                                        case ptr <ast.File> _:
                                            return(1L << (int)(nFile));

                                            break;

                                        case ptr <ast.ForStmt> _:
                                            return(1L << (int)(nForStmt));

                                            break;

                                        case ptr <ast.FuncDecl> _:
                                            return(1L << (int)(nFuncDecl));

                                            break;

                                        case ptr <ast.FuncLit> _:
                                            return(1L << (int)(nFuncLit));

                                            break;

                                        case ptr <ast.FuncType> _:
                                            return(1L << (int)(nFuncType));

                                            break;

                                        case ptr <ast.GenDecl> _:
                                            return(1L << (int)(nGenDecl));

                                            break;

                                        case ptr <ast.GoStmt> _:
                                            return(1L << (int)(nGoStmt));

                                            break;

                                        case ptr <ast.Ident> _:
                                            return(1L << (int)(nIdent));

                                            break;

                                        case ptr <ast.IfStmt> _:
                                            return(1L << (int)(nIfStmt));

                                            break;

                                        case ptr <ast.ImportSpec> _:
                                            return(1L << (int)(nImportSpec));

                                            break;

                                        case ptr <ast.IncDecStmt> _:
                                            return(1L << (int)(nIncDecStmt));

                                            break;

                                        case ptr <ast.IndexExpr> _:
                                            return(1L << (int)(nIndexExpr));

                                            break;

                                        case ptr <ast.InterfaceType> _:
                                            return(1L << (int)(nInterfaceType));

                                            break;

                                        case ptr <ast.KeyValueExpr> _:
                                            return(1L << (int)(nKeyValueExpr));

                                            break;

                                        case ptr <ast.LabeledStmt> _:
                                            return(1L << (int)(nLabeledStmt));

                                            break;

                                        case ptr <ast.MapType> _:
                                            return(1L << (int)(nMapType));

                                            break;

                                        case ptr <ast.Package> _:
                                            return(1L << (int)(nPackage));

                                            break;

                                        case ptr <ast.ParenExpr> _:
                                            return(1L << (int)(nParenExpr));

                                            break;

                                        case ptr <ast.RangeStmt> _:
                                            return(1L << (int)(nRangeStmt));

                                            break;

                                        case ptr <ast.ReturnStmt> _:
                                            return(1L << (int)(nReturnStmt));

                                            break;

                                        case ptr <ast.SelectStmt> _:
                                            return(1L << (int)(nSelectStmt));

                                            break;

                                        case ptr <ast.SelectorExpr> _:
                                            return(1L << (int)(nSelectorExpr));

                                            break;

                                        case ptr <ast.SendStmt> _:
                                            return(1L << (int)(nSendStmt));

                                            break;

                                        case ptr <ast.SliceExpr> _:
                                            return(1L << (int)(nSliceExpr));

                                            break;

                                        case ptr <ast.StarExpr> _:
                                            return(1L << (int)(nStarExpr));

                                            break;

                                        case ptr <ast.StructType> _:
                                            return(1L << (int)(nStructType));

                                            break;

                                        case ptr <ast.SwitchStmt> _:
                                            return(1L << (int)(nSwitchStmt));

                                            break;

                                        case ptr <ast.TypeAssertExpr> _:
                                            return(1L << (int)(nTypeAssertExpr));

                                            break;

                                        case ptr <ast.TypeSpec> _:
                                            return(1L << (int)(nTypeSpec));

                                            break;

                                        case ptr <ast.TypeSwitchStmt> _:
                                            return(1L << (int)(nTypeSwitchStmt));

                                            break;

                                        case ptr <ast.UnaryExpr> _:
                                            return(1L << (int)(nUnaryExpr));

                                            break;

                                        case ptr <ast.ValueSpec> _:
                                            return(1L << (int)(nValueSpec));

                                            break;
                                        }
                                        return(0L);
                                    }
Beispiel #10
0
        private static ast.Visitor Visit(this simplifier s, ast.Node node)
        {
            switch (node.type())
            {
            case ptr <ast.CompositeLit> n:
                var      outer = n;
                ast.Expr keyType = default;                    ast.Expr eltType = default;

                switch (outer.Type.type())
                {
                case ptr <ast.ArrayType> typ:
                    eltType = typ.Elt;
                    break;

                case ptr <ast.MapType> typ:
                    keyType = typ.Key;
                    eltType = typ.Value;
                    break;
                }

                if (eltType != null)
                {
                    reflect.Value ktyp = default;
                    if (keyType != null)
                    {
                        ktyp = reflect.ValueOf(keyType);
                    }

                    var typ = reflect.ValueOf(eltType);
                    foreach (var(i, x) in outer.Elts)
                    {
                        var px = _addr_outer.Elts[i];
                        // look at value of indexed/named elements
                        {
                            ptr <ast.KeyValueExpr> (t, ok) = x._ <ptr <ast.KeyValueExpr> >();

                            if (ok)
                            {
                                if (keyType != null)
                                {
                                    s.simplifyLiteral(ktyp, keyType, t.Key, _addr_t.Key);
                                }

                                x  = t.Value;
                                px = _addr_t.Value;
                            }
                        }

                        s.simplifyLiteral(typ, eltType, x, px);
                    }
                    // node was simplified - stop walk (there are no subnodes to simplify)
                    return(null);
                }

                break;

            case ptr <ast.SliceExpr> n:
                if (n.Max != null)
                {
                    // - 3-index slices always require the 2nd and 3rd index
                    break;
                }

                {
                    ptr <ast.Ident> (s, _) = n.X._ <ptr <ast.Ident> >();

                    if (s != null && s.Obj != null)
                    {
                        // the array/slice object is a single, resolved identifier
                        {
                            ptr <ast.CallExpr> (call, _) = n.High._ <ptr <ast.CallExpr> >();

                            if (call != null && len(call.Args) == 1L && !call.Ellipsis.IsValid())
                            {
                                // the high expression is a function call with a single argument
                                {
                                    ptr <ast.Ident> (fun, _) = call.Fun._ <ptr <ast.Ident> >();

                                    if (fun != null && fun.Name == "len" && fun.Obj == null)
                                    {
                                        // the function called is "len" and it is not locally defined; and
                                        // because we don't have dot imports, it must be the predefined len()
                                        {
                                            ptr <ast.Ident> (arg, _) = call.Args[0L]._ <ptr <ast.Ident> >();

                                            if (arg != null && arg.Obj == s.Obj)
                                            {
                                                // the len argument is the array/slice object
                                                n.High = null;
                                            }
                                        }
                                    }
                                }
                            }
                        }
                    }
                    // Note: We could also simplify slice expressions of the form s[0:b] to s[:b]
                    //       but we leave them as is since sometimes we want to be very explicit
                    //       about the lower bound.
                    // An example where the 0 helps:
                    //       x, y, z := b[0:2], b[2:4], b[4:6]
                    // An example where it does not:
                    //       x, y := b[:n], b[n:]
                }
                // Note: We could also simplify slice expressions of the form s[0:b] to s[:b]
                //       but we leave them as is since sometimes we want to be very explicit
                //       about the lower bound.
                // An example where the 0 helps:
                //       x, y, z := b[0:2], b[2:4], b[4:6]
                // An example where it does not:
                //       x, y := b[:n], b[n:]
                break;

            case ptr <ast.RangeStmt> n:
                if (isBlank(n.Value))
                {
                    n.Value = null;
                }

                if (isBlank(n.Key) && n.Value == null)
                {
                    n.Key = null;
                }

                break;
            }

            return(s);
        }
Beispiel #11
0
 public Example(@string Name = default, @string Suffix = default, @string Doc = default, ast.Node Code = default, ref ptr <ast.File> Play = default, slice <ptr <ast.CommentGroup> > Comments = default, @string Output = default, bool Unordered = default, bool EmptyOutput = default, long Order = default)
 {
     this.Name        = Name;
     this.Suffix      = Suffix;
     this.Doc         = Doc;
     this.Code        = Code;
     this.Play        = Play;
     this.Comments    = Comments;
     this.Output      = Output;
     this.Unordered   = Unordered;
     this.EmptyOutput = EmptyOutput;
     this.Order       = Order;
 }