func TestParse3(t *testing.T) { for _, filename := range validFiles { fileNode, err := ParseFile(fset, filename, nil, DeclarationErrors|Trace) if err != nil { t.Errorf("ParseFile(%s): %v", filename, err) } ast.Print(fset, fileNode) } }
func TestParse3(t *testing.T) { dbg.InitLogging(0) relish.InitRuntime("relish.db") builtin.InitBuiltinFunctions() var g *Generator for _, filename := range validFiles { fileNode, err := parser.ParseFile(fset, filename, nil, parser.DeclarationErrors|parser.Trace) if err != nil { t.Errorf("ParseFile(%s): %v", filename, err) } ast.Print(fset, fileNode) fileNameRoot := filename[:len(filename)-4] g = NewGenerator(fileNode, fileNameRoot) g.GenerateCode() //g.TestWalk() } g.Interp.RunMain() }
// makeType makes a new type for an AST type specification x or returns // the type referred to by a type name x. If cycleOk is set, a type may // refer to itself directly or indirectly; otherwise cycles are errors. // func (c *checker) makeType(x ast.Expr, cycleOk bool) (typ Type) { if debug { fmt.Printf("makeType (cycleOk = %v)\n", cycleOk) ast.Print(c.fset, x) defer func() { fmt.Printf("-> %T %v\n\n", typ, typ) }() } switch t := x.(type) { case *ast.BadExpr: return &Bad{} case *ast.Ident: // type name obj := t.Obj if obj == nil { // unresolved identifier (error has been reported before) return &Bad{Msg: "unresolved identifier"} } if obj.Kind != ast.Typ { msg := c.errorf(t.Pos(), "%s is not a type", t.Name) return &Bad{Msg: msg} } c.checkObj(obj, cycleOk) if !cycleOk && obj.Type.(*Name).Underlying == nil { // TODO(gri) Enable this message again once its position // is independent of the underlying map implementation. // msg := c.errorf(obj.Pos(), "illegal cycle in declaration of %s", obj.Name) msg := "illegal cycle" return &Bad{Msg: msg} } return obj.Type.(Type) case *ast.ParenExpr: return c.makeType(t.X, cycleOk) case *ast.SelectorExpr: // qualified identifier // TODO (gri) eventually, this code belongs to expression // type checking - here for the time being if ident, ok := t.X.(*ast.Ident); ok { if obj := ident.Obj; obj != nil { if obj.Kind != ast.Pkg { msg := c.errorf(ident.Pos(), "%s is not a package", obj.Name) return &Bad{Msg: msg} } // TODO(gri) we have a package name but don't // have the mapping from package name to package // scope anymore (created in ast.NewPackage). return &Bad{} // for now } } // TODO(gri) can this really happen (the parser should have excluded this)? msg := c.errorf(t.Pos(), "expected qualified identifier") return &Bad{Msg: msg} case *ast.StarExpr: return &Pointer{Base: c.makeType(t.X, true)} case *ast.ArrayType: if t.Len != nil { // TODO(gri) compute length return &Array{Elt: c.makeType(t.Elt, cycleOk)} } return &Slice{Elt: c.makeType(t.Elt, true)} case *ast.StructType: fields, tags, _ := c.collectFields(token.STRUCT, t.Fields, cycleOk) return &Struct{Fields: fields, Tags: tags} case *ast.FuncType: params, _, _ := c.collectFields(token.FUNC, t.Params, true) results, _, isVariadic := c.collectFields(token.FUNC, t.Results, true) return &Func{Recv: nil, Params: params, Results: results, IsVariadic: isVariadic} case *ast.InterfaceType: methods, _, _ := c.collectFields(token.INTERFACE, t.Methods, cycleOk) methods.Sort() return &Interface{Methods: methods} case *ast.MapType: return &Map{Key: c.makeType(t.Key, true), Elt: c.makeType(t.Key, true)} case *ast.ChanType: return &Chan{Dir: t.Dir, Elt: c.makeType(t.Value, true)} } panic(fmt.Sprintf("unreachable (%T)", x)) }