Exemplo n.º 1
0
Arquivo: file.go Projeto: kij/gocode
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)
		}
	}
}
Exemplo n.º 2
0
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
}
Exemplo n.º 3
0
// 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)
		}
	}

}
Exemplo n.º 4
0
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)
	}
}
Exemplo n.º 5
0
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)
			}
		}
	}
}
Exemplo n.º 6
0
Arquivo: module.go Projeto: kij/gocode
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
}
Exemplo n.º 7
0
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)
			}
		}
	}
}