From 0974c6b95b40b27cddb50b2d0d87bbfd0c15a8d9 Mon Sep 17 00:00:00 2001 From: Tyler Rhodes Date: Sun, 25 Feb 2018 17:03:04 -0800 Subject: [PATCH] Clean up wave logic a bit. Group stuff based on wave (and order appropriately) --- bin/spicy.go | 42 ++++++++++++++------------- entry_source.go | 14 ++++----- ld.go | 16 +++++----- spec.go | 77 +++++++++++++++++++++++++------------------------ 4 files changed, 77 insertions(+), 72 deletions(-) diff --git a/bin/spicy.go b/bin/spicy.go index 5d95cca..91541ec 100644 --- a/bin/spicy.go +++ b/bin/spicy.go @@ -72,26 +72,28 @@ func main() { spec, err := spicy.ParseSpec(bufio.NewReader(f)) if err != nil { panic(err) } err = spec.CheckValidity() - if err != nil { panic(err) } - err = spicy.LinkSpec(spec, *ld_command) - if err != nil { panic(err) } - entry, err := spicy.CreateEntryBinary(spec, *as_command, *ld_command) - if err != nil { panic(err) } - defer entry.Close() - var romheader *os.File - var bootstrap *os.File - var font *os.File - var code *os.File - var raw *os.File - name := spec.Waves[0].Name - out, err := os.OpenFile(fmt.Sprintf("%s.n64", name), os.O_CREATE|os.O_RDWR, 0755) - if err != nil { - panic(err) - } - defer out.Close() - err = spicy.WriteRomImage(out, romheader, bootstrap, font, entry, code, raw) - if err != nil { - panic(err) + for _, w := range spec.Waves { + if err != nil { panic(err) } + err = spicy.LinkSpec(w, *ld_command) + if err != nil { panic(err) } + entry, err := spicy.CreateEntryBinary(w, *as_command, *ld_command) + if err != nil { panic(err) } + defer entry.Close() + + var romheader *os.File + var bootstrap *os.File + var font *os.File + var code *os.File + var raw *os.File + out, err := os.OpenFile(fmt.Sprintf("%s.n64", w.Name), os.O_CREATE|os.O_RDWR, 0755) + if err != nil { + panic(err) + } + defer out.Close() + err = spicy.WriteRomImage(out, romheader, bootstrap, font, entry, code, raw) + if err != nil { + panic(err) + } } } diff --git a/entry_source.go b/entry_source.go index ecfa8bd..74507a8 100644 --- a/entry_source.go +++ b/entry_source.go @@ -37,9 +37,9 @@ _start: return b.String(), err } -func generateEntryScript(s *Spec) (string, error) { +func generateEntryScript(w *Wave) (string, error) { glog.V(1).Infoln("Starting to generate entry script.") - content, err := createEntrySource(s.GetBootSegment()) + content, err := createEntrySource(w.GetBootSegment()) if err != nil { return "", err } @@ -60,10 +60,10 @@ func generateEntryScript(s *Spec) (string, error) { return path, nil } -func CreateEntryBinary(s *Spec, as_command string, ld_command string) (*os.File, error) { - name := s.Waves[0].Name +func CreateEntryBinary(w *Wave, as_command string, ld_command string) (*os.File, error) { + name := w.Name glog.Infof("Creating entry for \"%s\".", name) - entry_source_path, err := generateEntryScript(s) + entry_source_path, err := generateEntryScript(w) if err != nil { return nil, err } @@ -74,10 +74,10 @@ func CreateEntryBinary(s *Spec, as_command string, ld_command string) (*os.File, cmd.Stderr = &errout err = cmd.Run() if glog.V(2) { - glog.V(2).Info("Ld stdout: ", out.String()) + glog.V(2).Info("as stdout: ", out.String()) } if err != nil { - glog.Error("Error running ld. Stderr output: ", errout.String()) + glog.Error("Error running as. Stderr output: ", errout.String()) } return nil, err } diff --git a/ld.go b/ld.go index 24c434c..9fc76b1 100644 --- a/ld.go +++ b/ld.go @@ -10,7 +10,7 @@ import ( "text/template" ) -func createLdScript(s *Spec) (string, error) { +func createLdScript(w *Wave) (string, error) { t := ` MEMORY { {{range .Segments}} @@ -77,13 +77,13 @@ SECTIONS { return "", err } b := &bytes.Buffer{} - err = tmpl.Execute(b, s) + err = tmpl.Execute(b, w) return b.String(), err } -func generateLdScript(s *Spec) (string, error) { +func generateLdScript(w *Wave) (string, error) { glog.V(1).Infoln("Starting to generate ld script.") - content, err := createLdScript(s) + content, err := createLdScript(w) if err != nil { return "", err } @@ -104,10 +104,10 @@ func generateLdScript(s *Spec) (string, error) { return path, nil } -func LinkSpec(s *Spec, ld_command string) error { - name := s.Waves[0].Name +func LinkSpec(w *Wave, ld_command string) error { + name := w.Name glog.Infof("Linking spec \"%s\".", name) - ld_path, err := generateLdScript(s) + ld_path, err := generateLdScript(w) if err != nil { return err } @@ -118,7 +118,7 @@ func LinkSpec(s *Spec, ld_command string) error { cmd.Stderr = &errout err = cmd.Run() if glog.V(2) { - glog.V(2).Info("Ld stdout: ", out.String()) + glog.V(2).Info("ld stdout: ", out.String()) } if err != nil { glog.Error("Error running ld. Stderr output: ", errout.String()) diff --git a/spec.go b/spec.go index c573538..62639e5 100644 --- a/spec.go +++ b/spec.go @@ -113,12 +113,11 @@ type Segment struct { type Wave struct { Name string - Includes []string + Segments []*Segment } type Spec struct { - Segments []*Segment - Waves []*Wave + Waves []*Wave } func convertSegmentAst(s *SegmentAst) (*Segment, error) { @@ -190,7 +189,7 @@ func convertSegmentAst(s *SegmentAst) (*Segment, error) { return seg, nil } -func convertWaveAst(s *WaveAst) (*Wave, error) { +func convertWaveAst(s *WaveAst, segments map[string]*Segment) (*Wave, error) { out := &Wave{} for _, statement := range s.Statements { switch statement.Name { @@ -198,7 +197,8 @@ func convertWaveAst(s *WaveAst) (*Wave, error) { out.Name = statement.Value.String break case "include": - out.Includes = append(out.Includes, statement.Value.String) + seg := segments[statement.Value.String] + out.Segments = append(out.Segments, seg) break default: return nil, errors.New(fmt.Sprintf("Unknown name %s", statement.Name)) @@ -209,15 +209,16 @@ func convertWaveAst(s *WaveAst) (*Wave, error) { func convertAstToSpec(s SpecAst) (*Spec, error) { out := &Spec{} + segments := map[string]*Segment{} for _, segAst := range s.Segments { seg, err := convertSegmentAst(segAst) if err != nil { return nil, err } - out.Segments = append(out.Segments, seg) + segments[seg.Name] = seg } for _, waveAst := range s.Waves { - wave, err := convertWaveAst(waveAst) + wave, err := convertWaveAst(waveAst, segments) if err != nil { return nil, err } @@ -244,34 +245,36 @@ func ParseSpec(r io.Reader) (*Spec, error) { func (s *Spec) CheckValidity() error { // Per-segment checks - for _, seg := range s.Segments { - numSet := 0 - if seg.Name == "" { - return errors.New("Name must be non-empty.") - } - if seg.Flags.Boot && seg.StackInfo == nil { - return errors.New("Boot segments must have stack info specified.") - } - if seg.Flags.Boot && seg.Entry == nil { - return errors.New("Boot segments must have entry point specified.") - } - if seg.Positioning.Address > 0 { - numSet++ - } - if seg.Positioning.Number > 0 { - numSet++ - } - if seg.Positioning.AfterSegment != "" { - numSet++ - } - if seg.Positioning.AfterMinSegment[0] != "" { - numSet++ - } - if seg.Positioning.AfterMaxSegment[0] != "" { - numSet++ - } - if numSet > 1 { - return errors.New(fmt.Sprintf("Too many addressing sections specified in segment %s.", seg.Name)) + for _, wave := range s.Waves { + for _, seg := range wave.Segments { + numSet := 0 + if seg.Name == "" { + return errors.New("Name must be non-empty.") + } + if seg.Flags.Boot && seg.StackInfo == nil { + return errors.New("Boot segments must have stack info specified.") + } + if seg.Flags.Boot && seg.Entry == nil { + return errors.New("Boot segments must have entry point specified.") + } + if seg.Positioning.Address > 0 { + numSet++ + } + if seg.Positioning.Number > 0 { + numSet++ + } + if seg.Positioning.AfterSegment != "" { + numSet++ + } + if seg.Positioning.AfterMinSegment[0] != "" { + numSet++ + } + if seg.Positioning.AfterMaxSegment[0] != "" { + numSet++ + } + if numSet > 1 { + return errors.New(fmt.Sprintf("Too many addressing sections specified in segment %s.", seg.Name)) + } } } // Per-spec checks @@ -279,8 +282,8 @@ func (s *Spec) CheckValidity() error { return nil } -func (s *Spec) GetBootSegment() *Segment { - for _, seg := range s.Segments { +func (w *Wave) GetBootSegment() *Segment { + for _, seg := range w.Segments { if seg.Flags.Boot { return seg }