github.com/aloncn/graphics-go@v0.0.1/src/cmd/compile/internal/gc/syntax.go (about) 1 // Copyright 2009 The Go Authors. All rights reserved. 2 // Use of this source code is governed by a BSD-style 3 // license that can be found in the LICENSE file. 4 5 // “Abstract” syntax representation. 6 7 package gc 8 9 // A Node is a single node in the syntax tree. 10 // Actually the syntax tree is a syntax DAG, because there is only one 11 // node with Op=ONAME for a given instance of a variable x. 12 // The same is true for Op=OTYPE and Op=OLITERAL. 13 type Node struct { 14 // Tree structure. 15 // Generic recursive walks should follow these fields. 16 Left *Node 17 Right *Node 18 Ninit *NodeList 19 Nbody *NodeList 20 List *NodeList 21 Rlist *NodeList 22 23 // most nodes 24 Type *Type 25 Orig *Node // original form, for printing, and tracking copies of ONAMEs 26 27 // func 28 Func *Func 29 30 // ONAME 31 Name *Name 32 33 Sym *Sym // various 34 E interface{} // Opt or Val, see methods below 35 36 Xoffset int64 37 38 Lineno int32 39 40 // OREGISTER, OINDREG 41 Reg int16 42 43 Esc uint16 // EscXXX 44 45 Op Op 46 Nointerface bool 47 Ullman uint8 // sethi/ullman number 48 Addable bool // addressable 49 Etype EType // op for OASOP, etype for OTYPE, exclam for export, 6g saved reg 50 Bounded bool // bounds check unnecessary 51 Class Class // PPARAM, PAUTO, PEXTERN, etc 52 Embedded uint8 // ODCLFIELD embedded type 53 Colas bool // OAS resulting from := 54 Diag uint8 // already printed error about this 55 Noescape bool // func arguments do not escape; TODO(rsc): move Noescape to Func struct (see CL 7360) 56 Walkdef uint8 57 Typecheck uint8 58 Local bool 59 Dodata uint8 60 Initorder uint8 61 Used bool 62 Isddd bool // is the argument variadic 63 Implicit bool 64 Addrtaken bool // address taken, even if not moved to heap 65 Assigned bool // is the variable ever assigned to 66 Likely int8 // likeliness of if statement 67 Hasbreak bool // has break statement 68 hasVal int8 // +1 for Val, -1 for Opt, 0 for not yet set 69 } 70 71 // Val returns the Val for the node. 72 func (n *Node) Val() Val { 73 if n.hasVal != +1 { 74 return Val{} 75 } 76 return Val{n.E} 77 } 78 79 // SetVal sets the Val for the node, which must not have been used with SetOpt. 80 func (n *Node) SetVal(v Val) { 81 if n.hasVal == -1 { 82 Debug['h'] = 1 83 Dump("have Opt", n) 84 Fatalf("have Opt") 85 } 86 n.hasVal = +1 87 n.E = v.U 88 } 89 90 // Opt returns the optimizer data for the node. 91 func (n *Node) Opt() interface{} { 92 if n.hasVal != -1 { 93 return nil 94 } 95 return n.E 96 } 97 98 // SetOpt sets the optimizer data for the node, which must not have been used with SetVal. 99 // SetOpt(nil) is ignored for Vals to simplify call sites that are clearing Opts. 100 func (n *Node) SetOpt(x interface{}) { 101 if x == nil && n.hasVal >= 0 { 102 return 103 } 104 if n.hasVal == +1 { 105 Debug['h'] = 1 106 Dump("have Val", n) 107 Fatalf("have Val") 108 } 109 n.hasVal = -1 110 n.E = x 111 } 112 113 // Name holds Node fields used only by named nodes (ONAME, OPACK, some OLITERAL). 114 type Name struct { 115 Pack *Node // real package for import . names 116 Pkg *Pkg // pkg for OPACK nodes 117 Heapaddr *Node // temp holding heap address of param 118 Inlvar *Node // ONAME substitute while inlining 119 Defn *Node // initializing assignment 120 Curfn *Node // function for local variables 121 Param *Param 122 Decldepth int32 // declaration loop depth, increased for every loop or label 123 Vargen int32 // unique name for ONAME within a function. Function outputs are numbered starting at one. 124 Iota int32 // value if this name is iota 125 Funcdepth int32 126 Method bool // OCALLMETH name 127 Readonly bool 128 Captured bool // is the variable captured by a closure 129 Byval bool // is the variable captured by value or by reference 130 Needzero bool // if it contains pointers, needs to be zeroed on function entry 131 Keepalive bool // mark value live across unknown assembly call 132 } 133 134 type Param struct { 135 Ntype *Node 136 137 // ONAME func param with PHEAP 138 Outerexpr *Node // expression copied into closure for variable 139 Stackparam *Node // OPARAM node referring to stack copy of param 140 141 // ONAME PPARAM 142 Field *Type // TFIELD in arg struct 143 144 // ONAME closure param with PPARAMREF 145 Outer *Node // outer PPARAMREF in nested closure 146 Closure *Node // ONAME/PHEAP <-> ONAME/PPARAMREF 147 } 148 149 // Func holds Node fields used only with function-like nodes. 150 type Func struct { 151 Shortname *Node 152 Enter *NodeList 153 Exit *NodeList 154 Cvars *NodeList // closure params 155 Dcl *NodeList // autodcl for this func/closure 156 Inldcl *NodeList // copy of dcl for use in inlining 157 Closgen int 158 Outerfunc *Node 159 Fieldtrack []*Type 160 Outer *Node // outer func for closure 161 Ntype *Node // signature 162 Top int // top context (Ecall, Eproc, etc) 163 Closure *Node // OCLOSURE <-> ODCLFUNC 164 FCurfn *Node 165 Nname *Node 166 167 Inl *NodeList // copy of the body for use in inlining 168 InlCost int32 169 Depth int32 170 171 Endlineno int32 172 173 Norace bool // func must not have race detector annotations 174 Nosplit bool // func should not execute on separate stack 175 Noinline bool // func should not be inlined 176 Nowritebarrier bool // emit compiler error instead of write barrier 177 Nowritebarrierrec bool // error on write barrier in this or recursive callees 178 Dupok bool // duplicate definitions ok 179 Wrapper bool // is method wrapper 180 Needctxt bool // function uses context register (has closure variables) 181 Systemstack bool // must run on system stack 182 183 WBLineno int32 // line number of first write barrier 184 } 185 186 type Op uint8 187 188 // Node ops. 189 const ( 190 OXXX = Op(iota) 191 192 // names 193 ONAME // var, const or func name 194 ONONAME // unnamed arg or return value: f(int, string) (int, error) { etc } 195 OTYPE // type name 196 OPACK // import 197 OLITERAL // literal 198 199 // expressions 200 OADD // Left + Right 201 OSUB // Left - Right 202 OOR // Left | Right 203 OXOR // Left ^ Right 204 OADDSTR // Left + Right (string addition) 205 OADDR // &Left 206 OANDAND // Left && Right 207 OAPPEND // append(List) 208 OARRAYBYTESTR // Type(Left) (Type is string, Left is a []byte) 209 OARRAYBYTESTRTMP // Type(Left) (Type is string, Left is a []byte, ephemeral) 210 OARRAYRUNESTR // Type(Left) (Type is string, Left is a []rune) 211 OSTRARRAYBYTE // Type(Left) (Type is []byte, Left is a string) 212 OSTRARRAYBYTETMP // Type(Left) (Type is []byte, Left is a string, ephemeral) 213 OSTRARRAYRUNE // Type(Left) (Type is []rune, Left is a string) 214 OAS // Left = Right or (if Colas=true) Left := Right 215 OAS2 // List = Rlist (x, y, z = a, b, c) 216 OAS2FUNC // List = Rlist (x, y = f()) 217 OAS2RECV // List = Rlist (x, ok = <-c) 218 OAS2MAPR // List = Rlist (x, ok = m["foo"]) 219 OAS2DOTTYPE // List = Rlist (x, ok = I.(int)) 220 OASOP // Left Etype= Right (x += y) 221 OASWB // Left = Right (with write barrier) 222 OCALL // Left(List) (function call, method call or type conversion) 223 OCALLFUNC // Left(List) (function call f(args)) 224 OCALLMETH // Left(List) (direct method call x.Method(args)) 225 OCALLINTER // Left(List) (interface method call x.Method(args)) 226 OCALLPART // Left.Right (method expression x.Method, not called) 227 OCAP // cap(Left) 228 OCLOSE // close(Left) 229 OCLOSURE // func Type { Body } (func literal) 230 OCMPIFACE // Left Etype Right (interface comparison, x == y or x != y) 231 OCMPSTR // Left Etype Right (string comparison, x == y, x < y, etc) 232 OCOMPLIT // Right{List} (composite literal, not yet lowered to specific form) 233 OMAPLIT // Type{List} (composite literal, Type is map) 234 OSTRUCTLIT // Type{List} (composite literal, Type is struct) 235 OARRAYLIT // Type{List} (composite literal, Type is array or slice) 236 OPTRLIT // &Left (left is composite literal) 237 OCONV // Type(Left) (type conversion) 238 OCONVIFACE // Type(Left) (type conversion, to interface) 239 OCONVNOP // Type(Left) (type conversion, no effect) 240 OCOPY // copy(Left, Right) 241 ODCL // var Left (declares Left of type Left.Type) 242 243 // Used during parsing but don't last. 244 ODCLFUNC // func f() or func (r) f() 245 ODCLFIELD // struct field, interface field, or func/method argument/return value. 246 ODCLCONST // const pi = 3.14 247 ODCLTYPE // type Int int 248 249 ODELETE // delete(Left, Right) 250 ODOT // Left.Right (Left is of struct type) 251 ODOTPTR // Left.Right (Left is of pointer to struct type) 252 ODOTMETH // Left.Right (Left is non-interface, Right is method name) 253 ODOTINTER // Left.Right (Left is interface, Right is method name) 254 OXDOT // Left.Right (before rewrite to one of the preceding) 255 ODOTTYPE // Left.Right or Left.Type (.Right during parsing, .Type once resolved) 256 ODOTTYPE2 // Left.Right or Left.Type (.Right during parsing, .Type once resolved; on rhs of OAS2DOTTYPE) 257 OEQ // Left == Right 258 ONE // Left != Right 259 OLT // Left < Right 260 OLE // Left <= Right 261 OGE // Left >= Right 262 OGT // Left > Right 263 OIND // *Left 264 OINDEX // Left[Right] (index of array or slice) 265 OINDEXMAP // Left[Right] (index of map) 266 OKEY // Left:Right (key:value in struct/array/map literal, or slice index pair) 267 OPARAM // variant of ONAME for on-stack copy of a parameter or return value that escapes. 268 OLEN // len(Left) 269 OMAKE // make(List) (before type checking converts to one of the following) 270 OMAKECHAN // make(Type, Left) (type is chan) 271 OMAKEMAP // make(Type, Left) (type is map) 272 OMAKESLICE // make(Type, Left, Right) (type is slice) 273 OMUL // Left * Right 274 ODIV // Left / Right 275 OMOD // Left % Right 276 OLSH // Left << Right 277 ORSH // Left >> Right 278 OAND // Left & Right 279 OANDNOT // Left &^ Right 280 ONEW // new(Left) 281 ONOT // !Left 282 OCOM // ^Left 283 OPLUS // +Left 284 OMINUS // -Left 285 OOROR // Left || Right 286 OPANIC // panic(Left) 287 OPRINT // print(List) 288 OPRINTN // println(List) 289 OPAREN // (Left) 290 OSEND // Left <- Right 291 OSLICE // Left[Right.Left : Right.Right] (Left is untypechecked or slice; Right.Op==OKEY) 292 OSLICEARR // Left[Right.Left : Right.Right] (Left is array) 293 OSLICESTR // Left[Right.Left : Right.Right] (Left is string) 294 OSLICE3 // Left[R.Left : R.R.Left : R.R.R] (R=Right; Left is untypedchecked or slice; R.Op and R.R.Op==OKEY) 295 OSLICE3ARR // Left[R.Left : R.R.Left : R.R.R] (R=Right; Left is array; R.Op and R.R.Op==OKEY) 296 ORECOVER // recover() 297 ORECV // <-Left 298 ORUNESTR // Type(Left) (Type is string, Left is rune) 299 OSELRECV // Left = <-Right.Left: (appears as .Left of OCASE; Right.Op == ORECV) 300 OSELRECV2 // List = <-Right.Left: (apperas as .Left of OCASE; count(List) == 2, Right.Op == ORECV) 301 OIOTA // iota 302 OREAL // real(Left) 303 OIMAG // imag(Left) 304 OCOMPLEX // complex(Left, Right) 305 306 // statements 307 OBLOCK // { List } (block of code) 308 OBREAK // break 309 OCASE // case List: Nbody (select case after processing; List==nil means default) 310 OXCASE // case List: Nbody (select case before processing; List==nil means default) 311 OCONTINUE // continue 312 ODEFER // defer Left (Left must be call) 313 OEMPTY // no-op (empty statement) 314 OFALL // fallthrough (after processing) 315 OXFALL // fallthrough (before processing) 316 OFOR // for Ninit; Left; Right { Nbody } 317 OGOTO // goto Left 318 OIF // if Ninit; Left { Nbody } else { Rlist } 319 OLABEL // Left: 320 OPROC // go Left (Left must be call) 321 ORANGE // for List = range Right { Nbody } 322 ORETURN // return List 323 OSELECT // select { List } (List is list of OXCASE or OCASE) 324 OSWITCH // switch Ninit; Left { List } (List is a list of OXCASE or OCASE) 325 OTYPESW // List = Left.(type) (appears as .Left of OSWITCH) 326 327 // types 328 OTCHAN // chan int 329 OTMAP // map[string]int 330 OTSTRUCT // struct{} 331 OTINTER // interface{} 332 OTFUNC // func() 333 OTARRAY // []int, [8]int, [N]int or [...]int 334 335 // misc 336 ODDD // func f(args ...int) or f(l...) or var a = [...]int{0, 1, 2}. 337 ODDDARG // func f(args ...int), introduced by escape analysis. 338 OINLCALL // intermediary representation of an inlined call. 339 OEFACE // itable and data words of an empty-interface value. 340 OITAB // itable word of an interface value. 341 OSPTR // base pointer of a slice or string. 342 OCLOSUREVAR // variable reference at beginning of closure function 343 OCFUNC // reference to c function pointer (not go func value) 344 OCHECKNIL // emit code to ensure pointer/interface not nil 345 OVARKILL // variable is dead 346 OVARLIVE // variable is alive 347 348 // thearch-specific registers 349 OREGISTER // a register, such as AX. 350 OINDREG // offset plus indirect of a register, such as 8(SP). 351 352 // arch-specific opcodes 353 OCMP // compare: ACMP. 354 ODEC // decrement: ADEC. 355 OINC // increment: AINC. 356 OEXTEND // extend: ACWD/ACDQ/ACQO. 357 OHMUL // high mul: AMUL/AIMUL for unsigned/signed (OMUL uses AIMUL for both). 358 OLROT // left rotate: AROL. 359 ORROTC // right rotate-carry: ARCR. 360 ORETJMP // return to other function 361 OPS // compare parity set (for x86 NaN check) 362 OPC // compare parity clear (for x86 NaN check) 363 OSQRT // sqrt(float64), on systems that have hw support 364 OGETG // runtime.getg() (read g pointer) 365 366 OEND 367 ) 368 369 // A NodeList is a linked list of nodes. 370 // TODO(rsc): Some uses of NodeList should be made into slices. 371 // The remaining ones probably just need a simple linked list, 372 // not one with concatenation support. 373 type NodeList struct { 374 N *Node 375 Next *NodeList 376 End *NodeList 377 } 378 379 // concat returns the concatenation of the lists a and b. 380 // The storage taken by both is reused for the result. 381 func concat(a *NodeList, b *NodeList) *NodeList { 382 if a == nil { 383 return b 384 } 385 if b == nil { 386 return a 387 } 388 389 a.End.Next = b 390 a.End = b.End 391 b.End = nil 392 return a 393 } 394 395 // list1 returns a one-element list containing n. 396 func list1(n *Node) *NodeList { 397 if n == nil { 398 return nil 399 } 400 if n.Op == OBLOCK && n.Ninit == nil { 401 // Flatten list and steal storage. 402 // Poison pointer to catch errant uses. 403 l := n.List 404 405 n.List = nil 406 return l 407 } 408 409 l := new(NodeList) 410 l.N = n 411 l.End = l 412 return l 413 } 414 415 // list returns the result of appending n to l. 416 func list(l *NodeList, n *Node) *NodeList { 417 return concat(l, list1(n)) 418 } 419 420 // listsort sorts *l in place according to the comparison function lt. 421 // The algorithm expects lt(a, b) to be equivalent to a < b. 422 // The algorithm is mergesort, so it is guaranteed to be O(n log n). 423 func listsort(l **NodeList, lt func(*Node, *Node) bool) { 424 if *l == nil || (*l).Next == nil { 425 return 426 } 427 428 l1 := *l 429 l2 := *l 430 for { 431 l2 = l2.Next 432 if l2 == nil { 433 break 434 } 435 l2 = l2.Next 436 if l2 == nil { 437 break 438 } 439 l1 = l1.Next 440 } 441 442 l2 = l1.Next 443 l1.Next = nil 444 l2.End = (*l).End 445 (*l).End = l1 446 447 l1 = *l 448 listsort(&l1, lt) 449 listsort(&l2, lt) 450 451 if lt(l1.N, l2.N) { 452 *l = l1 453 } else { 454 *l = l2 455 l2 = l1 456 l1 = *l 457 } 458 459 // now l1 == *l; and l1 < l2 460 461 var le *NodeList 462 for (l1 != nil) && (l2 != nil) { 463 for (l1.Next != nil) && lt(l1.Next.N, l2.N) { 464 l1 = l1.Next 465 } 466 467 // l1 is last one from l1 that is < l2 468 le = l1.Next // le is the rest of l1, first one that is >= l2 469 if le != nil { 470 le.End = (*l).End 471 } 472 473 (*l).End = l1 // cut *l at l1 474 *l = concat(*l, l2) // glue l2 to *l's tail 475 476 l1 = l2 // l1 is the first element of *l that is < the new l2 477 l2 = le // ... because l2 now is the old tail of l1 478 } 479 480 *l = concat(*l, l2) // any remainder 481 } 482 483 // count returns the length of the list l. 484 func count(l *NodeList) int { 485 n := int64(0) 486 for ; l != nil; l = l.Next { 487 n++ 488 } 489 if int64(int(n)) != n { // Overflow. 490 Yyerror("too many elements in list") 491 } 492 return int(n) 493 }