<commit_before>package rap

import (
	"encoding/json"
	"errors"
	"fmt"
	"google.golang.org/appengine"
	"google.golang.org/appengine/datastore"
	"google.golang.org/appengine/log"
	"google.golang.org/appengine/memcache"
	"hash/fnv"
	"math"
	"net/http"
	"strconv"
	"strings"
)

type featurecollection struct {
	GeoType  string     `json:"type"`
	Features []*feature `json:"features"`
}

type feature struct {
	Geotype    string    `json:"type"`
	Geometry   *geometry `json:"geometry"`
	Properties *resource `json:"properties"`
}

type geometry struct {
	Geotype     string    `json:"type"`
	Coordinates []float64 `json:"coordinates"`
	Id          string    `json:"id"`
}

/* we need to format our resources like so
from the geojson spec:
http://geojson.org/geojson-spec.html#geometrycollection

I think we'll want to implement OData querying on resources with an extra flag for whether we return the data as json or geojson.
We need the geojson for easy population of maps, but the regular json would be more useful for anything else (like webpages that update the resource).

But... that's all future stuff. For now the only thing I am doing is geojson and caching.

{ "type": "FeatureCollection",
    "features": [
      { "type": "Feature",
        "geometry": {"type": "Point", "coordinates": [102.0, 0.5]},
        "properties": {"prop0": "value0"}
        },
*/

/*
I'm thinking we store the data under 4 keys, one for each category
func get_data(){
    data = memcache.Get('key')
    if data != nil{
        return data
   }
    else{
        data = self.Query_for_data()
        memcache.Add('key', data, 60)
        return data
   }
}
*/

func resources(w http.ResponseWriter, r *http.Request) *appError {
	//log.Infof(r.Method)

	switch r.Method {
	case "GET":
		return getResources(w, r)
	case "POST":
		//auth, validate, add to datastore, invalidate cache
		return &appError{
			errors.New("Post not yet implemented"),
			"RESTful updates not yet implemented",
			http.StatusNotImplemented,
		}
	case "PUT":
		//auth, validate, update in datastore, invalidate cache
		return &appError{
			errors.New("Put not yet implemented"),
			"RESTful updates not yet implemented",
			http.StatusNotImplemented,
		}
	case "DELETE":
		//auth, validate, update in datastore, invalidate cache
		return &appError{
			errors.New("Delete not yet implemented"),
			"RESTful updates not yet implemented",
			http.StatusNotImplemented,
		}
	default:
		return &appError{
			errors.New("Attempted unsupport HTTP method " + r.Method),
			"Unsupported HTTP method",
			http.StatusMethodNotAllowed,
		}
	}
}

func getResources(w http.ResponseWriter, r *http.Request) *appError {
	c := appengine.NewContext(r)
	//get query from request
	u := r.URL.Query()
	top := strings.Trim(u.Get("top"), " ")
	//qselect :=u.Get("select") //dunno if we'll ever support this
	//filter := strings.Trim(u.Get("filter"), " ")
	//count := strings.Trim(u.Get("count"), " ") //not yet implemented, maybe once there is a web interface for editting data
	//everything is text right now so this might not work as expected
	orderby := strings.ToLower(strings.Trim(u.Get("orderby"), " "))
	skip := strings.Trim(u.Get("skip"), " ")

	//This text search will hit the description field... or we would except that datastore doesn't support that kinda thing
	//you can get around that restriction by creating a field that is a unique list of all the strings and searching that. Of course we're not doing that right now.
	//search := strings.Trim(u.Get("search"), " ")

	//eventually allow for straight json as opposed to the geojson we normally serve - not supported yet :P
	//format:=u.Get("format")

	//here we should check the cache to see if it holds an identical query so we can return that
	h := fnv.New64a()
	h.Write([]byte("rap_query" + top + orderby + skip))
	cacheKey := h.Sum64()

	cv, err := memcache.Get(c, fmt.Sprint(cacheKey))
	if err == nil {
		w.Header().Set("Content-Type", "application/json; charset=utf-8")
		w.Write(cv.Value)
		return nil
	}

	//build query against the db
	q := datastore.NewQuery("Resource").Filter("isactive =", true)

	//loop through the filters - not yet implemented - awaiting import improvements
	/*
		if len(filter) > 0 {
			//= q.Filter(
		}
	*/

	//handle orderby - works for a single order
	if len(orderby) > 0 { //need to actually parse
		//check to see if the string ends with desc
		if strings.LastIndex(orderby, "desc") > len(orderby)-len(" desc") {
			orderby = strings.Trim(orderby[:len(orderby)-len(" desc")], " ")
			q = q.Order("-" + orderby)
		}
		q = q.Order(orderby)
	} else {
		q = q.Order("organizationname")
	}

	res := make([]*resource, 0)

	//based on https://cloud.google.com/appengine/docs/go/datastore/queries#Go_Sort_orders
	//use the cursor to handle the top and skip
	//In this case we don't care about the error because the int will then be zero. We'll proceed with the query with what worked.
	//Alternatively we could check the errors and return a bad request accordingly
	s, _ := strconv.Atoi(skip)
	t, _ := strconv.Atoi(top)
	if s > 0 || t > 0 {
		if t == 0 {
			t = math.MaxInt32
		}

		// Iterate over the results.
		iter := q.Run(c)
		var tmp resource
		var err error
		for i := 0; s+t > i; i++ {
			if s > i {
				_, err = iter.Next(nil) //don't pull anything till we're done skipping
			} else {
				_, err = iter.Next(&tmp)
			}

			if err == datastore.Done {
				log.Debugf(c, "i %d, s %d, t %d", i, s, t)
				break
			}
			if err != nil {
				return &appError{
					err,
					"Error in skip/top querying",
					http.StatusInternalServerError,
				}
			}

			//don't keep anything till we're done skipping
			if i >= s {
				res = append(res, &tmp)
			}
		}
	} else {
		//execute query against the db
		_, err := q.GetAll(c, &res)

		if err != nil {
			return &appError{err, "Error querying database", http.StatusInternalServerError}
		}
	}

	//make geojson from the db results
	f := make([]*feature, 0)

	log.Debugf(c, "res contains %v items", len(res))
	for _, v := range res {
		f = append(f, &feature{
			Geotype: "Feature",
			Geometry: &geometry{
				Geotype: "Point",
				Coordinates: []float64{
					v.Location.Lng,
					v.Location.Lat,
					0,
				},
				//Id: strconv.FormatInt(v.ID, 10), //not needed
			},
			Properties: v,
		})
	}

	gc := featurecollection{
		"FeatureCollection",
		f,
	}

	tmp, err := json.Marshal(gc)
	if err != nil {
		return &appError{err, "Error creating response", http.StatusInternalServerError}
	}

	//cache this result with it's query as the key
	memcache.Set(c, &memcache.Item{
		Key:   fmt.Sprint(cacheKey),
		Value: tmp,
	})

	//return the json version
	w.Header().Set("Content-Type", "application/json; charset=utf-8")
	w.Write(tmp)
	return nil
}

func odataLogicalOperatorConverter(eo string) (string, error) {
	switch strings.ToLower(strings.Trim(eo, " ")) {
	case "eq":
		return "=", nil
		//case "ne": //not directly supported by datastore
	//return "!="
	case "gt":
		return ">", nil
	case "ge":
		return ">=", nil
	case "lt":
		return "<", nil
	case "le":
		return "<=", nil
	default:
		return "", errors.New("Unknown or unsupported operator")
	}
}
<commit_msg>Added filtering.<commit_after>package rap

import (
	"encoding/json"
	"errors"
	"fmt"
	"google.golang.org/appengine"
	"google.golang.org/appengine/datastore"
	"google.golang.org/appengine/log"
	"google.golang.org/appengine/memcache"
	"hash/fnv"
	"math"
	"net/http"
	"strconv"
	"strings"
)

type featurecollection struct {
	GeoType  string     `json:"type"`
	Features []*feature `json:"features"`
}

type feature struct {
	Geotype    string    `json:"type"`
	Geometry   *geometry `json:"geometry"`
	Properties *resource `json:"properties"`
}

type geometry struct {
	Geotype     string    `json:"type"`
	Coordinates []float64 `json:"coordinates"`
	Id          string    `json:"id"`
}

/* we need to format our resources like so
from the geojson spec:
http://geojson.org/geojson-spec.html#geometrycollection

I think we'll want to implement OData querying on resources with an extra flag for whether we return the data as json or geojson.
We need the geojson for easy population of maps, but the regular json would be more useful for anything else (like webpages that update the resource).

But... that's all future stuff. For now the only thing I am doing is geojson and caching.

{ "type": "FeatureCollection",
    "features": [
      { "type": "Feature",
        "geometry": {"type": "Point", "coordinates": [102.0, 0.5]},
        "properties": {"prop0": "value0"}
        },
*/

/*
I'm thinking we store the data under 4 keys, one for each category
func get_data(){
    data = memcache.Get('key')
    if data != nil{
        return data
   }
    else{
        data = self.Query_for_data()
        memcache.Add('key', data, 60)
        return data
   }
}
*/

func resources(w http.ResponseWriter, r *http.Request) *appError {
	//log.Infof(r.Method)

	switch r.Method {
	case "GET":
		return getResources(w, r)
	case "POST":
		//auth, validate, add to datastore, invalidate cache
		return &appError{
			errors.New("Post not yet implemented"),
			"RESTful updates not yet implemented",
			http.StatusNotImplemented,
		}
	case "PUT":
		//auth, validate, update in datastore, invalidate cache
		return &appError{
			errors.New("Put not yet implemented"),
			"RESTful updates not yet implemented",
			http.StatusNotImplemented,
		}
	case "DELETE":
		//auth, validate, update in datastore, invalidate cache
		return &appError{
			errors.New("Delete not yet implemented"),
			"RESTful updates not yet implemented",
			http.StatusNotImplemented,
		}
	default:
		return &appError{
			errors.New("Attempted unsupport HTTP method " + r.Method),
			"Unsupported HTTP method",
			http.StatusMethodNotAllowed,
		}
	}
}

func getResources(w http.ResponseWriter, r *http.Request) *appError {
	c := appengine.NewContext(r)
	//get query from request
	u := r.URL.Query()
	top := strings.Trim(u.Get("top"), " ")
	//qselect :=u.Get("select") //dunno if we'll ever support this
	filter := strings.Trim(u.Get("filter"), " ")
	//count := strings.Trim(u.Get("count"), " ") //not yet implemented, maybe once there is a web interface for editting data
	//everything is text right now so this might not work as expected
	orderby := strings.ToLower(strings.Trim(u.Get("orderby"), " "))
	skip := strings.Trim(u.Get("skip"), " ")

	//This text search will hit the description field... or we would except that datastore doesn't support that kinda thing
	//you can get around that restriction by creating a field that is a unique list of all the strings and searching that. Of course we're not doing that right now.
	//search := strings.Trim(u.Get("search"), " ")

	//eventually allow for straight json as opposed to the geojson we normally serve - not supported yet :P
	//format:=u.Get("format")

	//here we should check the cache to see if it holds an identical query so we can return that
	h := fnv.New64a()
	h.Write([]byte("rap_query" + top + filter + orderby + skip))
	cacheKey := h.Sum64()

	cv, err := memcache.Get(c, fmt.Sprint(cacheKey))
	if err == nil {
		w.Header().Set("Content-Type", "application/json; charset=utf-8")
		w.Write(cv.Value)
		return nil
	}

	//build query against the db
	q := datastore.NewQuery("Resource").Filter("isactive =", true)

	//loop through the filters
	log.Debugf(c, "filter %s", filter)
	if len(filter) > 0 {
		if cn, eo, fv, err := filterParser(filter); err == nil {
			log.Debugf(c, "cn %s, eo %s, fv %s", cn, eo, fv)
			q = q.Filter(cn+" "+eo, fv)
		} else {
			log.Debugf(c, "filter parsing error %s", err)
		}
	}

	//handle orderby - works for a single order
	if len(orderby) > 0 { //need to actually parse
		//check to see if the string ends with desc
		if strings.LastIndex(orderby, "desc") > len(orderby)-len(" desc") {
			orderby = strings.Trim(orderby[:len(orderby)-len(" desc")], " ")
			orderby = "-" + orderby
		}
		q = q.Order(orderby)
	} else {
		q = q.Order("organizationname")
	}

	res := make([]*resource, 0)

	//based on https://cloud.google.com/appengine/docs/go/datastore/queries#Go_Sort_orders
	//use the cursor to handle the top and skip
	//In this case we don't care about the error because the int will then be zero. We'll proceed with the query with what worked.
	//Alternatively we could check the errors and return a bad request accordingly
	s, _ := strconv.Atoi(skip)
	t, _ := strconv.Atoi(top)
	if s > 0 || t > 0 {
		if t == 0 {
			t = math.MaxInt32
		}

		// Iterate over the results.
		iter := q.Run(c)
		var tmp resource
		var err error
		for i := 0; s+t > i; i++ {
			if s > i {
				_, err = iter.Next(nil) //don't pull anything till we're done skipping
			} else {
				_, err = iter.Next(&tmp)
			}

			if err == datastore.Done {
				log.Debugf(c, "i %d, s %d, t %d", i, s, t)
				break
			}
			if err != nil {
				return &appError{
					err,
					"Error in skip/top querying",
					http.StatusInternalServerError,
				}
			}

			//don't keep anything till we're done skipping
			if i >= s {
				res = append(res, &tmp)
			}
		}
	} else {
		//execute query against the db
		_, err := q.GetAll(c, &res)

		if err != nil {
			return &appError{err, "Error querying database", http.StatusInternalServerError}
		}
	}

	//make geojson from the db results
	f := make([]*feature, 0)

	log.Debugf(c, "res contains %v items", len(res))
	for _, v := range res {
		f = append(f, &feature{
			Geotype: "Feature",
			Geometry: &geometry{
				Geotype: "Point",
				Coordinates: []float64{
					v.Location.Lng,
					v.Location.Lat,
					0,
				},
				//Id: strconv.FormatInt(v.ID, 10), //not needed
			},
			Properties: v,
		})
	}

	gc := featurecollection{
		"FeatureCollection",
		f,
	}

	tmp, err := json.Marshal(gc)
	if err != nil {
		return &appError{err, "Error creating response", http.StatusInternalServerError}
	}

	//cache this result with it's query as the key
	memcache.Set(c, &memcache.Item{
		Key:   fmt.Sprint(cacheKey),
		Value: tmp,
	})

	//return the json version
	w.Header().Set("Content-Type", "application/json; charset=utf-8")
	w.Write(tmp)
	return nil
}

//I'd like to refactor this function and logicalOperatorConverter so that the logical operators are a single map used in both
func filterParser(f string) (cn, eo, fv string, err error) {
	odataOperators := []string{"eq", "gt", "ge", "lt", "le"}

	//find the operator in this filter and use it to split the filter
	for _, lo := range odataOperators {
		if strings.Index(f, lo) == -1 {
			continue
		}

		parts := strings.Split(f, lo)
		if len(parts) != 2 {
			err = errors.New("Incorrect number of filter parameters")
			break
		}

		if eo, err = logicalOperatorConverter(lo); err == nil {
			cn = strings.Trim(parts[0], " ")
			fv = strings.Trim(parts[1], " ")
			return
		}

		break
	}

	if err == nil {
		err = errors.New("No supported logical operator was found")
	}

	return "", "", "", err
}

func logicalOperatorConverter(eo string) (string, error) {
	switch strings.ToLower(strings.Trim(eo, " ")) {
	case "eq":
		return "=", nil
		//case "ne": //not directly supported by datastore
	//return "!="
	case "gt":
		return ">", nil
	case "ge":
		return ">=", nil
	case "lt":
		return "<", nil
	case "le":
		return "<=", nil
	default:
		return "", errors.New("Unknown or unsupported operator")
	}
}
<|endoftext|>


<commit_before>package sudoku

import (
	"math/rand"
)

//GenerationOptions provides configuration options for generating a sudoku puzzle.
type GenerationOptions struct {
	//symmetrty and symmetryType control the aesthetics of the generated grid. symmetryPercentage
	//controls roughly what percentage of cells with have a filled partner across the provided plane of
	//symmetry.
	Symmetry           SymmetryType
	SymmetryPercentage float64
	//The minimum number of cells to leave filled in the puzzle. The generated puzzle might have
	//more filled cells. A value of DIM * DIM - 1, for example, would return an extremely trivial
	//puzzle.
	MinFilledCells int
}

//TODO: consider providing a GenerationOptions.Default(), just like HumanSolveOptions does.
var defaultGenerationOptions GenerationOptions

func init() {
	defaultGenerationOptions = GenerationOptions{
		Symmetry:           SYMMETRY_VERTICAL,
		SymmetryPercentage: 0.7,
		MinFilledCells:     0,
	}
}

//Fill will find a random filling of the puzzle such that every cell is filled and no cells conflict with their neighbors. If it cannot find one,
// it will return false and leave the grid as it found it. Generally you would only want to call this on
//grids that have more than one solution (e.g. a fully blank grid). Fill provides a good starting point for generated puzzles.
func (self *Grid) Fill() bool {

	solutions := self.nOrFewerSolutions(1)

	if len(solutions) != 0 {
		self.Load(solutions[0].DataString())
		return true
	}

	return false
}

//GenerateGrid returns a new sudoku puzzle with a single unique solution and many of its cells unfilled--a
//puzzle that is appropriate (and hopefully fun) for humans to solve. GenerateGrid first finds a random
//full filling of the grid, then iteratively removes cells until just before the grid begins having
//multiple solutions. The result is a grid that has a single valid solution but many of its cells
//unfilled. Pass nil for options to use reasonable defaults.
//GenerateGrid doesn't currently give any way to define the desired difficulty; the best option is to
//repeatedly generate puzzles until you find one that matches your desired difficulty. cmd/dokugen
//applies this technique.
func GenerateGrid(options *GenerationOptions) *Grid {

	if options == nil {
		options = &defaultGenerationOptions
	}

	grid := NewGrid()
	//Do a random fill of the grid
	grid.Fill()

	//Make a copy so we don't mutate the passed in dict
	symmetryPercentage := options.SymmetryPercentage

	//Make sure symmetry percentage is within the legal range.
	if symmetryPercentage < 0.0 {
		symmetryPercentage = 0.0
	}
	if symmetryPercentage > 1.0 {
		symmetryPercentage = 1.0
	}

	cells := make([]*Cell, len(grid.cells[:]))

	for i, j := range rand.Perm(len(grid.cells[:])) {
		cells[i] = &grid.cells[j]
	}

	for _, cell := range cells {

		num := cell.Number()
		if num == 0 {
			continue
		}

		var otherNum int
		var otherCell *Cell

		if rand.Float64() < symmetryPercentage {

			//Pick a symmetrical partner for symmetryPercentage number of cells.
			otherCell = cell.SymmetricalPartner(options.Symmetry)

			if otherCell != nil {
				if otherCell.Number() == 0 {
					//We must have already un-filled it as a primary cell.
					//If we were to unfill this, we could get in a weird state where
					//we get multiple solutions without noticing (which caused bug #134).
					//So pretend like we didn't draw one.
					otherCell = nil
				} else {
					otherNum = otherCell.Number()
				}
			}
		}

		numCellsToFillThisStep := 1
		if otherCell != nil {
			numCellsToFillThisStep = 2
		}

		if grid.numFilledCells-numCellsToFillThisStep < options.MinFilledCells {
			//Doing this step would leave us with too few cells filled. Finish.
			continue
		}

		//Unfill it.
		cell.SetNumber(0)
		if otherCell != nil {
			otherCell.SetNumber(0)
		}
		if grid.HasMultipleSolutions() {
			//Put it back in.
			cell.SetNumber(num)
			if otherCell != nil {
				otherCell.SetNumber(otherNum)
			}
		}
	}

	return grid
}
<commit_msg>Fixed a small logic error that caused us to do extra work in some cases in generate. Fixes #142.<commit_after>package sudoku

import (
	"math/rand"
)

//GenerationOptions provides configuration options for generating a sudoku puzzle.
type GenerationOptions struct {
	//symmetrty and symmetryType control the aesthetics of the generated grid. symmetryPercentage
	//controls roughly what percentage of cells with have a filled partner across the provided plane of
	//symmetry.
	Symmetry           SymmetryType
	SymmetryPercentage float64
	//The minimum number of cells to leave filled in the puzzle. The generated puzzle might have
	//more filled cells. A value of DIM * DIM - 1, for example, would return an extremely trivial
	//puzzle.
	MinFilledCells int
}

//TODO: consider providing a GenerationOptions.Default(), just like HumanSolveOptions does.
var defaultGenerationOptions GenerationOptions

func init() {
	defaultGenerationOptions = GenerationOptions{
		Symmetry:           SYMMETRY_VERTICAL,
		SymmetryPercentage: 0.7,
		MinFilledCells:     0,
	}
}

//Fill will find a random filling of the puzzle such that every cell is filled and no cells conflict with their neighbors. If it cannot find one,
// it will return false and leave the grid as it found it. Generally you would only want to call this on
//grids that have more than one solution (e.g. a fully blank grid). Fill provides a good starting point for generated puzzles.
func (self *Grid) Fill() bool {

	solutions := self.nOrFewerSolutions(1)

	if len(solutions) != 0 {
		self.Load(solutions[0].DataString())
		return true
	}

	return false
}

//GenerateGrid returns a new sudoku puzzle with a single unique solution and many of its cells unfilled--a
//puzzle that is appropriate (and hopefully fun) for humans to solve. GenerateGrid first finds a random
//full filling of the grid, then iteratively removes cells until just before the grid begins having
//multiple solutions. The result is a grid that has a single valid solution but many of its cells
//unfilled. Pass nil for options to use reasonable defaults.
//GenerateGrid doesn't currently give any way to define the desired difficulty; the best option is to
//repeatedly generate puzzles until you find one that matches your desired difficulty. cmd/dokugen
//applies this technique.
func GenerateGrid(options *GenerationOptions) *Grid {

	if options == nil {
		options = &defaultGenerationOptions
	}

	grid := NewGrid()
	//Do a random fill of the grid
	grid.Fill()

	//Make a copy so we don't mutate the passed in dict
	symmetryPercentage := options.SymmetryPercentage

	//Make sure symmetry percentage is within the legal range.
	if symmetryPercentage < 0.0 {
		symmetryPercentage = 0.0
	}
	if symmetryPercentage > 1.0 {
		symmetryPercentage = 1.0
	}

	cells := make([]*Cell, len(grid.cells[:]))

	for i, j := range rand.Perm(len(grid.cells[:])) {
		cells[i] = &grid.cells[j]
	}

	for _, cell := range cells {

		num := cell.Number()
		if num == 0 {
			continue
		}

		var otherNum int
		var otherCell *Cell

		if rand.Float64() < symmetryPercentage {

			//Pick a symmetrical partner for symmetryPercentage number of cells.
			otherCell = cell.SymmetricalPartner(options.Symmetry)

			if otherCell != nil {
				if otherCell.Number() == 0 {
					//We must have already un-filled it as a primary cell.
					//If we were to unfill this, we could get in a weird state where
					//we get multiple solutions without noticing (which caused bug #134).
					//So pretend like we didn't draw one.
					otherCell = nil
				} else {
					otherNum = otherCell.Number()
				}
			}
		}

		numCellsToFillThisStep := 1
		if otherCell != nil {
			numCellsToFillThisStep = 2
		}

		if grid.numFilledCells-numCellsToFillThisStep < options.MinFilledCells {
			//Doing this step would leave us with too few cells filled. Finish.
			break
		}

		//Unfill it.
		cell.SetNumber(0)
		if otherCell != nil {
			otherCell.SetNumber(0)
		}
		if grid.HasMultipleSolutions() {
			//Put it back in.
			cell.SetNumber(num)
			if otherCell != nil {
				otherCell.SetNumber(otherNum)
			}
		}
	}

	return grid
}
<|endoftext|>


<commit_before>package match

import (
	"fmt"

	"github.com/tisp-lang/tisp/src/lib/ast"
	"github.com/tisp-lang/tisp/src/lib/debug"
	"github.com/tisp-lang/tisp/src/lib/gensym"
	"github.com/tisp-lang/tisp/src/lib/scalar"
)

type desugarer struct {
	letBoundNames, lets []interface{}
}

func newDesugarer() *desugarer {
	return &desugarer{nil, nil}
}

func (d *desugarer) desugar(x interface{}) interface{} {
	switch x := x.(type) {
	case ast.App:
		return ast.NewApp(
			d.desugar(x.Function()),
			d.desugar(x.Arguments()).(ast.Arguments),
			x.DebugInfo())
	case ast.Arguments:
		ps := make([]ast.PositionalArgument, 0, len(x.Positionals()))

		for _, p := range x.Positionals() {
			ps = append(ps, d.desugar(p).(ast.PositionalArgument))
		}

		ks := make([]ast.KeywordArgument, 0, len(x.Keywords()))

		for _, k := range x.Keywords() {
			ks = append(ks, d.desugar(k).(ast.KeywordArgument))
		}

		dicts := make([]interface{}, 0, len(x.ExpandedDicts()))

		for _, dict := range x.ExpandedDicts() {
			dicts = append(dicts, d.desugar(dict))
		}

		return ast.NewArguments(ps, ks, dicts)
	case ast.KeywordArgument:
		return ast.NewKeywordArgument(x.Name(), d.desugar(x.Value()))
	case ast.LetFunction:
		ls := make([]interface{}, 0, len(x.Lets()))

		for _, l := range x.Lets() {
			l := d.desugar(l)
			ls = append(ls, append(d.takeLets(), l)...)
		}

		b := d.desugar(x.Body())
		ls = append(ls, d.takeLets()...)

		return ast.NewLetFunction(
			x.Name(),
			x.Signature(),
			ls,
			b,
			x.DebugInfo())
	case ast.LetVar:
		return ast.NewLetVar(x.Name(), d.desugar(x.Expr()))
	case ast.Match:
		cs := make([]ast.MatchCase, 0, len(x.Cases()))

		for _, c := range x.Cases() {
			cs = append(cs, renameBoundNamesInCase(ast.NewMatchCase(c.Pattern(), d.desugar(c.Value()))))
		}

		return d.resultApp(d.createMatchFunction(cs), d.desugar(x.Value()))
	case ast.Output:
		return ast.NewOutput(d.desugar(x.Expr()), x.Expanded())
	case ast.PositionalArgument:
		return ast.NewPositionalArgument(d.desugar(x.Value()), x.Expanded())
	default:
		return x
	}
}

func (d *desugarer) takeLets() []interface{} {
	ls := append(d.letBoundNames, d.lets...)
	d.letBoundNames = nil
	d.lets = nil
	return ls
}

func (d *desugarer) letVar(s string, v interface{}) string {
	d.lets = append(d.lets, ast.NewLetVar(s, v))
	return s
}

func (d *desugarer) bindName(s string, v interface{}) string {
	d.letBoundNames = append(d.letBoundNames, ast.NewLetVar(s, v))
	return s
}

// matchedApp applies a function to arguments and creates a matched value of
// match expression.
func (d *desugarer) matchedApp(f interface{}, args ...interface{}) string {
	return d.bindName(gensym.GenSym("match", "app"), app(f, args...))
}

// resultApp applies a function to arguments and creates a result value of match
// expression.
func (d *desugarer) resultApp(f interface{}, args ...interface{}) string {
	return d.letVar(gensym.GenSym("match", "app"), app(f, args...))
}

func (d *desugarer) createMatchFunction(cs []ast.MatchCase) interface{} {
	arg := gensym.GenSym("match", "argument")
	body := d.desugarCases(arg, cs, "$matchError")

	f := ast.NewLetFunction(
		gensym.GenSym("match", "function"),
		ast.NewSignature([]string{arg}, nil, "", nil, nil, ""),
		d.takeLets(),
		body,
		debug.NewGoInfo(0))

	d.lets = append(d.lets, f)

	return f.Name()
}

func (d *desugarer) desugarCases(v interface{}, cs []ast.MatchCase, dc interface{}) interface{} {
	css := groupCases(cs)

	if cs, ok := css[namePattern]; ok {
		c := cs[0]
		d.bindName(c.Pattern().(string), v)
		dc = c.Value()
	}

	ks := []ast.SwitchCase{}

	if cs, ok := css[listPattern]; ok {
		ks = append(ks, ast.NewSwitchCase("\"list\"", d.desugarListCases(v, cs, dc)))
	}

	if cs, ok := css[dictPattern]; ok {
		ks = append(ks, ast.NewSwitchCase("\"dict\"", d.desugarDictCases(v, cs, dc)))
	}

	if cs, ok := css[scalarPattern]; ok {
		dc = d.desugarScalarCases(v, cs, dc)
	}

	return newSwitch(d.resultApp("$typeOf", v), ks, dc)
}

func groupCases(cs []ast.MatchCase) map[patternType][]ast.MatchCase {
	css := map[patternType][]ast.MatchCase{}

	for i, c := range cs {
		t := getPatternType(c.Pattern())

		if t == namePattern && i < len(cs)-1 {
			panic("A wildcard pattern is found while some patterns are left")
		}

		css[t] = append(css[t], c)
	}

	return css
}

func getPatternType(p interface{}) patternType {
	switch x := p.(type) {
	case string:
		if scalar.Defined(x) {
			return scalarPattern
		}

		return namePattern
	case ast.App:
		switch x.Function().(string) {
		case "$list":
			return listPattern
		case "$dict":
			return dictPattern
		}
	}

	panic(fmt.Errorf("Invalid pattern: %#v", p))
}

func (d *desugarer) desugarListCases(list interface{}, cs []ast.MatchCase, dc interface{}) interface{} {
	type group struct {
		first interface{}
		cases []ast.MatchCase
	}

	gs := []group{}
	first := d.matchedApp("$first", list)
	rest := d.matchedApp("$rest", list)

	for i, c := range cs {
		ps := c.Pattern().(ast.App).Arguments().Positionals()

		if len(ps) == 0 {
			dc = d.resultApp("$if", app("$=", list, "$emptyList"), c.Value(), dc)
			continue
		}

		if ps[0].Expanded() {
			panic("Not implemented")
		}

		v := ps[0].Value()

		c = ast.NewMatchCase(
			ast.NewApp("$list", ast.NewArguments(ps[1:], nil, nil), debug.NewGoInfo(0)),
			c.Value())

		if getPatternType(v) == namePattern {
			d.bindName(v.(string), first)
			dc = d.desugarCases(
				rest,
				[]ast.MatchCase{c},
				d.desugarListCases(list, cs[i+1:], dc))
			break
		}

		groupExist := false

		for i, g := range gs {
			if equalPatterns(v, g.first) {
				groupExist = true
				gs[i].cases = append(gs[i].cases, c)
			}
		}

		if !groupExist {
			gs = append(gs, group{v, []ast.MatchCase{c}})
		}
	}

	ks := make([]ast.MatchCase, 0, len(gs))

	for _, g := range gs {
		ks = append(ks, ast.NewMatchCase(g.first, d.desugarCases(rest, g.cases, dc)))
	}

	return d.desugarCases(first, ks, dc)
}

func (d *desugarer) desugarDictCases(v interface{}, cs []ast.MatchCase, dc interface{}) interface{} {
	type group struct {
		key   interface{}
		cases []ast.MatchCase
	}

	gs := []group{}

	for _, c := range cs {
		ps := c.Pattern().(ast.App).Arguments().Positionals()

		if len(ps) == 0 {
			dc = d.resultApp("$if", app("$=", v, "$emptyDict"), c.Value(), dc)
			continue
		}

		if ps[0].Expanded() {
			panic("Not implemented")
		}

		new := group{ps[0].Value(), []ast.MatchCase{c}}

		if len(gs) == 0 {
			gs = append(gs, new)
		} else if last := gs[len(gs)-1]; equalPatterns(new.key, last.key) {
			last.cases = append(last.cases, c)
		} else {
			gs = append(gs, new)
		}
	}

	x := dc

	for i := len(gs) - 1; i >= 0; i-- {
		g := gs[i]
		x = d.resultApp("$if",
			app("$include", v, g.key),
			d.desugarDictCasesOfSameKey(v, g.cases, x),
			x)
	}

	return x
}

func (d *desugarer) desugarDictCasesOfSameKey(v interface{}, cs []ast.MatchCase, dc interface{}) interface{} {
	type group struct {
		value interface{}
		cases []ast.MatchCase
	}

	key := cs[0].Pattern().(ast.App).Arguments().Positionals()[0].Value()
	gs := []group{}

	for i, c := range cs {
		ps := c.Pattern().(ast.App).Arguments().Positionals()
		value := ps[1].Value()

		c = ast.NewMatchCase(
			ast.NewApp("$dict", ast.NewArguments(ps[2:], nil, nil), debug.NewGoInfo(0)),
			c.Value())

		if getPatternType(value) == namePattern {
			d.bindName(value.(string), app(v, key))

			if rest := cs[i+1:]; len(rest) != 0 {
				dc = d.desugarDictCasesOfSameKey(v, rest, dc)
			}

			dc = d.desugarCases(app("$delete", v, key), []ast.MatchCase{c}, dc)

			break
		}

		groupExist := false

		for i, g := range gs {
			if equalPatterns(value, g.value) {
				groupExist = true
				gs[i].cases = append(gs[i].cases, c)
			}
		}

		if !groupExist {
			gs = append(gs, group{value, []ast.MatchCase{c}})
		}
	}

	cs = make([]ast.MatchCase, 0, len(gs))

	for _, g := range gs {
		cs = append(
			cs,
			ast.NewMatchCase(g.value, d.desugarCases(app("$delete", v, key), g.cases, dc)))
	}

	return d.desugarCases(app(v, key), cs, dc)
}

func (d *desugarer) desugarScalarCases(v interface{}, cs []ast.MatchCase, dc interface{}) interface{} {
	ks := []ast.SwitchCase{}

	for _, c := range cs {
		ks = append(ks, ast.NewSwitchCase(c.Pattern().(string), c.Value()))
	}

	return newSwitch(v, ks, dc)
}

func renameBoundNamesInCase(c ast.MatchCase) ast.MatchCase {
	p, ns := newPatternRenamer().rename(c.Pattern())
	return ast.NewMatchCase(p, newValueRenamer(ns).rename(c.Value()))
}

func equalPatterns(p, q interface{}) bool {
	switch x := p.(type) {
	case string:
		y, ok := q.(string)

		if !ok {
			return false
		}

		return x == y
	case ast.App:
		y, ok := q.(ast.App)

		if !ok ||
			x.Function().(string) != y.Function().(string) ||
			len(x.Arguments().Positionals()) != len(y.Arguments().Positionals()) {
			return false
		}

		for i := range x.Arguments().Positionals() {
			p := x.Arguments().Positionals()[i]
			q := y.Arguments().Positionals()[i]

			if p.Expanded() != q.Expanded() || !equalPatterns(p.Value(), q.Value()) {
				return false
			}
		}

		return true
	}

	panic(fmt.Errorf("Invalid pattern: %#v, %#v", p, q))
}
<commit_msg>Create intermediate variables for new dictionaries matched with patterns<commit_after>package match

import (
	"fmt"

	"github.com/tisp-lang/tisp/src/lib/ast"
	"github.com/tisp-lang/tisp/src/lib/debug"
	"github.com/tisp-lang/tisp/src/lib/gensym"
	"github.com/tisp-lang/tisp/src/lib/scalar"
)

type desugarer struct {
	letBoundNames, lets []interface{}
}

func newDesugarer() *desugarer {
	return &desugarer{nil, nil}
}

func (d *desugarer) desugar(x interface{}) interface{} {
	switch x := x.(type) {
	case ast.App:
		return ast.NewApp(
			d.desugar(x.Function()),
			d.desugar(x.Arguments()).(ast.Arguments),
			x.DebugInfo())
	case ast.Arguments:
		ps := make([]ast.PositionalArgument, 0, len(x.Positionals()))

		for _, p := range x.Positionals() {
			ps = append(ps, d.desugar(p).(ast.PositionalArgument))
		}

		ks := make([]ast.KeywordArgument, 0, len(x.Keywords()))

		for _, k := range x.Keywords() {
			ks = append(ks, d.desugar(k).(ast.KeywordArgument))
		}

		dicts := make([]interface{}, 0, len(x.ExpandedDicts()))

		for _, dict := range x.ExpandedDicts() {
			dicts = append(dicts, d.desugar(dict))
		}

		return ast.NewArguments(ps, ks, dicts)
	case ast.KeywordArgument:
		return ast.NewKeywordArgument(x.Name(), d.desugar(x.Value()))
	case ast.LetFunction:
		ls := make([]interface{}, 0, len(x.Lets()))

		for _, l := range x.Lets() {
			l := d.desugar(l)
			ls = append(ls, append(d.takeLets(), l)...)
		}

		b := d.desugar(x.Body())
		ls = append(ls, d.takeLets()...)

		return ast.NewLetFunction(
			x.Name(),
			x.Signature(),
			ls,
			b,
			x.DebugInfo())
	case ast.LetVar:
		return ast.NewLetVar(x.Name(), d.desugar(x.Expr()))
	case ast.Match:
		cs := make([]ast.MatchCase, 0, len(x.Cases()))

		for _, c := range x.Cases() {
			cs = append(cs, renameBoundNamesInCase(ast.NewMatchCase(c.Pattern(), d.desugar(c.Value()))))
		}

		return d.resultApp(d.createMatchFunction(cs), d.desugar(x.Value()))
	case ast.Output:
		return ast.NewOutput(d.desugar(x.Expr()), x.Expanded())
	case ast.PositionalArgument:
		return ast.NewPositionalArgument(d.desugar(x.Value()), x.Expanded())
	default:
		return x
	}
}

func (d *desugarer) takeLets() []interface{} {
	ls := append(d.letBoundNames, d.lets...)
	d.letBoundNames = nil
	d.lets = nil
	return ls
}

func (d *desugarer) letVar(s string, v interface{}) string {
	d.lets = append(d.lets, ast.NewLetVar(s, v))
	return s
}

func (d *desugarer) bindName(s string, v interface{}) string {
	d.letBoundNames = append(d.letBoundNames, ast.NewLetVar(s, v))
	return s
}

// matchedApp applies a function to arguments and creates a matched value of
// match expression.
func (d *desugarer) matchedApp(f interface{}, args ...interface{}) string {
	return d.bindName(gensym.GenSym("match", "app"), app(f, args...))
}

// resultApp applies a function to arguments and creates a result value of match
// expression.
func (d *desugarer) resultApp(f interface{}, args ...interface{}) string {
	return d.letVar(gensym.GenSym("match", "app"), app(f, args...))
}

func (d *desugarer) createMatchFunction(cs []ast.MatchCase) interface{} {
	arg := gensym.GenSym("match", "argument")
	body := d.desugarCases(arg, cs, "$matchError")

	f := ast.NewLetFunction(
		gensym.GenSym("match", "function"),
		ast.NewSignature([]string{arg}, nil, "", nil, nil, ""),
		d.takeLets(),
		body,
		debug.NewGoInfo(0))

	d.lets = append(d.lets, f)

	return f.Name()
}

func (d *desugarer) desugarCases(v interface{}, cs []ast.MatchCase, dc interface{}) interface{} {
	css := groupCases(cs)

	if cs, ok := css[namePattern]; ok {
		c := cs[0]
		d.bindName(c.Pattern().(string), v)
		dc = c.Value()
	}

	ks := []ast.SwitchCase{}

	if cs, ok := css[listPattern]; ok {
		ks = append(ks, ast.NewSwitchCase("\"list\"", d.desugarListCases(v, cs, dc)))
	}

	if cs, ok := css[dictPattern]; ok {
		ks = append(ks, ast.NewSwitchCase("\"dict\"", d.desugarDictCases(v, cs, dc)))
	}

	if cs, ok := css[scalarPattern]; ok {
		dc = d.desugarScalarCases(v, cs, dc)
	}

	return newSwitch(d.resultApp("$typeOf", v), ks, dc)
}

func groupCases(cs []ast.MatchCase) map[patternType][]ast.MatchCase {
	css := map[patternType][]ast.MatchCase{}

	for i, c := range cs {
		t := getPatternType(c.Pattern())

		if t == namePattern && i < len(cs)-1 {
			panic("A wildcard pattern is found while some patterns are left")
		}

		css[t] = append(css[t], c)
	}

	return css
}

func getPatternType(p interface{}) patternType {
	switch x := p.(type) {
	case string:
		if scalar.Defined(x) {
			return scalarPattern
		}

		return namePattern
	case ast.App:
		switch x.Function().(string) {
		case "$list":
			return listPattern
		case "$dict":
			return dictPattern
		}
	}

	panic(fmt.Errorf("Invalid pattern: %#v", p))
}

func (d *desugarer) desugarListCases(list interface{}, cs []ast.MatchCase, dc interface{}) interface{} {
	type group struct {
		first interface{}
		cases []ast.MatchCase
	}

	gs := []group{}
	first := d.matchedApp("$first", list)
	rest := d.matchedApp("$rest", list)

	for i, c := range cs {
		ps := c.Pattern().(ast.App).Arguments().Positionals()

		if len(ps) == 0 {
			dc = d.resultApp("$if", app("$=", list, "$emptyList"), c.Value(), dc)
			continue
		}

		if ps[0].Expanded() {
			panic("Not implemented")
		}

		v := ps[0].Value()

		c = ast.NewMatchCase(
			ast.NewApp("$list", ast.NewArguments(ps[1:], nil, nil), debug.NewGoInfo(0)),
			c.Value())

		if getPatternType(v) == namePattern {
			d.bindName(v.(string), first)
			dc = d.desugarCases(
				rest,
				[]ast.MatchCase{c},
				d.desugarListCases(list, cs[i+1:], dc))
			break
		}

		groupExist := false

		for i, g := range gs {
			if equalPatterns(v, g.first) {
				groupExist = true
				gs[i].cases = append(gs[i].cases, c)
			}
		}

		if !groupExist {
			gs = append(gs, group{v, []ast.MatchCase{c}})
		}
	}

	ks := make([]ast.MatchCase, 0, len(gs))

	for _, g := range gs {
		ks = append(ks, ast.NewMatchCase(g.first, d.desugarCases(rest, g.cases, dc)))
	}

	return d.desugarCases(first, ks, dc)
}

func (d *desugarer) desugarDictCases(v interface{}, cs []ast.MatchCase, dc interface{}) interface{} {
	type group struct {
		key   interface{}
		cases []ast.MatchCase
	}

	gs := []group{}

	for _, c := range cs {
		ps := c.Pattern().(ast.App).Arguments().Positionals()

		if len(ps) == 0 {
			dc = d.resultApp("$if", app("$=", v, "$emptyDict"), c.Value(), dc)
			continue
		}

		if ps[0].Expanded() {
			panic("Not implemented")
		}

		new := group{ps[0].Value(), []ast.MatchCase{c}}

		if len(gs) == 0 {
			gs = append(gs, new)
		} else if last := gs[len(gs)-1]; equalPatterns(new.key, last.key) {
			last.cases = append(last.cases, c)
		} else {
			gs = append(gs, new)
		}
	}

	x := dc

	for i := len(gs) - 1; i >= 0; i-- {
		g := gs[i]
		x = d.resultApp("$if",
			app("$include", v, g.key),
			d.desugarDictCasesOfSameKey(v, g.cases, x),
			x)
	}

	return x
}

func (d *desugarer) desugarDictCasesOfSameKey(v interface{}, cs []ast.MatchCase, dc interface{}) interface{} {
	type group struct {
		value interface{}
		cases []ast.MatchCase
	}

	key := cs[0].Pattern().(ast.App).Arguments().Positionals()[0].Value()
	newDict := d.matchedApp("delete", v, key)
	gs := []group{}

	for i, c := range cs {
		ps := c.Pattern().(ast.App).Arguments().Positionals()
		value := ps[1].Value()

		c = ast.NewMatchCase(
			ast.NewApp("$dict", ast.NewArguments(ps[2:], nil, nil), debug.NewGoInfo(0)),
			c.Value())

		if getPatternType(value) == namePattern {
			d.bindName(value.(string), app(v, key))

			if rest := cs[i+1:]; len(rest) != 0 {
				dc = d.desugarDictCasesOfSameKey(v, rest, dc)
			}

			dc = d.desugarCases(newDict, []ast.MatchCase{c}, dc)

			break
		}

		groupExist := false

		for i, g := range gs {
			if equalPatterns(value, g.value) {
				groupExist = true
				gs[i].cases = append(gs[i].cases, c)
			}
		}

		if !groupExist {
			gs = append(gs, group{value, []ast.MatchCase{c}})
		}
	}

	cs = make([]ast.MatchCase, 0, len(gs))

	for _, g := range gs {
		cs = append(
			cs,
			ast.NewMatchCase(g.value, d.desugarCases(newDict, g.cases, dc)))
	}

	return d.desugarCases(app(v, key), cs, dc)
}

func (d *desugarer) desugarScalarCases(v interface{}, cs []ast.MatchCase, dc interface{}) interface{} {
	ks := []ast.SwitchCase{}

	for _, c := range cs {
		ks = append(ks, ast.NewSwitchCase(c.Pattern().(string), c.Value()))
	}

	return newSwitch(v, ks, dc)
}

func renameBoundNamesInCase(c ast.MatchCase) ast.MatchCase {
	p, ns := newPatternRenamer().rename(c.Pattern())
	return ast.NewMatchCase(p, newValueRenamer(ns).rename(c.Value()))
}

func equalPatterns(p, q interface{}) bool {
	switch x := p.(type) {
	case string:
		y, ok := q.(string)

		if !ok {
			return false
		}

		return x == y
	case ast.App:
		y, ok := q.(ast.App)

		if !ok ||
			x.Function().(string) != y.Function().(string) ||
			len(x.Arguments().Positionals()) != len(y.Arguments().Positionals()) {
			return false
		}

		for i := range x.Arguments().Positionals() {
			p := x.Arguments().Positionals()[i]
			q := y.Arguments().Positionals()[i]

			if p.Expanded() != q.Expanded() || !equalPatterns(p.Value(), q.Value()) {
				return false
			}
		}

		return true
	}

	panic(fmt.Errorf("Invalid pattern: %#v, %#v", p, q))
}
<|endoftext|>


<commit_before>// Copyright 2015 Google Inc. All Rights Reserved.
// Author: jacobsa@google.com (Aaron Jacobs)

package fuseutil

// A 64-bit number used to uniquely identify a file or directory in the file
// system.
//
// This corresponds to struct inode::i_no in the VFS layer.
// (Cf. http://goo.gl/tvYyQt)
type InodeID uint64

// A generation number for an inode. Irrelevant for file systems that won't be
// exported over NFS. For those that will and that reuse inode IDs when they
// become free, the generation number must change when an ID is reused.
//
// This corresponds to struct inode::i_generation in the VFS layer.
// (Cf. http://goo.gl/tvYyQt)
//
// Some related reading:
//
//     http://fuse.sourceforge.net/doxygen/structfuse__entry__param.html
//     http://stackoverflow.com/q/11071996/1505451
//     http://goo.gl/CqvwyX
//     http://julipedia.meroh.net/2005/09/nfs-file-handles.html
//     http://goo.gl/wvo3MB
//
type GenerationNumber uint64

// A request to look up a child by name within a parent directory. This is sent
// by the kernel when resolving user paths to dentry structs, which are then
// cached.
type LookupRequest struct {
	// The ID of the directory inode to which the child belongs.
	Parent InodeID

	// The name of the child of interest, relative to the parent. For example, in
	// this directory structure:
	//
	//     foo/
	//         bar/
	//             baz
	//
	// the file system may receive a request to look up the child named "bar" for
	// the parent foo/.
	Name string
}

// XXX: Comments
type LookupResponse struct {
	// XXX: Fields
}

// An interface that must be implemented by file systems to be mounted with
// FUSE. Comments reflect requirements on the file system imposed by the
// kernel. See also the comments on request and response structs.
//
// Not all methods need to have interesting implementations. Embed a field of
// type NothingImplementedFileSystem to inherit defaults that return ENOSYS to
// the kernel.
type FileSystem interface {
	// Look up a child by name within a parent directory. The kernel calls this
	// when resolving user paths to dentry structs, which are then cached.
	//
	// The returned inode ID must be valid until a later call to Forget.
	Lookup(
		ctx context.Contexst,
		req *LookupRequest) (*LookupResponse, error)

	// Forget an inode ID previously issued (e.g. by Lookup). The kernel calls
	// this when removing an inode from its internal caches.
	//
	// The node ID will not be used in further calls to the file system (unless
	// it is reissued by the file system).
	Forget(
		ctx context.Context,
		req *ForgetRequest) (*ForgetResponse, error)
}

type NothingImplementedFileSystem struct {
}

var _ FileSystem = NothingImplementedFileSystem{}
<commit_msg>Re-ordered things.<commit_after>// Copyright 2015 Google Inc. All Rights Reserved.
// Author: jacobsa@google.com (Aaron Jacobs)

package fuseutil

// An interface that must be implemented by file systems to be mounted with
// FUSE. Comments reflect requirements on the file system imposed by the
// kernel. See also the comments on request and response structs.
//
// Not all methods need to have interesting implementations. Embed a field of
// type NothingImplementedFileSystem to inherit defaults that return ENOSYS to
// the kernel.
type FileSystem interface {
	// Look up a child by name within a parent directory. The kernel calls this
	// when resolving user paths to dentry structs, which are then cached.
	//
	// The returned inode ID must be valid until a later call to Forget.
	Lookup(
		ctx context.Contexst,
		req *LookupRequest) (*LookupResponse, error)

	// Forget an inode ID previously issued (e.g. by Lookup). The kernel calls
	// this when removing an inode from its internal caches.
	//
	// The node ID will not be used in further calls to the file system (unless
	// it is reissued by the file system).
	Forget(
		ctx context.Context,
		req *ForgetRequest) (*ForgetResponse, error)
}

// A 64-bit number used to uniquely identify a file or directory in the file
// system.
//
// This corresponds to struct inode::i_no in the VFS layer.
// (Cf. http://goo.gl/tvYyQt)
type InodeID uint64

// A generation number for an inode. Irrelevant for file systems that won't be
// exported over NFS. For those that will and that reuse inode IDs when they
// become free, the generation number must change when an ID is reused.
//
// This corresponds to struct inode::i_generation in the VFS layer.
// (Cf. http://goo.gl/tvYyQt)
//
// Some related reading:
//
//     http://fuse.sourceforge.net/doxygen/structfuse__entry__param.html
//     http://stackoverflow.com/q/11071996/1505451
//     http://goo.gl/CqvwyX
//     http://julipedia.meroh.net/2005/09/nfs-file-handles.html
//     http://goo.gl/wvo3MB
//
type GenerationNumber uint64

// A request to look up a child by name within a parent directory. This is sent
// by the kernel when resolving user paths to dentry structs, which are then
// cached.
type LookupRequest struct {
	// The ID of the directory inode to which the child belongs.
	Parent InodeID

	// The name of the child of interest, relative to the parent. For example, in
	// this directory structure:
	//
	//     foo/
	//         bar/
	//             baz
	//
	// the file system may receive a request to look up the child named "bar" for
	// the parent foo/.
	Name string
}

// XXX: Comments
type LookupResponse struct {
	// XXX: Fields
}

type NothingImplementedFileSystem struct {
}

var _ FileSystem = NothingImplementedFileSystem{}
<|endoftext|>


<commit_before>// Copyright 2009 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.

/*
	Package fmt implements formatted I/O with functions analogous
	to C's printf and scanf.  The format 'verbs' are derived from C's but
	are simpler.

	Printing

	The verbs:

	General:
		%v	the value in a default format.
			when printing structs, the plus flag (%+v) adds field names
		%#v	a Go-syntax representation of the value
		%T	a Go-syntax representation of the type of the value
		%%	a literal percent sign; consumes no value

	Boolean:
		%t	the word true or false
	Integer:
		%b	base 2
		%c	the character represented by the corresponding Unicode code point
		%d	base 10
		%o	base 8
		%q	a single-quoted character literal safely escaped with Go syntax.
		%x	base 16, with lower-case letters for a-f
		%X	base 16, with upper-case letters for A-F
		%U	Unicode format: U+1234; same as "U+%04X"
	Floating-point and complex constituents:
		%b	decimalless scientific notation with exponent a power of two,
			in the manner of strconv.FormatFloat with the 'b' format,
			e.g. -123456p-78
		%e	scientific notation, e.g. -1234.456e+78
		%E	scientific notation, e.g. -1234.456E+78
		%f	decimal point but no exponent, e.g. 123.456
		%F	synonym for %f
		%g	whichever of %e or %f produces more compact output
		%G	whichever of %E or %f produces more compact output
	String and slice of bytes:
		%s	the uninterpreted bytes of the string or slice
		%q	a double-quoted string safely escaped with Go syntax
		%x	base 16, lower-case, two characters per byte
		%X	base 16, upper-case, two characters per byte
	Pointer:
		%p	base 16 notation, with leading 0x

	There is no 'u' flag.  Integers are printed unsigned if they have unsigned type.
	Similarly, there is no need to specify the size of the operand (int8, int64).

	Width is specified by an optional decimal number immediately following the verb.
	If absent, the width is whatever is necessary to represent the value.
	Precision is specified after the (optional) width by a period followed by a
	decimal number. If no period is present, a default precision is used.
	A period with no following number specifies a precision of zero.
	Examples:
		%f:    default width, default precision
		%9f    width 9, default precision
		%.2f   default width, precision 2
		%9.2f  width 9, precision 2
		%9.f   width 9, precision 0

	Width and precision are measured in units of Unicode code points.
	(This differs from C's printf where the units are numbers
	of bytes.) Either or both of the flags may be replaced with the
	character '*', causing their values to be obtained from the next
	operand, which must be of type int.

	For most values, width is the minimum number of characters to output,
	padding the formatted form with spaces if necessary.
	For strings, precision is the maximum number of characters to output,
	truncating if necessary.

	For floating-point values, width sets the minimum width of the field and
	precision sets the number of places after the decimal, if appropriate,
	except that for %g/%G it sets the total number of digits. For example,
	given 123.45 the format %6.2f prints 123.45 while %.4g prints 123.5.
	The default precision for %e and %f is 6; for %g it is the smallest
	number of digits necessary to identify the value uniquely.

	For complex numbers, the width and precision apply to the two
	components independently and the result is parenthesized, so %f applied
	to 1.2+3.4i produces (1.200000+3.400000i).

	Other flags:
		+	always print a sign for numeric values;
			guarantee ASCII-only output for %q (%+q)
		-	pad with spaces on the right rather than the left (left-justify the field)
		#	alternate format: add leading 0 for octal (%#o), 0x for hex (%#x);
			0X for hex (%#X); suppress 0x for %p (%#p);
			for %q, print a raw (backquoted) string if strconv.CanBackquote
			returns true;
			write e.g. U+0078 'x' if the character is printable for %U (%#U).
		' '	(space) leave a space for elided sign in numbers (% d);
			put spaces between bytes printing strings or slices in hex (% x, % X)
		0	pad with leading zeros rather than spaces;
			for numbers, this moves the padding after the sign

	Flags are ignored by verbs that do not expect them.
	For example there is no alternate decimal format, so %#d and %d
	behave identically.

	For each Printf-like function, there is also a Print function
	that takes no format and is equivalent to saying %v for every
	operand.  Another variant Println inserts blanks between
	operands and appends a newline.

	Regardless of the verb, if an operand is an interface value,
	the internal concrete value is used, not the interface itself.
	Thus:
		var i interface{} = 23
		fmt.Printf("%v\n", i)
	will print 23.

	Except when printed using the verbs %T and %p, special
	formatting considerations apply for operands that implement
	certain interfaces. In order of application:

	1. If an operand implements the Formatter interface, it will
	be invoked. Formatter provides fine control of formatting.

	2. If the %v verb is used with the # flag (%#v) and the operand
	implements the GoStringer interface, that will be invoked.

	If the format (which is implicitly %v for Println etc.) is valid
	for a string (%s %q %v %x %X), the following two rules apply:

	3. If an operand implements the error interface, the Error method
	will be invoked to convert the object to a string, which will then
	be formatted as required by the verb (if any).

	4. If an operand implements method String() string, that method
	will be invoked to convert the object to a string, which will then
	be formatted as required by the verb (if any).

	For compound operands such as slices and structs, the format
	applies to the elements of each operand, recursively, not to the
	operand as a whole. Thus %q will quote each element of a slice
	of strings, and %6.2f will control formatting for each element
	of a floating-point array.

	To avoid recursion in cases such as
		type X string
		func (x X) String() string { return Sprintf("<%s>", x) }
	convert the value before recurring:
		func (x X) String() string { return Sprintf("<%s>", string(x)) }

	Explicit argument indexes:

	In Printf, Sprintf, and Fprintf, the default behavior is for each
	formatting verb to format successive arguments passed in the call.
	However, the notation [n] immediately before the verb indicates that the
	nth one-indexed argument is to be formatted instead. The same notation
	before a '*' for a width or precision selects the argument index holding
	the value. After processing a bracketed expression [n], arguments n+1,
	n+2, etc. will be processed unless otherwise directed.

	For example,
		fmt.Sprintf("%[2]d %[1]d\n", 11, 22)
	will yield "22, 11", while
		fmt.Sprintf("%[3]*.[2]*[1]f", 12.0, 2, 6),
	equivalent to
		fmt.Sprintf("%6.2f", 12.0),
	will yield " 12.00". Because an explicit index affects subsequent verbs,
	this notation can be used to print the same values multiple times
	by resetting the index for the first argument to be repeated:
		fmt.Sprintf("%d %d %#[1]x %#x", 16, 17)
	will yield "16 17 0x10 0x11".

	Format errors:

	If an invalid argument is given for a verb, such as providing
	a string to %d, the generated string will contain a
	description of the problem, as in these examples:

		Wrong type or unknown verb: %!verb(type=value)
			Printf("%d", hi):          %!d(string=hi)
		Too many arguments: %!(EXTRA type=value)
			Printf("hi", "guys"):      hi%!(EXTRA string=guys)
		Too few arguments: %!verb(MISSING)
			Printf("hi%d"):            hi %!d(MISSING)
		Non-int for width or precision: %!(BADWIDTH) or %!(BADPREC)
			Printf("%*s", 4.5, "hi"):  %!(BADWIDTH)hi
			Printf("%.*s", 4.5, "hi"): %!(BADPREC)hi
		Invalid or invalid use of argument index: %!(BADINDEX)
			Printf("%*[2]d", 7):       %!d(BADINDEX)
			Printf("%.[2]d", 7):       %!d(BADINDEX)

	All errors begin with the string "%!" followed sometimes
	by a single character (the verb) and end with a parenthesized
	description.

	If an Error or String method triggers a panic when called by a
	print routine, the fmt package reformats the error message
	from the panic, decorating it with an indication that it came
	through the fmt package.  For example, if a String method
	calls panic("bad"), the resulting formatted message will look
	like
		%!s(PANIC=bad)

	The %!s just shows the print verb in use when the failure
	occurred.

	Scanning

	An analogous set of functions scans formatted text to yield
	values.  Scan, Scanf and Scanln read from os.Stdin; Fscan,
	Fscanf and Fscanln read from a specified io.Reader; Sscan,
	Sscanf and Sscanln read from an argument string.  Scanln,
	Fscanln and Sscanln stop scanning at a newline and require that
	the items be followed by one; Scanf, Fscanf and Sscanf require
	newlines in the input to match newlines in the format; the other
	routines treat newlines as spaces.

	Scanf, Fscanf, and Sscanf parse the arguments according to a
	format string, analogous to that of Printf.  For example, %x
	will scan an integer as a hexadecimal number, and %v will scan
	the default representation format for the value.

	The formats behave analogously to those of Printf with the
	following exceptions:

		%p is not implemented
		%T is not implemented
		%e %E %f %F %g %G are all equivalent and scan any floating point or complex value
		%s and %v on strings scan a space-delimited token
		Flags # and + are not implemented.

	The familiar base-setting prefixes 0 (octal) and 0x
	(hexadecimal) are accepted when scanning integers without a
	format or with the %v verb.

	Width is interpreted in the input text (%5s means at most
	five runes of input will be read to scan a string) but there
	is no syntax for scanning with a precision (no %5.2f, just
	%5f).

	When scanning with a format, all non-empty runs of space
	characters (except newline) are equivalent to a single
	space in both the format and the input.  With that proviso,
	text in the format string must match the input text; scanning
	stops if it does not, with the return value of the function
	indicating the number of arguments scanned.

	In all the scanning functions, a carriage return followed
	immediately by a newline is treated as a plain newline
	(\r\n means the same as \n).

	In all the scanning functions, if an operand implements method
	Scan (that is, it implements the Scanner interface) that
	method will be used to scan the text for that operand.  Also,
	if the number of arguments scanned is less than the number of
	arguments provided, an error is returned.

	All arguments to be scanned must be either pointers to basic
	types or implementations of the Scanner interface.

	Note: Fscan etc. can read one character (rune) past the input
	they return, which means that a loop calling a scan routine
	may skip some of the input.  This is usually a problem only
	when there is no space between input values.  If the reader
	provided to Fscan implements ReadRune, that method will be used
	to read characters.  If the reader also implements UnreadRune,
	that method will be used to save the character and successive
	calls will not lose data.  To attach ReadRune and UnreadRune
	methods to a reader without that capability, use
	bufio.NewReader.
*/
package fmt
<commit_msg>fmt: fix typo in help doc<commit_after>// Copyright 2009 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.

/*
	Package fmt implements formatted I/O with functions analogous
	to C's printf and scanf.  The format 'verbs' are derived from C's but
	are simpler.

	Printing

	The verbs:

	General:
		%v	the value in a default format.
			when printing structs, the plus flag (%+v) adds field names
		%#v	a Go-syntax representation of the value
		%T	a Go-syntax representation of the type of the value
		%%	a literal percent sign; consumes no value

	Boolean:
		%t	the word true or false
	Integer:
		%b	base 2
		%c	the character represented by the corresponding Unicode code point
		%d	base 10
		%o	base 8
		%q	a single-quoted character literal safely escaped with Go syntax.
		%x	base 16, with lower-case letters for a-f
		%X	base 16, with upper-case letters for A-F
		%U	Unicode format: U+1234; same as "U+%04X"
	Floating-point and complex constituents:
		%b	decimalless scientific notation with exponent a power of two,
			in the manner of strconv.FormatFloat with the 'b' format,
			e.g. -123456p-78
		%e	scientific notation, e.g. -1234.456e+78
		%E	scientific notation, e.g. -1234.456E+78
		%f	decimal point but no exponent, e.g. 123.456
		%F	synonym for %f
		%g	whichever of %e or %f produces more compact output
		%G	whichever of %E or %f produces more compact output
	String and slice of bytes:
		%s	the uninterpreted bytes of the string or slice
		%q	a double-quoted string safely escaped with Go syntax
		%x	base 16, lower-case, two characters per byte
		%X	base 16, upper-case, two characters per byte
	Pointer:
		%p	base 16 notation, with leading 0x

	There is no 'u' flag.  Integers are printed unsigned if they have unsigned type.
	Similarly, there is no need to specify the size of the operand (int8, int64).

	Width is specified by an optional decimal number immediately following the verb.
	If absent, the width is whatever is necessary to represent the value.
	Precision is specified after the (optional) width by a period followed by a
	decimal number. If no period is present, a default precision is used.
	A period with no following number specifies a precision of zero.
	Examples:
		%f:    default width, default precision
		%9f    width 9, default precision
		%.2f   default width, precision 2
		%9.2f  width 9, precision 2
		%9.f   width 9, precision 0

	Width and precision are measured in units of Unicode code points.
	(This differs from C's printf where the units are numbers
	of bytes.) Either or both of the flags may be replaced with the
	character '*', causing their values to be obtained from the next
	operand, which must be of type int.

	For most values, width is the minimum number of characters to output,
	padding the formatted form with spaces if necessary.
	For strings, precision is the maximum number of characters to output,
	truncating if necessary.

	For floating-point values, width sets the minimum width of the field and
	precision sets the number of places after the decimal, if appropriate,
	except that for %g/%G it sets the total number of digits. For example,
	given 123.45 the format %6.2f prints 123.45 while %.4g prints 123.5.
	The default precision for %e and %f is 6; for %g it is the smallest
	number of digits necessary to identify the value uniquely.

	For complex numbers, the width and precision apply to the two
	components independently and the result is parenthesized, so %f applied
	to 1.2+3.4i produces (1.200000+3.400000i).

	Other flags:
		+	always print a sign for numeric values;
			guarantee ASCII-only output for %q (%+q)
		-	pad with spaces on the right rather than the left (left-justify the field)
		#	alternate format: add leading 0 for octal (%#o), 0x for hex (%#x);
			0X for hex (%#X); suppress 0x for %p (%#p);
			for %q, print a raw (backquoted) string if strconv.CanBackquote
			returns true;
			write e.g. U+0078 'x' if the character is printable for %U (%#U).
		' '	(space) leave a space for elided sign in numbers (% d);
			put spaces between bytes printing strings or slices in hex (% x, % X)
		0	pad with leading zeros rather than spaces;
			for numbers, this moves the padding after the sign

	Flags are ignored by verbs that do not expect them.
	For example there is no alternate decimal format, so %#d and %d
	behave identically.

	For each Printf-like function, there is also a Print function
	that takes no format and is equivalent to saying %v for every
	operand.  Another variant Println inserts blanks between
	operands and appends a newline.

	Regardless of the verb, if an operand is an interface value,
	the internal concrete value is used, not the interface itself.
	Thus:
		var i interface{} = 23
		fmt.Printf("%v\n", i)
	will print 23.

	Except when printed using the verbs %T and %p, special
	formatting considerations apply for operands that implement
	certain interfaces. In order of application:

	1. If an operand implements the Formatter interface, it will
	be invoked. Formatter provides fine control of formatting.

	2. If the %v verb is used with the # flag (%#v) and the operand
	implements the GoStringer interface, that will be invoked.

	If the format (which is implicitly %v for Println etc.) is valid
	for a string (%s %q %v %x %X), the following two rules apply:

	3. If an operand implements the error interface, the Error method
	will be invoked to convert the object to a string, which will then
	be formatted as required by the verb (if any).

	4. If an operand implements method String() string, that method
	will be invoked to convert the object to a string, which will then
	be formatted as required by the verb (if any).

	For compound operands such as slices and structs, the format
	applies to the elements of each operand, recursively, not to the
	operand as a whole. Thus %q will quote each element of a slice
	of strings, and %6.2f will control formatting for each element
	of a floating-point array.

	To avoid recursion in cases such as
		type X string
		func (x X) String() string { return Sprintf("<%s>", x) }
	convert the value before recurring:
		func (x X) String() string { return Sprintf("<%s>", string(x)) }

	Explicit argument indexes:

	In Printf, Sprintf, and Fprintf, the default behavior is for each
	formatting verb to format successive arguments passed in the call.
	However, the notation [n] immediately before the verb indicates that the
	nth one-indexed argument is to be formatted instead. The same notation
	before a '*' for a width or precision selects the argument index holding
	the value. After processing a bracketed expression [n], arguments n+1,
	n+2, etc. will be processed unless otherwise directed.

	For example,
		fmt.Sprintf("%[2]d %[1]d\n", 11, 22)
	will yield "22 11", while
		fmt.Sprintf("%[3]*.[2]*[1]f", 12.0, 2, 6),
	equivalent to
		fmt.Sprintf("%6.2f", 12.0),
	will yield " 12.00". Because an explicit index affects subsequent verbs,
	this notation can be used to print the same values multiple times
	by resetting the index for the first argument to be repeated:
		fmt.Sprintf("%d %d %#[1]x %#x", 16, 17)
	will yield "16 17 0x10 0x11".

	Format errors:

	If an invalid argument is given for a verb, such as providing
	a string to %d, the generated string will contain a
	description of the problem, as in these examples:

		Wrong type or unknown verb: %!verb(type=value)
			Printf("%d", hi):          %!d(string=hi)
		Too many arguments: %!(EXTRA type=value)
			Printf("hi", "guys"):      hi%!(EXTRA string=guys)
		Too few arguments: %!verb(MISSING)
			Printf("hi%d"):            hi %!d(MISSING)
		Non-int for width or precision: %!(BADWIDTH) or %!(BADPREC)
			Printf("%*s", 4.5, "hi"):  %!(BADWIDTH)hi
			Printf("%.*s", 4.5, "hi"): %!(BADPREC)hi
		Invalid or invalid use of argument index: %!(BADINDEX)
			Printf("%*[2]d", 7):       %!d(BADINDEX)
			Printf("%.[2]d", 7):       %!d(BADINDEX)

	All errors begin with the string "%!" followed sometimes
	by a single character (the verb) and end with a parenthesized
	description.

	If an Error or String method triggers a panic when called by a
	print routine, the fmt package reformats the error message
	from the panic, decorating it with an indication that it came
	through the fmt package.  For example, if a String method
	calls panic("bad"), the resulting formatted message will look
	like
		%!s(PANIC=bad)

	The %!s just shows the print verb in use when the failure
	occurred.

	Scanning

	An analogous set of functions scans formatted text to yield
	values.  Scan, Scanf and Scanln read from os.Stdin; Fscan,
	Fscanf and Fscanln read from a specified io.Reader; Sscan,
	Sscanf and Sscanln read from an argument string.  Scanln,
	Fscanln and Sscanln stop scanning at a newline and require that
	the items be followed by one; Scanf, Fscanf and Sscanf require
	newlines in the input to match newlines in the format; the other
	routines treat newlines as spaces.

	Scanf, Fscanf, and Sscanf parse the arguments according to a
	format string, analogous to that of Printf.  For example, %x
	will scan an integer as a hexadecimal number, and %v will scan
	the default representation format for the value.

	The formats behave analogously to those of Printf with the
	following exceptions:

		%p is not implemented
		%T is not implemented
		%e %E %f %F %g %G are all equivalent and scan any floating point or complex value
		%s and %v on strings scan a space-delimited token
		Flags # and + are not implemented.

	The familiar base-setting prefixes 0 (octal) and 0x
	(hexadecimal) are accepted when scanning integers without a
	format or with the %v verb.

	Width is interpreted in the input text (%5s means at most
	five runes of input will be read to scan a string) but there
	is no syntax for scanning with a precision (no %5.2f, just
	%5f).

	When scanning with a format, all non-empty runs of space
	characters (except newline) are equivalent to a single
	space in both the format and the input.  With that proviso,
	text in the format string must match the input text; scanning
	stops if it does not, with the return value of the function
	indicating the number of arguments scanned.

	In all the scanning functions, a carriage return followed
	immediately by a newline is treated as a plain newline
	(\r\n means the same as \n).

	In all the scanning functions, if an operand implements method
	Scan (that is, it implements the Scanner interface) that
	method will be used to scan the text for that operand.  Also,
	if the number of arguments scanned is less than the number of
	arguments provided, an error is returned.

	All arguments to be scanned must be either pointers to basic
	types or implementations of the Scanner interface.

	Note: Fscan etc. can read one character (rune) past the input
	they return, which means that a loop calling a scan routine
	may skip some of the input.  This is usually a problem only
	when there is no space between input values.  If the reader
	provided to Fscan implements ReadRune, that method will be used
	to read characters.  If the reader also implements UnreadRune,
	that method will be used to save the character and successive
	calls will not lose data.  To attach ReadRune and UnreadRune
	methods to a reader without that capability, use
	bufio.NewReader.
*/
package fmt
<|endoftext|>


<commit_before>// Copyright 2009 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.

/*
The gob package manages streams of gobs - binary values exchanged between an
Encoder (transmitter) and a Decoder (receiver).  A typical use is transporting
arguments and results of remote procedure calls (RPCs) such as those provided by
package "rpc".

A stream of gobs is self-describing.  Each data item in the stream is preceded by
a specification of its type, expressed in terms of a small set of predefined
types.  Pointers are not transmitted, but the things they point to are
transmitted; that is, the values are flattened.  Recursive types work fine, but
recursive values (data with cycles) are problematic.  This may change.

To use gobs, create an Encoder and present it with a series of data items as
values or addresses that can be dereferenced to values.  The Encoder makes sure
all type information is sent before it is needed.  At the receive side, a
Decoder retrieves values from the encoded stream and unpacks them into local
variables.

The source and destination values/types need not correspond exactly.  For structs,
fields (identified by name) that are in the source but absent from the receiving
variable will be ignored.  Fields that are in the receiving variable but missing
from the transmitted type or value will be ignored in the destination.  If a field
with the same name is present in both, their types must be compatible. Both the
receiver and transmitter will do all necessary indirection and dereferencing to
convert between gobs and actual Go values.  For instance, a gob type that is
schematically,

	struct { a, b int }

can be sent from or received into any of these Go types:

	struct { a, b int }	// the same
	*struct { a, b int }	// extra indirection of the struct
	struct { *a, **b int }	// extra indirection of the fields
	struct { a, b int64 }	// different concrete value type; see below

It may also be received into any of these:

	struct { a, b int }	// the same
	struct { b, a int }	// ordering doesn't matter; matching is by name
	struct { a, b, c int }	// extra field (c) ignored
	struct { b int }	// missing field (a) ignored; data will be dropped
	struct { b, c int }	// missing field (a) ignored; extra field (c) ignored.

Attempting to receive into these types will draw a decode error:

	struct { a int; b uint }	// change of signedness for b
	struct { a int; b float }	// change of type for b
	struct { }			// no field names in common
	struct { c, d int }		// no field names in common

Integers are transmitted two ways: arbitrary precision signed integers or
arbitrary precision unsigned integers.  There is no int8, int16 etc.
discrimination in the gob format; there are only signed and unsigned integers.  As
described below, the transmitter sends the value in a variable-length encoding;
the receiver accepts the value and stores it in the destination variable.
Floating-point numbers are always sent using IEEE-754 64-bit precision (see
below).

Signed integers may be received into any signed integer variable: int, int16, etc.;
unsigned integers may be received into any unsigned integer variable; and floating
point values may be received into any floating point variable.  However,
the destination variable must be able to represent the value or the decode
operation will fail.

Structs, arrays and slices are also supported.  Strings and arrays of bytes are
supported with a special, efficient representation (see below).

Interfaces, functions, and channels cannot be sent in a gob.  Attempting
to encode a value that contains one will fail.

The rest of this comment documents the encoding, details that are not important
for most users.  Details are presented bottom-up.

An unsigned integer is sent one of two ways.  If it is less than 128, it is sent
as a byte with that value.  Otherwise it is sent as a minimal-length big-endian
(high byte first) byte stream holding the value, preceded by one byte holding the
byte count, negated.  Thus 0 is transmitted as (00), 7 is transmitted as (07) and
256 is transmitted as (FE 01 00).

A boolean is encoded within an unsigned integer: 0 for false, 1 for true.

A signed integer, i, is encoded within an unsigned integer, u.  Within u, bits 1
upward contain the value; bit 0 says whether they should be complemented upon
receipt.  The encode algorithm looks like this:

	uint u;
	if i < 0 {
		u = (^i << 1) | 1	// complement i, bit 0 is 1
	} else {
		u = (i << 1)	// do not complement i, bit 0 is 0
	}
	encodeUnsigned(u)

The low bit is therefore analogous to a sign bit, but making it the complement bit
instead guarantees that the largest negative integer is not a special case.  For
example, -129=^128=(^256>>1) encodes as (FE 01 01).

Floating-point numbers are always sent as a representation of a float64 value.
That value is converted to a uint64 using math.Float64bits.  The uint64 is then
byte-reversed and sent as a regular unsigned integer.  The byte-reversal means the
exponent and high-precision part of the mantissa go first.  Since the low bits are
often zero, this can save encoding bytes.  For instance, 17.0 is encoded in only
three bytes (FE 31 40).

Strings and slices of bytes are sent as an unsigned count followed by that many
uninterpreted bytes of the value.

All other slices and arrays are sent as an unsigned count followed by that many
elements using the standard gob encoding for their type, recursively.

Structs are sent as a sequence of (field number, field value) pairs.  The field
value is sent using the standard gob encoding for its type, recursively.  If a
field has the zero value for its type, it is omitted from the transmission.  The
field number is defined by the type of the encoded struct: the first field of the
encoded type is field 0, the second is field 1, etc.  When encoding a value, the
field numbers are delta encoded for efficiency and the fields are always sent in
order of increasing field number; the deltas are therefore unsigned.  The
initialization for the delta encoding sets the field number to -1, so an unsigned
integer field 0 with value 7 is transmitted as unsigned delta = 1, unsigned value
= 7 or (01 07).  Finally, after all the fields have been sent a terminating mark
denotes the end of the struct.  That mark is a delta=0 value, which has
representation (00).

Interface types are not checked for compatibility; all interface types are
treated, for transmission, as members of a single "interface" type, analogous to
int or []byte - in effect they're all treated as interface{}.  Interface values
are transmitted as a string identifying the concrete type being sent (a name
that must be pre-defined by calling Register), followed by a byte count of the
length of the following data (so the value can be skipped if it cannot be
stored), followed by the usual encoding of concrete (dynamic) value stored in
the interface value.  (A nil interface value is identified by the empty string
and transmits a zero-length value.) Upon receipt, the decoder verifies that the
unpacked concrete item satisfies the interface of the receiving variable.

The representation of types is described below.  When a type is defined on a given
connection between an Encoder and Decoder, it is assigned a signed integer type
id.  When Encoder.Encode(v) is called, it makes sure there is an id assigned for
the type of v and all its elements and then it sends the pair (typeid, encoded-v)
where typeid is the type id of the encoded type of v and encoded-v is the gob
encoding of the value v.

To define a type, the encoder chooses an unused, positive type id and sends the
pair (-type id, encoded-type) where encoded-type is the gob encoding of a wireType
description, constructed from these types:

	type wireType struct {
		s structType
	}
	type arrayType struct {
		commonType
		Elem typeId
		Len  int
	}
	type commonType {
		name string // the name of the struct type
		_id  int    // the id of the type, repeated for so it's inside the type
	}
	type sliceType struct {
		commonType
		Elem typeId
	}
	type structType struct {
		commonType
		field []*fieldType // the fields of the struct.
	}
	type fieldType struct {
		name string // the name of the field.
		id   int    // the type id of the field, which must be already defined
	}
	type mapType struct {
		commonType
		Key  typeId
		Elem typeId
	}

If there are nested type ids, the types for all inner type ids must be defined
before the top-level type id is used to describe an encoded-v.

For simplicity in setup, the connection is defined to understand these types a
priori, as well as the basic gob types int, uint, etc.  Their ids are:

	bool        1
	int         2
	uint        3
	float       4
	[]byte      5
	string      6
	complex     7
	interface   8
	// gap for reserved ids.
	wireType    16
	arrayType   17
	commonType  18
	sliceType   19
	structType  20
	fieldType   21
	// 22 is slice of fieldType.
	mapType     23

In summary, a gob stream looks like

	((-type id, encoding of a wireType)* (type id, encoding of a value))*

where * signifies zero or more repetitions and the type id of a value must
be predefined or be defined before the value in the stream.
*/
package gob

/*
For implementers and the curious, here is an encoded example.  Given
	type Point struct {x, y int}
and the value
	p := Point{22, 33}
the bytes transmitted that encode p will be:
	1f ff 81 03 01 01 05 50 6f 69 6e 74 01 ff 82 00
	01 02 01 01 78 01 04 00 01 01 79 01 04 00 00 00
	07 ff 82 01 2c 01 42 00
They are determined as follows.

Since this is the first transmission of type Point, the type descriptor
for Point itself must be sent before the value.  This is the first type
we've sent on this Encoder, so it has type id 65 (0 through 64 are
reserved).

	1f	// This item (a type descriptor) is 31 bytes long.
	ff 81	// The negative of the id for the type we're defining, -65.
		// This is one byte (indicated by FF = -1) followed by
		// ^-65<<1 | 1.  The low 1 bit signals to complement the
		// rest upon receipt.

	// Now we send a type descriptor, which is itself a struct (wireType).
	// The type of wireType itself is known (it's built in, as is the type of
	// all its components), so we just need to send a *value* of type wireType
	// that represents type "Point".
	// Here starts the encoding of that value.
	// Set the field number implicitly to -1; this is done at the beginning
	// of every struct, including nested structs.
	03	// Add 3 to field number; now 2 (wireType.structType; this is a struct).
		// structType starts with an embedded commonType, which appears
		// as a regular structure here too.
	01	// add 1 to field number (now 0); start of embedded commonType.
	01	// add 1 to field number (now 0, the name of the type)
	05	// string is (unsigned) 5 bytes long
	50 6f 69 6e 74	// wireType.structType.commonType.name = "Point"
	01	// add 1 to field number (now 1, the id of the type)
	ff 82	// wireType.structType.commonType._id = 65
	00	// end of embedded wiretype.structType.commonType struct
	01	// add 1 to field number (now 1, the field array in wireType.structType)
	02	// There are two fields in the type (len(structType.field))
	01	// Start of first field structure; add 1 to get field number 0: field[0].name
	01	// 1 byte
	78	// structType.field[0].name = "x"
	01	// Add 1 to get field number 1: field[0].id
	04	// structType.field[0].typeId is 2 (signed int).
	00	// End of structType.field[0]; start structType.field[1]; set field number to -1.
	01	// Add 1 to get field number 0: field[1].name
	01	// 1 byte
	79	// structType.field[1].name = "y"
	01	// Add 1 to get field number 1: field[0].id
	04	// struct.Type.field[1].typeId is 2 (signed int).
	00	// End of structType.field[1]; end of structType.field.
	00	// end of wireType.structType structure
	00	// end of wireType structure

Now we can send the Point value.  Again the field number resets to -1:

	07	// this value is 7 bytes long
	ff 82	// the type number, 65 (1 byte (-FF) followed by 65<<1)
	01	// add one to field number, yielding field 0
	2c	// encoding of signed "22" (0x22 = 44 = 22<<1); Point.x = 22
	01	// add one to field number, yielding field 1
	42	// encoding of signed "33" (0x42 = 66 = 33<<1); Point.y = 33
	00	// end of structure

The type encoding is long and fairly intricate but we send it only once.
If p is transmitted a second time, the type is already known so the
output will be just:

	07 ff 82 01 2c 01 42 00

A single non-struct value at top level is transmitted like a field with
delta tag 0.  For instance, a signed integer with value 3 presented as
the argument to Encode will emit:

	03 04 00 06

Which represents:

	03	// this value is 3 bytes long
	04	// the type number, 2, represents an integer
	00	// tag delta 0
	06	// value 3

*/
<commit_msg>gob: documentation. this time for sure. if the interface value is nil, it sends no value,<commit_after>// Copyright 2009 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.

/*
The gob package manages streams of gobs - binary values exchanged between an
Encoder (transmitter) and a Decoder (receiver).  A typical use is transporting
arguments and results of remote procedure calls (RPCs) such as those provided by
package "rpc".

A stream of gobs is self-describing.  Each data item in the stream is preceded by
a specification of its type, expressed in terms of a small set of predefined
types.  Pointers are not transmitted, but the things they point to are
transmitted; that is, the values are flattened.  Recursive types work fine, but
recursive values (data with cycles) are problematic.  This may change.

To use gobs, create an Encoder and present it with a series of data items as
values or addresses that can be dereferenced to values.  The Encoder makes sure
all type information is sent before it is needed.  At the receive side, a
Decoder retrieves values from the encoded stream and unpacks them into local
variables.

The source and destination values/types need not correspond exactly.  For structs,
fields (identified by name) that are in the source but absent from the receiving
variable will be ignored.  Fields that are in the receiving variable but missing
from the transmitted type or value will be ignored in the destination.  If a field
with the same name is present in both, their types must be compatible. Both the
receiver and transmitter will do all necessary indirection and dereferencing to
convert between gobs and actual Go values.  For instance, a gob type that is
schematically,

	struct { a, b int }

can be sent from or received into any of these Go types:

	struct { a, b int }	// the same
	*struct { a, b int }	// extra indirection of the struct
	struct { *a, **b int }	// extra indirection of the fields
	struct { a, b int64 }	// different concrete value type; see below

It may also be received into any of these:

	struct { a, b int }	// the same
	struct { b, a int }	// ordering doesn't matter; matching is by name
	struct { a, b, c int }	// extra field (c) ignored
	struct { b int }	// missing field (a) ignored; data will be dropped
	struct { b, c int }	// missing field (a) ignored; extra field (c) ignored.

Attempting to receive into these types will draw a decode error:

	struct { a int; b uint }	// change of signedness for b
	struct { a int; b float }	// change of type for b
	struct { }			// no field names in common
	struct { c, d int }		// no field names in common

Integers are transmitted two ways: arbitrary precision signed integers or
arbitrary precision unsigned integers.  There is no int8, int16 etc.
discrimination in the gob format; there are only signed and unsigned integers.  As
described below, the transmitter sends the value in a variable-length encoding;
the receiver accepts the value and stores it in the destination variable.
Floating-point numbers are always sent using IEEE-754 64-bit precision (see
below).

Signed integers may be received into any signed integer variable: int, int16, etc.;
unsigned integers may be received into any unsigned integer variable; and floating
point values may be received into any floating point variable.  However,
the destination variable must be able to represent the value or the decode
operation will fail.

Structs, arrays and slices are also supported.  Strings and arrays of bytes are
supported with a special, efficient representation (see below).

Interfaces, functions, and channels cannot be sent in a gob.  Attempting
to encode a value that contains one will fail.

The rest of this comment documents the encoding, details that are not important
for most users.  Details are presented bottom-up.

An unsigned integer is sent one of two ways.  If it is less than 128, it is sent
as a byte with that value.  Otherwise it is sent as a minimal-length big-endian
(high byte first) byte stream holding the value, preceded by one byte holding the
byte count, negated.  Thus 0 is transmitted as (00), 7 is transmitted as (07) and
256 is transmitted as (FE 01 00).

A boolean is encoded within an unsigned integer: 0 for false, 1 for true.

A signed integer, i, is encoded within an unsigned integer, u.  Within u, bits 1
upward contain the value; bit 0 says whether they should be complemented upon
receipt.  The encode algorithm looks like this:

	uint u;
	if i < 0 {
		u = (^i << 1) | 1	// complement i, bit 0 is 1
	} else {
		u = (i << 1)	// do not complement i, bit 0 is 0
	}
	encodeUnsigned(u)

The low bit is therefore analogous to a sign bit, but making it the complement bit
instead guarantees that the largest negative integer is not a special case.  For
example, -129=^128=(^256>>1) encodes as (FE 01 01).

Floating-point numbers are always sent as a representation of a float64 value.
That value is converted to a uint64 using math.Float64bits.  The uint64 is then
byte-reversed and sent as a regular unsigned integer.  The byte-reversal means the
exponent and high-precision part of the mantissa go first.  Since the low bits are
often zero, this can save encoding bytes.  For instance, 17.0 is encoded in only
three bytes (FE 31 40).

Strings and slices of bytes are sent as an unsigned count followed by that many
uninterpreted bytes of the value.

All other slices and arrays are sent as an unsigned count followed by that many
elements using the standard gob encoding for their type, recursively.

Structs are sent as a sequence of (field number, field value) pairs.  The field
value is sent using the standard gob encoding for its type, recursively.  If a
field has the zero value for its type, it is omitted from the transmission.  The
field number is defined by the type of the encoded struct: the first field of the
encoded type is field 0, the second is field 1, etc.  When encoding a value, the
field numbers are delta encoded for efficiency and the fields are always sent in
order of increasing field number; the deltas are therefore unsigned.  The
initialization for the delta encoding sets the field number to -1, so an unsigned
integer field 0 with value 7 is transmitted as unsigned delta = 1, unsigned value
= 7 or (01 07).  Finally, after all the fields have been sent a terminating mark
denotes the end of the struct.  That mark is a delta=0 value, which has
representation (00).

Interface types are not checked for compatibility; all interface types are
treated, for transmission, as members of a single "interface" type, analogous to
int or []byte - in effect they're all treated as interface{}.  Interface values
are transmitted as a string identifying the concrete type being sent (a name
that must be pre-defined by calling Register), followed by a byte count of the
length of the following data (so the value can be skipped if it cannot be
stored), followed by the usual encoding of concrete (dynamic) value stored in
the interface value.  (A nil interface value is identified by the empty string
and transmits no value.) Upon receipt, the decoder verifies that the unpacked
concrete item satisfies the interface of the receiving variable.

The representation of types is described below.  When a type is defined on a given
connection between an Encoder and Decoder, it is assigned a signed integer type
id.  When Encoder.Encode(v) is called, it makes sure there is an id assigned for
the type of v and all its elements and then it sends the pair (typeid, encoded-v)
where typeid is the type id of the encoded type of v and encoded-v is the gob
encoding of the value v.

To define a type, the encoder chooses an unused, positive type id and sends the
pair (-type id, encoded-type) where encoded-type is the gob encoding of a wireType
description, constructed from these types:

	type wireType struct {
		s structType
	}
	type arrayType struct {
		commonType
		Elem typeId
		Len  int
	}
	type commonType {
		name string // the name of the struct type
		_id  int    // the id of the type, repeated for so it's inside the type
	}
	type sliceType struct {
		commonType
		Elem typeId
	}
	type structType struct {
		commonType
		field []*fieldType // the fields of the struct.
	}
	type fieldType struct {
		name string // the name of the field.
		id   int    // the type id of the field, which must be already defined
	}
	type mapType struct {
		commonType
		Key  typeId
		Elem typeId
	}

If there are nested type ids, the types for all inner type ids must be defined
before the top-level type id is used to describe an encoded-v.

For simplicity in setup, the connection is defined to understand these types a
priori, as well as the basic gob types int, uint, etc.  Their ids are:

	bool        1
	int         2
	uint        3
	float       4
	[]byte      5
	string      6
	complex     7
	interface   8
	// gap for reserved ids.
	wireType    16
	arrayType   17
	commonType  18
	sliceType   19
	structType  20
	fieldType   21
	// 22 is slice of fieldType.
	mapType     23

In summary, a gob stream looks like

	((-type id, encoding of a wireType)* (type id, encoding of a value))*

where * signifies zero or more repetitions and the type id of a value must
be predefined or be defined before the value in the stream.
*/
package gob

/*
For implementers and the curious, here is an encoded example.  Given
	type Point struct {x, y int}
and the value
	p := Point{22, 33}
the bytes transmitted that encode p will be:
	1f ff 81 03 01 01 05 50 6f 69 6e 74 01 ff 82 00
	01 02 01 01 78 01 04 00 01 01 79 01 04 00 00 00
	07 ff 82 01 2c 01 42 00
They are determined as follows.

Since this is the first transmission of type Point, the type descriptor
for Point itself must be sent before the value.  This is the first type
we've sent on this Encoder, so it has type id 65 (0 through 64 are
reserved).

	1f	// This item (a type descriptor) is 31 bytes long.
	ff 81	// The negative of the id for the type we're defining, -65.
		// This is one byte (indicated by FF = -1) followed by
		// ^-65<<1 | 1.  The low 1 bit signals to complement the
		// rest upon receipt.

	// Now we send a type descriptor, which is itself a struct (wireType).
	// The type of wireType itself is known (it's built in, as is the type of
	// all its components), so we just need to send a *value* of type wireType
	// that represents type "Point".
	// Here starts the encoding of that value.
	// Set the field number implicitly to -1; this is done at the beginning
	// of every struct, including nested structs.
	03	// Add 3 to field number; now 2 (wireType.structType; this is a struct).
		// structType starts with an embedded commonType, which appears
		// as a regular structure here too.
	01	// add 1 to field number (now 0); start of embedded commonType.
	01	// add 1 to field number (now 0, the name of the type)
	05	// string is (unsigned) 5 bytes long
	50 6f 69 6e 74	// wireType.structType.commonType.name = "Point"
	01	// add 1 to field number (now 1, the id of the type)
	ff 82	// wireType.structType.commonType._id = 65
	00	// end of embedded wiretype.structType.commonType struct
	01	// add 1 to field number (now 1, the field array in wireType.structType)
	02	// There are two fields in the type (len(structType.field))
	01	// Start of first field structure; add 1 to get field number 0: field[0].name
	01	// 1 byte
	78	// structType.field[0].name = "x"
	01	// Add 1 to get field number 1: field[0].id
	04	// structType.field[0].typeId is 2 (signed int).
	00	// End of structType.field[0]; start structType.field[1]; set field number to -1.
	01	// Add 1 to get field number 0: field[1].name
	01	// 1 byte
	79	// structType.field[1].name = "y"
	01	// Add 1 to get field number 1: field[0].id
	04	// struct.Type.field[1].typeId is 2 (signed int).
	00	// End of structType.field[1]; end of structType.field.
	00	// end of wireType.structType structure
	00	// end of wireType structure

Now we can send the Point value.  Again the field number resets to -1:

	07	// this value is 7 bytes long
	ff 82	// the type number, 65 (1 byte (-FF) followed by 65<<1)
	01	// add one to field number, yielding field 0
	2c	// encoding of signed "22" (0x22 = 44 = 22<<1); Point.x = 22
	01	// add one to field number, yielding field 1
	42	// encoding of signed "33" (0x42 = 66 = 33<<1); Point.y = 33
	00	// end of structure

The type encoding is long and fairly intricate but we send it only once.
If p is transmitted a second time, the type is already known so the
output will be just:

	07 ff 82 01 2c 01 42 00

A single non-struct value at top level is transmitted like a field with
delta tag 0.  For instance, a signed integer with value 3 presented as
the argument to Encode will emit:

	03 04 00 06

Which represents:

	03	// this value is 3 bytes long
	04	// the type number, 2, represents an integer
	00	// tag delta 0
	06	// value 3

*/
<|endoftext|>