FAQ
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?

--
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.

Search Discussions

  • Ian Lance Taylor at Oct 4, 2013 at 1:33 pm

    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.

    Ian

    --
    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.
  • Florian Weimer at Oct 6, 2013 at 5:55 pm

    * 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.

Related Discussions

Discussion Navigation
viewthread | post
Discussion Overview
groupgolang-nuts @
categoriesgo
postedOct 4, '13 at 12:54p
activeOct 6, '13 at 5:55p
posts3
users2
websitegolang.org

People

Translate

site design / logo © 2022 Grokbase