// initGameSession if a load file exists load the old game otherwise // create a new game session. func initGameSession(a *area.Area) (sav *save.Save, err error) { path, err := goutil.SrcDir("github.com/karlek/reason/") if err != nil { return nil, errutil.Err(err) } sav, err = save.New(path + "debug.save") if err != nil { return nil, errutil.Err(err) } err = initGameLibs() if err != nil { return nil, errutil.Err(err) } // If save exists load old game session. // Otherwise create a new game session. if sav.Exists() { err = load(sav, a) } else { err = newGame(a) } if err != nil { return nil, errutil.Err(err) } // Initalize turn priority queue. turn.Init(a) return sav, nil }
// dump stores the graph as a DOT file and an image representation of the graph // as a PNG file with filenames based on "-o" flag. func dump(graph *dot.Graph) error { // Store graph to DOT file. dotPath := flagOut if !flagQuiet { log.Printf("Creating: %q\n", dotPath) } err := ioutil.WriteFile(dotPath, []byte(graph.String()), 0644) if err != nil { return errutil.Err(err) } // Generate an image representation of the graph. if flagImage { pngPath := pathutil.TrimExt(dotPath) + ".png" if !flagQuiet { log.Printf("Creating: %q\n", pngPath) } cmd := exec.Command("dot", "-Tpng", "-o", pngPath, dotPath) cmd.Stdout = os.Stdout cmd.Stderr = os.Stderr err = cmd.Run() if err != nil { return errutil.Err(err) } } return nil }
// parseSubs parses the graph representations of the given high-level control // flow primitives. If unable to locate a subgraph, a second attempt is made by // prepending $GOPATH/src/decomp.org/decomp/cmd/restructure/primitives/ to the // subgraph path. func parseSubs(subPaths []string) (subs []*graphs.SubGraph, err error) { // Prepend $GOPATH/src/decomp.org/decomp/cmd/restructure/primitives/ to the path // of missing subgraphs. subDir, err := goutil.SrcDir("decomp.org/decomp/cmd/restructure/primitives") if err != nil { return nil, errutil.Err(err) } for i, subPath := range subPaths { if ok, _ := osutil.Exists(subPath); !ok { subPath = filepath.Join(subDir, subPath) subPaths[i] = subPath } } // Parse subgraphs representing control flow primitives. for _, subPath := range subPaths { sub, err := graphs.ParseSubGraph(subPath) if err != nil { return nil, errutil.Err(err) } subs = append(subs, sub) } return subs, nil }
// Wait for input and send output to client. func takeInput(conn net.Conn) (err error) { for { query, err := bufioutil.NewReader(conn).ReadLine() if err != nil { if err.Error() == "EOF" { break } return errutil.Err(err) } // Do something with the query switch query { case settings.QueryUpdates: // Encode (send) the value. err = gob.NewEncoder(conn).Encode(settings.Updates) case settings.QueryClearAll: settings.Updates = make(map[string]bool) err = settings.SaveUpdates() case settings.QueryForceRecheck: pages, err := ini.ReadPages(settings.PagesPath) if err != nil { return errutil.Err(err) } err = page.ForceUpdate(pages) } if err != nil { return errutil.Err(err) } } return nil }
func watchConfig(watcher *fsnotify.Watcher) (err error) { for { select { case ev := <-watcher.Event: if ev != nil { if ev.Name == settings.ConfigPath { // Read settings from config file. err = ini.ReadSettings(settings.ConfigPath) if err != nil { return errutil.Err(err) } } // Retrieve an array of pages from INI file. pages, err := ini.ReadPages(settings.PagesPath) if err != nil { return errutil.Err(err) } err = page.ForceUpdate(pages) if err != nil { return errutil.Err(err) } } case err = <-watcher.Error: if err != nil { return errutil.Err(err) } } } }
// clean removes old cache files from cache root. func clean() (err error) { // Get a list of all pages. pages, err := ini.ReadPages(settings.PagesPath) if err != nil { return errutil.Err(err) } // Get a list of all cached pages. caches, err := ioutil.ReadDir(settings.CacheRoot) if err != nil { return errutil.Err(err) } for _, cache := range caches { remove := true for _, p := range pages { pageName, err := filename.Encode(p.UrlAsFilename()) if err != nil { return errutil.Err(err) } if cache.Name() == pageName+".htm" { remove = false break } } if remove { err = os.Remove(settings.CacheRoot + cache.Name()) if err != nil { return err } } } return nil }
// ascii opens an image file and prints an ascii art image. func ascii(filename string) (err error) { reader, err := os.Open(filename) if err != nil { return errutil.Err(err) } defer reader.Close() i, _, err := image.Decode(reader) if err != nil { return errutil.Err(err) } // Image width and height. width, height := i.Bounds().Dx(), i.Bounds().Dy() // Different change in x and y values depending on the aspect ratio. dx, dy := aspectRatio(width, height) // Print each line. var line string for y := 0; y < height; y += dy { line = "" // Create a line. Convert the color level of the pixel into a ascii // character. for x := 0; x < width; x += dx { line += level(i.At(x, y).RGBA()) } fmt.Println(line) } return nil }
// ReadSettings reads settings file and updates settings.Global. func ReadSettings(configPath string) (err error) { // Parse config file. file := ini.New() err = file.Load(configPath) if err != nil { return errutil.Err(err) } config, settingExist := file.Sections[sectionSettings] mail, mailExist := file.Sections[sectionMail] if settingExist { err = parseSettings(config) if err != nil { return errutil.Err(err) } } if mailExist { err = parseMail(mail) if err != nil { return errutil.Err(err) } } return nil }
// Opens all links with browser. func readAll(bw *bufioutil.Writer, conn net.Conn) (err error) { // Read in config file to settings.Global err = ini.ReadSettings(settings.ConfigPath) if err != nil { return errutil.Err(err) } ups, err := getUpdates(bw, conn) if err != nil { return errutil.Err(err) } if settings.Global.Browser == "" { fmt.Println("No browser path set in:", settings.ConfigPath) return nil } // If no updates was found, ask for forgiveness. if len(ups) == 0 { fmt.Println("Sorry, no updates :(") return nil } var arguments []string // Loop through all updates and open them with the browser for up := range ups { arguments = append(arguments, up) } cmd := exec.Command(settings.Global.Browser, arguments...) err = cmd.Start() if err != nil { return errutil.Err(err) } return nil }
// initGameLibs initializes creature, fauna and item libraries. func initGameLibs() (err error) { // Init graphic library. err = termbox.Init() if err != nil { return errutil.Err(err) } // Initialize creatures. err = creature.Load() if err != nil { return errutil.Err(err) } // Initialize fauna. err = terrain.Load() if err != nil { return errutil.Err(err) } // Initialize items. err = item.Load() if err != nil { return errutil.Err(err) } // Initialize Objects. err = object.Load() if err != nil { return errutil.Err(err) } ui.SetTerminal() return nil }
// NewFunc returns a new function based on the given result type, function name, // and function parameters. func NewFunc(result, gname, params interface{}) (*ir.Function, error) { if result, ok := result.(types.Type); ok { name, err := getGlobalName(gname) if err != nil { return nil, errutil.Err(err) } var sig *types.Func switch params := params.(type) { case *Params: sig, err = types.NewFunc(result, params.params, params.variadic) if err != nil { return nil, errutil.Err(err) } case nil: sig, err = types.NewFunc(result, nil, false) if err != nil { return nil, errutil.Err(err) } default: return nil, errutil.Newf("invalid function parameters specifier type; expected *Params, got %T", params) } return ir.NewFunction(name, sig), nil } return nil, errutil.Newf("invalid function result type; expected types.Type, got %T", result) }
// walls downloads wallpapers based on the given search query, output dir, and // search options. Download at most n wallpapers (0 = infinite). func walls(query string, dir string, n int, options []wallhaven.Option) error { // Create output directory. if err := os.MkdirAll(dir, 0755); err != nil { return errutil.Err(err) } // Download at most n wallpapers (0 = infinite). total := 0 for { ids, err := wallhaven.Search(query, options...) if err != nil { return errutil.Err(err) } if len(ids) == 0 { return nil } for _, id := range ids { path, err := id.Download(dir) if err != nil { return errutil.Err(err) } fmt.Println(path) // Download at most n wallpapers. if total+1 == n { return nil } total++ } // Turn to the next result page. options = nextPage(options) } }
// Check performs a static semantic analysis check on the given file. func Check(file *ast.File) (*Info, error) { // Semantic analysis is done in two passes to allow for forward references. // Firstly, the global declarations are added to the file-scope. Secondly, // the global function declaration bodies are traversed to resolve // identifiers and deduce the types of expressions. // Identifier resolution. info := &Info{ Types: make(map[ast.Expr]types.Type), Scopes: make(map[ast.Node]*Scope), } if err := resolve(file, info.Scopes); err != nil { return nil, errutil.Err(err) } // Type-checking. if err := typecheck.Check(file, info.Types); err != nil { return nil, errutil.Err(err) } // Semantic analysis. if err := semcheck.Check(file); err != nil { return nil, errutil.Err(err) } return info, nil }
// NewCharArray returns a character array constant based on the given array type // and string. func NewCharArray(typ types.Type, s string) (*Array, error) { // Verify array type. v := new(Array) var ok bool v.typ, ok = typ.(*types.Array) if !ok { return nil, fmt.Errorf("invalid type %q for array constant", typ) } var err error s, err = unquote(s) if err != nil { return nil, errutil.Err(err) } // Verify array element types. if len(s) != v.typ.Len() { return nil, fmt.Errorf("incorrect number of elements in character array constant; expected %d, got %d", v.typ.Len(), len(s)) } elemType := v.typ.Elem() if !types.Equal(elemType, types.I8) { return nil, fmt.Errorf("invalid character array element type; expected %q, got %q", types.I8, elemType) } for i := 0; i < len(s); i++ { elem, err := NewInt(elemType, strconv.Itoa(int(s[i]))) if err != nil { return nil, errutil.Err(err) } v.elems = append(v.elems, elem) } return v, nil }
// parseBasicBlock converts the provided LLVM IR basic block into a basic block // in which the instructions have been translated to Go AST statement nodes but // the terminator instruction is an unmodified LLVM IR value. func parseBasicBlock(llBB llvm.BasicBlock) (bb *basicBlock, err error) { name, err := getBBName(llBB.AsValue()) if err != nil { return nil, err } bb = &basicBlock{name: name, phis: make(map[string][]*definition)} for inst := llBB.FirstInstruction(); !inst.IsNil(); inst = llvm.NextInstruction(inst) { // Handle terminator instruction. if inst == llBB.LastInstruction() { err = bb.addTerm(inst) if err != nil { return nil, errutil.Err(err) } return bb, nil } // Handle PHI instructions. if inst.InstructionOpcode() == llvm.PHI { ident, def, err := parsePHIInst(inst) if err != nil { return nil, errutil.Err(err) } bb.phis[ident] = def continue } // Handle non-terminator instructions. stmt, err := parseInst(inst) if err != nil { return nil, err } bb.stmts = append(bb.stmts, stmt) } return nil, errutil.Newf("invalid basic block %q; contains no instructions", name) }
func speak(grammarPath string) error { // Parse the grammar. f, err := os.Open(grammarPath) if err != nil { return errutil.Err(err) } defer f.Close() grammar, err := ebnf.Parse(filepath.Base(grammarPath), f) if err != nil { return errutil.Err(err) } if err = ebnf.Verify(grammar, "Program"); err != nil { return errutil.Err(err) } pretty.Println(grammar) terms := Terminals(grammar) _ = pretty.Print //fmt.Println("=== [ Grammar ] ===") //pretty.Println(grammar) //fmt.Println("=== [ Terminals ] ===") //pretty.Println(terms) fmt.Println("=== [ Regular expressions ] ===") for _, term := range terms { //pretty.Println(term) fmt.Println("term:", RegexpString(grammar, term)) } return nil }
// createDOT creates a DOT graph with the given file name. func createDOT(stepName string, graph *dot.Graph) error { dotPath := stepName + ".dot" if !flagQuiet { log.Printf("Creating: %q", dotPath) } buf := []byte(graph.String()) if err := ioutil.WriteFile(dotPath, buf, 0644); err != nil { return errutil.Err(err) } // Generate an image representation of the control flow graph. if flagImage { pngPath := stepName + ".png" if !flagQuiet { log.Printf("Creating: %q", pngPath) } cmd := exec.Command("dot", "-Tpng", "-o", pngPath, dotPath) cmd.Stdout = os.Stdout cmd.Stderr = os.Stderr if err := cmd.Run(); err != nil { return errutil.Err(err) } } return nil }
// checkFile performs a static semantic analysis check on the given file. func compileFile(path string, output io.Writer, goccLexer bool) error { // Lexical analysis // Syntactic analysis // Semantic analysis // Intermediate representation generation // Create lexer for the input. buf, err := ioutilx.ReadFile(path) if err != nil { return errutil.Err(err) } if path == "-" { path = "<stdin>" } fmt.Fprintf(os.Stderr, "Compiling %q\n", path) var s parser.Scanner if goccLexer { s = goccscanner.NewFromBytes(buf) } else { s = handscanner.NewFromBytes(buf) } // Parse input. p := parser.NewParser() f, err := p.Parse(s) if err != nil { if err, ok := err.(*goccerrors.Error); ok { // Unwrap Gocc error. return parser.NewError(err) } return errutil.Err(err) } file := f.(*ast.File) input := string(buf) src := semerrors.NewSource(path, input) info, err := sem.Check(file) if err != nil { if err, ok := err.(*errutil.ErrInfo); ok { // Unwrap errutil error. if err, ok := err.Err.(*semerrors.Error); ok { // Unwrap semantic analysis error, and add input source information. err.Src = src return err } } return errutil.Err(err) } // Generate LLVM IR module based on the syntax tree of the given file. module := irgen.Gen(file, info) if _, err := fmt.Fprint(output, module); err != nil { return errutil.Err(err) } return nil }
// walkIdent walks the parse tree of the given identifier expression in depth // first order. func walkIdent(ident *ast.Ident, before, after func(ast.Node) error) error { if err := before(ident); err != nil { return errutil.Err(err) } if err := after(ident); err != nil { return errutil.Err(err) } return nil }
// walkBasicLit walks the parse tree of the given basic literal expression in // depth first order. func walkBasicLit(lit *ast.BasicLit, before, after func(ast.Node) error) error { if err := before(lit); err != nil { return errutil.Err(err) } if err := after(lit); err != nil { return errutil.Err(err) } return nil }
// Download the page with or without user specified headers. func (p *Page) download() (doc *html.Node, err error) { // Construct the request. req, err := http.NewRequest("GET", p.ReqUrl.String(), nil) if err != nil { return nil, errutil.Err(err) } // If special headers were specified, add them to the request. if p.Settings.Header != nil { for key, val := range p.Settings.Header { req.Header.Add(key, val) } } // Do request and read response. resp, err := http.DefaultClient.Do(req) if err != nil { if serr, ok := err.(*url.Error); ok { if serr.Err == io.EOF { return nil, errutil.NewNoPosf("Update was empty: %s", p.ReqUrl) } } return nil, errutil.Err(err) } defer resp.Body.Close() // If response contained a client or server error, fail with that error. if resp.StatusCode >= 400 { return nil, errutil.Newf("%s: (%d) - %s", p.ReqUrl.String(), resp.StatusCode, resp.Status) } // Read the response body to []byte. buf, err := ioutil.ReadAll(resp.Body) if err != nil { return nil, errutil.Err(err) } // Fix charset problems with servers that doesn't use utf-8 charset := "utf-8" content := string(buf) types := strings.Split(resp.Header.Get("Content-Type"), ` `) for _, typ := range types { if strings.Contains(typ, "charset") { keyval := strings.Split(typ, `=`) if len(keyval) == 2 { charset = keyval[1] } } } if charset != "utf-8" { content = mahonia.NewDecoder(charset).ConvertString(content) } // Parse response into html.Node. return html.Parse(strings.NewReader(content)) }
// walkEmptyStmt walks the parse tree of the given empty statement in depth // first order. func walkEmptyStmt(stmt *ast.EmptyStmt, before, after func(ast.Node) error) error { if err := before(stmt); err != nil { return errutil.Err(err) } if err := after(stmt); err != nil { return errutil.Err(err) } return nil }
// checkFile performs a static semantic analysis check on the given file. func checkFile(path string, goccLexer bool) error { // Lexical analysis // Syntactic analysis (skip function bodies) // Top-level declarations; used for forward-declarations. // Syntactic analysis (including function bodies) // NOTE: "For each method body, we rewind the lexer to the point where the // method body began and parse the method body." // // ref: https://blogs.msdn.microsoft.com/ericlippert/2010/02/04/how-many-passes/ // Semantic analysis // Create lexer for the input. buf, err := ioutilx.ReadFile(path) if err != nil { return errutil.Err(err) } if path == "-" { path = "<stdin>" } fmt.Fprintf(os.Stderr, "Checking %q\n", path) var s parser.Scanner if goccLexer { s = goccscanner.NewFromBytes(buf) } else { s = handscanner.NewFromBytes(buf) } // Parse input. p := parser.NewParser() f, err := p.Parse(s) if err != nil { if err, ok := err.(*goccerrors.Error); ok { // Unwrap Gocc error. return parser.NewError(err) } return errutil.Err(err) } file := f.(*ast.File) input := string(buf) src := semerrors.NewSource(path, input) if _, err := sem.Check(file); err != nil { if err, ok := err.(*errutil.ErrInfo); ok { // Unwrap errutil error. if err, ok := err.Err.(*semerrors.Error); ok { // Unwrap semantic analysis error, and add input source information. err.Src = src return err } } return errutil.Err(err) } return nil }
// load parses a JSON data file into a go creature object. func load(filename string) (c *Creature, err error) { // jsonCreature is a temporary struct for easier conversion between JSON and // go structs. type jsonCreature struct { Name string Graphics struct { Ch string Fg map[string]string Bg map[string]string } Hp int Strength int Sight int Speed int Regeneration int } buf, err := ioutil.ReadFile(filename) if err != nil { return nil, errutil.Err(err) } var jc jsonCreature err = json.Unmarshal(buf, &jc) if err != nil { return nil, errutil.Err(err) } fg, err := util.ParseColor(jc.Graphics.Fg) if err != nil { return nil, errutil.Err(err) } bg, err := util.ParseColor(jc.Graphics.Bg) if err != nil { return nil, errutil.Err(err) } c = &Creature{ name: jc.Name, Hp: jc.Hp, MaxHp: jc.Hp, Strength: jc.Strength, Speed: jc.Speed, Sight: jc.Sight, Regeneration: jc.Regeneration, Inventory: make(Inventory, len(item.Positions)), } c.SetPathable(false) c.SetGraphics(termbox.Cell{ Ch: rune(jc.Graphics.Ch[0]), Fg: fg, Bg: bg, }) return c, nil }
// NewFMul returns a new fmul instruction based on the given operand type and // operands. func NewFMulInst(typ, xVal, yVal interface{}) (*instruction.FMul, error) { x, err := NewValue(typ, xVal) if err != nil { return nil, errutil.Err(err) } y, err := NewValue(typ, yVal) if err != nil { return nil, errutil.Err(err) } return instruction.NewFMul(x, y) }
// walkReturnStmt walks the parse tree of the given return statement in depth // first order. func walkReturnStmt(stmt *ast.ReturnStmt, before, after func(ast.Node) error) error { if err := before(stmt); err != nil { return errutil.Err(err) } if err := WalkBeforeAfter(stmt.Result, before, after); err != nil { return errutil.Err(err) } if err := after(stmt); err != nil { return errutil.Err(err) } return nil }
// walkArrayType walks the parse tree of the given array type in depth first // order. func walkArrayType(arr *ast.ArrayType, before, after func(ast.Node) error) error { if err := before(arr); err != nil { return errutil.Err(err) } if err := WalkBeforeAfter(arr.Elem, before, after); err != nil { return errutil.Err(err) } if err := after(arr); err != nil { return errutil.Err(err) } return nil }
// walkUnaryExpr walks the parse tree of the given unary expression in depth // first order. func walkUnaryExpr(expr *ast.UnaryExpr, before, after func(ast.Node) error) error { if err := before(expr); err != nil { return errutil.Err(err) } if err := WalkBeforeAfter(expr.X, before, after); err != nil { return errutil.Err(err) } if err := after(expr); err != nil { return errutil.Err(err) } return nil }
// locate parses the provided graphs and tries to locate isomorphisms of the // subgraph in the graph. func locate(graphPath, subPath string) error { // Parse graph. graph, err := dot.ParseFile(graphPath) if err != nil { return errutil.Err(err) } // Search for subgraph in GOPATH if not found. if ok, _ := osutil.Exists(subPath); !ok { dir, err := goutil.SrcDir("decomp.org/decomp/graphs/testdata/primitives") if err != nil { return errutil.Err(err) } subPath = filepath.Join(dir, subPath) } sub, err := graphs.ParseSubGraph(subPath) if err != nil { return errutil.Err(err) } // Locate isomorphisms. found := false if len(flagStart) > 0 { // Locate an isomorphism of sub in graph which starts at the node // specified by the "-start" flag. m, ok := iso.Isomorphism(graph, flagStart, sub) if ok { found = true printMapping(graph, sub, m) } } else { // Locate all isomorphisms of sub in graph. var names []string for name := range graph.Nodes.Lookup { names = append(names, name) } sort.Strings(names) for _, name := range names { m, ok := iso.Isomorphism(graph, name, sub) if !ok { continue } found = true printMapping(graph, sub, m) } } if !found { fmt.Println("not found.") } return nil }
// Check type-checks the given file, and store a mapping from expression nodes // to types in exprTypes. func Check(file *ast.File, exprTypes map[ast.Expr]types.Type) error { // Deduce the types of expressions. if err := deduce(file, exprTypes); err != nil { return errutil.Err(err) } // Type-check file. if err := check(file, exprTypes); err != nil { return errutil.Err(err) } return nil }