Skip to content

Instantly share code, notes, and snippets.

@tenntenn
Last active May 15, 2017 11:05
Show Gist options
  • Save tenntenn/45642f26062ded03d633c8e186950a66 to your computer and use it in GitHub Desktop.
Save tenntenn/45642f26062ded03d633c8e186950a66 to your computer and use it in GitHub Desktop.
Goの抽象構文木(AST)を手入力してHello, Worldを作る #golang ref: http://qiita.com/tenntenn/items/0cbc6f1f00dc579fcd8c
package main
import "fmt"
func main() {
fmt.Println("Hello, 世界")
}
type File struct {
Doc *CommentGroup // associated documentation; or nil
Package token.Pos // position of "package" keyword
Name *Ident // package name
Decls []Decl // top-level declarations; or nil
Scope *Scope // package scope (this file only)
Imports []*ImportSpec // imports in this file
Unresolved []*Ident // unresolved identifiers in this file
Comments []*CommentGroup // list of all comments in the source file
}
type ExprStmt struct {
X Expr // expression
}
type CallExpr struct {
Fun Expr // function expression
Lparen token.Pos // position of "("
Args []Expr // function arguments; or nil
Ellipsis token.Pos // position of "...", if any
Rparen token.Pos // position of ")"
}
type SelectorExpr struct {
X Expr // expression
Sel *Ident // field selector
}
type CallExpr struct {
Fun Expr // function expression
Lparen token.Pos // position of "("
Args []Expr // function arguments; or nil
Ellipsis token.Pos // position of "...", if any
Rparen token.Pos // position of ")"
}
&ast.ExprStmt{
X: &ast.CallExpr{
Fun: &ast.SelectorExpr{
X: ast.NewIdent("fmt"),
Sel: ast.NewIdent("Println"),
},
Args: []ast.Expr{
&ast.BasicLit{
Kind: token.STRING,
Value: strconv.Quote("Hello, 世界"),
},
},
},
}
format.Node(os.Stdout, token.NewFileSet(), f)
package main
import (
"go/ast"
"go/format"
"go/token"
"os"
"strconv"
)
func main() {
f := &ast.File{
Name: ast.NewIdent("main"),
Decls: []ast.Decl{
&ast.GenDecl{
Tok: token.IMPORT,
Specs: []ast.Spec{
&ast.ImportSpec{
Path: &ast.BasicLit{
Kind: token.STRING,
Value: strconv.Quote("fmt"),
},
},
},
},
&ast.FuncDecl{
Name: ast.NewIdent("main"),
Type: &ast.FuncType{},
Body: &ast.BlockStmt{
List: []ast.Stmt{
&ast.ExprStmt{
X: &ast.CallExpr{
Fun: &ast.SelectorExpr{
X: ast.NewIdent("fmt"),
Sel: ast.NewIdent("Println"),
},
Args: []ast.Expr{
&ast.BasicLit{
Kind: token.STRING,
Value: strconv.Quote("Hello, 世界"),
},
},
},
},
},
},
},
},
}
format.Node(os.Stdout, token.NewFileSet(), f)
}
type GenDecl struct {
Doc *CommentGroup // associated documentation; or nil
TokPos token.Pos // position of Tok
Tok token.Token // IMPORT, CONST, TYPE, VAR
Lparen token.Pos // position of '(', if any
Specs []Spec
Rparen token.Pos // position of ')', if any
}
&ast.GenDecl{
Tok: token.IMPORT,
Specs: []ast.Spec{
&ast.ImportSpec{
// TODO: フィールドを埋める
},
},
}
type ImportSpec struct {
Doc *CommentGroup // associated documentation; or nil
Name *Ident // local package name (including "."); or nil
Path *BasicLit // import path
Comment *CommentGroup // line comments; or nil
EndPos token.Pos // end of spec (overrides Path.Pos if nonzero)
}
&ast.ImportSpec{
Path: &ast.BasicLit{
Kind: token.STRING,
Value: strconv.Quote("fmt"),
},
}
type FuncDecl struct {
Doc *CommentGroup // associated documentation; or nil
Recv *FieldList // receiver (methods); or nil (functions)
Name *Ident // function/method name
Type *FuncType // function signature: parameters, results, and position of "func" keyword
Body *BlockStmt // function body; or nil (forward declaration)
}
type FuncType struct {
Func token.Pos // position of "func" keyword (token.NoPos if there is no "func")
Params *FieldList // (incoming) parameters; non-nil
Results *FieldList // (outgoing) results; or nil
}
&ast.FuncDecl{
Name: ast.NewIdent("main"),
Type: &ast.FuncType{},
Body: /* TODO: 本体を設定する */,
}
type BlockStmt struct {
Lbrace token.Pos // position of "{"
List []Stmt
Rbrace token.Pos // position of "}"
}
package main
import "fmt"
func main() {
fmt.Println("Hello, 世界")
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment