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) }
func wrapFunc(b *builder, name, wrapName string) { f := findFunc(b, name, types.VoidFunc) if f == nil { return } b.f = b.p.NewFunc(wrapName, nil, ir.VoidFuncSig) b.b = b.f.NewBlock(nil) b.b.Call(nil, f.IR()) } func addStart(b *builder) { wrapFunc(b, "main", startName) } func addInit(b *builder) { wrapFunc(b, "init", initName) } var testMainFuncType = types.NewVoidFunc(types.VoidFunc) func addTestStart(b *builder, testList ir.Ref, n int) { b.f = b.p.NewFunc(testStartName, nil, ir.VoidFuncSig) b.b = b.f.NewBlock(nil) argAddr := ir.Num(arch8.AddrBootArg) // the arg index := b.newTempIR(types.Uint) // to save the index b.b.Assign(index, ir.NewAddrRef(argAddr, arch8.RegSize, 0, false, true)) size := ir.Num(uint32(n)) checkInRange(b, index, size, "u<") base := b.newPtr() b.b.Arith(base, nil, "&", testList) addr := b.newPtr()