summaryrefslogtreecommitdiff
path: root/src/nbc/history.sml
blob: 52c1bb2d52ee1a2e400d0ac580a17c9bc83cbf81 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
structure History :> sig
	type history
	val create: int -> history
	val clear: history -> history
	val push: history * char -> string option * history
end = struct
	type history = {maximumSize: int, content: string}
	fun create maximumSize = {maximumSize = maximumSize, content = ""}
	fun clear {maximumSize, content = _} =
		{maximumSize = maximumSize, content = ""}
	fun addToString (string, newCharacter) =
		let
			val size = size string
		in
			CharVector.tabulate (
				size + 1
				, fn index =>
					if index = size then newCharacter
					else String.sub (string, index)
			)
		end
	fun shiftIntoString (string, newCharacter) =
		let
			val size = size string
		in
			CharVector.tabulate (
				size
				, fn index =>
					if index = size - 1 then newCharacter
					else String.sub (string, index + 1)
			)
		end
	fun push ({maximumSize, content}, newCharacter) =
		let
			val currentSize = size content
		in
			if currentSize = maximumSize then
				let
					val newContent = shiftIntoString (
						content
						, newCharacter
					)
				in (
					SOME newContent
					, {
						maximumSize = maximumSize
						, content = newContent
					}
				) end
			else if currentSize = maximumSize - 1 then
				let
					val newContent = addToString (
						content
						, newCharacter
					)
				in (
					SOME newContent
					, {
						maximumSize = maximumSize
						, content = newContent
					}
				) end
			else (
				NONE
				, {
					maximumSize = maximumSize
					, content = addToString (
						content
						, newCharacter
					)
				}
			)
		end
end