func (self *PackageFile) processDataStage2(ctx *ProcessDataContext) { // STAGE 2 self.applyImports() for _, decl := range ctx.file.Decls { self.processDecl(decl) } if ctx.block != nil { // parse local function as global ctx.decls, _ = parser.ParseDeclList("", ctx.block, nil) for _, decl := range ctx.decls { self.processDecl(decl) } } }
func (w *World) Compile(fset *token.FileSet, text string) (Code, os.Error) { stmts, err := parser.ParseStmtList(fset, "input", text) if err == nil { return w.CompileStmtList(fset, stmts) } // Otherwise try as DeclList. decls, err1 := parser.ParseDeclList(fset, "input", text) if err1 == nil { return w.CompileDeclList(fset, decls) } // Have to pick an error. // Parsing as statement list admits more forms, // its error is more likely to be useful. return nil, err }
// this one is used for current file buffer exclusively func (f *AutoCompleteFile) processData(data []byte) { cur, filedata, block := RipOffDecl(data, f.cursor) file, _ := parser.ParseFile(f.fset, "", filedata, 0) f.packageName = packageName(file) f.decls = make(map[string]*Decl) f.packages = NewPackageImports(f.name, file.Decls) f.filescope = NewScope(nil) f.scope = f.filescope for _, d := range file.Decls { anonymifyAst(d, 0, f.filescope) } // process all top-level declarations for _, decl := range file.Decls { appendToTopDecls(f.decls, decl, f.scope) } if block != nil { // process local function as top-level declaration decls, _ := parser.ParseDeclList(f.fset, "", block) for _, d := range decls { anonymifyAst(d, 0, f.filescope) } for _, decl := range decls { appendToTopDecls(f.decls, decl, f.scope) } // process function internals f.cursor = cur for _, decl := range decls { f.processDeclLocals(decl) } } }
func (m *PackageFileCache) processPackageData(s string) { m.scope = NewScope(nil) // Find first $$ i := strings.Index(s, "\n$$") if i == -1 { panic("Can't find the import section in the archive file") } s = s[i+len("\n$$"):] // Skip to the beginning of the package statement i = strings.Index(s, "package") if i == -1 { panic("Wrong file") } s = s[i:] // Find second $$ i = strings.Index(s, "\n$$") if i == -1 { panic("Can't find the end of the import section in the archive file") } s = s[:i] // leave only import section i = strings.Index(s, "\n") if i == -1 { panic("Wrong file") } m.defalias = strings.TrimSpace(s[len("package "):i]) s = s[i+1:] m.pathToAlias = make(map[string]string) // hack, add ourselves to the package scope m.addPackageToScope(m.defalias, m.name) internalPackages := make(map[string]*bytes.Buffer) for { // for each line i := strings.Index(s, "\n") if i == -1 { break } decl := strings.TrimSpace(s[:i]) if len(decl) == 0 { s = s[i+1:] continue } decl2, pkg := m.processExport(decl) if len(decl2) == 0 { s = s[i+1:] continue } buf := internalPackages[pkg] if buf == nil { buf = bytes.NewBuffer(make([]byte, 0, 4096)) internalPackages[pkg] = buf } buf.WriteString(decl2) buf.WriteString("\n") s = s[i+1:] } m.others = make(map[string]*Decl) for key, value := range internalPackages { tmp := m.expandPackages(value.Bytes()) decls, err := parser.ParseDeclList(token.NewFileSet(), "", tmp) if err != nil { panic(fmt.Sprintf("failure in:\n%s\n%s\n", tmp, err.String())) } else { tmp = nil if key == m.name { // main package m.main = NewDecl(m.name, DECL_PACKAGE, nil) addAstDeclsToPackage(m.main, decls, m.scope) } else { // others m.others[key] = NewDecl(key, DECL_PACKAGE, nil) addAstDeclsToPackage(m.others[key], decls, m.scope) } } } m.pathToAlias = nil for key, value := range m.scope.entities { pkg, ok := m.others[value.Name] if !ok && value.Name == m.name { pkg = m.main } m.scope.replaceDecl(key, pkg) } }
func main() { fmt.Println("Welcome to the Go REPL!") fmt.Println("Enter '?' for a list of commands.") w := new(World) w.pkgs = new(vector.StringVector) w.defs = new(vector.StringVector) w.code = new(vector.Vector) buf := bufio.NewReader(os.Stdin) unstable := false for { if unstable { fmt.Print("! ") } fmt.Print(strings.Join(w.pkgs.Data(), " ") + "> ") read, err := buf.ReadString('\n') if err != nil { println() break } line := read[0 : len(read)-1] if len(line) == 0 { continue } w.exec = "" switch line[0] { case '?': fmt.Println("Commands:") fmt.Println("\t?\thelp") fmt.Println("\t+ (pkg)\timport package") fmt.Println("\t- (pkg)\tremove package") fmt.Println("\t-[dpc]\tpop last (declaration|package|code)") fmt.Println("\t~\treset") fmt.Println("\t: (...)\tadd persistent code") fmt.Println("\t!\tinspect source") case '+': w.pkgs.Push(line[2:]) unstable = true case '-': if len(line) > 1 && line[1] != ' ' { switch line[1] { case 'd': if w.defs.Len() > 0 { w.defs.Pop() } case 'p': if w.pkgs.Len() > 0 { w.pkgs.Pop() } case 'c': if w.code.Len() > 0 { w.code.Pop() } } } else { if len(line) > 2 && w.pkgs.Len() > 0 { for i, v := range w.pkgs.Data() { if v == line[2:] { w.pkgs.Delete(i) break } } } else { if w.code.Len() > 0 { w.code.Pop() } } } unstable = compile(w).Len() > 0 case '~': w.pkgs.Resize(0, 0) w.defs.Resize(0, 0) w.code.Resize(0, 0) unstable = false case '!': fmt.Println(w.source()) case ':': tree, err := parser.ParseStmtList("go-repl", line[2:], nil) if err != nil { fmt.Println("Parse error:", err) continue } w.code.Push(tree[0]) unstable = compile(w).Len() > 0 default: var tree interface{} tree, err := parser.ParseStmtList("go-repl", line[0:], nil) if err != nil { tree, err = parser.ParseDeclList("go-repl", line[0:], nil) if err != nil { fmt.Println("Parse error:", err) continue } } changed := false switch tree.(type) { case []ast.Stmt: for _, v := range tree.([]ast.Stmt) { str := new(bytes.Buffer) printer.Fprint(str, v) switch v.(type) { case *ast.AssignStmt: w.code.Push(v) changed = true default: w.exec = str.String() } } case []ast.Decl: for _, v := range tree.([]ast.Decl) { str := new(bytes.Buffer) printer.Fprint(str, v) w.defs.Push(str.String()) } changed = true } if err := compile(w); err.Len() > 0 { fmt.Println("Compile error:", err) if changed { unstable = true } } else if out, err := run(); err.Len() > 0 { fmt.Println("Runtime error:\n", err) if changed { unstable = true } } else { fmt.Print(out) } } } }
func (self *ModuleCache) processPackageData(s string) { self.scope = NewScope(nil) i := strings.Index(s, "import\n$$\n") if i == -1 { panic("Can't find the import section in the archive file") } s = s[i+len("import\n$$\n"):] i = strings.Index(s, "$$\n") if i == -1 { panic("Can't find the end of the import section in the archive file") } s = s[0:i] // leave only import section i = strings.Index(s, "\n") if i == -1 { panic("Wrong file") } self.defalias = s[len("package ") : i-1] s = s[i+1:] internalPackages := make(map[string]*bytes.Buffer) for { // for each line i := strings.Index(s, "\n") if i == -1 { break } decl := strings.TrimSpace(s[0:i]) if len(decl) == 0 { s = s[i+1:] continue } decl2, pkg := self.processExport(decl) if len(decl2) == 0 { s = s[i+1:] continue } buf := internalPackages[pkg] if buf == nil { buf = bytes.NewBuffer(make([]byte, 0, 4096)) internalPackages[pkg] = buf } buf.WriteString(decl2) buf.WriteString("\n") s = s[i+1:] } self.others = make(map[string]*Decl) for key, value := range internalPackages { decls, err := parser.ParseDeclList("", value.Bytes(), nil) if err != nil { panic(fmt.Sprintf("failure in:\n%s\n%s\n", value, err.String())) } else { if key == self.name { // main package self.main = NewDecl(self.name, DECL_MODULE, nil) addAstDeclsToModule(self.main, decls, self.scope) } else { // others self.others[key] = NewDecl(key, DECL_MODULE, nil) addAstDeclsToModule(self.others[key], decls, self.scope) } } } self.scope = nil }
func main() { fmt.Println("Welcome to the Go REPL!") fmt.Println("Enter '?' for a list of commands.") w := new(World) w.pkgs = &[]string{} w.code = &[]interface{}{} w.defs = &[]string{} w.files = token.NewFileSet() buf := bufio.NewReader(os.Stdin) unstable := false for { if unstable { fmt.Print("! ") } fmt.Print(strings.Join(*w.pkgs, " ") + "> ") read, err := buf.ReadString('\n') if err != nil { println() break } line := read[0 : len(read)-1] if len(line) == 0 { continue } w.exec = "" switch line[0] { case '?': fmt.Println("Commands:") fmt.Println("\t?\thelp") fmt.Println("\t+ (pkg)\timport package") fmt.Println("\t- (pkg)\tremove package") fmt.Println("\t-[dpc]\tpop last (declaration|package|code)") fmt.Println("\t~\treset") fmt.Println("\t: (...)\tadd persistent code") fmt.Println("\t!\tinspect source") case '+': *w.pkgs = append(*w.pkgs, strings.Trim(line[1:], " ")) unstable = true case '-': if len(line) > 1 && line[1] != ' ' { switch line[1] { case 'd': if len(*w.defs) > 0 { *w.defs = (*w.defs)[:len(*w.defs)-1] } case 'p': if len(*w.pkgs) > 0 { *w.pkgs = (*w.pkgs)[:len(*w.pkgs)-1] } case 'c': if len(*w.code) > 0 { *w.code = (*w.code)[:len(*w.code)-1] } } } else { if len(line) > 2 && len(*w.pkgs) > 0 { for i, v := range *w.pkgs { if v == line[2:] { copy((*w.pkgs)[i:], (*w.pkgs)[i+1:]) *w.pkgs = (*w.pkgs)[:len(*w.pkgs)-1] break } } } else { if len(*w.code) > 0 { *w.code = (*w.code)[:len(*w.code)-1] } } } unstable = compile(w).Len() > 0 case '~': *w.pkgs = (*w.pkgs)[:0] *w.defs = (*w.pkgs)[:0] *w.code = (*w.code)[:0] unstable = false case '!': fmt.Println(w.source()) case ':': line = line + ";" tree, err := parser.ParseStmtList(w.files, "go-repl", strings.Trim(line[1:], " ")) if err != nil { fmt.Println("Parse error:", err) continue } *w.code = append(*w.code, tree[0]) unstable = compile(w).Len() > 0 default: line = line + ";" var tree interface{} tree, err := parser.ParseStmtList(w.files, "go-repl", line[0:]) if err != nil { tree, err = parser.ParseDeclList(w.files, "go-repl", line[0:]) if err != nil { fmt.Println("Parse error:", err) continue } } changed := false switch tree.(type) { case []ast.Stmt: for _, v := range tree.([]ast.Stmt) { str := new(bytes.Buffer) printer.Fprint(str, w.files, v) switch v.(type) { case *ast.AssignStmt: *w.code = append(*w.code, v) changed = true default: w.exec = str.String() } } case []ast.Decl: for _, v := range tree.([]ast.Decl) { str := new(bytes.Buffer) printer.Fprint(str, w.files, v) *w.defs = append(*w.defs, str.String()) } changed = true } if err := compile(w); err.Len() > 0 { fmt.Println("Compile error:", err) if changed { unstable = true } } else if out, err := run(); err.Len() > 0 { fmt.Println("Runtime error:\n", err) if changed { unstable = true } } else { fmt.Print(out) } } } }