コード例 #1
0
ファイル: matchers.go プロジェクト: boggle/gospec
// The actual collection must contain all expected elements and nothing else.
// The order of elements is not significant.
func ContainsExactly(actual_ interface{}, expected_ interface{}) (match bool, pos Message, neg Message, err os.Error) {
	actual, err := toArray(actual_)
	if err != nil {
		return
	}
	expected, err := toArray(expected_)
	if err != nil {
		return
	}

	containsAll := true
	remaining := new(vector.Vector)
	remaining.AppendVector((*vector.Vector)(&actual))
	for i := 0; i < len(expected); i++ {
		if idx, found := findIndex(*remaining, expected[i]); found {
			remaining.Delete(idx)
		} else {
			containsAll = false
			break
		}
	}

	match = containsAll && remaining.Len() == 0
	pos = Messagef(actual, "contains exactly “%v”", expected)
	neg = Messagef(actual, "does NOT contain exactly “%v”", expected)
	return
}
コード例 #2
0
ファイル: vectors.go プロジェクト: ivanwyc/google-go
func test1() {
	var a [1000]*S
	for i := 0; i < len(a); i++ {
		a[i] = new(S).Init(i)
	}

	v := new(vector.Vector)
	for i := 0; i < len(a); i++ {
		v.Insert(0, a[i])
		if v.Len() != i+1 {
			panic("len = ", v.Len(), "\n")
		}
	}

	for i := 0; i < v.Len(); i++ {
		x := v.At(i).(*S)
		if x.val != v.Len()-i-1 {
			panic("expected ", i, ", found ", x.val, "\n")
		}
	}

	for v.Len() > 10 {
		v.Delete(10)
	}
}
コード例 #3
0
ファイル: ot.go プロジェクト: AaronO/lightwave
func (self Transformer) shorten(arr vec.Vector, index, inside, count int) (rindex int, rinside int) {
	mut := arr[index]
	if IsDeleteMutation(mut) {
		del := toDeleteMutation(mut)
		del.SetCount(del.Count() - count)
		if inside == del.Count() {
			inside = 0
			if del.Count() == 0 {
				arr.Delete(index)
			} else {
				index++
			}
		}
	} else if IsSkipMutation(mut) {
		skip := toSkipMutation(mut)
		skip.SetCount(skip.Count() - 1)
		if inside == skip.Count() {
			inside = 0
			if skip.Count() == 0 {
				arr.Delete(index)
			} else {
				index++
			}
		}
	} else {
		panic("Unsupported mutation for shorten()")
	}

	return index, inside
}
コード例 #4
0
ファイル: otapply.go プロジェクト: AaronO/lightwave
func (self DocumentMutation) applyArrayMutation(arr []interface{}, mutation ArrayMutation, flags uint32) []interface{} {
	index := 0
	var v vec.Vector = arr

	// Find the lifts
	lifts := make(map[string]interface{})
	for _, mut := range mutation.Array() {
		switch {
		case IsInsertMutation(mut), IsSqueezeMutation(mut):
			continue
		case IsDeleteMutation(mut):
			index += toDeleteMutation(mut).Count()
		case IsSkipMutation(mut):
			index += toSkipMutation(mut).Count()
		case IsObjectMutation(mut), IsArrayMutation(mut), IsTextMutation(mut):
			index++
		case IsLiftMutation(mut):
			l := toLiftMutation(mut)
			val := v[index]
			if l.HasMutation() {
				val = self.apply(val, l.Mutation(), flags)
			}
			lifts[l.Id()] = val
			index++
		default:
			panic("Should never happen")
		}
	}

	index = 0
	for _, m := range mutation.Array() {
		switch {
		case IsDeleteMutation(m):
			count := toDeleteMutation(m).Count()
			for i := 0; i < count; i++ {
				v.Delete(i)
			}
		case IsSkipMutation(m):
			index += toSkipMutation(m).Count()
		case IsLiftMutation(m):
			v.Delete(index)
		case IsSqueezeMutation(m):
			v.Insert(index, lifts[toSqueezeMutation(m).Id()])
			index++
		case IsObjectMutation(m), IsArrayMutation(m), IsTextMutation(m):
			v[index] = self.apply(v[index], m, flags)
			index++
		default:
			// Must be an insert mutation
			v.Insert(index, self.apply(nil, m, flags))
			index++
		}
	}

	return v
}
コード例 #5
0
ファイル: Game.go プロジェクト: skoji/Gdd11jpSlidePuzzle_go
func (g *Game) calcDistances() {
	q := new(vector.Vector)
	g.distances = make([][]int, len(g.rootBoard))
	for i, x := range g.rootBoard {
		g.distances[i] = make([]int, len(g.rootBoard))
		if x >= 0 {
			visited := make(map[int]bool)
			q.Push([]int{i, 0})
			for q.Len() > 0 {
				cell := q.At(0).([]int)
				index, step := cell[0], cell[1]
				q.Delete(0)
				visited[index] = true
				g.distances[i][index] = step
				for _, next := range g.nexts(index) {
					if visited[next+index] != true {
						q.Push([]int{next + index, step + 1})
					}
				}
			}
		}
	}
}
コード例 #6
0
ファイル: ot.go プロジェクト: AaronO/lightwave
func (self Transformer) transform_pass1_array(sobj, cobj ArrayMutation) os.Error {
	var (
		sarr    vec.Vector = sobj.Array()
		carr    vec.Vector = cobj.Array()
		sindex  int        = 0
		cindex  int        = 0
		sinside int        = 0
		cinside int        = 0
	)

	// Loop until end of one mutation is reached
	for sindex < len(sarr) || cindex < len(carr) {
		var smut, cmut interface{}
		if sindex < len(sarr) {
			smut = sarr[sindex]
		}
		if cindex < len(carr) {
			cmut = carr[cindex]
		}

		// Server insert/squeeze go first
		for IsInsertMutation(smut) || IsSqueezeMutation(smut) {
			if cinside > 0 {
				self.split(&carr, cindex, cinside)
				cinside = 0
				cindex++
				cmut = carr[cindex]
			}

			if IsInsertMutation(smut) {
				// TODO: check the Insert mutation individually for correctness
				carr.Insert(cindex, NewSkipMutation(1))
				cindex++
				sindex++
			} else if IsSqueezeMutation(smut) {
				sSqueeze := toSqueezeMutation(smut)
				// Which operation does the client side have for this object?
				c, hasCounterpart := self.cLiftCounterpart[sSqueeze.Id()]
				if !hasCounterpart || IsSkipMutation(c) {
					// Server lift remains, client skips it at the new position
					carr.Insert(cindex, NewSkipMutation(1))
					cindex++
					sindex++
				} else if IsDeleteMutation(c) {
					// Client deletes the object at its new position
					carr.Insert(cindex, NewDeleteMutation(1))
					cindex++
					// Server removes squeeze because it is already deleted by the client
					sarr.Delete(sindex)
				} else if IsLiftMutation(c) {
					// sLift := self.sLifts[sSqueeze.Id()]
					cLift := toLiftMutation(c)
					if cLift.HasMutation() {
						// The client does not lift it and therefore it mutates it at the new position
						carr.Insert(cindex, cLift.Mutation())
						cindex++
						// Server keeps its squeeze at this position
						sindex++
					} else {
						// Client skips the squeezed object and does not lift it
						carr.Insert(cindex, NewSkipMutation(1))
						cindex++
						// Server keeps its squeeze at this position
						sindex++
					}
				} else {
					// The client somehow mutates the object. It must do so at its new position
					carr.Insert(cindex, c)
					cindex++
					sindex++
				}
			}

			if sindex < len(sarr) {
				smut = sarr[sindex]
			} else {
				smut = nil
			}
		}

		// Client insert/squeeze go next
		for IsInsertMutation(cmut) || IsSqueezeMutation(cmut) {
			if sinside > 0 {
				self.split(&sarr, sindex, sinside)
				sinside = 0
				sindex++
				smut = sarr[sindex]
			}

			if IsInsertMutation(cmut) {
				// TODO: check the Insert mutation individually for correctness
				cindex++
				sarr.Insert(sindex, NewSkipMutation(1))
				sindex++
			} else {
				cSqueeze := toSqueezeMutation(cmut)
				// Which operation does the server side have for this object?
				s, hasCounterpart := self.sLiftCounterpart[cSqueeze.Id()]
				if !hasCounterpart || IsSkipMutation(s) {
					sarr.Insert(sindex, NewSkipMutation(1))
					sindex++
					cindex++
				} else if IsDeleteMutation(s) {
					// Server deletes the object at its the new position
					sarr.Insert(sindex, NewDeleteMutation(1))
					sindex++
					// Client removes squeeze because it is already deleted by the client
					carr.Delete(cindex)
				} else if IsLiftMutation(s) {
					// The server must lift the object here instead
					sarr.Insert(sindex, s)
					sindex++
					// The server lifted this object as well -> the client cannot lift it ->
					// then the client cannot squeeze it in here
					carr.Delete(cindex)
				} else {
					// The server mutates the object at its new position
					sarr.Insert(sindex, s)
					sindex++
					// The client squeezes the object in here
					cindex++
				}
			}

			if cindex < len(carr) {
				cmut = carr[sindex]
			} else {
				cmut = nil
			}
		}

		if sindex == len(sarr) && cindex == len(carr) {
			break
		}
		if sindex == len(sarr) || cindex == len(carr) {
			return os.NewError("The mutations do not have equal length")
		}

		//
		// Lift, Skip, Delete, mutations
		//

		if IsLiftMutation(smut) {
			// Both are lifting the same object?
			if IsLiftMutation(cmut) {
				// The client removes its lift. If it has a mutation then it will be moved to the corresponding squeeze
				carr.Delete(cindex)
				// The server removes its lift. It will be placed where the client moved it.
				sarr.Delete(sindex)
			} else if IsDeleteMutation(cmut) {
				// The server does not lift the object because it is deleted
				sarr.Delete(sindex)
				// The client removes its delete. The delete is put where the server squeezed it.
				cindex, cinside = self.shorten(carr, cindex, cinside, 1)
			} else if IsSkipMutation(cmut) {
				// The client does not skip this element here. It is skipped where it is squeezed in
				cindex, cinside = self.shorten(carr, cindex, cinside, 1)
				// Server remains with its lift
				sindex++
			} else {
				// Q_ASSERT(cmut.isArrayMutation() || cmut.isObjectMutation() || cmut.isTextMutation() || cmut.isRichTextMutation() );
				// The client removes its mutation here. It is shifted to the new position where the object is squeezed in.
				carr.Delete(cindex)
				// Server remains with its lift
				sindex++
			}
		} else if IsLiftMutation(cmut) {
			if IsDeleteMutation(smut) {
				// The client does not lift the object because it is deleted
				carr.Delete(cindex)
				// The server removes its delete. The delete is put where the client squeezed it.
				sindex, sinside = self.shorten(sarr, sindex, sinside, 1)
			} else if IsSkipMutation(smut) {
				// The server does not skip this element here. It is skipped where it is squeezed in
				sindex, sinside = self.shorten(sarr, sindex, sinside, 1)
				// Client remains with its lift
				cindex++
			} else {
				// Q_ASSERT(smut.isArrayMutation() || smut.isObjectMutation() || smut.isTextMutation() || smut.isRichTextMutation() );
				// The server removes its mutation here. It is shifted to the new position where the object is squeezed in.
				sarr.Delete(sindex)
				// Client remains with its lift
				cindex++
			}
		} else if IsDeleteMutation(smut) && IsDeleteMutation(cmut) {
			sdel := toDeleteMutation(smut).Count()
			cdel := toDeleteMutation(cmut).Count()
			del := IntMin(sdel-sinside, cdel-cinside)
			sindex, sinside = self.shorten(sarr, sindex, sinside, del)
			cindex, cinside = self.shorten(carr, cindex, cinside, del)
		} else if IsSkipMutation(smut) && IsSkipMutation(cmut) {
			sskip := toSkipMutation(smut).Count()
			cskip := toSkipMutation(cmut).Count()
			skip := IntMin(sskip-sinside, cskip-cinside)
			sinside += skip
			cinside += skip
			if sinside == sskip {
				sinside = 0
				sindex++
			}
			if cinside == cskip {
				cinside = 0
				cindex++
			}
		} else if IsDeleteMutation(smut) && IsSkipMutation(cmut) {
			sdel := toDeleteMutation(smut).Count()
			cskip := toSkipMutation(cmut).Count()
			count := IntMin(sdel-sinside, cskip-cinside)
			sinside += count
			if sinside == sdel {
				sinside = 0
				sindex++
			}
			cindex, cinside = self.shorten(carr, cindex, cinside, count)
		} else if IsSkipMutation(smut) && IsDeleteMutation(cmut) {
			sskip := toSkipMutation(smut).Count()
			cdel := toDeleteMutation(cmut).Count()
			count := IntMin(sskip-sinside, cdel-cinside)
			sindex, sinside = self.shorten(sarr, sindex, sinside, count)
			cinside += count
			if cinside == cdel {
				cinside = 0
				cindex++
			}
		} else if IsSkipMutation(smut) { // ... and mutation at the client
			cindex++
			sinside++
			if toSkipMutation(smut).Count() == sinside {
				sinside = 0
				sindex++
			}
		} else if IsSkipMutation(cmut) { // ... and mutation at the srver
			sindex++
			cinside++
			if toSkipMutation(cmut).Count() == cinside {
				cinside = 0
				cindex++
			}
		} else if IsDeleteMutation(smut) { // ... and mutation at the client
			carr.Delete(cindex)
			sinside++
			if toDeleteMutation(smut).Count() == sinside {
				sinside = 0
				sindex++
			}
		} else if IsDeleteMutation(cmut) { // ... and mutation at the server
			sarr.Delete(sindex)
			cinside++
			if toDeleteMutation(cmut).Count() == cinside {
				cinside = 0
				cindex++
			}
		} else {
			if IsObjectMutation(smut) && IsObjectMutation(cmut) {
				if err := self.transform_pass1_object(toObjectMutation(smut), toObjectMutation(cmut)); err != nil {
					return err
				}
			} else if IsArrayMutation(smut) && IsArrayMutation(cmut) {
				if err := self.transform_pass1_array(toArrayMutation(smut), toArrayMutation(cmut)); err != nil {
					return err
				}
			} else if IsTextMutation(smut) && IsTextMutation(cmut) {
				if err := self.transform_pass1_text(toTextMutation(smut), toTextMutation(cmut)); err != nil {
					return err
				}
			} else if IsRichTextMutation(smut) && IsRichTextMutation(cmut) {
				if err := self.transform_pass1_richtext(toRichTextMutation(smut), toRichTextMutation(cmut)); err != nil {
					return err
				}
			} else {
				return os.NewError("The mutations are not compatible or not allowed inside an array mutation")
			}
			sindex++
			cindex++
		}
	}

	sobj.SetArray(sarr)
	cobj.SetArray(carr)

	return nil
}
コード例 #7
0
ファイル: ot.go プロジェクト: AaronO/lightwave
func (self Transformer) transform_pass1_richtext(sobj, cobj RichTextMutation) os.Error {
	var (
		sarr    vec.Vector = sobj.TextArray()
		carr    vec.Vector = cobj.TextArray()
		sindex  int        = 0
		cindex  int        = 0
		sinside int        = 0
		cinside int        = 0
	)

	// Loop until end of one mutation is reached
	for sindex < len(sarr) || cindex < len(carr) {
		var smut, cmut interface{}
		if sindex < len(sarr) {
			smut = sarr[sindex]
		}
		if cindex < len(carr) {
			cmut = carr[cindex]
		}

		// Server insertions go first
		if IsInsertMutation(smut) {
			// In the middle of a client skip/delete? Split it
			if cinside > 0 {
				self.split(&carr, cindex, cinside)
				cinside = 0
				cindex++
				cmut = carr[cindex]
			}
			if str, ok := smut.(string); ok {
				sindex++
				if len(str) > 0 {
					carr.Insert(cindex, NewSkipMutation(len(str)))
					cindex++
				}
			} else if _, ok := smut.(map[string]interface{}); ok {
				sindex++
				carr.Insert(cindex, NewSkipMutation(1))
				cindex++
			} else {
				panic("Only strings allowed inside a text mutation")
			}
			continue
		}
		// Client insertions go next
		if IsInsertMutation(cmut) {
			// In the middle of a server skip/delete? Split it
			if sinside > 0 {
				self.split(&sarr, sindex, sinside)
				sinside = 0
				sindex++
				smut = sarr[sindex]
			}
			if str, ok := cmut.(string); ok {
				cindex++
				if len(str) > 0 {
					sarr.Insert(sindex, NewSkipMutation(len(str)))
					sindex++
				}
			} else if _, ok := cmut.(map[string]interface{}); ok {
				cindex++
				sarr.Insert(sindex, NewSkipMutation(1))
				sindex++
			} else {
				return os.NewError("Only strings allowed inside a text mutation")
			}
			continue
		}

		if sindex == len(sarr) && cindex == len(carr) {
			break
		}
		if sindex == len(sarr) || cindex == len(carr) {
			return os.NewError("The mutations do not have equal length")
		}

		if IsDeleteMutation(smut) && IsDeleteMutation(cmut) {
			sdel := toDeleteMutation(smut).Count()
			cdel := toDeleteMutation(cmut).Count()
			del := IntMin(sdel-sinside, cdel-cinside)
			sindex, sinside = self.shorten(sarr, sindex, sinside, del)
			cindex, cinside = self.shorten(carr, cindex, cinside, del)
		} else if IsSkipMutation(smut) && IsSkipMutation(cmut) {
			sskip := toSkipMutation(smut).Count()
			cskip := toSkipMutation(cmut).Count()
			skip := IntMin(sskip-sinside, cskip-cinside)
			sinside += skip
			cinside += skip
			if sinside == sskip {
				sinside = 0
				sindex++
			}
			if cinside == cskip {
				cinside = 0
				cindex++
			}
		} else if IsDeleteMutation(smut) && IsSkipMutation(cmut) {
			sdel := toDeleteMutation(smut).Count()
			cskip := toSkipMutation(cmut).Count()
			count := IntMin(sdel-sinside, cskip-cinside)
			sinside += count
			if sinside == sdel {
				sinside = 0
				sindex++
			}
			cindex, cinside = self.shorten(carr, cindex, cinside, count)
		} else if IsSkipMutation(smut) && IsDeleteMutation(cmut) {
			sskip := toSkipMutation(smut).Count()
			cdel := toDeleteMutation(cmut).Count()
			count := IntMin(sskip-sinside, cdel-cinside)
			sindex, sinside = self.shorten(sarr, sindex, sinside, count)
			cinside += count
			if cinside == cdel {
				cinside = 0
				cindex++
			}
		} else if IsSkipMutation(smut) && IsObjectMutation(cmut) {
			sskip := toSkipMutation(smut).Count()
			sinside += 1
			cindex++
			if sinside == sskip {
				sinside = 0
				sindex++
			}
		} else if IsObjectMutation(smut) && IsSkipMutation(cmut) {
			cskip := toSkipMutation(cmut).Count()
			cinside += 1
			sindex++
			if cinside == cskip {
				cinside = 0
				cindex++
			}
		} else if IsObjectMutation(smut) && IsDeleteMutation(cmut) {
			sarr.Delete(sindex)
			cdel := toDeleteMutation(cmut).Count()
			cinside += 1
			if cinside == cdel {
				cinside = 0
				cindex++
			}
		} else if IsDeleteMutation(smut) && IsObjectMutation(cmut) {
			carr.Delete(cindex)
			sdel := toDeleteMutation(smut).Count()
			sinside += 1
			if sinside == sdel {
				sinside = 0
				sindex++
			}
		} else {
			return os.NewError(fmt.Sprintf("Mutation not allowed in a richtext mutation:\n%v %v\n%v %v", smut, IsSkipMutation(smut), cmut, IsSkipMutation(cmut)))
		}
	}

	sobj.SetTextArray(sarr)
	cobj.SetTextArray(carr)

	return nil
}
コード例 #8
0
ファイル: otapply.go プロジェクト: AaronO/lightwave
func (self DocumentMutation) applyRichTextMutation(obj map[string]interface{}, mutation RichTextMutation, flags uint32) {
	if flags&CreateIDs == CreateIDs {
		if _, ok := obj["_id"]; !ok {
			obj["_id"] = uniqueId()
		}
		obj["_rev"] = self.AppliedAtRevision()
	}

	var text vec.Vector = obj["text"].([]interface{})
	index := 0
	inside := 0
	for _, m := range mutation.TextArray() {
		switch {
		case IsDeleteMutation(m):
			count := toDeleteMutation(m).Count()
			for count > 0 {
				if str, ok := text[index].(string); ok {
					l := min(len(str)-inside, count)
					// inside += l
					// str = str[inside:]
					str = str[:inside] + str[inside+l:]
					if len(str) == 0 {
						text.Delete(index)
						inside = 0
					} else if inside == len(str) {
						text[index] = str
						index++
						inside = 0
					} else {
						text[index] = str
					}
					count -= l
				} else {
					inside = 0
					text.Delete(index)
					count--
				}
			}
			// ** Ended up in the middle between two strings? -> Join them **
			if inside == 0 && index < len(text) {
				if str1, ok := text[index-1].(string); ok {
					if str2, ok := text[index].(string); ok {
						text[index-1] = str1 + str2
						text.Delete(index)
						index--
						inside = len(str1)
						continue
					}
				}
			} else if index < len(text)-1 {
				if str1, ok := text[index].(string); inside == len(str1) && ok {
					if str2, ok := text[index+1].(string); ok {
						text[index] = str1 + str2
						inside = len(str1)
						text.Delete(index + 1)
						continue
					}
				}
			}
		case IsSkipMutation(m):
			count := toSkipMutation(m).Count()
			for count > 0 {
				if str, ok := text[index].(string); ok {
					l := min(len(str)-inside, count)
					inside += l
					count -= count
					if inside == len(str) {
						index++
						inside = 0
					}
				} else {
					inside = 0
					index++
					count--
				}
			}
		default:
			// *** A string? ***
			if s, ok := m.(string); ok {
				// Appending to a string?
				if inside == 0 && index > 0 {
					if str, ok := text[index-1].(string); ok {
						text[index-1] = str + s
						continue
					}
				}
				// End of string?
				if index == len(text) {
					text.Insert(index, s)
					index++
					continue
				}
				// Prepending/Inserting to an existing string?
				if str, ok := text[index].(string); ok {
					// Insert into an existing string ?
					text[index] = str[0:inside] + s + str[inside:]
					inside += len(str)
					continue
				}
				// Insert in front of an object
				text.Insert(index, s)
				index++
				continue
			}
			// *** Insert an object ***
			if index < len(text) && inside > 0 && inside == len(text[index].(string)) {
				// End of string?
				inside = 0
				index++
			}
			// Middle of a string -> split it
			if inside > 0 {
				str := text[index].(string)
				text.Insert(index+1, str[inside:])
				text[index] = str[:inside]
				text.Insert(index+1, m)
				inside = 0
				index += 2
			} else {
				text.Insert(index, m)
				index++
			}
		}
	}

	obj["text"] = []interface{}(text)
}
コード例 #9
0
ファイル: main.go プロジェクト: nunb/GoForth
func parse_forth(dat string, DataStack *vector.Vector) {
	L := DataStack.Len()

	switch strings.TrimSpace(string(dat)) {
	case "":
	case "<cr>":
		return
	case "t":
		//check the DataStack size using the popped value
		//	if it passes, then the program continues
		minimum := int(DataStack.Pop().(float32))
		if DataStack.Len() < minimum {
			log.Println("DataStack has not enough minerals (values)")
		}
	case ".":
		log.Println(DataStack.Pop())
	case "0SP":
		DataStack.Cut(0, L)
	case ".S":
		log.Println(DataStack)
	case "2/":
		DataStack.Push(DataStack.Pop().(float32) / 2)
	case "2*":
		DataStack.Push(DataStack.Pop().(float32) * 2)
	case "2-":
		DataStack.Push(DataStack.Pop().(float32) - 2)
	case "2+":
		DataStack.Push(DataStack.Pop().(float32) + 2)
	case "1-":
		DataStack.Push(DataStack.Pop().(float32) - 1)
	case "1+":
		DataStack.Push(DataStack.Pop().(float32) + 1)
	case "DUP":
		DataStack.Push(DataStack.Last())
	case "?DUP":
		if DataStack.Last().(float32) != 0 {
			DataStack.Push(DataStack.Last().(float32))
		}
	case "PICK":
		number := int(DataStack.Pop().(float32))

		if number < L {
			DataStack.Push(DataStack.At(L - 1 - number).(float32))
		} else {
			log.Fatal("picking out of stack not allowed. Stack Length: " + string(L) + ". Selecting: " + string(number) + ".")
			return
		}
	case "TUCK":
		DataStack.Insert(L-2, int(DataStack.Last().(float32)))
	case "NIP":
		DataStack.Delete(L - 2)
	case "2DROP":
		DataStack.Pop()
		DataStack.Pop()
	case "2DUP":
		DataStack.Push(DataStack.At(L - 2))
		DataStack.Push(DataStack.At(DataStack.Len() - 2))
	case "DROP":
		DataStack.Pop()
	case "OVER":
		DataStack.Push(DataStack.At(L - 2))
	case "SWAP":
		l := DataStack.Len()
		DataStack.Swap(l-2, l-1)
	case "*":
		num1 := DataStack.Pop().(float32)
		num2 := DataStack.Pop().(float32)
		DataStack.Push(num1 * num2)
	case "+":
		num1 := DataStack.Pop().(float32)
		num2 := DataStack.Pop().(float32)
		DataStack.Push(num1 + num2)
	case "-":
		num1 := DataStack.Pop().(float32)
		num2 := DataStack.Pop().(float32)
		DataStack.Push(num2 - num1)
	case "/":
		num1 := DataStack.Pop().(float32)
		num2 := DataStack.Pop().(float32)
		DataStack.Push(num2 / num1)
	case "-ROT":
		DataStack.Swap(L-1, L-2)
		DataStack.Swap(L-2, L-3)
	case "ROT":
		DataStack.Swap(L-3, L-2)
		DataStack.Swap(L-2, L-1)
	case "2OVER":
		DataStack.Push(DataStack.At(L - 4))
		DataStack.Push(DataStack.At(DataStack.Len() - 4))
	case "2SWAP":
		DataStack.Swap(L-4, L-2)
		DataStack.Swap(L-3, L-1)
	case "EMIT":
		log.Println(string([]byte{uint8(DataStack.Last().(float32))}))
	default:
		val, ok := strconv.Atof32(dat)

		if ok == nil {
			DataStack.Push(val)
		} else {
			log.Println(ok)
			log.Fatalln("error, unknown token \"" + dat + "\"")
		}
	}
}
コード例 #10
0
ファイル: overlay.go プロジェクト: ebering/zellij
func (m *Map) Overlay(n *Map, mergeFaces func(interface{}, interface{}) (interface{}, os.Error)) (*Map, os.Error) {
	o := NewMap()
	CopiedEdges := new(vector.Vector)
	m.Edges.Do(func(l interface{}) {
		e := l.(*Edge)
		if e.start.Point.Less(e.end.Point) {
			f, g := NewEdgePair(NewVertex(e.start.Copy()), NewVertex(e.end.Copy()))
			f.face = e.face
			g.face = e.twin.face
			f.Generation = e.Generation
			g.Generation = e.twin.Generation
			f.fromMap,g.fromMap = m,m
			CopiedEdges.Push(f)
			CopiedEdges.Push(g)
		}
	})
	n.Edges.Do(func(l interface{}) {
		e := l.(*Edge)
		if e.start.Point.Less(e.end.Point) {
			f, g := NewEdgePair(NewVertex(e.start.Copy()), NewVertex(e.end.Copy()))
			f.face = e.face
			g.face = e.twin.face
			f.Generation = e.Generation
			g.Generation = e.twin.Generation
			f.fromMap,g.fromMap = n,n
			CopiedEdges.Push(f)
			CopiedEdges.Push(g)
		}
	})

	Q := new(vector.Vector)
	T := new(sweepStatus)
	T.segments = new(vector.Vector)

	CopiedEdges.Do(func(l interface{}) {
		e, _ := l.(*Edge)
		if e.start.Point.Less(e.end.Point) {
			evt := new(sweepEvent)
			evt.point = e.start.Point
			evt.coincidentEdge = e
			Q.Push(evt)
			evt = new(sweepEvent)
			evt.point = e.end.Point
			evt.coincidentEdge = nil
			Q.Push(evt)
		}
	})

	heap.Init(Q)

	for Q.Len() > 0 {
		evt, _ := heap.Pop(Q).(*sweepEvent)
		//fmt.Fprintf(os.Stderr,"event: %v\n",evt.point)
		L := new(vector.Vector)
		Lswp := new(sweepStatus)
		Lswp.segments = L
		Lswp.sweepLocation = evt.point
		if evt.coincidentEdge != nil {
			L.Push(evt.coincidentEdge)
		}
		for Q.Len() > 0 && evt.point.Equal(Q.At(0).(*sweepEvent).point) {
			evt, _ := heap.Pop(Q).(*sweepEvent)
			if evt.coincidentEdge != nil {
				L.Push(evt.coincidentEdge)
			}
		}
		sort.Sort(Lswp)
		for i := 0; i < L.Len()-1; {
			if L.At(i).(*Edge).Equal(L.At(i + 1).(*Edge)) {
				L.At(i).(*Edge).newFace = L.At(i + 1).(*Edge).face
				L.At(i).(*Edge).twin.newFace = L.At(i + 1).(*Edge).twin.face
				L.At(i).(*Edge).fromMap = nil //no longer from a unique map
				L.At(i).(*Edge).twin.fromMap = nil //no longer from a unique map
				L.Delete(i + 1)
			} else {
				i++
			}
		}
		//fmt.Fprintf(os.Stderr,"L: %v\n",L)
		R := new(vector.Vector)
		for i := 0; i < T.segments.Len(); {
			e := T.segments.At(i).(*Edge)
			if e.end.Point.Equal(evt.point) {
				R.Push(e)
				T.segments.Delete(i)
			} else if e.Line().On(evt.point) {
				return nil, os.NewError("intersection not at an endpoint")
			} else {
				i++
			}
		}

		// Fill in handle event. You won't need the whole damn thing because
		// Most of the time you just abort with non-terminal intersection
		T.sweepLocation = evt.point
		sort.Sort(T)
		//fmt.Fprintf(os.Stderr,"status: %v\n",T.segments)
		if L.Len() == 0 && R.Len() == 0 {
			return nil, os.NewError("event point with no edges terminal at it " + evt.point.String() + fmt.Sprintf("current status: %v", T.segments))
		} else if L.Len() == 0 {
			above := sort.Search(T.Len(), func(i int) bool {
				return T.segments.At(i).(*Edge).Line().Below(evt.point)
			})
			//fmt.Fprintf(os.Stderr,"Testing status point, no new edge. above: %v, Len: %v\n",above,T.Len())
			if 0 < above && above < T.Len() {
				sa := T.segments.At(above).(*Edge)
				sb := T.segments.At(above - 1).(*Edge)

				cross, _, _ := sb.Line().IntersectAsFloats(sa.Line())
				if cross && !sa.Coterminal(sb) {
					return nil, os.NewError("intersection not at an endpoint")
				}
			}
		} else {
			aboveL := sort.Search(T.Len(), func(i int) bool {
				return L.Last().(*Edge).Line().LessAt(T.segments.At(i).(*Edge).Line(), evt.point)
			})
			belowL := aboveL - 1
			//fmt.Fprintf(os.Stderr,"Testing status point, new edges. above: %v, Len: %v\n",aboveL,T.Len())
			if 0 <= belowL && belowL < T.Len() {
				sa := L.At(0).(*Edge)
				sb := T.segments.At(belowL).(*Edge)

				cross, _, _ := sa.Line().IntersectAsFloats(sb.Line())
				if cross && !sa.Coterminal(sb) {
					return nil, os.NewError("intersection not at an endpoint")
				}
			}
			if aboveL < T.Len() {
				sa := T.segments.At(aboveL).(*Edge)
				sb := L.Last().(*Edge)

				cross, _, _ := sa.Line().IntersectAsFloats(sb.Line())
				if cross && !sa.Coterminal(sb) {
					return nil, os.NewError("intersection not at an endpoint")
				}
			}
		}

		// This is the barrier between preparing the new vertex (below) and determining if the new vertex is good 

		// Setting up edges
		nv := NewVertex(evt.point.Copy())
		R.Do(func(r interface{}) {
			nv.OutgoingEdges.Push(r.(*Edge).twin)
			r.(*Edge).end = nv
			r.(*Edge).twin.start = nv
			o.Edges.Push(r)
			o.Edges.Push(r.(*Edge).twin)
		})
		L.Do(func(l interface{}) {
			l.(*Edge).start = nv
			l.(*Edge).twin.end = nv
			nv.OutgoingEdges.Push(l)
		})
		sort.Sort(nv.OutgoingEdges)

		for i := 0; i < nv.OutgoingEdges.Len(); i++ {
			e := nv.OutgoingEdges.At(i).(*Edge)
			f := nv.OutgoingEdges.At((i + 1) % nv.OutgoingEdges.Len()).(*Edge)
			e.prev = f.twin
			f.twin.next = e
		}

		// Setting up nv's inFace.
		// A new vertex only has relevant inFace information when it comes exclusively from one map, we first determine that
		fromOneMap := true
		fromMap := nv.OutgoingEdges.At(0).(*Edge).fromMap
		nv.OutgoingEdges.Do(func(e interface{}) {
			fromOneMap = fromOneMap && e.(*Edge).fromMap == fromMap && e.(*Edge).fromMap != nil
		})
		// we're from one map, got to find the elements in T from the other map above and below us
		if fromOneMap {
			//fmt.Fprintf(os.Stderr,"from one map, finding face of other\n")
			TfromOtherMap := new(sweepStatus)
			TfromOtherMap.sweepLocation = evt.point
			TfromOtherMap.segments = new(vector.Vector)
			T.segments.Do(func(e interface{}) {
				if e.(*Edge).fromMap != fromMap {
					TfromOtherMap.segments.Push(e)
				}
			})
			sort.Sort(TfromOtherMap)
			above := sort.Search(TfromOtherMap.Len(), func(i int) bool {
				return TfromOtherMap.segments.At(i).(*Edge).Line().Below(evt.point)
			})
			if 0 < above && above < TfromOtherMap.Len() {
				//fmt.Fprintf(os.Stderr,"Testing status point, looking for vertex in face. above: %v, Len: %v\n",above,TfromOtherMap.Len())
				sb := TfromOtherMap.segments.At(above - 1).(*Edge)
				if sb.fromMap == nil {
					if sb.face.fromMap == fromMap {
						nv.inFace = sb.newFace
					} else { 
						nv.inFace = sb.face
					}
				} else {
					nv.inFace = sb.face
				}
			} else if TfromOtherMap.Len() == 0 {
				nv.inFace = nil // completely outside other map, not our problem
			} else if above == 0 {
				sa := TfromOtherMap.segments.At(above).(*Edge)
				if sa.twin.fromMap == nil {
					if sa.twin.face.fromMap == fromMap {
						nv.inFace = sa.twin.newFace
					} else { 
						nv.inFace = sa.twin.face
					}
				} else {
					nv.inFace = sa.twin.face
				}
			} else if above == TfromOtherMap.Len() {
				sb := TfromOtherMap.segments.At(above - 1).(*Edge)
				nv.inFace = sb.face
				if sb.fromMap == nil {
					if sb.face.fromMap == fromMap {
						nv.inFace = sb.newFace
					} else { 
						nv.inFace = sb.face
					}
				} else {
					nv.inFace = sb.face
				}
			} 
		} else {
			nv.inFace = nil //we're not from one map, this vertex happens at the overlay, edges have complete face information.
		}

		o.Verticies.Push(nv)

		// Vertex done, add any new edges to the sweep line.

		L.Do(func(l interface{}) {
			T.segments.Push(l)
		})
	}

	var leFuck string
	for i := 0; i < o.Edges.Len(); i++ {
		e, _ := o.Edges.At(i).(*Edge)
		if e.visited {
			continue
		}
		//fmt.Fprintf(os.Stderr,"found a face containing: %v,",e.start)

		F := new(Face)
		F.boundary = e
		F.fromMap = o
		e.visited = true
		oldFaces := make(map[*Face]int)
		//fmt.Fprintf(os.Stderr,"%v: ",e.start)
		if e.face != nil {
			//fmt.Fprintf(os.Stderr,"f %v ",e.face.Value)
			oldFaces[e.face]++
		}
		if e.newFace != nil {
			//fmt.Fprintf(os.Stderr,"nf %v ",e.newFace.Value)
			oldFaces[e.newFace]++
		}
		if e.start.inFace != nil {
			//fmt.Fprintf(os.Stderr,"if %v ",e.start.inFace.Value)
			oldFaces[e.start.inFace]++
		}
		if e.face == nil && e.newFace == nil {
			panic("the edge without a face\n")
		}
		e.face = F

		for f := e.Next(); f != e; f = f.Next() {
			//fmt.Fprintf(os.Stderr,"%v: ",f.start)
			f.visited = true
			if f.face != nil {
				//fmt.Fprintf(os.Stderr,"f %v ",f.face.Value)
				oldFaces[f.face]++
			}
			if f.newFace != nil {
				//fmt.Fprintf(os.Stderr,"nf %v ",f.newFace.Value)
				oldFaces[f.newFace]++
			}
			if f.start.inFace != nil {
				//fmt.Fprintf(os.Stderr,"if %v ",f.start.inFace.Value)
				oldFaces[f.start.inFace]++
			}
			//fmt.Fprintf(os.Stderr,",")
			f.face = F
		}
		//os.Stderr.WriteString("\n")

		//fmt.Fprintf(os.Stderr,"%v old faces\n",len(oldFaces))
		if len(oldFaces) > 2 {
			leFuck += fmt.Sprintf("%v faces overlapping a new face, input must have been malformed, maps m: %p n: %p\n", len(oldFaces), m, n)
			for f, _ := range oldFaces {
				leFuck = leFuck + fmt.Sprintf("face %p from: %p containing: %v\n", f, f.fromMap, f.Value)
			}
			//os.Stderr.WriteString(leFuck)
		} else if len(oldFaces) == 0 {
			panic(fmt.Sprintf("No old faces. e: %v, e.face: %+v, maps: m: %p n: %p o: %p\n", e, e.face, m, n, o))
		}

		var mFace, nFace *Face
		for f, _ := range oldFaces {
			if f.fromMap == m {
				mFace = f
			} else {
				nFace = f
			}
		}
		if mFace != nil && nFace != nil {
			v, ok := mergeFaces(mFace.Value, nFace.Value)
			if ok != nil {
				return nil, ok
			}
			if mFace.Type != "" {
				F.Type = mFace.Type
			} else if nFace.Type != "" {
				F.Type = nFace.Type
			}
			F.Value = v
		} else if mFace != nil {
			F.Value = mFace.Value
			F.Type = mFace.Type
		} else if nFace != nil {
			F.Value = nFace.Value
			F.Type = nFace.Type
		} else {
			panic(fmt.Sprintf("face didn't come from an mFace or an nFace, pointers m: %v n: %v o: %v face: %v", m, n, o, e.face))
		}

		o.Faces.Push(F)
	}

	if leFuck != "" {
		return o, os.NewError(leFuck)
	}

	o.Init()
	return o, nil
}
コード例 #11
0
ファイル: sorter.go プロジェクト: mcherba/dagsched
// returns a topologically sorted vector of Node's
func TopSort(dag vec.Vector, s byte) vec.Vector {

	sortDag := new(vec.Vector)
	tempDag := new(vec.Vector)
	destDag := new(vec.Vector)
	setVec := new(vec.Vector)

	for i := 0; i < dag.Len(); i++ {
		tempDag.Push((dag.At(i).(*par.Node)).Copy())
		destDag.Push((dag.At(i).(*par.Node)).Copy())
	}
	// t-level gets regular top sort
	if s == 't' {
		setVec.Push(tempDag.At(0))
		destDag.Delete(0)
		for i := setVec.Len(); i > 0; i = setVec.Len() {
			n := (setVec.Pop().(*par.Node)).Copy()
			sortDag.Push(n)
			for j := 0; j < (n.Cl).Len(); j++ {
				c := ((n.Cl).At(j).(*par.Rel)).Id
				for k := 0; k < destDag.Len(); k++ {
					if (destDag.At(k).(*par.Node)).Id == c {
						for l := 0; l < (destDag.At(k).(*par.Node)).Pl.Len(); l++ {
							if (destDag.At(k).(*par.Node)).Pl.At(l).(*par.Rel).Id == n.Id {
								(destDag.At(k).(*par.Node)).Pl.Delete(l)
								break
							}
						}
					}
				}
			}
			for j := 0; j < destDag.Len(); j++ {
				if (destDag.At(j).(*par.Node)).Pl.Len() == 0 {
					c := (destDag.At(j).(*par.Node)).Id
					for k := 0; k < tempDag.Len(); k++ {
						if (tempDag.At(k).(*par.Node)).Id == c {
							setVec.Push(tempDag.At(k))
							break
						}
					}
					destDag.Delete(j)
					j--
				}
			}
		}
		// b-level gets reverse top sort
	} else if s == 'b' {
		setVec.Push(tempDag.At(tempDag.Len() - 1))
		destDag.Delete(destDag.Len() - 1)
		for i := setVec.Len(); i > 0; i = setVec.Len() {
			n := (setVec.Pop().(*par.Node)).Copy()
			sortDag.Push(n)
			for j := 0; j < (n.Pl).Len(); j++ {
				c := ((n.Pl).At(j).(*par.Rel)).Id
				for k := 0; k < destDag.Len(); k++ {
					if (destDag.At(k).(*par.Node)).Id == c {
						for l := 0; l < (destDag.At(k).(*par.Node)).Cl.Len(); l++ {
							if (destDag.At(k).(*par.Node)).Cl.At(l).(*par.Rel).Id == n.Id {
								(destDag.At(k).(*par.Node)).Cl.Delete(l)
								break
							}
						}
					}
				}
			}
			for j := 0; j < destDag.Len(); j++ {
				if (destDag.At(j).(*par.Node)).Cl.Len() == 0 {
					c := (destDag.At(j).(*par.Node)).Id
					for k := 0; k < tempDag.Len(); k++ {
						if (tempDag.At(k).(*par.Node)).Id == c {
							setVec.Push(tempDag.At(k))
							break
						}
					}
					destDag.Delete(j)
					j--
				}
			}
		}
	} else {
		fmt.Printf("Error")
	}

	return sortDag.Copy()

}