作者:nagyistg
项目:hm-workspac
// zeroConst returns a new "zero" constant of the specified type,
// which must not be an array or struct type: the zero values of
// aggregates are well-defined but cannot be represented by Const.
//
func zeroConst(t types.Type) *Const {
switch t := t.(type) {
case *types.Basic:
switch {
case t.Info()&types.IsBoolean != 0:
return NewConst(exact.MakeBool(false), t)
case t.Info()&types.IsNumeric != 0:
return NewConst(exact.MakeInt64(0), t)
case t.Info()&types.IsString != 0:
return NewConst(exact.MakeString(""), t)
case t.Kind() == types.UnsafePointer:
fallthrough
case t.Kind() == types.UntypedNil:
return nilConst(t)
default:
panic(fmt.Sprint("zeroConst for unexpected type:", t))
}
case *types.Pointer, *types.Slice, *types.Interface, *types.Chan, *types.Map, *types.Signature:
return nilConst(t)
case *types.Named:
return NewConst(zeroConst(t.Underlying()).Value, t)
case *types.Array, *types.Struct, *types.Tuple:
panic(fmt.Sprint("zeroConst applied to aggregate:", t))
}
panic(fmt.Sprint("zeroConst: unexpected ", t))
}
作者:min4builde
项目:go-operator
// number = int_lit [ "p" int_lit ] .
//
func (p *gcParser) parseNumber() (x operand) {
x.mode = constant
// mantissa
mant := exact.MakeFromLiteral(p.parseInt(), token.INT)
assert(mant != nil)
if p.lit == "p" {
// exponent (base 2)
p.next()
exp, err := strconv.ParseInt(p.parseInt(), 10, 0)
if err != nil {
p.error(err)
}
if exp < 0 {
denom := exact.MakeInt64(1)
denom = exact.Shift(denom, token.SHL, uint(-exp))
x.typ = Typ[UntypedFloat]
x.val = exact.BinaryOp(mant, token.QUO, denom)
return
}
if exp > 0 {
mant = exact.Shift(mant, token.SHL, uint(exp))
}
x.typ = Typ[UntypedFloat]
x.val = mant
return
}
x.typ = Typ[UntypedInt]
x.val = mant
return
}
作者:ufo2294026
项目:two-server-other
// number = int_lit [ "p" int_lit ] .
//
func (p *parser) parseNumber() (typ *types.Basic, val exact.Value) {
// mantissa
mant := exact.MakeFromLiteral(p.parseInt(), token.INT)
if mant == nil {
panic("invalid mantissa")
}
if p.lit == "p" {
// exponent (base 2)
p.next()
exp, err := strconv.ParseInt(p.parseInt(), 10, 0)
if err != nil {
p.error(err)
}
if exp < 0 {
denom := exact.MakeInt64(1)
denom = exact.Shift(denom, token.SHL, uint(-exp))
typ = types.Typ[types.UntypedFloat]
val = exact.BinaryOp(mant, token.QUO, denom)
return
}
if exp > 0 {
mant = exact.Shift(mant, token.SHL, uint(exp))
}
typ = types.Typ[types.UntypedFloat]
val = mant
return
}
typ = types.Typ[types.UntypedInt]
val = mant
return
}
作者:hackrol
项目:daily-progra
func (p *importer) ufloat() exact.Value {
exp := p.int()
x := exact.MakeFromBytes(p.bytes())
switch {
case exp < 0:
d := exact.Shift(exact.MakeInt64(1), token.SHL, uint(-exp))
x = exact.BinaryOp(x, token.QUO, d)
case exp > 0:
x = exact.Shift(x, token.SHL, uint(exp))
}
return x
}
作者:hackrol
项目:daily-progra
func (p *importer) fraction() exact.Value {
sign := p.int()
if sign == 0 {
return exact.MakeInt64(0)
}
x := exact.BinaryOp(p.ufloat(), token.QUO, p.ufloat())
if sign < 0 {
x = exact.UnaryOp(token.SUB, x, 0)
}
return x
}
作者:hackrol
项目:daily-progra
func (p *importer) value() exact.Value {
switch kind := exact.Kind(p.int()); kind {
case falseTag:
return exact.MakeBool(false)
case trueTag:
return exact.MakeBool(true)
case int64Tag:
return exact.MakeInt64(p.int64())
case floatTag:
return p.float()
case fractionTag:
return p.fraction()
case complexTag:
re := p.fraction()
im := p.fraction()
return exact.BinaryOp(re, token.ADD, exact.MakeImag(im))
case stringTag:
return exact.MakeString(p.string())
default:
panic(fmt.Sprintf("unexpected value kind %d", kind))
}
}
作者:nagyistg
项目:hm-workspac
// intConst returns an untyped integer constant that evaluates to i.
func intConst(i int64) *Const {
return NewConst(exact.MakeInt64(i), types.Typ[types.UntypedInt])
}
作者:nvdnkp
项目:gopherj
func (c *funcContext) newInt(i int, t types.Type) *ast.BasicLit {
lit := &ast.BasicLit{Kind: token.INT}
c.p.info.Types[lit] = types.TypeAndValue{Type: t, Value: exact.MakeInt64(int64(i))}
return lit
}
作者:samuelyao31
项目:myg
//.........这里部分代码省略.........
// A package scope may contain non-exported objects,
// do not import them!
if obj.Exported() {
check.declare(fileScope, nil, obj)
check.recordImplicit(s, obj)
}
}
// add position to set of dot-import positions for this file
// (this is only needed for "imported but not used" errors)
posSet := check.dotImports[fileNo]
if posSet == nil {
posSet = make(map[*Package]token.Pos)
check.dotImports[fileNo] = posSet
}
posSet[imp] = s.Pos()
} else {
// declare imported package object in file scope
check.declare(fileScope, nil, obj)
}
case *ast.ValueSpec:
switch d.Tok {
case token.CONST:
// determine which initialization expressions to use
switch {
case s.Type != nil || len(s.Values) > 0:
last = s
case last == nil:
last = new(ast.ValueSpec) // make sure last exists
}
// declare all constants
for i, name := range s.Names {
obj := NewConst(name.Pos(), pkg, name.Name, nil, exact.MakeInt64(int64(iota)))
var init ast.Expr
if i < len(last.Values) {
init = last.Values[i]
}
d := &declInfo{file: fileScope, typ: last.Type, init: init}
check.declarePkgObj(name, obj, d)
}
check.arityMatch(s, last)
case token.VAR:
lhs := make([]*Var, len(s.Names))
// If there's exactly one rhs initializer, use
// the same declInfo d1 for all lhs variables
// so that each lhs variable depends on the same
// rhs initializer (n:1 var declaration).
var d1 *declInfo
if len(s.Values) == 1 {
// The lhs elements are only set up after the for loop below,
// but that's ok because declareVar only collects the declInfo
// for a later phase.
d1 = &declInfo{file: fileScope, lhs: lhs, typ: s.Type, init: s.Values[0]}
}
// declare all variables
for i, name := range s.Names {
obj := NewVar(name.Pos(), pkg, name.Name, nil)
lhs[i] = obj
d := d1
作者:pombredann
项目:gopherj
//.........这里部分代码省略.........
lhs = removeParens(lhs)
if !isBlank(lhs) {
out += " " + c.translateAssign(lhs, fmt.Sprintf("%s[%d]", tupleVar, i))
}
}
c.Printf("%s", out)
default:
panic("Invalid arity of AssignStmt.")
}
case *ast.IncDecStmt:
t := c.p.info.Types[s.X].Type
if iExpr, isIExpr := s.X.(*ast.IndexExpr); isIExpr {
switch u := c.p.info.Types[iExpr.X].Type.Underlying().(type) {
case *types.Array:
t = u.Elem()
case *types.Slice:
t = u.Elem()
case *types.Map:
t = u.Elem()
}
}
tok := token.ADD_ASSIGN
if s.Tok == token.DEC {
tok = token.SUB_ASSIGN
}
one := &ast.BasicLit{
Kind: token.INT,
Value: "1",
}
c.p.info.Types[one] = types.TypeAndValue{Type: t, Value: exact.MakeInt64(1)}
c.translateStmt(&ast.AssignStmt{
Lhs: []ast.Expr{s.X},
Tok: tok,
Rhs: []ast.Expr{one},
}, label)
case *ast.ExprStmt:
c.printLabel(label)
c.Printf("%s;", c.translateExpr(s.X).String())
case *ast.DeclStmt:
c.printLabel(label)
decl := s.Decl.(*ast.GenDecl)
switch decl.Tok {
case token.VAR:
for _, spec := range s.Decl.(*ast.GenDecl).Specs {
valueSpec := spec.(*ast.ValueSpec)
lhs := make([]ast.Expr, len(valueSpec.Names))
for i, name := range valueSpec.Names {
lhs[i] = name
}
rhs := valueSpec.Values
isTuple := false
if len(rhs) == 1 {
_, isTuple = c.p.info.Types[rhs[0]].Type.(*types.Tuple)
}
for len(rhs) < len(lhs) && !isTuple {
rhs = append(rhs, nil)
}
c.translateStmt(&ast.AssignStmt{
Lhs: lhs,
Tok: token.DEFINE,
作者:nagyistg
项目:hm-workspac
// builtin typechecks a call to a built-in and returns the result via x.
// If the call has type errors, the returned x is marked as invalid.
//
func (check *checker) builtin(x *operand, call *ast.CallExpr, id builtinId) {
args := call.Args
// declare before goto's
var arg0 ast.Expr // first argument, if present
// check argument count
n := len(args)
msg := ""
bin := predeclaredFuncs[id]
if n < bin.nargs {
msg = "not enough"
} else if !bin.variadic && n > bin.nargs {
msg = "too many"
}
if msg != "" {
check.invalidOp(call.Pos(), msg+" arguments for %s (expected %d, found %d)", call, bin.nargs, n)
goto Error
}
// common case: evaluate first argument if present;
// if it is an expression, x has the expression value
if n > 0 {
arg0 = args[0]
switch id {
case _Make, _New, _Print, _Println, _Offsetof, _Trace:
// respective cases below do the work
default:
// argument must be an expression
check.expr(x, arg0)
if x.mode == invalid {
goto Error
}
}
}
switch id {
case _Append:
if _, ok := x.typ.Underlying().(*Slice); !ok {
check.invalidArg(x.pos(), "%s is not a typed slice", x)
goto Error
}
resultTyp := x.typ
for _, arg := range args[1:] {
check.expr(x, arg)
if x.mode == invalid {
goto Error
}
// TODO(gri) check assignability
}
x.mode = value
x.typ = resultTyp
case _Cap, _Len:
mode := invalid
var val exact.Value
switch typ := implicitArrayDeref(x.typ.Underlying()).(type) {
case *Basic:
if isString(typ) && id == _Len {
if x.mode == constant {
mode = constant
val = exact.MakeInt64(int64(len(exact.StringVal(x.val))))
} else {
mode = value
}
}
case *Array:
mode = value
// spec: "The expressions len(s) and cap(s) are constants
// if the type of s is an array or pointer to an array and
// the expression s does not contain channel receives or
// function calls; in this case s is not evaluated."
if !check.containsCallsOrReceives(arg0) {
mode = constant
val = exact.MakeInt64(typ.len)
}
case *Slice, *Chan:
mode = value
case *Map:
if id == _Len {
mode = value
}
}
if mode == invalid {
check.invalidArg(x.pos(), "%s for %s", x, bin.name)
goto Error
}
x.mode = mode
x.typ = Typ[Int]
x.val = val
case _Close:
ch, ok := x.typ.Underlying().(*Chan)
//.........这里部分代码省略.........
作者:nagyistg
项目:hm-workspac
//.........这里部分代码省略.........
if obj.IsExported() {
// Note: This will change each imported object's scope!
// May be an issue for type aliases.
check.declareObj(fileScope, nil, obj)
check.recordImplicit(s, obj)
}
}
// add position to set of dot-import positions for this file
// (this is only needed for "imported but not used" errors)
posSet := dotImports[len(dotImports)-1]
if posSet == nil {
posSet = make(map[*Package]token.Pos)
dotImports[len(dotImports)-1] = posSet
}
posSet[imp] = s.Pos()
} else {
// declare imported package object in file scope
check.declareObj(fileScope, nil, obj)
}
case *ast.ValueSpec:
switch d.Tok {
case token.CONST:
// determine which initialization expressions to use
switch {
case s.Type != nil || len(s.Values) > 0:
last = s
case last == nil:
last = new(ast.ValueSpec) // make sure last exists
}
// declare all constants
for i, name := range s.Names {
obj := NewConst(name.Pos(), pkg, name.Name, nil, exact.MakeInt64(int64(iota)))
var init ast.Expr
if i < len(last.Values) {
init = last.Values[i]
}
declare(name, obj, last.Type, init)
}
check.arityMatch(s, last)
case token.VAR:
// declare all variables
lhs := make([]*Var, len(s.Names))
for i, name := range s.Names {
obj := NewVar(name.Pos(), pkg, name.Name, nil)
lhs[i] = obj
var init ast.Expr
switch len(s.Values) {
case len(s.Names):
// lhs and rhs match
init = s.Values[i]
case 1:
// rhs must be a multi-valued expression
// (lhs may not be fully set up yet, but
// that's fine because declare simply collects
// the information for later processing.)
init = &multiExpr{lhs, s.Values, nil}
default:
if i < len(s.Values) {
init = s.Values[i]
作者:min4builde
项目:go-operator
// ConstDecl = "const" ExportedName [ Type ] "=" Literal .
// Literal = bool_lit | int_lit | float_lit | complex_lit | rune_lit | string_lit .
// bool_lit = "true" | "false" .
// complex_lit = "(" float_lit "+" float_lit "i" ")" .
// rune_lit = "(" int_lit "+" int_lit ")" .
// string_lit = `"` { unicode_char } `"` .
//
func (p *gcParser) parseConstDecl() {
p.expectKeyword("const")
pkg, name := p.parseExportedName()
obj := declConst(pkg, name)
var x operand
if p.tok != '=' {
obj.typ = p.parseType()
}
p.expect('=')
switch p.tok {
case scanner.Ident:
// bool_lit
if p.lit != "true" && p.lit != "false" {
p.error("expected true or false")
}
x.typ = Typ[UntypedBool]
x.val = exact.MakeBool(p.lit == "true")
p.next()
case '-', scanner.Int:
// int_lit
x = p.parseNumber()
case '(':
// complex_lit or rune_lit
p.next()
if p.tok == scanner.Char {
p.next()
p.expect('+')
x = p.parseNumber()
x.typ = Typ[UntypedRune]
p.expect(')')
break
}
re := p.parseNumber()
p.expect('+')
im := p.parseNumber()
p.expectKeyword("i")
p.expect(')')
x.typ = Typ[UntypedComplex]
// TODO(gri) fix this
_, _ = re, im
x.val = exact.MakeInt64(0)
case scanner.Char:
// rune_lit
x.setConst(token.CHAR, p.lit)
p.next()
case scanner.String:
// string_lit
x.setConst(token.STRING, p.lit)
p.next()
default:
p.errorf("expected literal got %s", scanner.TokenString(p.tok))
}
if obj.typ == nil {
obj.typ = x.typ
}
assert(x.val != nil)
obj.val = x.val
}
作者:4hono
项目:obd
// intConst returns an 'int' constant that evaluates to i.
// (i is an int64 in case the host is narrower than the target.)
func intConst(i int64) *Const {
return NewConst(exact.MakeInt64(i), tInt)
}
作者:postfi
项目:GoProxyHun
func (check *Checker) declStmt(decl ast.Decl) {
pkg := check.pkg
switch d := decl.(type) {
case *ast.BadDecl:
// ignore
case *ast.GenDecl:
var last *ast.ValueSpec // last ValueSpec with type or init exprs seen
for iota, spec := range d.Specs {
switch s := spec.(type) {
case *ast.ValueSpec:
switch d.Tok {
case token.CONST:
// determine which init exprs to use
switch {
case s.Type != nil || len(s.Values) > 0:
last = s
case last == nil:
last = new(ast.ValueSpec) // make sure last exists
}
// declare all constants
lhs := make([]*Const, len(s.Names))
for i, name := range s.Names {
obj := NewConst(name.Pos(), pkg, name.Name, nil, exact.MakeInt64(int64(iota)))
lhs[i] = obj
var init ast.Expr
if i < len(last.Values) {
init = last.Values[i]
}
check.constDecl(obj, last.Type, init)
}
check.arityMatch(s, last)
for i, name := range s.Names {
check.declare(check.scope, name, lhs[i])
}
case token.VAR:
lhs0 := make([]*Var, len(s.Names))
for i, name := range s.Names {
lhs0[i] = NewVar(name.Pos(), pkg, name.Name, nil)
}
// initialize all variables
for i, obj := range lhs0 {
var lhs []*Var
var init ast.Expr
switch len(s.Values) {
case len(s.Names):
// lhs and rhs match
init = s.Values[i]
case 1:
// rhs is expected to be a multi-valued expression
lhs = lhs0
init = s.Values[0]
default:
if i < len(s.Values) {
init = s.Values[i]
}
}
check.varDecl(obj, lhs, s.Type, init)
if len(s.Values) == 1 {
// If we have a single lhs variable we are done either way.
// If we have a single rhs expression, it must be a multi-
// valued expression, in which case handling the first lhs
// variable will cause all lhs variables to have a type
// assigned, and we are done as well.
if debug {
for _, obj := range lhs0 {
assert(obj.typ != nil)
}
}
break
}
}
check.arityMatch(s, nil)
// declare all variables
// (only at this point are the variable scopes (parents) set)
for i, name := range s.Names {
check.declare(check.scope, name, lhs0[i])
}
default:
check.invalidAST(s.Pos(), "invalid token %s", d.Tok)
}
case *ast.TypeSpec:
obj := NewTypeName(s.Name.Pos(), pkg, s.Name.Name, nil)
check.declare(check.scope, s.Name, obj)
check.typeDecl(obj, s.Type, nil, nil)
default:
check.invalidAST(s.Pos(), "const, type, or var declaration expected")
//.........这里部分代码省略.........
作者:postfi
项目:GoProxyHun
//.........这里部分代码省略.........
// fallthrough
}
// check general case by creating custom signature
sig := makeSig(S, S, NewSlice(T)) // []T required for variadic signature
sig.variadic = true
check.arguments(x, call, sig, func(x *operand, i int) {
// only evaluate arguments that have not been evaluated before
if i < len(alist) {
*x = alist[i]
return
}
arg(x, i)
}, nargs)
// ok to continue even if check.arguments reported errors
x.mode = value
x.typ = S
if check.Types != nil {
check.recordBuiltinType(call.Fun, sig)
}
case _Cap, _Len:
// cap(x)
// len(x)
mode := invalid
var typ Type
var val exact.Value
switch typ = implicitArrayDeref(x.typ.Underlying()); t := typ.(type) {
case *Basic:
if isString(t) && id == _Len {
if x.mode == constant {
mode = constant
val = exact.MakeInt64(int64(len(exact.StringVal(x.val))))
} else {
mode = value
}
}
case *Array:
mode = value
// spec: "The expressions len(s) and cap(s) are constants
// if the type of s is an array or pointer to an array and
// the expression s does not contain channel receives or
// function calls; in this case s is not evaluated."
if !check.hasCallOrRecv {
mode = constant
val = exact.MakeInt64(t.len)
}
case *Slice, *Chan:
mode = value
case *Map:
if id == _Len {
mode = value
}
}
if mode == invalid {
check.invalidArg(x.pos(), "%s for %s", x, bin.name)
return
}
x.mode = mode
x.typ = Typ[Int]
作者:amulya
项目:bosh-cloudstack-cp
res := NewVar(token.NoPos, nil, "", Typ[String])
sig := &Signature{results: NewTuple(res)}
err := NewFunc(token.NoPos, nil, "Error", sig)
typ := &Named{underlying: NewInterface([]*Func{err}, nil), complete: true}
sig.recv = NewVar(token.NoPos, nil, "", typ)
def(NewTypeName(token.NoPos, nil, "error", typ))
}
var predeclaredConsts = [...]struct {
name string
kind BasicKind
val exact.Value
}{
{"true", UntypedBool, exact.MakeBool(true)},
{"false", UntypedBool, exact.MakeBool(false)},
{"iota", UntypedInt, exact.MakeInt64(0)},
}
func defPredeclaredConsts() {
for _, c := range predeclaredConsts {
def(NewConst(token.NoPos, nil, c.name, Typ[c.kind], c.val))
}
}
func defPredeclaredNil() {
def(&Nil{object{name: "nil", typ: Typ[UntypedNil]}})
}
// A builtinId is the id of a builtin function.
type builtinId int
作者:pombredann
项目:go.tool
// intLiteral returns an untyped integer literal that evaluates to i.
func intLiteral(i int64) *Literal {
return newLiteral(exact.MakeInt64(i), types.Typ[types.UntypedInt])
}
作者:nagyistg
项目:hm-workspac
func (check *checker) declStmt(decl ast.Decl) {
pkg := check.pkg
switch d := decl.(type) {
case *ast.BadDecl:
// ignore
case *ast.GenDecl:
var last *ast.ValueSpec // last ValueSpec with type or init exprs seen
for iota, spec := range d.Specs {
switch s := spec.(type) {
case *ast.ValueSpec:
switch d.Tok {
case token.CONST:
// determine which init exprs to use
switch {
case s.Type != nil || len(s.Values) > 0:
last = s
case last == nil:
last = new(ast.ValueSpec) // make sure last exists
}
// declare all constants
lhs := make([]*Const, len(s.Names))
for i, name := range s.Names {
obj := NewConst(name.Pos(), pkg, name.Name, nil, exact.MakeInt64(int64(iota)))
lhs[i] = obj
var init ast.Expr
if i < len(last.Values) {
init = last.Values[i]
}
check.constDecl(obj, last.Type, init)
}
check.arityMatch(s, last)
for i, name := range s.Names {
check.declareObj(check.topScope, name, lhs[i])
}
case token.VAR:
// For varDecl called with a multiExpr we need the fully
// initialized lhs. Compute it in a separate pre-pass.
lhs := make([]*Var, len(s.Names))
for i, name := range s.Names {
lhs[i] = NewVar(name.Pos(), pkg, name.Name, nil)
}
// declare all variables
for i, obj := range lhs {
var init ast.Expr
switch len(s.Values) {
case len(s.Names):
// lhs and rhs match
init = s.Values[i]
case 1:
// rhs is expected to be a multi-valued expression
init = &multiExpr{lhs, s.Values, nil}
default:
if i < len(s.Values) {
init = s.Values[i]
}
}
check.varDecl(obj, s.Type, init)
}
check.arityMatch(s, nil)
for i, name := range s.Names {
check.declareObj(check.topScope, name, lhs[i])
}
default:
check.invalidAST(s.Pos(), "invalid token %s", d.Tok)
}
case *ast.TypeSpec:
obj := NewTypeName(s.Name.Pos(), pkg, s.Name.Name, nil)
check.declareObj(check.topScope, s.Name, obj)
check.typeDecl(obj, s.Type, nil, false)
default:
check.invalidAST(s.Pos(), "const, type, or var declaration expected")
}
}
default:
check.invalidAST(d.Pos(), "unknown ast.Decl node %T", d)
}
}
作者:umisam
项目:gopherj
//.........这里部分代码省略.........
parts = append(parts, c.translateAssign(lhs, c.translateExpr(binaryExpr)))
return strings.Join(parts, ", ")
}
if s.Tok == token.DEFINE {
for _, lhs := range s.Lhs {
if !isBlank(lhs) {
c.info.Types[lhs] = c.info.Objects[lhs.(*ast.Ident)].Type()
}
}
}
switch {
case len(s.Lhs) == 1 && len(s.Rhs) == 1:
return c.translateAssign(s.Lhs[0], c.translateExprToType(s.Rhs[0], c.info.Types[s.Lhs[0]]))
case len(s.Lhs) > 1 && len(s.Rhs) == 1:
out := "Go$tuple = " + c.translateExpr(s.Rhs[0])
tuple := c.info.Types[s.Rhs[0]].(*types.Tuple)
for i, lhs := range s.Lhs {
if !isBlank(lhs) {
out += ", " + c.translateAssign(lhs, c.translateExprToType(c.newIdent(fmt.Sprintf("Go$tuple[%d]", i), tuple.At(i).Type()), c.info.Types[s.Lhs[i]]))
}
}
return out
case len(s.Lhs) == len(s.Rhs):
parts := make([]string, len(s.Rhs))
for i, rhs := range s.Rhs {
parts[i] = c.translateExprToType(rhs, c.info.Types[s.Lhs[i]])
}
out := "Go$tuple = [" + strings.Join(parts, ", ") + "]"
for i, lhs := range s.Lhs {
if !isBlank(lhs) {
out += ", " + c.translateAssign(lhs, fmt.Sprintf("Go$tuple[%d]", i))
}
}
return out
default:
panic("Invalid arity of AssignStmt.")
}
case *ast.IncDecStmt:
t := c.info.Types[s.X]
if iExpr, isIExpr := s.X.(*ast.IndexExpr); isIExpr {
switch u := c.info.Types[iExpr.X].Underlying().(type) {
case *types.Array:
t = u.Elem()
case *types.Slice:
t = u.Elem()
case *types.Map:
t = u.Elem()
}
}
tok := token.ADD_ASSIGN
if s.Tok == token.DEC {
tok = token.SUB_ASSIGN
}
one := &ast.BasicLit{
Kind: token.INT,
Value: "1",
}
c.info.Types[one] = t
c.info.Values[one] = exact.MakeInt64(1)
return c.translateSimpleStmt(&ast.AssignStmt{
Lhs: []ast.Expr{s.X},
Tok: tok,
Rhs: []ast.Expr{one},
})
case *ast.ExprStmt:
return c.translateExpr(s.X)
case *ast.DeclStmt:
var parts []string
for _, spec := range s.Decl.(*ast.GenDecl).Specs {
for _, singleSpec := range c.splitValueSpec(spec.(*ast.ValueSpec)) {
lhs := make([]ast.Expr, len(singleSpec.Names))
for i, name := range singleSpec.Names {
lhs[i] = name
}
parts = append(parts, c.translateSimpleStmt(&ast.AssignStmt{
Lhs: lhs,
Tok: token.DEFINE,
Rhs: singleSpec.Values,
}))
}
}
return strings.Join(parts, ", ")
case *ast.SendStmt:
return `throw new Go$Panic("Statement not supported: send")`
default:
panic(fmt.Sprintf("Unhandled statement: %T\n", s))
}
}