func newBuilder(path string, scope *sym8.Scope) *builder { return &builder{ ErrorList: lex8.NewErrorList(), path: path, scope: scope, } }
// BuildBareFunc builds a function body into an image. func BuildBareFunc(f string, rc io.ReadCloser) ([]byte, []*lex8.Error) { fn, es := parse.BareFunc(f, rc) if es != nil { return nil, es } // resolving pass log := lex8.NewErrorList() rfunc := resolveFunc(log, fn) if es := log.Errs(); es != nil { return nil, es } // building pass b := newBuilder("main") fobj := buildFunc(b, rfunc) if es := b.Errs(); es != nil { return nil, es } ret, e := link8.LinkBareFunc(fobj) if e != nil { return nil, lex8.SingleErr(e) } return ret, nil }
func runPkgTests(c *context, p *pkg) []*lex8.Error { lib := p.pkg.Lib tests := p.pkg.Tests testMain := p.pkg.TestMain if testMain != "" && lib.HasFunc(testMain) { log := lex8.NewErrorList() if len(tests) > 0 { bs := new(bytes.Buffer) lex8.LogError(log, link(c, bs, p, testMain)) fout := c.output.TestBin(p.path) img := bs.Bytes() _, err := fout.Write(img) lex8.LogError(log, err) lex8.LogError(log, fout.Close()) if es := log.Errs(); es != nil { return es } runTests(log, tests, img, c.Options) if es := log.Errs(); es != nil { return es } } } return nil }
func (b *Builder) runTests(p *pkg) []*lex8.Error { lib := p.pkg.Lib tests := p.pkg.Tests testMain := p.pkg.TestMain if testMain != "" && lib.HasFunc(testMain) { log := lex8.NewErrorList() if len(tests) > 0 { bs := new(bytes.Buffer) lex8.LogError(log, b.link(bs, p, testMain)) fout := b.home.CreateTestBin(p.path) img := bs.Bytes() _, err := fout.Write(img) lex8.LogError(log, err) lex8.LogError(log, fout.Close()) if es := log.Errs(); es != nil { return es } runTests(log, tests, img, b.Verbose) if es := log.Errs(); es != nil { return es } } } return nil }
func newBuilder(path string) *builder { return &builder{ ErrorList: lex8.NewErrorList(), scope: sym8.NewScope(), path: path, imports: make(map[string]string), pkgUsed: make(map[string]struct{}), } }
func newBuilder(path string) *builder { s := sym8.NewScope() return &builder{ ErrorList: lex8.NewErrorList(), path: path, p: ir.NewPkg(path), scope: s, // package scope continues: newBlockStack(), breaks: newBlockStack(), } }
func (lang) Compile(pinfo *build8.PkgInfo, opts *build8.Options) ( *build8.Package, []*lex8.Error, ) { // resolve pass, will also parse the files pkg, es := resolvePkg(pinfo.Path, pinfo.Src) if es != nil { return nil, es } // import errs := lex8.NewErrorList() if pkg.imports != nil { for _, stmt := range pkg.imports.stmts { imp := pinfo.Import[stmt.as] if imp == nil || imp.Package == nil { errs.Errorf(stmt.Path.Pos, "import missing") continue } if imp.Lang != "asm8" { errs.Errorf(stmt.Path.Pos, "can only import asm8 package") continue } stmt.pkg = imp.Package if stmt.pkg == nil { panic("import missing") } } if es := errs.Errs(); es != nil { return nil, es } } // library building b := newBuilder(pinfo.Path) lib := buildLib(b, pkg) if es := b.Errs(); es != nil { return nil, es } ret := &build8.Package{ Lang: "asm8", Lib: lib.Pkg, Main: "main", Symbols: buildSymTable(lib), } return ret, nil }
func (b *Builder) buildMain(p *pkg) []*lex8.Error { lib := p.pkg.Lib main := p.pkg.Main if main == "" || !lib.HasFunc(main) { return nil } log := lex8.NewErrorList() fout := b.output.Bin(p.path) lex8.LogError(log, b.link(fout, p, main)) lex8.LogError(log, fout.Close()) return log.Errs() }
func buildMain(c *context, p *pkg) []*lex8.Error { lib := p.pkg.Lib main := p.pkg.Main if main == "" || !lib.HasFunc(main) { return nil } log := lex8.NewErrorList() fout := c.output.Bin(p.path) lex8.LogError(log, link(c, fout, p, main)) lex8.LogError(log, fout.Close()) return log.Errs() }
func resolvePkg(p string, src map[string]*build8.File) (*pkg, []*lex8.Error) { log := lex8.NewErrorList() ret := new(pkg) ret.path = p asts := make(map[string]*ast.File) // parse all the files first var parseErrs []*lex8.Error for name, f := range src { astFile, es := parse.File(f.Path, f) if es != nil { parseErrs = append(parseErrs, es...) } asts[name] = astFile } if len(parseErrs) > 0 { return nil, parseErrs } for name, astFile := range asts { // then resolve the file file := resolveFile(log, astFile) ret.files = append(ret.files, file) // enforce import policy if len(src) == 1 || name == "import.s" { if ret.imports != nil { log.Errorf(file.imports.Kw.Pos, "double valid import stmt; two import.s?", ) } else { ret.imports = file.imports } } else if file.imports != nil { log.Errorf(file.imports.Kw.Pos, "invalid import outside import.s in a multi-file package", ) } } if es := log.Errs(); es != nil { return nil, es } return ret, nil }
func listImport( f string, rc io.ReadCloser, imp build8.Importer, golike bool, ) []*lex8.Error { fast, _, es := parse.File(f, rc, golike) if es != nil { return es } if fast.Imports == nil { return nil } m := make(map[string]*importDecl) log := lex8.NewErrorList() for _, d := range fast.Imports.Decls { p, as, e := ast.ImportPathAs(d) if e != nil { log.Errorf(d.Path.Pos, "invalid path string %s", d.Path.Lit) continue } pos := ast.ImportPos(d) if other, found := m[as]; found { log.Errorf(pos, "%s already imported", as) log.Errorf(other.pos, " previously imported here") continue } m[as] = &importDecl{as: as, path: p, pos: pos} } if errs := log.Errs(); errs != nil { return errs } for as, d := range m { imp.Import(as, d.path, d.pos) } return nil }
// CheckRect checks if a program is within a rectangular area. func CheckRect(file string, r io.Reader, h, w int) []*lex8.Error { br := bufio.NewReader(r) row := 0 col := 0 errs := lex8.NewErrorList() pos := func() *lex8.Pos { return &lex8.Pos{file, row + 1, col + 1} } newLine := func() { if col > w { errs.Errorf(pos(), "line too wide") } row++ col = 0 } for { r, _, e := br.ReadRune() if e == io.EOF { if col > 0 { newLine() } break } else if lex8.LogError(errs, e) { break } if r == '\n' { newLine() } else { col += runeWidth(r) } } if row > h { errs.Errorf(pos(), "too many lines") } return errs.Errs() }
func listImport( f string, rc io.ReadCloser, imp build8.Importer, ) []*lex8.Error { astFile, es := parse.File(f, rc) if es != nil { return es } if astFile.Imports == nil { return nil } log := lex8.NewErrorList() impDecl := resolveImportDecl(log, astFile.Imports) if es := log.Errs(); es != nil { return es } for as, stmt := range impDecl.stmts { imp.Import(as, stmt.path, stmt.Path.Pos) } return nil }
func newGener() *gener { return &gener{ ErrorList: lex8.NewErrorList(), } }