Skip to content

Commit

Permalink
Clean up wave logic a bit. Group stuff based on wave (and order
Browse files Browse the repository at this point in the history
appropriately)
  • Loading branch information
trhodeos committed Feb 26, 2018
1 parent d0fcd77 commit 0974c6b
Show file tree
Hide file tree
Showing 4 changed files with 77 additions and 72 deletions.
42 changes: 22 additions & 20 deletions bin/spicy.go
Original file line number Diff line number Diff line change
Expand Up @@ -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)
}
}
}
14 changes: 7 additions & 7 deletions entry_source.go
Original file line number Diff line number Diff line change
Expand Up @@ -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
}
Expand All @@ -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
}
Expand All @@ -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
}
16 changes: 8 additions & 8 deletions ld.go
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ import (
"text/template"
)

func createLdScript(s *Spec) (string, error) {
func createLdScript(w *Wave) (string, error) {
t := `
MEMORY {
{{range .Segments}}
Expand Down Expand Up @@ -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
}
Expand All @@ -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
}
Expand All @@ -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())
Expand Down
77 changes: 40 additions & 37 deletions spec.go
Original file line number Diff line number Diff line change
Expand Up @@ -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) {
Expand Down Expand Up @@ -190,15 +189,16 @@ 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 {
case "name":
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))
Expand All @@ -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
}
Expand All @@ -244,43 +245,45 @@ 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
// Wave checks
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
}
Expand Down

0 comments on commit 0974c6b

Please sign in to comment.