func declareFile(b *builder, pkg *pkg, file *file) { // declare functions for _, fn := range file.funcs { t := fn.Name sym := sym8.Make(b.path, t.Lit, SymFunc, fn, nil, t.Pos) if !declareSymbol(b, sym) { continue } b.curPkg.declare(sym) // b.index(t.Lit, b.curPkg.Declare(sym)) } // declare variables for _, v := range file.vars { t := v.Name sym := sym8.Make(b.path, t.Lit, SymVar, v, nil, t.Pos) if !declareSymbol(b, sym) { continue } b.curPkg.declare(sym) // b.index(t.Lit, b.curPkg.Declare(sym)) } }
func buildFields(b *builder, ps *pkgStruct) { s := ps.ast t := ps.t for _, f := range s.Fields { ft := b.buildType(f.Type) if ft == nil { continue } for _, id := range f.Idents.Idents { name := id.Lit field := &types.Field{Name: name, T: ft} sym := sym8.Make(b.path, name, tast.SymField, field, ft, id.Pos) conflict := t.Syms.Declare(sym) if conflict != nil { b.Errorf(id.Pos, "field %s already defined", id.Lit) b.Errorf(conflict.Pos, "previously defined here") continue } t.AddField(field) } } }
func declareVar(b *builder, tok *lex8.Token, t types.T) *sym8.Symbol { name := tok.Lit s := sym8.Make(b.path, name, tast.SymVar, nil, t, tok.Pos) conflict := b.scope.Declare(s) if conflict != nil { b.Errorf(tok.Pos, "%q already defined as a %s", name, tast.SymStr(conflict.Type), ) b.Errorf(conflict.Pos, "previously defined here") return nil } return s }
func declareFuncSym(b *builder, f *ast.Func, t types.T) *sym8.Symbol { name := f.Name.Lit s := sym8.Make(b.path, name, tast.SymFunc, nil, t, f.Name.Pos) conflict := b.scope.Declare(s) if conflict != nil { b.Errorf(f.Name.Pos, "%q already defined as a %s", name, tast.SymStr(conflict.Type), ) b.Errorf(conflict.Pos, "previously defined here") return nil } return s }
// declareLabels adds the labels into the scope, // so that later they can be queried for filling. func declareLabels(b *builder, f *funcDecl) { for _, stmt := range f.stmts { if !stmt.isLabel() { continue } lab := stmt.label op := stmt.Ops[0] sym := sym8.Make(b.path, lab, SymLabel, stmt, nil, op.Pos) decl := b.scope.Declare(sym) if decl != nil { b.Errorf(op.Pos, "%q already declared", lab) b.Errorf(decl.Pos, " here as a %s", SymStr(decl.Type)) continue } } }
func buildPkgScope(b *builder, pkg *pkg) { if pkg.imports != nil { for as, stmt := range pkg.imports.stmts { sym := sym8.Make(b.path, as, SymImport, stmt, nil, stmt.Path.Pos) if !declareSymbol(b, sym) { continue } b.importPkg(stmt.path, as) // b.index(as, b.curPkg.Require(stmt.lib)) } } for _, file := range pkg.files { declareFile(b, pkg, file) } }
func declareStruct(b *builder, s *ast.Struct) *pkgStruct { ret := newPkgStruct(s) name := ret.name.Lit pos := ret.name.Pos t := &types.Type{ret.t} sym := sym8.Make(b.path, name, tast.SymStruct, nil, t, pos) conflict := b.scope.Declare(sym) if conflict != nil { b.Errorf(pos, "%s already defined", name) b.Errorf(conflict.Pos, "previously defined here as a %s", tast.SymStr(conflict.Type), ) return nil } ret.sym = sym return ret }
func buildImports( b *builder, f *ast.File, imps map[string]*build8.Package, ) []*sym8.Symbol { if f.Imports == nil { return nil } var ret []*sym8.Symbol for _, d := range f.Imports.Decls { _, as, e := ast.ImportPathAs(d) if e != nil { b.Errorf(d.Path.Pos, "invalid import path") continue } p := imps[as] if p == nil { b.Errorf(d.Path.Pos, "package %s missing", as) continue } pos := ast.ImportPos(d) if !(p.Lang == "asm8" || p.Lang == "g8") { b.Errorf(pos, "cannot import %q pacakge %q", p.Lang, as, ) continue } t := &types.Pkg{as, p.Lang, p.Symbols} sym := sym8.Make(b.path, as, tast.SymImport, nil, t, pos) conflict := b.scope.Declare(sym) if conflict != nil { b.Errorf(pos, "%s already imported", as) continue } ret = append(ret, sym) } return ret }
func declareMethod(b *builder, ps *pkgStruct, f *ast.Func) *pkgFunc { if f.Alias != nil { b.Errorf(f.Alias.Eq.Pos, "cannot alias a function for a method") return nil } t := buildFuncType(b, ps.pt, f.FuncSig) if t == nil { return nil } name := f.Name.Lit sym := sym8.Make(b.path, name, tast.SymFunc, nil, t, f.Name.Pos) conflict := ps.t.Syms.Declare(sym) if conflict != nil { b.Errorf(f.Name.Pos, "member %s already defined", name) b.Errorf(conflict.Pos, "previously defined here") return nil } return &pkgFunc{sym: sym, f: f, recv: ps} }
func declareBuiltin(b *builder, builtin *link8.Pkg) { path := builtin.Path() e := b.p.HookBuiltin(builtin) if e != nil { b.Errorf(nil, e.Error()) return } o := func(name, as string, t *types.Func) ir.Ref { sym := builtin.SymbolByName(name) if sym == nil { b.Errorf(nil, "builtin symbol %s missing", name) return nil } else if sym.Type != link8.SymFunc { b.Errorf(nil, "builtin symbol %s is not a function", name) return nil } ref := ir.NewFuncSym(path, name, makeFuncSig(t)) obj := &objFunc{name: as, ref: newRef(t, ref)} s := sym8.Make(b.path, as, tast.SymFunc, obj, t, nil) pre := b.scope.Declare(s) if pre != nil { b.Errorf(nil, "builtin symbol %s declare failed", name) return nil } return ref } // TODO: export these as generic function pointer symbols, and convert // them into G functions in g files, rather than inside here in the // compiler. o("PrintInt32", "printInt", types.NewVoidFunc(types.Int)) o("PrintUint32", "printUint", types.NewVoidFunc(types.Uint)) o("PrintChar", "printChar", types.NewVoidFunc(types.Int8)) b.panicFunc = o("Panic", "panic", types.VoidFunc) bi := func(name string) { t := types.NewBuiltInFunc(name) obj := &objFunc{name: name, ref: newRef(t, nil)} s := sym8.Make(b.path, name, tast.SymFunc, obj, t, nil) pre := b.scope.Declare(s) if pre != nil { b.Errorf(nil, "builtin symbol %s declare failed", name) } } bi("len") bi("make") c := func(name string, r *ref) { // TODO: declare these as typed consts obj := &objConst{name, r} s := sym8.Make(b.path, name, tast.SymConst, obj, r.Type(), nil) pre := b.scope.Declare(s) if pre != nil { b.Errorf(nil, "builtin symbol %s declare failed", name) } } c("true", refTrue) c("false", refFalse) c("nil", refNil) t := func(name string, t types.T) { s := sym8.Make(b.path, name, tast.SymType, nil, &types.Type{t}, nil) pre := b.scope.Declare(s) if pre != nil { b.Errorf(nil, "builtin symbol %s declare failed", name) } } t("int", types.Int) t("uint", types.Uint) t("int32", types.Int) t("uint32", types.Uint) t("int8", types.Int8) t("uint8", types.Uint8) t("char", types.Int8) t("byte", types.Uint8) t("bool", types.Bool) t("float", types.Float32) t("string", types.String) // t("ptr", &types.Pointer{types.Uint8}) // t("float32", types.Float32) // t("string", types.String) }