func declareBuiltin(b *builder, builtin *link8.Pkg) { pindex := b.p.Require(builtin) o := func(name string, as string, t *types.Func) { sym, index := builtin.SymbolByName(name) if sym == nil { b.Errorf(nil, "builtin symbol %s missing", name) return } ref := ir.FuncSym(pindex, index, nil) // a reference to the function obj := &objFunc{as, newRef(t, ref), nil} pre := b.scope.Declare(sym8.Make(as, symFunc, obj, nil)) if pre != nil { b.Errorf(nil, "builtin symbol %s declare failed", name) } } o("PrintInt32", "printInt", types.NewVoidFunc(types.Int)) o("PrintUint32", "printUint", types.NewVoidFunc(types.Uint)) o("PrintChar", "printChar", types.NewVoidFunc(types.Uint8)) c := func(name string, t types.T, r ir.Ref) { obj := &objConst{name, newRef(t, r)} pre := b.scope.Declare(sym8.Make(name, symConst, obj, nil)) if pre != nil { b.Errorf(nil, "builtin symbol %s declare failed", name) } } c("true", types.Bool, ir.Snum(1)) c("false", types.Bool, ir.Snum(0)) t := func(name string, t types.T) { obj := &objType{name, newRef(&types.Type{t}, nil)} pre := b.scope.Declare(sym8.Make(name, symType, obj, nil)) 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("float32", types.Float32) // t("string", types.String) }
func declareFunc(b *builder, f *ast.Func) *objFunc { ftype := buildFuncType(b, f) if ftype == nil { return nil } // NewFunc() will create the variables required for the sigs name := f.Name.Lit ret := new(objFunc) ret.name = name ret.f = f irFunc := b.p.NewFunc(name, ftype.Sig) ret.ref = newRef(ftype, irFunc) // add this item to the top scope s := sym8.Make(name, symFunc, ret, f.Name.Pos) conflict := b.scope.Declare(s) // lets declare the function if conflict != nil { b.Errorf(f.Name.Pos, "%q already declared as a %s", name, symStr(conflict.Type), ) b.Errorf(conflict.Pos, "previously declared here") return nil } return ret }
func declareVar(b *builder, tok *lex8.Token, r *ref) { name := tok.Lit v := &objVar{name, r} s := sym8.Make(name, symVar, v, tok.Pos) conflict := b.scope.Declare(s) if conflict != nil { b.Errorf(tok.Pos, "%q already declared as a %s", name, symStr(conflict.Type), ) } }
func declareFile(b *builder, pkg *pkg, file *file) { // declare functions for _, fn := range file.funcs { t := fn.Name sym := sym8.Make(t.Lit, SymFunc, fn, t.Pos) if !declareSymbol(b, sym) { continue } b.index(t.Lit, b.curPkg.Declare(sym)) } // declare variables for _, v := range file.vars { t := v.Name sym := sym8.Make(t.Lit, SymVar, v, t.Pos) if !declareSymbol(b, sym) { continue } b.index(t.Lit, b.curPkg.Declare(sym)) } }
func buildPkgScope(b *builder, pkg *pkg) { if pkg.imports != nil { for as, stmt := range pkg.imports.stmts { sym := sym8.Make(as, SymImport, stmt, stmt.Path.Pos) if !declareSymbol(b, sym) { continue } b.index(as, b.curPkg.Require(stmt.lib)) } } for _, file := range pkg.files { declareFile(b, pkg, file) } }
// 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(lab, SymLabel, stmt, 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 } } }