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.
19 idealZero
= big
.NewInt(0)
20 idealOne
= big
.NewInt(1)
23 // An expr is the result of compiling an expression. It stores the
24 // type of the expression and its evaluator function.
29 // Evaluate this node as the given type.
32 // Map index expressions permit special forms of assignment,
33 // for which we need to know the Map and key.
34 evalMapValue
func(t
*Thread
) (Map
, interface{})
36 // Evaluate to the "address of" this value; that is, the
37 // settable Value object. nil for expressions whose address
39 evalAddr
func(t
*Thread
) Value
41 // Execute this expression as a statement. Only expressions
42 // that are valid expression statements should set this.
45 // If this expression is a type, this is its compiled type.
46 // This is only permitted in the function position of a call
47 // expression. In this case, t should be nil.
50 // A short string describing this expression for error
55 // exprInfo stores information needed to compile any expression node.
56 // Each expr also stores its exprInfo so further expressions can be
58 type exprInfo
struct {
63 func (a
*exprInfo
) newExpr(t Type
, desc
string) *expr
{
64 return &expr
{exprInfo
: a
, t
: t
, desc
: desc
}
67 func (a
*exprInfo
) diag(format
string, args
...interface{}) {
68 a
.diagAt(&a
.pos
, format
, args
...)
71 func (a
*exprInfo
) diagOpType(op token
.Token
, vt Type
) {
72 a
.diag("illegal operand type for '%v' operator\n\t%v", op
, vt
)
75 func (a
*exprInfo
) diagOpTypes(op token
.Token
, lt Type
, rt Type
) {
76 a
.diag("illegal operand types for '%v' operator\n\t%v\n\t%v", op
, lt
, rt
)
80 * Common expression manipulations
83 // a.convertTo(t) converts the value of the analyzed expression a,
84 // which must be a constant, ideal number, to a new analyzed
85 // expression with a constant value of type t.
87 // TODO(austin) Rename to resolveIdeal or something?
88 func (a
*expr
) convertTo(t Type
) *expr
{
90 log
.Panicf("attempted to convert from %v, expected ideal", a
.t
)
95 // XXX(Spec) The spec says "It is erroneous".
97 // It is an error to assign a value with a non-zero fractional
98 // part to an integer, or if the assignment would overflow or
99 // underflow, or in general if the value cannot be represented
100 // by the type of the variable.
103 rat
= a
.asIdealFloat()()
104 if t
.isInteger() && !rat
.IsInt() {
105 a
.diag("constant %v truncated to integer", rat
.FloatString(6))
109 i
:= a
.asIdealInt()()
110 rat
= new(big
.Rat
).SetInt(i
)
112 log
.Panicf("unexpected ideal type %v", a
.t
)
116 if t
, ok
:= t
.lit().(BoundedType
); ok
{
117 if rat
.Cmp(t
.minVal()) < 0 {
118 a
.diag("constant %v underflows %v", rat
.FloatString(6), t
)
121 if rat
.Cmp(t
.maxVal()) > 0 {
122 a
.diag("constant %v overflows %v", rat
.FloatString(6), t
)
127 // Convert rat to type t.
128 res
:= a
.newExpr(t
, a
.desc
)
129 switch t
:= t
.lit().(type) {
131 n
, d
:= rat
.Num(), rat
.Denom()
132 f
:= new(big
.Int
).Quo(n
, d
)
134 v
:= uint64(f
.Int64())
135 res
.eval
= func(*Thread
) uint64 { return v
}
137 n
, d
:= rat
.Num(), rat
.Denom()
138 f
:= new(big
.Int
).Quo(n
, d
)
140 res
.eval
= func(*Thread
) int64 { return v
}
142 n
, d
:= rat
.Num(), rat
.Denom()
143 f
:= new(big
.Int
).Quo(n
, d
)
144 res
.eval
= func() *big
.Int
{ return f
}
146 n
, d
:= rat
.Num(), rat
.Denom()
147 v
:= float64(n
.Int64()) / float64(d
.Int64())
148 res
.eval
= func(*Thread
) float64 { return v
}
149 case *idealFloatType
:
150 res
.eval
= func() *big
.Rat
{ return rat
}
152 log
.Panicf("cannot convert to type %T", t
)
158 // convertToInt converts this expression to an integer, if possible,
159 // or produces an error if not. This accepts ideal ints, uints, and
160 // ints. If max is not -1, produces an error if possible if the value
161 // exceeds max. If negErr is not "", produces an error if possible if
162 // the value is negative.
163 func (a
*expr
) convertToInt(max
int64, negErr
string, errOp
string) *expr
{
164 switch a
.t
.lit().(type) {
166 val
:= a
.asIdealInt()()
167 if negErr
!= "" && val
.Sign() < 0 {
168 a
.diag("negative %s: %s", negErr
, val
)
172 if negErr
== "slice" {
175 if max
!= -1 && val
.Cmp(big
.NewInt(bound
)) >= 0 {
176 a
.diag("index %s exceeds length %d", val
, max
)
179 return a
.convertTo(IntType
)
183 na
:= a
.newExpr(IntType
, a
.desc
)
185 na
.eval
= func(t
*Thread
) int64 { return int64(af(t
)) }
193 a
.diag("illegal operand type for %s\n\t%v", errOp
, a
.t
)
197 // derefArray returns an expression of array type if the given
198 // expression is a *array type. Otherwise, returns the given
200 func (a
*expr
) derefArray() *expr
{
201 if pt
, ok
:= a
.t
.lit().(*PtrType
); ok
{
202 if _
, ok
:= pt
.Elem
.lit().(*ArrayType
); ok
{
203 deref
:= a
.compileStarExpr(a
)
205 log
.Panicf("failed to dereference *array")
217 // An assignCompiler compiles assignment operations. Anything other
218 // than short declarations should use the compileAssign wrapper.
220 // There are three valid types of assignment:
222 // Assigning a single expression with single-valued type to a
223 // single-valued type.
225 // Assigning multiple expressions with single-valued types to a
226 // multi-valued type.
228 // Assigning a single expression with multi-valued type to a
229 // multi-valued type.
230 type assignCompiler
struct {
233 // The RHS expressions. This may include nil's for
234 // expressions that failed to compile.
236 // The (possibly unary) MultiType of the RHS.
238 // Whether this is an unpack assignment (case 3).
240 // Whether map special assignment forms are allowed.
242 // Whether this is a "r, ok = a[x]" assignment.
244 // The operation name to use in error messages, such as
245 // "assignment" or "function call".
247 // The name to use for positions in error messages, such as
252 // Type check the RHS of an assignment, returning a new assignCompiler
253 // and indicating if the type check succeeded. This always returns an
254 // assignCompiler with rmt set, but if type checking fails, slots in
255 // the MultiType may be nil. If rs contains nil's, type checking will
256 // fail and these expressions given a nil type.
257 func (a
*compiler
) checkAssign(pos token
.Position
, rs
[]*expr
, errOp
, errPosName
string) (*assignCompiler
, bool) {
258 c
:= &assignCompiler
{
263 errPosName
: errPosName
,
266 // Is this an unpack?
267 if len(rs
) == 1 && rs
[0] != nil {
268 if rmt
, isUnpack
:= rs
[0].t
.(*MultiType
); isUnpack
{
275 // Create MultiType for RHS and check that all RHS expressions
276 // are single-valued.
277 rts
:= make([]Type
, len(rs
))
279 for i
, r
:= range rs
{
285 if _
, isMT
:= r
.t
.(*MultiType
); isMT
{
286 r
.diag("multi-valued expression not allowed in %s", errOp
)
294 c
.rmt
= NewMultiType(rts
)
298 func (a
*assignCompiler
) allowMapForms(nls
int) {
301 // Update unpacking info if this is r, ok = a[x]
302 if nls
== 2 && len(a
.rs
) == 1 && a
.rs
[0] != nil && a
.rs
[0].evalMapValue
!= nil {
304 a
.rmt
= NewMultiType([]Type
{a
.rs
[0].t
, BoolType
})
309 // compile type checks and compiles an assignment operation, returning
310 // a function that expects an l-value and the frame in which to
311 // evaluate the RHS expressions. The l-value must have exactly the
312 // type given by lt. Returns nil if type checking fails.
313 func (a
*assignCompiler
) compile(b
*block
, lt Type
) func(Value
, *Thread
) {
314 lmt
, isMT
:= lt
.(*MultiType
)
315 rmt
, isUnpack
:= a
.rmt
, a
.isUnpack
317 // Create unary MultiType for single LHS
319 lmt
= NewMultiType([]Type
{lt
})
322 // Check that the assignment count matches
323 lcount
:= len(lmt
.Elems
)
324 rcount
:= len(rmt
.Elems
)
325 if lcount
!= rcount
{
331 pos
= a
.rs
[lcount
-1].pos
334 a
.diagAt(&pos
, "%s %ss for %s\n\t%s\n\t%s", msg
, a
.errPosName
, a
.errOp
, lt
, rmt
)
340 // If this is an unpack, create a temporary to store the
341 // multi-value and replace the RHS with expressions to pull
342 // out values from the temporary. Technically, this is only
343 // necessary when we need to perform assignment conversions.
344 var effect
func(*Thread
)
346 // This leaks a slot, but is definitely safe.
347 temp
:= b
.DefineTemp(a
.rmt
)
348 tempIdx
:= temp
.Index
350 panic(fmt
.Sprintln("tempidx", tempIdx
))
353 rf
:= a
.rs
[0].evalMapValue
355 effect
= func(t
*Thread
) {
363 t
.f
.Vars
[tempIdx
] = multiV([]Value
{v
, &found
})
366 rf
:= a
.rs
[0].asMulti()
367 effect
= func(t
*Thread
) { t
.f
.Vars
[tempIdx
] = multiV(rf(t
)) }
370 a
.rs
= make([]*expr
, len(a
.rmt
.Elems
))
371 for i
, t
:= range a
.rmt
.Elems
{
373 log
.Panicf("Right side of unpack contains ideal: %s", rmt
)
375 a
.rs
[i
] = orig
.newExpr(t
, orig
.desc
)
377 a
.rs
[i
].genValue(func(t
*Thread
) Value
{ return t
.f
.Vars
[tempIdx
].(multiV
)[index
] })
380 // Now len(a.rs) == len(a.rmt) and we've reduced any unpacking
381 // to multi-assignment.
383 // TODO(austin) Deal with assignment special cases.
385 // Values of any type may always be assigned to variables of
386 // compatible static type.
387 for i
, lt
:= range lmt
.Elems
{
390 // When [an ideal is] (used in an expression) assigned
391 // to a variable or typed constant, the destination
392 // must be able to represent the assigned value.
394 a
.rs
[i
] = a
.rs
[i
].convertTo(lmt
.Elems
[i
])
402 // A pointer p to an array can be assigned to a slice
403 // variable v with compatible element type if the type
404 // of p or v is unnamed.
405 if rpt
, ok
:= rt
.lit().(*PtrType
); ok
{
406 if at
, ok
:= rpt
.Elem
.lit().(*ArrayType
); ok
{
407 if lst
, ok
:= lt
.lit().(*SliceType
); ok
{
408 if lst
.Elem
.compat(at
.Elem
, false) && (rt
.lit() == Type(rt
) || lt
.lit() == Type(lt
)) {
409 rf
:= a
.rs
[i
].asPtr()
410 a
.rs
[i
] = a
.rs
[i
].newExpr(lt
, a
.rs
[i
].desc
)
412 a
.rs
[i
].eval
= func(t
*Thread
) Slice
{ return Slice
{rf(t
).(ArrayValue
), len, len} }
419 if !lt
.compat(rt
, false) {
421 a
.rs
[0].diag("illegal operand types for %s\n\t%v\n\t%v", a
.errOp
, lt
, rt
)
423 a
.rs
[i
].diag("illegal operand types in %s %d of %s\n\t%v\n\t%v", a
.errPosName
, i
+1, a
.errOp
, lt
, rt
)
435 return genAssign(lt
, a
.rs
[0])
438 as
:= make([]func(lv Value
, t
*Thread
), len(a
.rs
))
439 for i
, r
:= range a
.rs
{
440 as
[i
] = genAssign(lmt
.Elems
[i
], r
)
442 return func(lv Value
, t
*Thread
) {
447 for i
, a
:= range as
{
453 // compileAssign compiles an assignment operation without the full
454 // generality of an assignCompiler. See assignCompiler for a
455 // description of the arguments.
456 func (a
*compiler
) compileAssign(pos token
.Position
, b
*block
, lt Type
, rs
[]*expr
, errOp
, errPosName
string) func(Value
, *Thread
) {
457 ac
, ok
:= a
.checkAssign(pos
, rs
, errOp
, errPosName
)
461 return ac
.compile(b
, lt
)
465 * Expression compiler
468 // An exprCompiler stores information used throughout the compilation
469 // of a single expression. It does not embed funcCompiler because
470 // expressions can appear at top level.
471 type exprCompiler
struct {
473 // The block this expression is being compiled in.
475 // Whether this expression is used in a constant context.
479 // compile compiles an expression AST. callCtx should be true if this
480 // AST is in the function position of a function call node; it allows
481 // the returned expression to be a type or a built-in function (which
482 // otherwise result in errors).
483 func (a
*exprCompiler
) compile(x ast
.Expr
, callCtx
bool) *expr
{
484 ei
:= &exprInfo
{a
.compiler
, x
.Pos()}
486 switch x
:= x
.(type) {
491 return ei
.compileIntLit(string(x
.Value
))
493 return ei
.compileFloatLit(string(x
.Value
))
495 return ei
.compileCharLit(string(x
.Value
))
497 return ei
.compileStringLit(string(x
.Value
))
499 log
.Panicf("unexpected basic literal type %v", x
.Kind
)
502 case *ast
.CompositeLit
:
506 decl
:= ei
.compileFuncType(a
.block
, x
.Type
)
508 // TODO(austin) Try compiling the body,
509 // perhaps with dummy argument definitions
512 fn
:= ei
.compileFunc(a
.block
, decl
, x
.Body
)
517 a
.diagAt(x
, "function literal used in constant expression")
520 return ei
.compileFuncLit(decl
, fn
)
524 // TODO(austin) Use a multi-type case
536 case *ast
.InterfaceType
:
542 // Remaining expressions
544 // Error already reported by parser
548 case *ast
.BinaryExpr
:
549 l
, r
:= a
.compile(x
.X
, false), a
.compile(x
.Y
, false)
550 if l
== nil || r
== nil {
553 return ei
.compileBinaryExpr(x
.Op
, l
, r
)
556 l
:= a
.compile(x
.Fun
, true)
557 args
:= make([]*expr
, len(x
.Args
))
559 for i
, arg
:= range x
.Args
{
560 if i
== 0 && l
!= nil && (l
.t
== Type(makeType
) || l
.t
== Type(newType
)) {
561 argei
:= &exprInfo
{a
.compiler
, arg
.Pos()}
562 args
[i
] = argei
.exprFromType(a
.compileType(a
.block
, arg
))
564 args
[i
] = a
.compile(arg
, false)
574 a
.diagAt(x
, "function call in constant context")
578 if l
.valType
!= nil {
579 a
.diagAt(x
, "type conversions not implemented")
581 } else if ft
, ok
:= l
.t
.(*FuncType
); ok
&& ft
.builtin
!= "" {
582 return ei
.compileBuiltinCallExpr(a
.block
, ft
, args
)
584 return ei
.compileCallExpr(a
.block
, l
, args
)
588 return ei
.compileIdent(a
.block
, a
.constant
, callCtx
, x
.Name
)
591 l
, r
:= a
.compile(x
.X
, false), a
.compile(x
.Index
, false)
592 if l
== nil || r
== nil {
595 return ei
.compileIndexExpr(l
, r
)
599 arr
:= a
.compile(x
.X
, false)
600 lo
:= a
.compile(x
.Index
, false)
602 // End was omitted, so we need to compute len(x.X)
603 ei
:= &exprInfo
{a
.compiler
, x
.Pos()}
604 hi
= ei
.compileBuiltinCallExpr(a
.block
, lenType
, []*expr
{arr
})
606 hi
= a
.compile(x
.End
, false)
608 if arr
== nil || lo
== nil || hi
== nil {
611 return ei
.compileSliceExpr(arr
, lo
, hi
)
613 case *ast
.KeyValueExpr
:
617 return a
.compile(x
.X
, callCtx
)
619 case *ast
.SelectorExpr
:
620 v
:= a
.compile(x
.X
, false)
624 return ei
.compileSelectorExpr(v
, x
.Sel
.Name
)
627 // We pass down our call context because this could be
628 // a pointer type (and thus a type conversion)
629 v
:= a
.compile(x
.X
, callCtx
)
633 if v
.valType
!= nil {
634 // Turns out this was a pointer type, not a dereference
635 return ei
.exprFromType(NewPtrType(v
.valType
))
637 return ei
.compileStarExpr(v
)
639 case *ast
.StructType
:
642 case *ast
.TypeAssertExpr
:
646 v
:= a
.compile(x
.X
, false)
650 return ei
.compileUnaryExpr(x
.Op
, v
)
652 log
.Panicf("unexpected ast node type %T", x
)
657 a
.diagAt(x
, "type used as expression")
660 return ei
.exprFromType(a
.compileType(a
.block
, x
))
663 a
.diagAt(x
, "%T expression node not implemented", x
)
667 func (a
*exprInfo
) exprFromType(t Type
) *expr
{
671 expr
:= a
.newExpr(nil, "type")
676 func (a
*exprInfo
) compileIdent(b
*block
, constant
bool, callCtx
bool, name
string) *expr
{
677 bl
, level
, def
:= b
.Lookup(name
)
679 a
.diag("%s: undefined", name
)
682 switch def
:= def
.(type) {
684 expr
:= a
.newExpr(def
.Type
, "constant")
685 if ft
, ok
:= def
.Type
.(*FuncType
); ok
&& ft
.builtin
!= "" {
686 // XXX(Spec) I don't think anything says that
687 // built-in functions can't be used as values.
689 a
.diag("built-in function %s cannot be used as a value", ft
.builtin
)
692 // Otherwise, we leave the evaluators empty
693 // because this is handled specially
695 expr
.genConstant(def
.Value
)
700 a
.diag("variable %s used in constant expression", name
)
704 return a
.compileGlobalVariable(def
)
706 return a
.compileVariable(level
, def
)
709 return a
.exprFromType(def
)
711 a
.diag("type %v used as expression", name
)
714 log
.Panicf("name %s has unknown type %T", name
, def
)
718 func (a
*exprInfo
) compileVariable(level
int, v
*Variable
) *expr
{
720 // Placeholder definition from an earlier error
724 expr
:= a
.newExpr(v
.Type
, "variable")
725 expr
.genIdentOp(level
, v
.Index
)
729 func (a
*exprInfo
) compileGlobalVariable(v
*Variable
) *expr
{
731 // Placeholder definition from an earlier error
736 v
.Init
= v
.Type
.Zero()
738 expr
:= a
.newExpr(v
.Type
, "variable")
740 expr
.genValue(func(t
*Thread
) Value
{ return val
})
744 func (a
*exprInfo
) compileIdealInt(i
*big
.Int
, desc
string) *expr
{
745 expr
:= a
.newExpr(IdealIntType
, desc
)
746 expr
.eval
= func() *big
.Int
{ return i
}
750 func (a
*exprInfo
) compileIntLit(lit
string) *expr
{
751 i
, _
:= new(big
.Int
).SetString(lit
, 0)
752 return a
.compileIdealInt(i
, "integer literal")
755 func (a
*exprInfo
) compileCharLit(lit
string) *expr
{
761 v
, _
, tail
, err
:= strconv
.UnquoteChar(lit
[1:], '\'')
762 if err
!= nil || tail
!= "'" {
767 return a
.compileIdealInt(big
.NewInt(int64(v
)), "character literal")
770 func (a
*exprInfo
) compileFloatLit(lit
string) *expr
{
771 f
, ok
:= new(big
.Rat
).SetString(lit
)
773 log
.Panicf("malformed float literal %s at %v passed parser", lit
, a
.pos
)
775 expr
:= a
.newExpr(IdealFloatType
, "float literal")
776 expr
.eval
= func() *big
.Rat
{ return f
}
780 func (a
*exprInfo
) compileString(s
string) *expr
{
781 // Ideal strings don't have a named type but they are
782 // compatible with type string.
784 // TODO(austin) Use unnamed string type.
785 expr
:= a
.newExpr(StringType
, "string literal")
786 expr
.eval
= func(*Thread
) string { return s
}
790 func (a
*exprInfo
) compileStringLit(lit
string) *expr
{
791 s
, err
:= strconv
.Unquote(lit
)
793 a
.diag("illegal string literal, %v", err
)
796 return a
.compileString(s
)
799 func (a
*exprInfo
) compileStringList(list
[]*expr
) *expr
{
800 ss
:= make([]string, len(list
))
801 for i
, s
:= range list
{
802 ss
[i
] = s
.asString()(nil)
804 return a
.compileString(strings
.Join(ss
, ""))
807 func (a
*exprInfo
) compileFuncLit(decl
*FuncDecl
, fn
func(*Thread
) Func
) *expr
{
808 expr
:= a
.newExpr(decl
.Type
, "function literal")
813 func (a
*exprInfo
) compileSelectorExpr(v
*expr
, name
string) *expr
{
814 // mark marks a field that matches the selector name. It
815 // tracks the best depth found so far and whether more than
816 // one field has been found at that depth.
820 mark
:= func(depth
int, pathName
string) {
822 case bestDepth
== -1 || depth
< bestDepth
:
827 case depth
== bestDepth
:
831 log
.Panicf("Marked field at depth %d, but already found one at depth %d", depth
, bestDepth
)
833 amberr
+= "\n\t" + pathName
[1:]
836 visited
:= make(map[Type
]bool)
838 // find recursively searches for the named field, starting at
839 // type t. If it finds the named field, it returns a function
840 // which takes an expr that represents a value of type 't' and
841 // returns an expr that retrieves the named field. We delay
842 // expr construction to avoid producing lots of useless expr's
845 // TODO(austin) Now that the expression compiler works on
846 // semantic values instead of AST's, there should be a much
847 // better way of doing this.
848 var find
func(Type
, int, string) func(*expr
) *expr
849 find
= func(t Type
, depth
int, pathName
string) func(*expr
) *expr
{
850 // Don't bother looking if we've found something shallower
851 if bestDepth
!= -1 && bestDepth
< depth
{
855 // Don't check the same type twice and avoid loops
861 // Implicit dereference
863 if ti
, ok
:= t
.(*PtrType
); ok
{
868 // If it's a named type, look for methods
869 if ti
, ok
:= t
.(*NamedType
); ok
{
870 _
, ok
:= ti
.methods
[name
]
872 mark(depth
, pathName
+"."+name
)
873 log
.Panic("Methods not implemented")
878 // If it's a struct type, check fields and embedded types
879 var builder
func(*expr
) *expr
880 if t
, ok
:= t
.(*StructType
); ok
{
881 for i
, f
:= range t
.Elems
{
882 var sub
func(*expr
) *expr
885 mark(depth
, pathName
+"."+name
)
886 sub
= func(e
*expr
) *expr
{ return e
}
889 sub
= find(f
.Type
, depth
+1, pathName
+"."+f
.Name
)
898 // We found something. Create a
899 // builder for accessing this field.
902 builder
= func(parent
*expr
) *expr
{
904 parent
= a
.compileStarExpr(parent
)
906 expr
:= a
.newExpr(ft
, "selector expression")
907 pf
:= parent
.asStruct()
908 evalAddr
:= func(t
*Thread
) Value
{ return pf(t
).Field(t
, index
) }
909 expr
.genValue(evalAddr
)
918 builder
:= find(v
.t
, 0, "")
920 a
.diag("type %v has no field or method %s", v
.t
, name
)
924 a
.diag("field %s is ambiguous in type %v%s", name
, v
.t
, amberr
)
931 func (a
*exprInfo
) compileSliceExpr(arr
, lo
, hi
*expr
) *expr
{
933 arr
= arr
.derefArray()
936 var maxIndex
int64 = -1
938 switch lt
:= arr
.t
.lit().(type) {
940 at
= NewSliceType(lt
.Elem
)
950 a
.diag("cannot slice %v", arr
.t
)
954 // Type check index and convert to int
955 // XXX(Spec) It's unclear if ideal floats with no
956 // fractional part are allowed here. 6g allows it. I
957 // believe that's wrong.
958 lo
= lo
.convertToInt(maxIndex
, "slice", "slice")
959 hi
= hi
.convertToInt(maxIndex
, "slice", "slice")
960 if lo
== nil || hi
== nil {
964 expr
:= a
.newExpr(at
, "slice expression")
969 switch lt
:= arr
.t
.lit().(type) {
971 arrf
:= arr
.asArray()
973 expr
.eval
= func(t
*Thread
) Slice
{
974 arr
, lo
, hi
:= arrf(t
), lof(t
), hif(t
)
975 if lo
> hi || hi
> bound || lo
< 0 {
976 t
.Abort(SliceError
{lo
, hi
, bound
})
978 return Slice
{arr
.Sub(lo
, bound
-lo
), hi
- lo
, bound
- lo
}
982 arrf
:= arr
.asSlice()
983 expr
.eval
= func(t
*Thread
) Slice
{
984 arr
, lo
, hi
:= arrf(t
), lof(t
), hif(t
)
985 if lo
> hi || hi
> arr
.Cap || lo
< 0 {
986 t
.Abort(SliceError
{lo
, hi
, arr
.Cap
})
988 return Slice
{arr
.Base
.Sub(lo
, arr
.Cap
-lo
), hi
- lo
, arr
.Cap
- lo
}
992 arrf
:= arr
.asString()
993 // TODO(austin) This pulls over the whole string in a
994 // remote setting, instead of creating a substring backed
996 expr
.eval
= func(t
*Thread
) string {
997 arr
, lo
, hi
:= arrf(t
), lof(t
), hif(t
)
998 if lo
> hi || hi
> int64(len(arr
)) || lo
< 0 {
999 t
.Abort(SliceError
{lo
, hi
, int64(len(arr
))})
1005 log
.Panicf("unexpected left operand type %T", arr
.t
.lit())
1011 func (a
*exprInfo
) compileIndexExpr(l
, r
*expr
) *expr
{
1012 // Type check object
1017 var maxIndex
int64 = -1
1019 switch lt
:= l
.t
.lit().(type) {
1036 r
= r
.convertTo(lt
.Key
)
1041 if !lt
.Key
.compat(r
.t
, false) {
1042 a
.diag("cannot use %s as index into %s", r
.t
, lt
)
1047 a
.diag("cannot index into %v", l
.t
)
1051 // Type check index and convert to int if necessary
1053 // XXX(Spec) It's unclear if ideal floats with no
1054 // fractional part are allowed here. 6g allows it. I
1055 // believe that's wrong.
1056 r
= r
.convertToInt(maxIndex
, "index", "index")
1062 expr
:= a
.newExpr(at
, "index expression")
1065 switch lt
:= l
.t
.lit().(type) {
1070 expr
.genValue(func(t
*Thread
) Value
{
1071 l
, r
:= lf(t
), rf(t
)
1072 if r
< 0 || r
>= bound
{
1073 t
.Abort(IndexError
{r
, bound
})
1081 expr
.genValue(func(t
*Thread
) Value
{
1082 l
, r
:= lf(t
), rf(t
)
1084 t
.Abort(NilPointerError
{})
1086 if r
< 0 || r
>= l
.Len
{
1087 t
.Abort(IndexError
{r
, l
.Len
})
1089 return l
.Base
.Elem(t
, r
)
1095 // TODO(austin) This pulls over the whole string in a
1096 // remote setting, instead of just the one character.
1097 expr
.eval
= func(t
*Thread
) uint64 {
1098 l
, r
:= lf(t
), rf(t
)
1099 if r
< 0 || r
>= int64(len(l
)) {
1100 t
.Abort(IndexError
{r
, int64(len(l
))})
1107 rf
:= r
.asInterface()
1108 expr
.genValue(func(t
*Thread
) Value
{
1112 t
.Abort(NilPointerError
{})
1116 t
.Abort(KeyError
{k
})
1120 // genValue makes things addressable, but map values
1121 // aren't addressable.
1123 expr
.evalMapValue
= func(t
*Thread
) (Map
, interface{}) {
1124 // TODO(austin) Key check? nil check?
1129 log
.Panicf("unexpected left operand type %T", l
.t
.lit())
1135 func (a
*exprInfo
) compileCallExpr(b
*block
, l
*expr
, as
[]*expr
) *expr
{
1136 // TODO(austin) Variadic functions.
1140 // XXX(Spec) Calling a named function type is okay. I really
1141 // think there needs to be a general discussion of named
1142 // types. A named type creates a new, distinct type, but the
1143 // type of that type is still whatever it's defined to. Thus,
1144 // in "type Foo int", Foo is still an integer type and in
1145 // "type Foo func()", Foo is a function type.
1146 lt
, ok
:= l
.t
.lit().(*FuncType
)
1148 a
.diag("cannot call non-function type %v", l
.t
)
1152 // The arguments must be single-valued expressions assignment
1153 // compatible with the parameters of F.
1155 // XXX(Spec) The spec is wrong. It can also be a single
1156 // multi-valued expression.
1158 assign
:= a
.compileAssign(a
.pos
, b
, NewMultiType(lt
.In
), as
, "function call", "argument")
1171 t
= NewMultiType(lt
.Out
)
1173 expr
:= a
.newExpr(t
, "function call")
1175 // Gather argument and out types to initialize frame variables
1176 vts
:= make([]Type
, nin
+nout
)
1178 copy(vts
[nin
:], lt
.Out
)
1182 call
:= func(t
*Thread
) []Value
{
1184 fr
:= fun
.NewFrame()
1185 for i
, t
:= range vts
{
1186 fr
.Vars
[i
] = t
.Zero()
1188 assign(multiV(fr
.Vars
[0:nin
]), t
)
1193 return fr
.Vars
[nin
: nin
+nout
]
1195 expr
.genFuncCall(call
)
1200 func (a
*exprInfo
) compileBuiltinCallExpr(b
*block
, ft
*FuncType
, as
[]*expr
) *expr
{
1201 checkCount
:= func(min
, max
int) bool {
1203 a
.diag("not enough arguments to %s", ft
.builtin
)
1205 } else if len(as
) > max
{
1206 a
.diag("too many arguments to %s", ft
.builtin
)
1214 if !checkCount(1, 1) {
1217 arg
:= as
[0].derefArray()
1218 expr
:= a
.newExpr(IntType
, "function call")
1219 switch t
:= arg
.t
.lit().(type) {
1221 // TODO(austin) It would be nice if this could
1222 // be a constant int.
1224 expr
.eval
= func(t
*Thread
) int64 { return v
}
1228 expr
.eval
= func(t
*Thread
) int64 { return vf(t
).Cap
}
1233 a
.diag("illegal argument type for cap function\n\t%v", arg
.t
)
1239 if !checkCount(2, 2) {
1245 a
.diag("arguments to built-in function 'copy' must have same type\nsrc: %s\ndst: %s\n", src
.t
, dst
.t
)
1248 if _
, ok
:= src
.t
.lit().(*SliceType
); !ok
{
1249 a
.diag("src argument to 'copy' must be a slice (got: %s)", src
.t
)
1252 if _
, ok
:= dst
.t
.lit().(*SliceType
); !ok
{
1253 a
.diag("dst argument to 'copy' must be a slice (got: %s)", dst
.t
)
1256 expr
:= a
.newExpr(IntType
, "function call")
1257 srcf
:= src
.asSlice()
1258 dstf
:= dst
.asSlice()
1259 expr
.eval
= func(t
*Thread
) int64 {
1260 src
, dst
:= srcf(t
), dstf(t
)
1262 if nelems
> dst
.Len
{
1265 dst
.Base
.Sub(0, nelems
).Assign(t
, src
.Base
.Sub(0, nelems
))
1271 if !checkCount(1, 1) {
1274 arg
:= as
[0].derefArray()
1275 expr
:= a
.newExpr(IntType
, "function call")
1276 switch t
:= arg
.t
.lit().(type) {
1278 vf
:= arg
.asString()
1279 expr
.eval
= func(t
*Thread
) int64 { return int64(len(vf(t
))) }
1282 // TODO(austin) It would be nice if this could
1283 // be a constant int.
1285 expr
.eval
= func(t
*Thread
) int64 { return v
}
1289 expr
.eval
= func(t
*Thread
) int64 { return vf(t
).Len
}
1293 expr
.eval
= func(t
*Thread
) int64 {
1294 // XXX(Spec) What's the len of an
1295 // uninitialized map?
1306 a
.diag("illegal argument type for len function\n\t%v", arg
.t
)
1312 if !checkCount(1, 3) {
1315 // XXX(Spec) What are the types of the
1316 // arguments? Do they have to be ints? 6g
1317 // accepts any integral type.
1318 var lenexpr
, capexpr
*expr
1319 var lenf
, capf
func(*Thread
) int64
1321 lenexpr
= as
[1].convertToInt(-1, "length", "make function")
1325 lenf
= lenexpr
.asInt()
1328 capexpr
= as
[2].convertToInt(-1, "capacity", "make function")
1332 capf
= capexpr
.asInt()
1335 switch t
:= as
[0].valType
.lit().(type) {
1337 // A new, initialized slice value for a given
1338 // element type T is made using the built-in
1339 // function make, which takes a slice type and
1340 // parameters specifying the length and
1341 // optionally the capacity.
1342 if !checkCount(2, 3) {
1346 expr
:= a
.newExpr(t
, "function call")
1347 expr
.eval
= func(t
*Thread
) Slice
{
1349 // XXX(Spec) What if len or cap is
1350 // negative? The runtime panics.
1352 t
.Abort(NegativeLengthError
{l
})
1358 t
.Abort(NegativeCapacityError
{c
})
1360 // XXX(Spec) What happens if
1361 // len > cap? The runtime
1367 base
:= arrayV(make([]Value
, c
))
1368 for i
:= int64(0); i
< c
; i
++ {
1371 return Slice
{&base
, l
, c
}
1376 // A new, empty map value is made using the
1377 // built-in function make, which takes the map
1378 // type and an optional capacity hint as
1380 if !checkCount(1, 2) {
1383 expr
:= a
.newExpr(t
, "function call")
1384 expr
.eval
= func(t
*Thread
) Map
{
1386 return make(evalMap
)
1389 return make(evalMap
, l
)
1396 a
.diag("illegal argument type for make function\n\t%v", as
[0].valType
)
1400 case closeType
, closedType
:
1401 a
.diag("built-in function %s not implemented", ft
.builtin
)
1405 if !checkCount(1, 1) {
1410 expr
:= a
.newExpr(NewPtrType(t
), "new")
1411 expr
.eval
= func(*Thread
) Value
{ return t
.Zero() }
1414 case panicType
, printType
, printlnType
:
1415 evals
:= make([]func(*Thread
) interface{}, len(as
))
1416 for i
, x
:= range as
{
1417 evals
[i
] = x
.asInterface()
1419 spaces
:= ft
== printlnType
1420 newline
:= ft
!= printType
1421 printer
:= func(t
*Thread
) {
1422 for i
, eval
:= range evals
{
1423 if i
> 0 && spaces
{
1427 type stringer
interface {
1430 switch v1
:= v
.(type) {
1451 expr
:= a
.newExpr(EmptyType
, "print")
1453 if ft
== panicType
{
1454 expr
.exec
= func(t
*Thread
) {
1456 t
.Abort(os
.NewError("panic"))
1462 log
.Panicf("unexpected built-in function '%s'", ft
.builtin
)
1463 panic("unreachable")
1466 func (a
*exprInfo
) compileStarExpr(v
*expr
) *expr
{
1467 switch vt
:= v
.t
.lit().(type) {
1469 expr
:= a
.newExpr(vt
.Elem
, "indirect expression")
1471 expr
.genValue(func(t
*Thread
) Value
{
1474 t
.Abort(NilPointerError
{})
1481 a
.diagOpType(token
.MUL
, v
.t
)
1485 var unaryOpDescs
= make(map[token
.Token
]string)
1487 func (a
*exprInfo
) compileUnaryExpr(op token
.Token
, v
*expr
) *expr
{
1491 case token
.ADD
, token
.SUB
:
1492 if !v
.t
.isInteger() && !v
.t
.isFloat() {
1493 a
.diagOpType(op
, v
.t
)
1499 if !v
.t
.isBoolean() {
1500 a
.diagOpType(op
, v
.t
)
1506 if !v
.t
.isInteger() {
1507 a
.diagOpType(op
, v
.t
)
1513 // The unary prefix address-of operator & generates
1514 // the address of its operand, which must be a
1515 // variable, pointer indirection, field selector, or
1516 // array or slice indexing operation.
1517 if v
.evalAddr
== nil {
1518 a
.diag("cannot take the address of %s", v
.desc
)
1522 // TODO(austin) Implement "It is illegal to take the
1523 // address of a function result variable" once I have
1524 // function result variables.
1529 log
.Panicf("Unary op %v not implemented", op
)
1532 log
.Panicf("unknown unary operator %v", op
)
1535 desc
, ok
:= unaryOpDescs
[op
]
1537 desc
= "unary " + op
.String() + " expression"
1538 unaryOpDescs
[op
] = desc
1542 expr
:= a
.newExpr(t
, desc
)
1545 // Just compile it out
1550 expr
.genUnaryOpNeg(v
)
1553 expr
.genUnaryOpNot(v
)
1556 expr
.genUnaryOpXor(v
)
1560 expr
.eval
= func(t
*Thread
) Value
{ return vf(t
) }
1563 log
.Panicf("Compilation of unary op %v not implemented", op
)
1569 var binOpDescs
= make(map[token
.Token
]string)
1571 func (a
*exprInfo
) compileBinaryExpr(op token
.Token
, l
, r
*expr
) *expr
{
1572 // Save the original types of l.t and r.t for error messages.
1576 // XXX(Spec) What is the exact definition of a "named type"?
1578 // XXX(Spec) Arithmetic operators: "Integer types" apparently
1579 // means all types compatible with basic integer types, though
1580 // this is never explained. Likewise for float types, etc.
1581 // This relates to the missing explanation of named types.
1583 // XXX(Spec) Operators: "If both operands are ideal numbers,
1584 // the conversion is to ideal floats if one of the operands is
1585 // an ideal float (relevant for / and %)." How is that
1586 // relevant only for / and %? If I add an ideal int and an
1587 // ideal float, I get an ideal float.
1589 if op
!= token
.SHL
&& op
!= token
.SHR
{
1590 // Except in shift expressions, if one operand has
1591 // numeric type and the other operand is an ideal
1592 // number, the ideal number is converted to match the
1593 // type of the other operand.
1594 if (l
.t
.isInteger() || l
.t
.isFloat()) && !l
.t
.isIdeal() && r
.t
.isIdeal() {
1595 r
= r
.convertTo(l
.t
)
1596 } else if (r
.t
.isInteger() || r
.t
.isFloat()) && !r
.t
.isIdeal() && l
.t
.isIdeal() {
1597 l
= l
.convertTo(r
.t
)
1599 if l
== nil || r
== nil {
1603 // Except in shift expressions, if both operands are
1604 // ideal numbers and one is an ideal float, the other
1605 // is converted to ideal float.
1606 if l
.t
.isIdeal() && r
.t
.isIdeal() {
1607 if l
.t
.isInteger() && r
.t
.isFloat() {
1608 l
= l
.convertTo(r
.t
)
1609 } else if l
.t
.isFloat() && r
.t
.isInteger() {
1610 r
= r
.convertTo(l
.t
)
1612 if l
== nil || r
== nil {
1618 // Useful type predicates
1619 // TODO(austin) CL 33668 mandates identical types except for comparisons.
1620 compat
:= func() bool { return l
.t
.compat(r
.t
, false) }
1621 integers
:= func() bool { return l
.t
.isInteger() && r
.t
.isInteger() }
1622 floats
:= func() bool { return l
.t
.isFloat() && r
.t
.isFloat() }
1623 strings
:= func() bool {
1624 // TODO(austin) Deal with named types
1625 return l
.t
== StringType
&& r
.t
== StringType
1627 booleans
:= func() bool { return l
.t
.isBoolean() && r
.t
.isBoolean() }
1633 if !compat() ||
(!integers() && !floats() && !strings()) {
1634 a
.diagOpTypes(op
, origlt
, origrt
)
1639 case token
.SUB
, token
.MUL
, token
.QUO
:
1640 if !compat() ||
(!integers() && !floats()) {
1641 a
.diagOpTypes(op
, origlt
, origrt
)
1646 case token
.REM
, token
.AND
, token
.OR
, token
.XOR
, token
.AND_NOT
:
1647 if !compat() ||
!integers() {
1648 a
.diagOpTypes(op
, origlt
, origrt
)
1653 case token
.SHL
, token
.SHR
:
1654 // XXX(Spec) Is it okay for the right operand to be an
1655 // ideal float with no fractional part? "The right
1656 // operand in a shift operation must be always be of
1657 // unsigned integer type or an ideal number that can
1658 // be safely converted into an unsigned integer type
1659 // (§Arithmetic operators)" suggests so and 6g agrees.
1661 if !l
.t
.isInteger() ||
!(r
.t
.isInteger() || r
.t
.isIdeal()) {
1662 a
.diagOpTypes(op
, origlt
, origrt
)
1666 // The right operand in a shift operation must be
1667 // always be of unsigned integer type or an ideal
1668 // number that can be safely converted into an
1669 // unsigned integer type.
1671 r2
:= r
.convertTo(UintType
)
1676 // If the left operand is not ideal, convert
1677 // the right to not ideal.
1682 // If both are ideal, but the right side isn't
1683 // an ideal int, convert it to simplify things.
1684 if l
.t
.isIdeal() && !r
.t
.isInteger() {
1685 r
= r
.convertTo(IdealIntType
)
1687 log
.Panicf("conversion to uintType succeeded, but conversion to idealIntType failed")
1690 } else if _
, ok
:= r
.t
.lit().(*uintType
); !ok
{
1691 a
.diag("right operand of shift must be unsigned")
1695 if l
.t
.isIdeal() && !r
.t
.isIdeal() {
1696 // XXX(Spec) What is the meaning of "ideal >>
1697 // non-ideal"? Russ says the ideal should be
1698 // converted to an int. 6g propagates the
1699 // type down from assignments as a hint.
1701 l
= l
.convertTo(IntType
)
1707 // At this point, we should have one of three cases:
1708 // 1) uint SHIFT uint
1709 // 2) int SHIFT uint
1710 // 3) ideal int SHIFT ideal int
1714 case token
.LOR
, token
.LAND
:
1718 // XXX(Spec) There's no mention of *which* boolean
1719 // type the logical operators return. From poking at
1720 // 6g, it appears to be the named boolean type, NOT
1721 // the type of the left operand, and NOT an unnamed
1727 // The operands in channel sends differ in type: one
1728 // is always a channel and the other is a variable or
1729 // value of the channel's element type.
1730 log
.Panic("Binary op <- not implemented")
1733 case token
.LSS
, token
.GTR
, token
.LEQ
, token
.GEQ
:
1734 // XXX(Spec) It's really unclear what types which
1735 // comparison operators apply to. I feel like the
1736 // text is trying to paint a Venn diagram for me,
1737 // which it's really pretty simple: <, <=, >, >= apply
1738 // only to numeric types and strings. == and != apply
1739 // to everything except arrays and structs, and there
1740 // are some restrictions on when it applies to slices.
1742 if !compat() ||
(!integers() && !floats() && !strings()) {
1743 a
.diagOpTypes(op
, origlt
, origrt
)
1748 case token
.EQL
, token
.NEQ
:
1749 // XXX(Spec) The rules for type checking comparison
1750 // operators are spread across three places that all
1751 // partially overlap with each other: the Comparison
1752 // Compatibility section, the Operators section, and
1753 // the Comparison Operators section. The Operators
1754 // section should just say that operators require
1755 // identical types (as it does currently) except that
1756 // there a few special cases for comparison, which are
1757 // described in section X. Currently it includes just
1758 // one of the four special cases. The Comparison
1759 // Compatibility section and the Comparison Operators
1760 // section should either be merged, or at least the
1761 // Comparison Compatibility section should be
1762 // exclusively about type checking and the Comparison
1763 // Operators section should be exclusively about
1766 // XXX(Spec) Comparison operators: "All comparison
1767 // operators apply to basic types except bools." This
1768 // is very difficult to parse. It's explained much
1769 // better in the Comparison Compatibility section.
1771 // XXX(Spec) Comparison compatibility: "Function
1772 // values are equal if they refer to the same
1773 // function." is rather vague. It should probably be
1774 // similar to the way the rule for map values is
1775 // written: Function values are equal if they were
1776 // created by the same execution of a function literal
1777 // or refer to the same function declaration. This is
1778 // *almost* but not quite waht 6g implements. If a
1779 // function literals does not capture any variables,
1780 // then multiple executions of it will result in the
1781 // same closure. Russ says he'll change that.
1783 // TODO(austin) Deal with remaining special cases
1786 a
.diagOpTypes(op
, origlt
, origrt
)
1789 // Arrays and structs may not be compared to anything.
1791 case *ArrayType
, *StructType
:
1792 a
.diagOpTypes(op
, origlt
, origrt
)
1798 log
.Panicf("unknown binary operator %v", op
)
1801 desc
, ok
:= binOpDescs
[op
]
1803 desc
= op
.String() + " expression"
1804 binOpDescs
[op
] = desc
1807 // Check for ideal divide by zero
1809 case token
.QUO
, token
.REM
:
1811 if (r
.t
.isInteger() && r
.asIdealInt()().Sign() == 0) ||
1812 (r
.t
.isFloat() && r
.asIdealFloat()().Sign() == 0) {
1813 a
.diag("divide by zero")
1820 expr
:= a
.newExpr(t
, desc
)
1823 expr
.genBinOpAdd(l
, r
)
1826 expr
.genBinOpSub(l
, r
)
1829 expr
.genBinOpMul(l
, r
)
1832 expr
.genBinOpQuo(l
, r
)
1835 expr
.genBinOpRem(l
, r
)
1838 expr
.genBinOpAnd(l
, r
)
1841 expr
.genBinOpOr(l
, r
)
1844 expr
.genBinOpXor(l
, r
)
1847 expr
.genBinOpAndNot(l
, r
)
1851 lv
:= l
.asIdealInt()()
1852 rv
:= r
.asIdealInt()()
1853 const maxShift
= 99999
1854 if rv
.Cmp(big
.NewInt(maxShift
)) > 0 {
1855 a
.diag("left shift by %v; exceeds implementation limit of %v", rv
, maxShift
)
1859 val
:= new(big
.Int
).Lsh(lv
, uint(rv
.Int64()))
1860 expr
.eval
= func() *big
.Int
{ return val
}
1862 expr
.genBinOpShl(l
, r
)
1867 lv
:= l
.asIdealInt()()
1868 rv
:= r
.asIdealInt()()
1869 val
:= new(big
.Int
).Rsh(lv
, uint(rv
.Int64()))
1870 expr
.eval
= func() *big
.Int
{ return val
}
1872 expr
.genBinOpShr(l
, r
)
1876 expr
.genBinOpLss(l
, r
)
1879 expr
.genBinOpGtr(l
, r
)
1882 expr
.genBinOpLeq(l
, r
)
1885 expr
.genBinOpGeq(l
, r
)
1888 expr
.genBinOpEql(l
, r
)
1891 expr
.genBinOpNeq(l
, r
)
1894 expr
.genBinOpLogAnd(l
, r
)
1897 expr
.genBinOpLogOr(l
, r
)
1900 log
.Panicf("Compilation of binary op %v not implemented", op
)
1906 // TODO(austin) This is a hack to eliminate a circular dependency
1907 // between type.go and expr.go
1908 func (a
*compiler
) compileArrayLen(b
*block
, expr ast
.Expr
) (int64, bool) {
1909 lenExpr
:= a
.compileExpr(b
, true, expr
)
1914 // XXX(Spec) Are ideal floats with no fractional part okay?
1915 if lenExpr
.t
.isIdeal() {
1916 lenExpr
= lenExpr
.convertTo(IntType
)
1922 if !lenExpr
.t
.isInteger() {
1923 a
.diagAt(expr
, "array size must be an integer")
1927 switch lenExpr
.t
.lit().(type) {
1929 return lenExpr
.asInt()(nil), true
1931 return int64(lenExpr
.asUint()(nil)), true
1933 log
.Panicf("unexpected integer type %T", lenExpr
.t
)
1937 func (a
*compiler
) compileExpr(b
*block
, constant
bool, expr ast
.Expr
) *expr
{
1938 ec
:= &exprCompiler
{a
, b
, constant
}
1939 nerr
:= a
.numError()
1940 e
:= ec
.compile(expr
, false)
1941 if e
== nil && nerr
== a
.numError() {
1942 log
.Panicf("expression compilation failed without reporting errors")
1947 // extractEffect separates out any effects that the expression may
1948 // have, returning a function that will perform those effects and a
1949 // new exprCompiler that is guaranteed to be side-effect free. These
1950 // are the moral equivalents of "temp := expr" and "temp" (or "temp :=
1951 // &expr" and "*temp" for addressable exprs). Because this creates a
1952 // temporary variable, the caller should create a temporary block for
1953 // the compilation of this expression and the evaluation of the
1955 func (a
*expr
) extractEffect(b
*block
, errOp
string) (func(*Thread
), *expr
) {
1956 // Create "&a" if a is addressable
1958 if a
.evalAddr
!= nil {
1959 rhs
= a
.compileUnaryExpr(token
.AND
, rhs
)
1963 ac
, ok
:= a
.checkAssign(a
.pos
, []*expr
{rhs
}, errOp
, "")
1967 if len(ac
.rmt
.Elems
) != 1 {
1968 a
.diag("multi-valued expression not allowed in %s", errOp
)
1971 tempType
:= ac
.rmt
.Elems
[0]
1972 if tempType
.isIdeal() {
1973 // It's too bad we have to duplicate this rule.
1975 case tempType
.isInteger():
1977 case tempType
.isFloat():
1978 tempType
= FloatType
1980 log
.Panicf("unexpected ideal type %v", tempType
)
1983 temp
:= b
.DefineTemp(tempType
)
1984 tempIdx
:= temp
.Index
1986 // Create "temp := rhs"
1987 assign
:= ac
.compile(b
, tempType
)
1989 log
.Panicf("compileAssign type check failed")
1992 effect
:= func(t
*Thread
) {
1993 tempVal
:= tempType
.Zero()
1994 t
.f
.Vars
[tempIdx
] = tempVal
1998 // Generate "temp" or "*temp"
1999 getTemp
:= a
.compileVariable(0, temp
)
2000 if a
.evalAddr
== nil {
2001 return effect
, getTemp
2004 deref
:= a
.compileStarExpr(getTemp
)
2008 return effect
, deref