* Ian Lance Taylor:
On Fri, Oct 4, 2013 at 5:53 AM, Florian Weimer wrote:
Is code.google.com/p/go.tools/go/types still the place to go for if I
want an AST annotated with types? How complete is the implementation?
Yes. Very.
Thanks. It turns out that Go is slightly more complex than expected,
but I got some useful data for my exhaustiveness checker.
But it turns out that the encoding is somewhat verbose. The following
description in Zephyr ASDL syntax
stm = Compound(stm,stm)
Assign(identifier,exp)
Print(exp_list)
exp_list = ExpList(exp,exp_list) | Nil
exp = Id(identifier)
Num(int)
Op(exp,binop,exp)
binop = Plus | Minus | Times | Div
turns into quite a bit of Go code (see below). Switching over these
emulation variant types is quite compact, though:
func (ctx *Context) Eval(exp Exp) (*big.Int, error) {
switch exp := exp.(type) {
case Id:
if val, ok := ctx.Vars[exp.Identifier]; ok {
return val, nil
} else {
return nil, errors.New(
"undefined variable " + string(exp.Identifier))
}
case Num:
return exp.Int, nil
case Op:
left, err := ctx.Eval(exp.Left)
if err != nil {
return nil, err
}
right, err := ctx.Eval(exp.Right)
if err != nil {
return nil, err
}
var result big.Int
switch exp.Binop.(type) {
case Plus:
result.Add(left, right)
case Minus:
result.Sub(left, right)
case Times:
result.Mul(left, right)
case Div:
result.Div(left, right)
}
return &result, nil
}
panic("invalid exp")
}
The Go translation of the ASDL snippet follows. This could probably
generated automatically from the ASDL syntax.
package figure3
type Stm interface {
stm_tag()
}
type stm_base struct {}
func (stm_base) stm_tag() {}
type Compound struct {
stm_base
First Stm
Second Stm
}
type Assign struct {
stm_base
Identifier Identifier
Exp Exp
}
type Print struct {
stm_base
Exp_list Exp_list
}
type Exp_list interface {
exp_list_tag()
}
// Alternative tag encoding. Allows omitting the field names in
// literals.
type ExpList struct {
Exp Exp
Exp_list Exp_list
}
func (ExpList) exp_list_tag() {}
type Nil struct {}
func (Nil) exp_list_tag() {}
type Exp interface {
exp_tag()
}
type exp_base struct {}
func (exp_base) exp_tag() {}
type Id struct {Identifier Identifier}
func (Id) exp_tag() {}
type Num struct {Int Int}
func (Num) exp_tag() {}
type Op struct {
exp_base
Left Exp
Binop Binop
Right Exp
}
type Binop interface {
binop_tag()
}
type binop_base struct {}
func (binop_base) binop_tag() {}
type Plus struct {binop_base}
type Minus struct {binop_base}
type Times struct {binop_base}
type Div struct {binop_base}
--
You received this message because you are subscribed to the Google Groups "golang-nuts" group.
To unsubscribe from this group and stop receiving emails from it, send an email to golang-nuts+unsubscribe@googlegroups.com.
For more options, visit
https://groups.google.com/groups/opt_out.