// 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 {
	// Tree structure.
	// Generic recursive walks should follow these fields.
	Left  *Node
	Right *Node
	Ninit *NodeList
	Nbody *NodeList
	List  *NodeList
	Rlist *NodeList

	// most nodes
	Type *Type
	Orig *Node // original form, for printing, and tracking copies of ONAMEs

	// func
	Func *Func

	// ONAME
	Name *Name

	Sym *Sym // various

	Opt interface{} // for optimization passes

	// OLITERAL
	Val Val

	Xoffset int64

	Lineno int32

	// OREGISTER, OINDREG
	Reg int16

	Esc uint16 // EscXXX

	Op          uint8
	Nointerface bool
	Ullman      uint8 // sethi/ullman number
	Addable     bool  // addressable
	Etype       uint8 // op for OASOP, etype for OTYPE, exclam for export, 6g saved reg
	Bounded     bool  // bounds check unnecessary
	Class       uint8 // PPARAM, PAUTO, PEXTERN, etc
	Embedded    uint8 // ODCLFIELD embedded type
	Colas       bool  // OAS resulting from :=
	Diag        uint8 // already printed error about this
	Noescape    bool  // func arguments do not escape; TODO(rsc): move Noescape to Func struct (see CL 7360)
	Walkdef     uint8
	Typecheck   uint8
	Local       bool
	Dodata      uint8
	Initorder   uint8
	Used        bool
	Isddd       bool // is the argument variadic
	Implicit    bool
	Addrtaken   bool // address taken, even if not moved to heap
	Assigned    bool // is the variable ever assigned to
	Likely      int8 // likeliness of if statement
	Hasbreak    bool // has break statement
}

// Name holds Node fields used only by named nodes (ONAME, OPACK, some OLITERAL).
type Name struct {
	Pack     *Node // real package for import . names
	Pkg      *Pkg  // pkg for OPACK nodes
	Heapaddr *Node // temp holding heap address of param
	Inlvar   *Node // ONAME substitute while inlining
	Defn     *Node // initializing assignment
	Curfn    *Node // function for local variables
	*Param
	Decldepth int32 // declaration loop depth, increased for every loop or label
	Vargen    int32 // unique name for OTYPE/ONAME within a function.  Function outputs are numbered starting at one.
	Iota      int32 // value if this name is iota
	Funcdepth int32
	Method    bool // OCALLMETH name
	Readonly  bool
	Captured  bool // is the variable captured by a closure
	Byval     bool // is the variable captured by value or by reference
	Needzero  bool // if it contains pointers, needs to be zeroed on function entry
}

type Param struct {
	Ntype *Node

	// ONAME func param with PHEAP
	Outerexpr  *Node // expression copied into closure for variable
	Stackparam *Node // OPARAM node referring to stack copy of param

	// ONAME PPARAM
	Field *Type // TFIELD in arg struct

	// ONAME closure param with PPARAMREF
	Outer   *Node // outer PPARAMREF in nested closure
	Closure *Node // ONAME/PHEAP <-> ONAME/PPARAMREF
}

// Func holds Node fields used only with function-like nodes.
type Func struct {
	Shortname  *Node
	Enter      *NodeList
	Exit       *NodeList
	Cvars      *NodeList // closure params
	Dcl        *NodeList // autodcl for this func/closure
	Inldcl     *NodeList // copy of dcl for use in inlining
	Closgen    int
	Outerfunc  *Node
	Fieldtrack []*Type
	Outer      *Node // outer func for closure
	Ntype      *Node // signature
	Top        int   // top context (Ecall, Eproc, etc)
	Closure    *Node // OCLOSURE <-> ODCLFUNC
	FCurfn     *Node
	Nname      *Node

	Inl     *NodeList // copy of the body for use in inlining
	InlCost int32
	Depth   int32

	Endlineno int32

	Nosplit        bool // func should not execute on separate stack
	Nowritebarrier bool // emit compiler error instead of write barrier
	Dupok          bool // duplicate definitions ok
	Wrapper        bool // is method wrapper
	Needctxt       bool // function uses context register (has closure variables)
}

// Node ops.
const (
	OXXX = iota

	// names
	ONAME    // var, const or func name
	ONONAME  // unnamed arg or return value: f(int, string) (int, error) { etc }
	OTYPE    // type name
	OPACK    // import
	OLITERAL // literal

	// expressions
	OADD             // x + y
	OSUB             // x - y
	OOR              // x | y
	OXOR             // x ^ y
	OADDSTR          // s + "foo"
	OADDR            // &x
	OANDAND          // b0 && b1
	OAPPEND          // append
	OARRAYBYTESTR    // string(bytes)
	OARRAYBYTESTRTMP // string(bytes) ephemeral
	OARRAYRUNESTR    // string(runes)
	OSTRARRAYBYTE    // []byte(s)
	OSTRARRAYBYTETMP // []byte(s) ephemeral
	OSTRARRAYRUNE    // []rune(s)
	OAS              // x = y or x := y
	OAS2             // x, y, z = xx, yy, zz
	OAS2FUNC         // x, y = f()
	OAS2RECV         // x, ok = <-c
	OAS2MAPR         // x, ok = m["foo"]
	OAS2DOTTYPE      // x, ok = I.(int)
	OASOP            // x += y
	OASWB            // OAS but with write barrier
	OCALL            // function call, method call or type conversion, possibly preceded by defer or go.
	OCALLFUNC        // f()
	OCALLMETH        // t.Method()
	OCALLINTER       // err.Error()
	OCALLPART        // t.Method (without ())
	OCAP             // cap
	OCLOSE           // close
	OCLOSURE         // f = func() { etc }
	OCMPIFACE        // err1 == err2
	OCMPSTR          // s1 == s2
	OCOMPLIT         // composite literal, typechecking may convert to a more specific OXXXLIT.
	OMAPLIT          // M{"foo":3, "bar":4}
	OSTRUCTLIT       // T{x:3, y:4}
	OARRAYLIT        // [2]int{3, 4}
	OPTRLIT          // &T{x:3, y:4}
	OCONV            // var i int; var u uint; i = int(u)
	OCONVIFACE       // I(t)
	OCONVNOP         // type Int int; var i int; var j Int; i = int(j)
	OCOPY            // copy
	ODCL             // var x int
	ODCLFUNC         // func f() or func (r) f()
	ODCLFIELD        // struct field, interface field, or func/method argument/return value.
	ODCLCONST        // const pi = 3.14
	ODCLTYPE         // type Int int
	ODELETE          // delete
	ODOT             // t.x
	ODOTPTR          // p.x that is implicitly (*p).x
	ODOTMETH         // t.Method
	ODOTINTER        // err.Error
	OXDOT            // t.x, typechecking may convert to a more specific ODOTXXX.
	ODOTTYPE         // e = err.(MyErr)
	ODOTTYPE2        // e, ok = err.(MyErr)
	OEQ              // x == y
	ONE              // x != y
	OLT              // x < y
	OLE              // x <= y
	OGE              // x >= y
	OGT              // x > y
	OIND             // *p
	OINDEX           // a[i]
	OINDEXMAP        // m[s]
	OKEY             // The x:3 in t{x:3, y:4}, the 1:2 in a[1:2], the 2:20 in [3]int{2:20}, etc.
	OPARAM           // The on-stack copy of a parameter or return value that escapes.
	OLEN             // len
	OMAKE            // make, typechecking may convert to a more specific OMAKEXXX.
	OMAKECHAN        // make(chan int)
	OMAKEMAP         // make(map[string]int)
	OMAKESLICE       // make([]int, 0)
	OMUL             // *
	ODIV             // x / y
	OMOD             // x % y
	OLSH             // x << u
	ORSH             // x >> u
	OAND             // x & y
	OANDNOT          // x &^ y
	ONEW             // new
	ONOT             // !b
	OCOM             // ^x
	OPLUS            // +x
	OMINUS           // -y
	OOROR            // b1 || b2
	OPANIC           // panic
	OPRINT           // print
	OPRINTN          // println
	OPAREN           // (x)
	OSEND            // c <- x
	OSLICE           // v[1:2], typechecking may convert to a more specific OSLICEXXX.
	OSLICEARR        // a[1:2]
	OSLICESTR        // s[1:2]
	OSLICE3          // v[1:2:3], typechecking may convert to OSLICE3ARR.
	OSLICE3ARR       // a[1:2:3]
	ORECOVER         // recover
	ORECV            // <-c
	ORUNESTR         // string(i)
	OSELRECV         // case x = <-c:
	OSELRECV2        // case x, ok = <-c:
	OIOTA            // iota
	OREAL            // real
	OIMAG            // imag
	OCOMPLEX         // complex

	// statements
	OBLOCK    // block of code
	OBREAK    // break
	OCASE     // case, after being verified by swt.c's casebody.
	OXCASE    // case, before verification.
	OCONTINUE // continue
	ODEFER    // defer
	OEMPTY    // no-op
	OFALL     // fallthrough, after being verified by swt.c's casebody.
	OXFALL    // fallthrough, before verification.
	OFOR      // for
	OGOTO     // goto
	OIF       // if
	OLABEL    // label:
	OPROC     // go
	ORANGE    // range
	ORETURN   // return
	OSELECT   // select
	OSWITCH   // switch x
	OTYPESW   // switch err.(type)

	// types
	OTCHAN   // chan int
	OTMAP    // map[string]int
	OTSTRUCT // struct{}
	OTINTER  // interface{}
	OTFUNC   // func()
	OTARRAY  // []int, [8]int, [N]int or [...]int

	// misc
	ODDD        // func f(args ...int) or f(l...) or var a = [...]int{0, 1, 2}.
	ODDDARG     // func f(args ...int), introduced by escape analysis.
	OINLCALL    // intermediary representation of an inlined call.
	OEFACE      // itable and data words of an empty-interface value.
	OITAB       // itable word of an interface value.
	OSPTR       // base pointer of a slice or string.
	OCLOSUREVAR // variable reference at beginning of closure function
	OCFUNC      // reference to c function pointer (not go func value)
	OCHECKNIL   // emit code to ensure pointer/interface not nil
	OVARKILL    // variable is dead

	// thearch-specific registers
	OREGISTER // a register, such as AX.
	OINDREG   // offset plus indirect of a register, such as 8(SP).

	// arch-specific opcodes
	OCMP    // compare: ACMP.
	ODEC    // decrement: ADEC.
	OINC    // increment: AINC.
	OEXTEND // extend: ACWD/ACDQ/ACQO.
	OHMUL   // high mul: AMUL/AIMUL for unsigned/signed (OMUL uses AIMUL for both).
	OLROT   // left rotate: AROL.
	ORROTC  // right rotate-carry: ARCR.
	ORETJMP // return to other function
	OPS     // compare parity set (for x86 NaN check)
	OPC     // compare parity clear (for x86 NaN check)
	OSQRT   // sqrt(float64), on systems that have hw support
	OGETG   // runtime.getg() (read g pointer)

	OEND
)

// 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)
}
