func (s *SourceContext) AddFile(filename string, length int) *SourceFile {
	if len(s.files) != 0 && s.last_file().length == -1 {
		panic("SourceContext: last file was not finalized")
	}
	offset := SourceLoc(0)
	if len(s.files) != 0 {
		last := s.last_file()
		offset = last.offset + SourceLoc(last.length)
	}
	f := &SourceFile{
		name:   filename,
		offset: offset,
		length: length,
		lines:  []source_line{{0, 1}},
	}
	s.files = append(s.files, f)
	return f
}
Adds a new file to the context, use -1 as length if the length is unknown, but
keep in mind that having a file with unknown length prevents further
AddFile calls, they will panic. In order to continue adding files to the
context, the last file with unknown length must be finalized. Method doesn't
read anything, all the arguments are purely informative.
package sexp
type SourceLoc uint32
type SourceLocEx struct {
	Filename   string
	Line       int  
	LineOffset int  
	Offset     int  
}
type source_line struct {
	offset int  
	num    int  
}
type SourceFile struct {
	name   string
	offset SourceLoc  
	length int
	lines  []source_line
}
func (f *SourceFile) last_line() source_line {
	return f.lines[len(f.lines)-1]
}
func (f *SourceFile) find_line(offset int) source_line {
	beg, end := 0, len(f.lines)
	for {
		len := end - beg
		if len == 1 {
			return f.lines[beg]
		}
		mid := beg + len/2
		if f.lines[mid].offset > offset {
			end = mid
			continue
		} else {
			beg = mid
			continue
		}
	}
	panic("unreachable")
}
func (f *SourceFile) AddLine(offset int) {
	f.lines = append(f.lines, source_line{
		offset: offset,
		num:    f.last_line().num + 1,
	})
}
func (f *SourceFile) Encode(offset int) SourceLoc {
	return f.offset + SourceLoc(offset)
}
func (f *SourceFile) Finalize(len int) {
	f.length = len
}
type SourceContext struct {
	files []*SourceFile
}
func (s *SourceContext) last_file() *SourceFile {
	return s.files[len(s.files)-1]
}
func (s *SourceContext) find_file(l SourceLoc) *SourceFile {
	beg, end := 0, len(s.files)
	for {
		len := end - beg
		if len == 1 {
			return s.files[beg]
		}
		mid := beg + len/2
		if s.files[mid].offset > l {
			end = mid
			continue
		} else {
			beg = mid
			continue
		}
	}
	panic("unreachable")
}