From: Russ Cox Date: Thu, 5 Mar 2015 15:45:56 +0000 (-0500) Subject: cmd/internal/gc: start syntax.go for syntax tree definitions X-Git-Tag: go1.5beta1~1683 X-Git-Url: http://www.git.cypherpunks.su/?a=commitdiff_plain;h=d970bea88500b21c85d51199d6b0deb1e764950a;p=gostls13.git cmd/internal/gc: start syntax.go for syntax tree definitions Minor comments added. More to come. Change-Id: I97511db54d59e1009ef934da38f306a2dc83a6e9 Reviewed-on: https://go-review.googlesource.com/6898 Reviewed-by: Rob Pike --- diff --git a/src/cmd/internal/gc/go.go b/src/cmd/internal/gc/go.go index aa0ac8481b..95c3c7ca13 100644 --- a/src/cmd/internal/gc/go.go +++ b/src/cmd/internal/gc/go.go @@ -95,13 +95,6 @@ type Val struct { } } -type Array struct { - length int32 - size int32 - capacity int32 - data string -} - type Pkg struct { Name string Path string @@ -132,106 +125,6 @@ type Sym struct { Lsym *obj.LSym } -type Node struct { - Left *Node - Right *Node - Ntest *Node - Nincr *Node - Ninit *NodeList - Nbody *NodeList - Nelse *NodeList - List *NodeList - Rlist *NodeList - Op uint8 - Nointerface bool - Ullman uint8 - Addable uint8 - Trecur uint8 - Etype uint8 - Bounded bool - Class uint8 - Method uint8 - Embedded uint8 - Colas uint8 - Diag uint8 - Noescape bool - Nosplit bool - Builtin uint8 - Nowritebarrier bool - Walkdef uint8 - Typecheck uint8 - Local uint8 - Dodata uint8 - Initorder uint8 - Used uint8 - Isddd uint8 - Readonly uint8 - Implicit uint8 - Addrtaken uint8 - Assigned uint8 - Captured uint8 - Byval uint8 - Dupok uint8 - Wrapper uint8 - Reslice uint8 - Likely int8 - Hasbreak uint8 - Needzero bool - Needctxt bool - Esc uint - Funcdepth int - Type *Type - Orig *Node - Nname *Node - Shortname *Node - Enter *NodeList - Exit *NodeList - Cvars *NodeList - Dcl *NodeList - Inl *NodeList - Inldcl *NodeList - Closgen int - Outerfunc *Node - Val Val - Ntype *Node - Defn *Node - Pack *Node - Curfn *Node - Paramfld *Type - Decldepth int - Heapaddr *Node - Outerexpr *Node - Stackparam *Node - Alloc *Node - Outer *Node - Closure *Node - Top int - Inlvar *Node - Pkg *Pkg - Initplan *InitPlan - Escflowsrc *NodeList - Escretval *NodeList - Escloopdepth int - Sym *Sym - InlCost int32 - Vargen int32 - Lineno int32 - Endlineno int32 - Xoffset int64 - Stkdelta int64 - Ostk int32 - Iota int32 - Walkgen uint32 - Esclevel int32 - Opt interface{} -} - -type NodeList struct { - N *Node - Next *NodeList - End *NodeList -} - type Type struct { Etype uint8 Nointerface bool @@ -316,22 +209,6 @@ const ( EscReturnBits = EscBits + 1 ) -/* - * Every node has a walkgen field. - * If you want to do a traversal of a node graph that - * might contain duplicates and want to avoid - * visiting the same nodes twice, increment walkgen - * before starting. Then before processing a node, do - * - * if(n->walkgen == walkgen) - * return; - * n->walkgen = walkgen; - * - * Such a walk cannot call another such walk recursively, - * because of the use of the global walkgen. - */ -var walkgen uint32 - const ( SymExport = 1 << 0 SymPackage = 1 << 1 @@ -352,163 +229,6 @@ type Iter struct { N *Node } -// Node ops. -const ( - OXXX = iota - ONAME - ONONAME - OTYPE - OPACK - OLITERAL - OADD - OSUB - OOR - OXOR - OADDSTR - OADDR - OANDAND - OAPPEND - OARRAYBYTESTR - OARRAYBYTESTRTMP - OARRAYRUNESTR - OSTRARRAYBYTE - OSTRARRAYBYTETMP - OSTRARRAYRUNE - OAS - OAS2 - OAS2FUNC - OAS2RECV - OAS2MAPR - OAS2DOTTYPE - OASOP - OCALL - OCALLFUNC - OCALLMETH - OCALLINTER - OCALLPART - OCAP - OCLOSE - OCLOSURE - OCMPIFACE - OCMPSTR - OCOMPLIT - OMAPLIT - OSTRUCTLIT - OARRAYLIT - OPTRLIT - OCONV - OCONVIFACE - OCONVNOP - OCOPY - ODCL - ODCLFUNC - ODCLFIELD - ODCLCONST - ODCLTYPE - ODELETE - ODOT - ODOTPTR - ODOTMETH - ODOTINTER - OXDOT - ODOTTYPE - ODOTTYPE2 - OEQ - ONE - OLT - OLE - OGE - OGT - OIND - OINDEX - OINDEXMAP - OKEY - OPARAM - OLEN - OMAKE - OMAKECHAN - OMAKEMAP - OMAKESLICE - OMUL - ODIV - OMOD - OLSH - ORSH - OAND - OANDNOT - ONEW - ONOT - OCOM - OPLUS - OMINUS - OOROR - OPANIC - OPRINT - OPRINTN - OPAREN - OSEND - OSLICE - OSLICEARR - OSLICESTR - OSLICE3 - OSLICE3ARR - ORECOVER - ORECV - ORUNESTR - OSELRECV - OSELRECV2 - OIOTA - OREAL - OIMAG - OCOMPLEX - OBLOCK - OBREAK - OCASE - OXCASE - OCONTINUE - ODEFER - OEMPTY - OFALL - OXFALL - OFOR - OGOTO - OIF - OLABEL - OPROC - ORANGE - ORETURN - OSELECT - OSWITCH - OTYPESW - OTCHAN - OTMAP - OTSTRUCT - OTINTER - OTFUNC - OTARRAY - ODDD - ODDDARG - OINLCALL - OEFACE - OITAB - OSPTR - OCLOSUREVAR - OCFUNC - OCHECKNIL - OVARKILL - OREGISTER - OINDREG - OCMP - ODEC - OINC - OEXTEND - OHMUL - OLROT - ORROTC - ORETJMP - OEND -) - const ( Txxx = iota TINT8 @@ -935,81 +655,6 @@ var bstdout obj.Biobuf var Nacl bool -/* - * y.tab.c - */ - -/* - * align.c - */ - -/* - * array.c - */ - -/* - * bits.c - */ - -/* - * mparith1.c - */ - -/* - * mparith2.c - */ - -/* - * mparith3.c - */ - -/* - * obj.c - */ - -/* - * order.c - */ - -/* - * range.c - */ - -/* - * reflect.c - */ - -/* - * select.c - */ - -/* - * sinit.c - */ - -/* - * subr.c - */ - -/* - * swt.c - */ - -/* - * typecheck.c - */ - -/* - * unsafe.c - */ - -/* - * walk.c - */ - -/* - * thearch-specific ggen.c/gsubr.c/gobj.c/pgen.c/plive.c - */ var continpc *obj.Prog var breakpc *obj.Prog @@ -1024,13 +669,6 @@ var Disable_checknil int var zerosize int64 -/* - * racewalk.c - */ - -/* - * flow.c - */ type Flow struct { Prog *obj.Prog P1 *Flow diff --git a/src/cmd/internal/gc/subr.go b/src/cmd/internal/gc/subr.go index 675befc91c..9eeb5d93d7 100644 --- a/src/cmd/internal/gc/subr.go +++ b/src/cmd/internal/gc/subr.go @@ -3127,103 +3127,6 @@ func Simsimtype(t *Type) int { return et } -func concat(a *NodeList, b *NodeList) *NodeList { - if a == nil { - return b - } - if b == nil { - return a - } - - a.End.Next = b - a.End = b.End - b.End = nil - return a -} - -func list1(n *Node) *NodeList { - if n == nil { - return nil - } - if n.Op == OBLOCK && n.Ninit == nil { - // Flatten list and steal storage. - // Poison pointer to catch errant uses. - l := n.List - - n.List = nil - return l - } - - l := new(NodeList) - l.N = n - l.End = l - return l -} - -func list(l *NodeList, n *Node) *NodeList { - return concat(l, list1(n)) -} - -func listsort(l **NodeList, f func(*Node, *Node) int) { - if *l == nil || (*l).Next == nil { - return - } - - l1 := *l - l2 := *l - for { - l2 = l2.Next - if l2 == nil { - break - } - l2 = l2.Next - if l2 == nil { - break - } - l1 = l1.Next - } - - l2 = l1.Next - l1.Next = nil - l2.End = (*l).End - (*l).End = l1 - - l1 = *l - listsort(&l1, f) - listsort(&l2, f) - - if f(l1.N, l2.N) < 0 { - *l = l1 - } else { - *l = l2 - l2 = l1 - l1 = *l - } - - // now l1 == *l; and l1 < l2 - - var le *NodeList - for (l1 != nil) && (l2 != nil) { - for (l1.Next != nil) && f(l1.Next.N, l2.N) < 0 { - l1 = l1.Next - } - - // l1 is last one from l1 that is < l2 - le = l1.Next // le is the rest of l1, first one that is >= l2 - if le != nil { - le.End = (*l).End - } - - (*l).End = l1 // cut *l at l1 - *l = concat(*l, l2) // glue l2 to *l's tail - - l1 = l2 // l1 is the first element of *l that is < the new l2 - l2 = le // ... because l2 now is the old tail of l1 - } - - *l = concat(*l, l2) // any remainder -} - func listtreecopy(l *NodeList) *NodeList { var out *NodeList for ; l != nil; l = l.Next { @@ -3241,21 +3144,6 @@ func liststmt(l *NodeList) *Node { return n } -/* - * return nelem of list - */ -func count(l *NodeList) int { - n := int64(0) - for ; l != nil; l = l.Next { - n++ - } - if int64(int(n)) != n { // Overflow. - Yyerror("too many elements in list") - } - - return int(n) -} - /* * return nelem of list */ diff --git a/src/cmd/internal/gc/syntax.go b/src/cmd/internal/gc/syntax.go new file mode 100644 index 0000000000..d2b735aa01 --- /dev/null +++ b/src/cmd/internal/gc/syntax.go @@ -0,0 +1,403 @@ +// Copyright 2009 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +// “Abstract” syntax representation. + +package gc + +// A Node is a single node in the syntax tree. +// Actually the syntax tree is a syntax DAG, because there is only one +// node with Op=ONAME for a given instance of a variable x. +// The same is true for Op=OTYPE and Op=OLITERAL. +type Node struct { + Left *Node + Right *Node + Ntest *Node + Nincr *Node + Ninit *NodeList + Nbody *NodeList + Nelse *NodeList + List *NodeList + Rlist *NodeList + Op uint8 + Nointerface bool + Ullman uint8 + Addable uint8 + Trecur uint8 + Etype uint8 + Bounded bool + Class uint8 + Method uint8 + Embedded uint8 + Colas uint8 + Diag uint8 + Noescape bool + Nosplit bool + Builtin uint8 + Nowritebarrier bool + Walkdef uint8 + Typecheck uint8 + Local uint8 + Dodata uint8 + Initorder uint8 + Used uint8 + Isddd uint8 + Readonly uint8 + Implicit uint8 + Addrtaken uint8 + Assigned uint8 + Captured uint8 + Byval uint8 + Dupok uint8 + Wrapper uint8 + Reslice uint8 + Likely int8 + Hasbreak uint8 + Needzero bool + Needctxt bool + Esc uint + Funcdepth int + Type *Type + Orig *Node + Nname *Node + Shortname *Node + Enter *NodeList + Exit *NodeList + Cvars *NodeList + Dcl *NodeList + Inl *NodeList + Inldcl *NodeList + Closgen int + Outerfunc *Node + Val Val + Ntype *Node + Defn *Node + Pack *Node + Curfn *Node + Paramfld *Type + Decldepth int + Heapaddr *Node + Outerexpr *Node + Stackparam *Node + Alloc *Node + Outer *Node + Closure *Node + Top int + Inlvar *Node + Pkg *Pkg + Initplan *InitPlan + Escflowsrc *NodeList + Escretval *NodeList + Escloopdepth int + Sym *Sym + InlCost int32 + Vargen int32 + Lineno int32 + Endlineno int32 + Xoffset int64 + Stkdelta int64 + Ostk int32 + Iota int32 + Walkgen uint32 + Esclevel int32 + Opt interface{} +} + +// Node ops. +const ( + OXXX = iota + ONAME + ONONAME + OTYPE + OPACK + OLITERAL + OADD + OSUB + OOR + OXOR + OADDSTR + OADDR + OANDAND + OAPPEND + OARRAYBYTESTR + OARRAYBYTESTRTMP + OARRAYRUNESTR + OSTRARRAYBYTE + OSTRARRAYBYTETMP + OSTRARRAYRUNE + OAS + OAS2 + OAS2FUNC + OAS2RECV + OAS2MAPR + OAS2DOTTYPE + OASOP + OCALL + OCALLFUNC + OCALLMETH + OCALLINTER + OCALLPART + OCAP + OCLOSE + OCLOSURE + OCMPIFACE + OCMPSTR + OCOMPLIT + OMAPLIT + OSTRUCTLIT + OARRAYLIT + OPTRLIT + OCONV + OCONVIFACE + OCONVNOP + OCOPY + ODCL + ODCLFUNC + ODCLFIELD + ODCLCONST + ODCLTYPE + ODELETE + ODOT + ODOTPTR + ODOTMETH + ODOTINTER + OXDOT + ODOTTYPE + ODOTTYPE2 + OEQ + ONE + OLT + OLE + OGE + OGT + OIND + OINDEX + OINDEXMAP + OKEY + OPARAM + OLEN + OMAKE + OMAKECHAN + OMAKEMAP + OMAKESLICE + OMUL + ODIV + OMOD + OLSH + ORSH + OAND + OANDNOT + ONEW + ONOT + OCOM + OPLUS + OMINUS + OOROR + OPANIC + OPRINT + OPRINTN + OPAREN + OSEND + OSLICE + OSLICEARR + OSLICESTR + OSLICE3 + OSLICE3ARR + ORECOVER + ORECV + ORUNESTR + OSELRECV + OSELRECV2 + OIOTA + OREAL + OIMAG + OCOMPLEX + OBLOCK + OBREAK + OCASE + OXCASE + OCONTINUE + ODEFER + OEMPTY + OFALL + OXFALL + OFOR + OGOTO + OIF + OLABEL + OPROC + ORANGE + ORETURN + OSELECT + OSWITCH + OTYPESW + OTCHAN + OTMAP + OTSTRUCT + OTINTER + OTFUNC + OTARRAY + ODDD + ODDDARG + OINLCALL + OEFACE + OITAB + OSPTR + OCLOSUREVAR + OCFUNC + OCHECKNIL + OVARKILL + OREGISTER + OINDREG + OCMP + ODEC + OINC + OEXTEND + OHMUL + OLROT + ORROTC + ORETJMP + OEND +) + +/* + * Every node has a walkgen field. + * If you want to do a traversal of a node graph that + * might contain duplicates and want to avoid + * visiting the same nodes twice, increment walkgen + * before starting. Then before processing a node, do + * + * if(n->walkgen == walkgen) + * return; + * n->walkgen = walkgen; + * + * Such a walk cannot call another such walk recursively, + * because of the use of the global walkgen. + */ +var walkgen uint32 + +// A NodeList is a linked list of nodes. +// TODO(rsc): Some uses of NodeList should be made into slices. +// The remaining ones probably just need a simple linked list, +// not one with concatenation support. +type NodeList struct { + N *Node + Next *NodeList + End *NodeList +} + +// concat returns the concatenation of the lists a and b. +// The storage taken by both is reused for the result. +func concat(a *NodeList, b *NodeList) *NodeList { + if a == nil { + return b + } + if b == nil { + return a + } + + a.End.Next = b + a.End = b.End + b.End = nil + return a +} + +// list1 returns a one-element list containing n. +func list1(n *Node) *NodeList { + if n == nil { + return nil + } + if n.Op == OBLOCK && n.Ninit == nil { + // Flatten list and steal storage. + // Poison pointer to catch errant uses. + l := n.List + + n.List = nil + return l + } + + l := new(NodeList) + l.N = n + l.End = l + return l +} + +// list returns the result of appending n to l. +func list(l *NodeList, n *Node) *NodeList { + return concat(l, list1(n)) +} + +// listsort sorts *l in place according to the 3-way comparison function f. +// The algorithm is mergesort, so it is guaranteed to be O(n log n). +func listsort(l **NodeList, f func(*Node, *Node) int) { + if *l == nil || (*l).Next == nil { + return + } + + l1 := *l + l2 := *l + for { + l2 = l2.Next + if l2 == nil { + break + } + l2 = l2.Next + if l2 == nil { + break + } + l1 = l1.Next + } + + l2 = l1.Next + l1.Next = nil + l2.End = (*l).End + (*l).End = l1 + + l1 = *l + listsort(&l1, f) + listsort(&l2, f) + + if f(l1.N, l2.N) < 0 { + *l = l1 + } else { + *l = l2 + l2 = l1 + l1 = *l + } + + // now l1 == *l; and l1 < l2 + + var le *NodeList + for (l1 != nil) && (l2 != nil) { + for (l1.Next != nil) && f(l1.Next.N, l2.N) < 0 { + l1 = l1.Next + } + + // l1 is last one from l1 that is < l2 + le = l1.Next // le is the rest of l1, first one that is >= l2 + if le != nil { + le.End = (*l).End + } + + (*l).End = l1 // cut *l at l1 + *l = concat(*l, l2) // glue l2 to *l's tail + + l1 = l2 // l1 is the first element of *l that is < the new l2 + l2 = le // ... because l2 now is the old tail of l1 + } + + *l = concat(*l, l2) // any remainder +} + +// count returns the length of the list l. +func count(l *NodeList) int { + n := int64(0) + for ; l != nil; l = l.Next { + n++ + } + if int64(int(n)) != n { // Overflow. + Yyerror("too many elements in list") + } + return int(n) +}