blob: f32a75b747e447259949874d884ad338533942a3 [file] [log] [blame]
Matthew Dempskyd68f52a2015-02-27 17:40:34 +09001// Copyright 2009 The Go Authors. All rights reserved.
2// Use of this source code is governed by a BSD-style
3// license that can be found in the LICENSE file.
4
5// +build ignore
6
7// Generate builtin.go from $* (runtime.go and unsafe.go).
8// Run this after changing runtime.go and unsafe.go
9// or after changing the export metadata format in the compiler.
10// Either way, you need to have a working compiler binary first.
11package main
12
13import (
14 "bufio"
15 "fmt"
16 "go/build"
17 "io"
18 "log"
19 "os"
20 "os/exec"
21 "runtime"
22 "strings"
23)
24
25func main() {
26 gochar, err := build.ArchChar(runtime.GOARCH)
27 if err != nil {
28 log.Fatal(err)
29 }
30
31 f, err := os.Create("builtin.go")
32 if err != nil {
33 log.Fatal(err)
34 }
35 defer f.Close()
36 w := bufio.NewWriter(f)
37
38 fmt.Fprintln(w, "// AUTO-GENERATED by mkbuiltin.go; DO NOT EDIT")
39 fmt.Fprintln(w, "")
40 fmt.Fprintln(w, "package gc")
41
42 for _, name := range os.Args[1:] {
43 mkbuiltin(w, gochar, name)
44 }
45
46 if err := w.Flush(); err != nil {
47 log.Fatal(err)
48 }
49}
50
51// Compile .go file, import data from .6 file, and write Go string version.
52func mkbuiltin(w io.Writer, gochar string, name string) {
53 if err := exec.Command("go", "tool", gochar+"g", "-A", "builtins/"+name+".go").Run(); err != nil {
54 log.Fatal(err)
55 }
56 obj := fmt.Sprintf("%s.%s", name, gochar)
57 defer os.Remove(obj)
58
59 r, err := os.Open(obj)
60 if err != nil {
61 log.Fatal(err)
62 }
63 defer r.Close()
64 scanner := bufio.NewScanner(r)
65
66 // Look for $$ that introduces imports.
67 for scanner.Scan() {
68 if strings.Contains(scanner.Text(), "$$") {
69 goto Begin
70 }
71 }
72 log.Fatal("did not find beginning of imports")
73
74Begin:
75 initfunc := fmt.Sprintf("init_%s_function", name)
76
77 fmt.Fprintf(w, "\nconst %simport = \"\" +\n", name)
78
79 // sys.go claims to be in package PACKAGE to avoid
80 // conflicts during "6g sys.go". Rename PACKAGE to $2.
81 replacer := strings.NewReplacer("PACKAGE", name)
82
83 // Process imports, stopping at $$ that closes them.
84 for scanner.Scan() {
85 p := scanner.Text()
86 if strings.Contains(p, "$$") {
87 goto End
88 }
89
90 // Chop leading white space.
91 p = strings.TrimLeft(p, " \t")
92
93 // Cut out decl of init_$1_function - it doesn't exist.
94 if strings.Contains(p, initfunc) {
95 continue
96 }
97
98 fmt.Fprintf(w, "\t%q +\n", replacer.Replace(p)+"\n")
99 }
100 log.Fatal("did not find end of imports")
101
102End:
103 fmt.Fprintf(w, "\t\"$$\\n\"\n")
104}