mirror of
https://github.com/zellyn/go6502.git
synced 2026-03-13 23:16:35 +00:00
119 lines
2.5 KiB
Go
119 lines
2.5 KiB
Go
package lines
|
|
|
|
import "fmt"
|
|
|
|
type Context struct {
|
|
Filename string // Pointer to the filename
|
|
Parent *Line // Pointer to parent line (eg. include, macro)
|
|
MacroCall int
|
|
MacroLocals map[string]bool
|
|
}
|
|
|
|
type Line struct {
|
|
LineNo int // Actual line number in file
|
|
DeclaredLineNo int // Declared line number in file, or 0
|
|
Context *Context // Pointer to the file/include/macro context
|
|
Parse *Parse // The lineparser
|
|
}
|
|
|
|
type LineSource interface {
|
|
Next() (line Line, done bool, err error)
|
|
Context() Context
|
|
}
|
|
|
|
func NewLine(s string, lineNo int, context *Context) Line {
|
|
l := Line{
|
|
LineNo: lineNo,
|
|
Context: context,
|
|
Parse: NewParse(s),
|
|
}
|
|
return l
|
|
}
|
|
|
|
var testFilename = "(test)"
|
|
|
|
func NewSimple(s string) Line {
|
|
return NewLine(s, 0, &Context{Filename: testFilename})
|
|
}
|
|
|
|
func (c *Context) GetMacroCall() int {
|
|
if c == nil {
|
|
return 0
|
|
}
|
|
if c.MacroCall > 0 {
|
|
return c.MacroCall
|
|
}
|
|
return c.Parent.GetMacroCall()
|
|
}
|
|
|
|
func (l *Line) GetMacroLocals() map[string]bool {
|
|
if l == nil || l.Context == nil {
|
|
return nil
|
|
}
|
|
return l.Context.MacroLocals
|
|
}
|
|
|
|
func (l *Line) GetMacroCall() int {
|
|
if l == nil {
|
|
return 0
|
|
}
|
|
return l.Context.GetMacroCall()
|
|
}
|
|
|
|
func (l Line) Text() string {
|
|
return l.Parse.Text()
|
|
}
|
|
|
|
func (l Line) String() string {
|
|
return fmt.Sprintf("%s:%d: %s", l.Context.Filename, l.LineNo, l.Parse.Text())
|
|
}
|
|
|
|
func (l Line) Errorf(format string, a ...interface{}) error {
|
|
filename := "unknown file"
|
|
if l.Context != nil {
|
|
filename = l.Context.Filename
|
|
}
|
|
return fmt.Errorf(fmt.Sprintf("%s:%d: %s", filename, l.LineNo, format), a...)
|
|
}
|
|
|
|
func (l Line) Sprintf(format string, a ...interface{}) string {
|
|
filename := "unknown file"
|
|
if l.Context != nil {
|
|
filename = l.Context.Filename
|
|
}
|
|
return fmt.Sprintf(fmt.Sprintf("%s:%d: %s", filename, l.LineNo, format), a...)
|
|
}
|
|
|
|
type SimpleLineSource struct {
|
|
context Context
|
|
lines []string
|
|
size int
|
|
curr int
|
|
prefix int
|
|
}
|
|
|
|
func (sls *SimpleLineSource) Next() (line Line, done bool, err error) {
|
|
if sls.curr >= sls.size {
|
|
return Line{}, true, nil
|
|
}
|
|
sls.curr++
|
|
l := NewLine(sls.lines[sls.curr-1], sls.curr, &sls.context)
|
|
for i := 0; i < sls.prefix; i++ {
|
|
l.Parse.Next()
|
|
l.Parse.Ignore()
|
|
}
|
|
return l, false, nil
|
|
}
|
|
|
|
func (sls SimpleLineSource) Context() Context {
|
|
return sls.context
|
|
}
|
|
func NewSimpleLineSource(context Context, ls []string, prefix int) LineSource {
|
|
return &SimpleLineSource{
|
|
context: context,
|
|
lines: ls,
|
|
size: len(ls),
|
|
prefix: prefix,
|
|
}
|
|
}
|