├── .gitignore
├── .travis.yml
├── LICENSE
├── README.md
├── docs
├── nimdoc.out.css
└── stacks.html
├── src
└── stacks.nim
├── stacks.nimble
└── tests
├── config.nims
└── test_stacks.nim
/.gitignore:
--------------------------------------------------------------------------------
1 | nimcache/
2 | .DS_Store
3 |
--------------------------------------------------------------------------------
/.travis.yml:
--------------------------------------------------------------------------------
1 | sudo: required
2 | services:
3 | - docker
4 | before_install:
5 | - docker pull nimlang/nim
6 | script:
7 | - docker run nimlang/nim nim --version
8 | - docker run -v "$(pwd):/project" -w /project nimlang/nim sh -c "nimble install -dy && nimble test"
9 |
--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
1 | MIT License
2 |
3 | Copyright (c) 2019 Max Skybin
4 |
5 | Permission is hereby granted, free of charge, to any person obtaining a copy
6 | of this software and associated documentation files (the "Software"), to deal
7 | in the Software without restriction, including without limitation the rights
8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9 | copies of the Software, and to permit persons to whom the Software is
10 | furnished to do so, subject to the following conditions:
11 |
12 | The above copyright notice and this permission notice shall be included in all
13 | copies or substantial portions of the Software.
14 |
15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21 | SOFTWARE.
22 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # nim-stacks
2 | Pure Nim stack implementation based on sequences
3 |
4 | * [Full documentation](https://rustomax.github.io/dev/nim/stacks/stacks.html)
5 |
6 | Version 0.4.2
7 |
8 | ### Installation
9 | ```sh
10 | nimble install stacks
11 | ```
12 |
13 | ### Example
14 |
15 | ```nim
16 | import stacks
17 |
18 | proc isPaired*(s: string): bool =
19 | ## Algorithm to detect unbalanced brackets using a stack
20 | var stack = Stack[char]()
21 |
22 | for c in s:
23 | case c:
24 | of '{': stack.push('}')
25 | of '[': stack.push(']')
26 | of '(': stack.push(')')
27 | of '}', ']', ')':
28 | if stack.isEmpty or stack.pop() != c: return false
29 | else: discard
30 |
31 | stack.isEmpty()
32 |
33 | when isMainModule:
34 | assert isPaired("(((185 + 223.85) * 15) - 543)/2") == true
35 | assert isPaired("for (i = 1; i < 11; ++i)\n{printf(\"i\");}\nreturn 0;}\n}") == false
36 | ```
37 |
38 |
--------------------------------------------------------------------------------
/docs/nimdoc.out.css:
--------------------------------------------------------------------------------
1 | /*
2 | Stylesheet for use with Docutils/rst2html.
3 |
4 | See http://docutils.sf.net/docs/howto/html-stylesheets.html for how to
5 | customize this style sheet.
6 |
7 | Modified from Chad Skeeters' rst2html-style
8 | https://bitbucket.org/cskeeters/rst2html-style/
9 |
10 | Modified by Boyd Greenfield and narimiran
11 | */
12 |
13 | :root {
14 | --primary-background: #fff;
15 | --secondary-background: ghostwhite;
16 | --third-background: #e8e8e8;
17 | --border: #dde;
18 | --text: #222;
19 | --anchor: #07b;
20 | --anchor-focus: #607c9f;
21 | --input-focus: #1fa0eb;
22 | --strong: #3c3c3c;
23 | --hint: #9A9A9A;
24 | --nim-sprite-base64: url("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAN4AAAA9CAYAAADCt9ebAAAACXBIWXMAAAsTAAALEwEAmpwYAAAFFmlUWHRYTUw6Y29tLmFkb2JlLnhtcAAAAAAAPD94cGFja2V0IGJlZ2luPSLvu78iIGlkPSJXNU0wTXBDZWhpSHpyZVN6TlRjemtjOWQiPz4gPHg6eG1wbWV0YSB4bWxuczp4PSJhZG9iZTpuczptZXRhLyIgeDp4bXB0az0iQWRvYmUgWE1QIENvcmUgNS42LWMxNDggNzkuMTY0MDM2LCAyMDE5LzA4LzEzLTAxOjA2OjU3ICAgICAgICAiPiA8cmRmOlJERiB4bWxuczpyZGY9Imh0dHA6Ly93d3cudzMub3JnLzE5OTkvMDIvMjItcmRmLXN5bnRheC1ucyMiPiA8cmRmOkRlc2NyaXB0aW9uIHJkZjphYm91dD0iIiB4bWxuczp4bXA9Imh0dHA6Ly9ucy5hZG9iZS5jb20veGFwLzEuMC8iIHhtbG5zOmRjPSJodHRwOi8vcHVybC5vcmcvZGMvZWxlbWVudHMvMS4xLyIgeG1sbnM6cGhvdG9zaG9wPSJodHRwOi8vbnMuYWRvYmUuY29tL3Bob3Rvc2hvcC8xLjAvIiB4bWxuczp4bXBNTT0iaHR0cDovL25zLmFkb2JlLmNvbS94YXAvMS4wL21tLyIgeG1sbnM6c3RFdnQ9Imh0dHA6Ly9ucy5hZG9iZS5jb20veGFwLzEuMC9zVHlwZS9SZXNvdXJjZUV2ZW50IyIgeG1wOkNyZWF0b3JUb29sPSJBZG9iZSBQaG90b3Nob3AgMjEuMCAoV2luZG93cykiIHhtcDpDcmVhdGVEYXRlPSIyMDE5LTEyLTAzVDAxOjAzOjQ4KzAxOjAwIiB4bXA6TW9kaWZ5RGF0ZT0iMjAxOS0xMi0wM1QwMjoyODo0MSswMTowMCIgeG1wOk1ldGFkYXRhRGF0ZT0iMjAxOS0xMi0wM1QwMjoyODo0MSswMTowMCIgZGM6Zm9ybWF0PSJpbWFnZS9wbmciIHBob3Rvc2hvcDpDb2xvck1vZGU9IjMiIHBob3Rvc2hvcDpJQ0NQcm9maWxlPSJzUkdCIElFQzYxOTY2LTIuMSIgeG1wTU06SW5zdGFuY2VJRD0ieG1wLmlpZDozMzM0ZjAxYS0yMDExLWE1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");
25 |
26 | --keyword: #5e8f60;
27 | --identifier: #222;
28 | --comment: #484a86;
29 | --operator: #155da4;
30 | --punctuation: black;
31 | --other: black;
32 | --escapeSequence: #c4891b;
33 | --number: #252dbe;
34 | --literal: #a4255b;
35 | --raw-data: #a4255b;
36 | }
37 |
38 | [data-theme="dark"] {
39 | --primary-background: #171921;
40 | --secondary-background: #1e202a;
41 | --third-background: #2b2e3b;
42 | --border: #0e1014;
43 | --text: #fff;
44 | --anchor: #8be9fd;
45 | --anchor-focus: #8be9fd;
46 | --input-focus: #8be9fd;
47 | --strong: #bd93f9;
48 | --hint: #7A7C85;
49 | --nim-sprite-base64: url("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAARMAAABMCAYAAABOBlMuAAAACXBIWXMAAAsTAAALEwEAmpwYAAAFFmlUWHRYTUw6Y29tLmFkb2JlLnhtcAAAAAAAPD94cGFja2V0IGJlZ2luPSLvu78iIGlkPSJXNU0wTXBDZWhpSHpyZVN6TlRjemtjOWQiPz4gPHg6eG1wbWV0YSB4bWxuczp4PSJhZG9iZTpuczptZXRhLyIgeDp4bXB0az0iQWRvYmUgWE1QIENvcmUgNS42LWMxNDggNzkuMTY0MDM2LCAyMDE5LzA4LzEzLTAxOjA2OjU3ICAgICAgICAiPiA8cmRmOlJERiB4bWxuczpyZGY9Imh0dHA6Ly93d3cudzMub3JnLzE5OTkvMDIvMjItcmRmLXN5bnRheC1ucyMiPiA8cmRmOkRlc2NyaXB0aW9uIHJkZjphYm91dD0iIiB4bWxuczp4bXA9Imh0dHA6Ly9ucy5hZG9iZS5jb20veGFwLzEuMC8iIHhtbG5zOmRjPSJodHRwOi8vcHVybC5vcmcvZGMvZWxlbWVudHMvMS4xLyIgeG1sbnM6cGhvdG9zaG9wPSJodHRwOi8vbnMuYWRvYmUuY29tL3Bob3Rvc2hvcC8xLjAvIiB4bWxuczp4bXBNTT0iaHR0cDovL25zLmFkb2JlLmNvbS94YXAvMS4wL21tLyIgeG1sbnM6c3RFdnQ9Imh0dHA6Ly9ucy5hZG9iZS5jb20veGFwLzEuMC9zVHlwZS9SZXNvdXJjZUV2ZW50IyIgeG1wOkNyZWF0b3JUb29sPSJBZG9iZSBQaG90b3Nob3AgMjEuMCAoV2luZG93cykiIHhtcDpDcmVhdGVEYXRlPSIyMDE5LTEyLTAzVDAxOjE4OjIyKzAxOjAwIiB4bXA6TW9kaWZ5RGF0ZT0iMjAxOS0xMi0wM1QwMToyMDoxMCswMTowMCIgeG1wOk1ldGFkYXRhRGF0ZT0iMjAxOS0xMi0wM1QwMToyMDoxMCswMTowMCIgZGM6Zm9ybWF0PSJpbWFnZS9wbmciIHBob3Rvc2hvcDpDb2xvck1vZGU9IjMiIHBob3Rvc2hvcDpJQ0NQcm9maWxlPSJzUkdCIElFQzYxOTY2LTIuMSIgeG1wTU06SW5zdGFuY2VJRD0ieG1wLmlpZDplZGViMzU3MC1iNmZjLWQy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");
50 |
51 | --keyword: #ff79c6;
52 | --identifier: #f8f8f2;
53 | --comment: #6272a4;
54 | --operator: #ff79c6;
55 | --punctuation: #f8f8f2;
56 | --other: #f8f8f2;
57 | --escapeSequence: #bd93f9;
58 | --number: #bd93f9;
59 | --literal: #f1fa8c;
60 | --raw-data: #8be9fd;
61 | }
62 |
63 | .theme-switch-wrapper {
64 | display: flex;
65 | align-items: center;
66 | }
67 |
68 | .theme-switch-wrapper em {
69 | margin-left: 10px;
70 | font-size: 1rem;
71 | }
72 |
73 | .theme-switch {
74 | display: inline-block;
75 | height: 22px;
76 | position: relative;
77 | width: 50px;
78 | }
79 |
80 | .theme-switch input {
81 | display: none;
82 | }
83 |
84 | .slider {
85 | background-color: #ccc;
86 | bottom: 0;
87 | cursor: pointer;
88 | left: 0;
89 | position: absolute;
90 | right: 0;
91 | top: 0;
92 | transition: .4s;
93 | }
94 |
95 | .slider:before {
96 | background-color: #fff;
97 | bottom: 4px;
98 | content: "";
99 | height: 13px;
100 | left: 4px;
101 | position: absolute;
102 | transition: .4s;
103 | width: 13px;
104 | }
105 |
106 | input:checked + .slider {
107 | background-color: #66bb6a;
108 | }
109 |
110 | input:checked + .slider:before {
111 | transform: translateX(26px);
112 | }
113 |
114 | .slider.round {
115 | border-radius: 17px;
116 | }
117 |
118 | .slider.round:before {
119 | border-radius: 50%;
120 | }
121 |
122 | html {
123 | font-size: 100%;
124 | -webkit-text-size-adjust: 100%;
125 | -ms-text-size-adjust: 100%; }
126 |
127 | body {
128 | font-family: "Lato", "Helvetica Neue", "HelveticaNeue", Helvetica, Arial, sans-serif;
129 | font-weight: 400;
130 | font-size: 1.125em;
131 | line-height: 1.5;
132 | color: var(--text);
133 | background-color: var(--primary-background); }
134 |
135 | /* Skeleton grid */
136 | .container {
137 | position: relative;
138 | width: 100%;
139 | max-width: 1050px;
140 | margin: 0 auto;
141 | padding: 0;
142 | box-sizing: border-box; }
143 |
144 | .column,
145 | .columns {
146 | width: 100%;
147 | float: left;
148 | box-sizing: border-box;
149 | margin-left: 1%;
150 | }
151 |
152 | .column:first-child,
153 | .columns:first-child {
154 | margin-left: 0; }
155 |
156 | .three.columns {
157 | width: 22%;
158 | line-break: anywhere;
159 | }
160 |
161 | .nine.columns {
162 | width: 77.0%; }
163 |
164 | .twelve.columns {
165 | width: 100%;
166 | margin-left: 0; }
167 |
168 | @media screen and (max-width: 860px) {
169 | .three.columns {
170 | display: none;
171 | }
172 | .nine.columns {
173 | width: 98.0%;
174 | }
175 | body {
176 | font-size: 1em;
177 | line-height: 1.35;
178 | }
179 | }
180 |
181 | cite {
182 | font-style: italic !important; }
183 |
184 |
185 | /* Nim search input */
186 | div#searchInputDiv {
187 | margin-bottom: 1em;
188 | }
189 | input#searchInput {
190 | width: 80%;
191 | }
192 |
193 | /*
194 | * Some custom formatting for input forms.
195 | * This also fixes input form colors on Firefox with a dark system theme on Linux.
196 | */
197 | input {
198 | -moz-appearance: none;
199 | background-color: var(--secondary-background);
200 | color: var(--text);
201 | border: 1px solid var(--border);
202 | font-family: "Lato", "Helvetica Neue", "HelveticaNeue", Helvetica, Arial, sans-serif;
203 | font-size: 0.9em;
204 | padding: 6px;
205 | }
206 |
207 | input:focus {
208 | border: 1px solid var(--input-focus);
209 | box-shadow: 0 0 3px var(--input-focus);
210 | }
211 |
212 | select {
213 | -moz-appearance: none;
214 | background-color: var(--secondary-background);
215 | color: var(--text);
216 | border: 1px solid var(--border);
217 | font-family: "Lato", "Helvetica Neue", "HelveticaNeue", Helvetica, Arial, sans-serif;
218 | font-size: 0.9em;
219 | padding: 6px;
220 | }
221 |
222 | select:focus {
223 | border: 1px solid var(--input-focus);
224 | box-shadow: 0 0 3px var(--input-focus);
225 | }
226 |
227 | /* Docgen styles */
228 | /* Links */
229 | a {
230 | color: var(--anchor);
231 | text-decoration: none;
232 | }
233 |
234 | a span.Identifier {
235 | text-decoration: underline;
236 | text-decoration-color: #aab;
237 | }
238 |
239 | a.reference-toplevel {
240 | font-weight: bold;
241 | }
242 |
243 | a.toc-backref {
244 | text-decoration: none;
245 | color: var(--text); }
246 |
247 | a.link-seesrc {
248 | color: #607c9f;
249 | font-size: 0.9em;
250 | font-style: italic; }
251 |
252 | a:hover,
253 | a:focus {
254 | color: var(--anchor-focus);
255 | text-decoration: underline; }
256 |
257 | a:hover span.Identifier {
258 | color: var(--anchor);
259 | }
260 |
261 |
262 | sub,
263 | sup {
264 | position: relative;
265 | font-size: 75%;
266 | line-height: 0;
267 | vertical-align: baseline; }
268 |
269 | sup {
270 | top: -0.5em; }
271 |
272 | sub {
273 | bottom: -0.25em; }
274 |
275 | img {
276 | width: auto;
277 | height: auto;
278 | max-width: 100%;
279 | vertical-align: middle;
280 | border: 0;
281 | -ms-interpolation-mode: bicubic; }
282 |
283 | @media print {
284 | * {
285 | color: black !important;
286 | text-shadow: none !important;
287 | background: transparent !important;
288 | box-shadow: none !important; }
289 |
290 | a,
291 | a:visited {
292 | text-decoration: underline; }
293 |
294 | a[href]:after {
295 | content: " (" attr(href) ")"; }
296 |
297 | abbr[title]:after {
298 | content: " (" attr(title) ")"; }
299 |
300 | .ir a:after,
301 | a[href^="javascript:"]:after,
302 | a[href^="#"]:after {
303 | content: ""; }
304 |
305 | pre,
306 | blockquote {
307 | border: 1px solid #999;
308 | page-break-inside: avoid; }
309 |
310 | thead {
311 | display: table-header-group; }
312 |
313 | tr,
314 | img {
315 | page-break-inside: avoid; }
316 |
317 | img {
318 | max-width: 100% !important; }
319 |
320 | @page {
321 | margin: 0.5cm; }
322 |
323 | h1 {
324 | page-break-before: always; }
325 |
326 | h1.title {
327 | page-break-before: avoid; }
328 |
329 | p,
330 | h2,
331 | h3 {
332 | orphans: 3;
333 | widows: 3; }
334 |
335 | h2,
336 | h3 {
337 | page-break-after: avoid; }
338 | }
339 |
340 |
341 | p {
342 | margin-top: 0.5em;
343 | margin-bottom: 0.5em;
344 | }
345 |
346 | small {
347 | font-size: 85%; }
348 |
349 | strong {
350 | font-weight: 600;
351 | font-size: 0.95em;
352 | color: var(--strong);
353 | }
354 |
355 | em {
356 | font-style: italic; }
357 |
358 | h1 {
359 | font-size: 1.8em;
360 | font-weight: 400;
361 | padding-bottom: .25em;
362 | border-bottom: 6px solid var(--third-background);
363 | margin-top: 2.5em;
364 | margin-bottom: 1em;
365 | line-height: 1.2em; }
366 |
367 | h1.title {
368 | padding-bottom: 1em;
369 | border-bottom: 0px;
370 | font-size: 2.5em;
371 | text-align: center;
372 | font-weight: 900;
373 | margin-top: 0.75em;
374 | margin-bottom: 0em;
375 | }
376 |
377 | h2 {
378 | font-size: 1.3em;
379 | margin-top: 2em; }
380 |
381 | h2.subtitle {
382 | text-align: center; }
383 |
384 | h3 {
385 | font-size: 1.125em;
386 | font-style: italic;
387 | margin-top: 1.5em; }
388 |
389 | h4 {
390 | font-size: 1.125em;
391 | margin-top: 1em; }
392 |
393 | h5 {
394 | font-size: 1.125em;
395 | margin-top: 0.75em; }
396 |
397 | h6 {
398 | font-size: 1.1em; }
399 |
400 |
401 | ul,
402 | ol {
403 | padding: 0;
404 | margin-top: 0.5em;
405 | margin-left: 0.75em; }
406 |
407 | ul ul,
408 | ul ol,
409 | ol ol,
410 | ol ul {
411 | margin-bottom: 0;
412 | margin-left: 1.25em; }
413 |
414 | li {
415 | list-style-type: circle;
416 | }
417 |
418 | ul.simple-boot li {
419 | list-style-type: none;
420 | margin-left: 0em;
421 | margin-bottom: 0.5em;
422 | }
423 |
424 | ol.simple > li, ul.simple > li {
425 | margin-bottom: 0.2em;
426 | margin-left: 0.4em }
427 |
428 | ul.simple.simple-toc > li {
429 | margin-top: 1em;
430 | }
431 |
432 | ul.simple-toc {
433 | list-style: none;
434 | font-size: 0.9em;
435 | margin-left: -0.3em;
436 | margin-top: 1em; }
437 |
438 | ul.simple-toc > li {
439 | list-style-type: none;
440 | }
441 |
442 | ul.simple-toc-section {
443 | list-style-type: circle;
444 | margin-left: 0.8em;
445 | color: #6c9aae; }
446 |
447 | ul.nested-toc-section {
448 | list-style-type: circle;
449 | margin-left: -0.75em;
450 | color: var(--text);
451 | }
452 |
453 | ul.nested-toc-section > li {
454 | margin-left: 1.25em;
455 | }
456 |
457 |
458 | ol.arabic {
459 | list-style: decimal; }
460 |
461 | ol.loweralpha {
462 | list-style: lower-alpha; }
463 |
464 | ol.upperalpha {
465 | list-style: upper-alpha; }
466 |
467 | ol.lowerroman {
468 | list-style: lower-roman; }
469 |
470 | ol.upperroman {
471 | list-style: upper-roman; }
472 |
473 | ul.auto-toc {
474 | list-style-type: none; }
475 |
476 |
477 | dl {
478 | margin-bottom: 1.5em; }
479 |
480 | dt {
481 | margin-bottom: -0.5em;
482 | margin-left: 0.0em; }
483 |
484 | dd {
485 | margin-left: 2.0em;
486 | margin-bottom: 3.0em;
487 | margin-top: 0.5em; }
488 |
489 |
490 | hr {
491 | margin: 2em 0;
492 | border: 0;
493 | border-top: 1px solid #aaa; }
494 |
495 | blockquote {
496 | font-size: 0.9em;
497 | font-style: italic;
498 | padding-left: 0.5em;
499 | margin-left: 0;
500 | border-left: 5px solid #bbc;
501 | }
502 |
503 | .pre {
504 | font-family: "Source Code Pro", Monaco, Menlo, Consolas, "Courier New", monospace;
505 | font-weight: 500;
506 | font-size: 0.85em;
507 | color: var(--text);
508 | background-color: var(--third-background);
509 | padding-left: 3px;
510 | padding-right: 3px;
511 | border-radius: 4px;
512 | }
513 |
514 | pre {
515 | font-family: "Source Code Pro", Monaco, Menlo, Consolas, "Courier New", monospace;
516 | color: var(--text);
517 | font-weight: 500;
518 | display: inline-block;
519 | box-sizing: border-box;
520 | min-width: 100%;
521 | padding: 0.5em;
522 | margin-top: 0.5em;
523 | margin-bottom: 0.5em;
524 | font-size: 0.85em;
525 | white-space: pre !important;
526 | overflow-y: hidden;
527 | overflow-x: visible;
528 | background-color: var(--secondary-background);
529 | border: 1px solid var(--border);
530 | -webkit-border-radius: 6px;
531 | -moz-border-radius: 6px;
532 | border-radius: 6px; }
533 |
534 | .pre-scrollable {
535 | max-height: 340px;
536 | overflow-y: scroll; }
537 |
538 |
539 | /* Nim line-numbered tables */
540 | .line-nums-table {
541 | width: 100%;
542 | table-layout: fixed; }
543 |
544 | table.line-nums-table {
545 | border-radius: 4px;
546 | border: 1px solid #cccccc;
547 | background-color: ghostwhite;
548 | border-collapse: separate;
549 | margin-top: 15px;
550 | margin-bottom: 25px; }
551 |
552 | .line-nums-table tbody {
553 | border: none; }
554 |
555 | .line-nums-table td pre {
556 | border: none;
557 | background-color: transparent; }
558 |
559 | .line-nums-table td.blob-line-nums {
560 | width: 28px; }
561 |
562 | .line-nums-table td.blob-line-nums pre {
563 | color: #b0b0b0;
564 | -webkit-filter: opacity(75%);
565 | text-align: right;
566 | border-color: transparent;
567 | background-color: transparent;
568 | padding-left: 0px;
569 | margin-left: 0px;
570 | padding-right: 0px;
571 | margin-right: 0px; }
572 |
573 |
574 | table {
575 | max-width: 100%;
576 | background-color: transparent;
577 | margin-top: 0.5em;
578 | margin-bottom: 1.5em;
579 | border-collapse: collapse;
580 | border-color: var(--third-background);
581 | border-spacing: 0;
582 | font-size: 0.9em;
583 | }
584 |
585 | table th, table td {
586 | padding: 0px 0.5em 0px;
587 | border-color: var(--third-background);
588 | }
589 |
590 | table th {
591 | background-color: var(--third-background);
592 | border-color: var(--third-background);
593 | font-weight: bold; }
594 |
595 | table th.docinfo-name {
596 | background-color: transparent;
597 | text-align: right;
598 | }
599 |
600 | table tr:hover {
601 | background-color: var(--third-background); }
602 |
603 |
604 | /* rst2html default used to remove borders from tables and images */
605 | .borderless, table.borderless td, table.borderless th {
606 | border: 0; }
607 |
608 | table.borderless td, table.borderless th {
609 | /* Override padding for "table.docutils td" with "! important".
610 | The right padding separates the table cells. */
611 | padding: 0 0.5em 0 0 !important; }
612 |
613 | .first {
614 | /* Override more specific margin styles with "! important". */
615 | margin-top: 0 !important; }
616 |
617 | .last, .with-subtitle {
618 | margin-bottom: 0 !important; }
619 |
620 | .hidden {
621 | display: none; }
622 |
623 | blockquote.epigraph {
624 | margin: 2em 5em; }
625 |
626 | dl.docutils dd {
627 | margin-bottom: 0.5em; }
628 |
629 | object[type="image/svg+xml"], object[type="application/x-shockwave-flash"] {
630 | overflow: hidden; }
631 |
632 |
633 | div.figure {
634 | margin-left: 2em;
635 | margin-right: 2em; }
636 |
637 | div.footer, div.header {
638 | clear: both;
639 | text-align: center;
640 | color: #666;
641 | font-size: smaller; }
642 |
643 | div.footer {
644 | padding-top: 5em;
645 | }
646 |
647 | div.line-block {
648 | display: block;
649 | margin-top: 1em;
650 | margin-bottom: 1em; }
651 |
652 | div.line-block div.line-block {
653 | margin-top: 0;
654 | margin-bottom: 0;
655 | margin-left: 1.5em; }
656 |
657 | div.topic {
658 | margin: 2em; }
659 |
660 | div.search_results {
661 | background-color: var(--third-background);
662 | margin: 3em;
663 | padding: 1em;
664 | border: 1px solid #4d4d4d;
665 | }
666 |
667 | div#global-links ul {
668 | margin-left: 0;
669 | list-style-type: none;
670 | }
671 |
672 | div#global-links > simple-boot {
673 | margin-left: 3em;
674 | }
675 |
676 | hr.docutils {
677 | width: 75%; }
678 |
679 | img.align-left, .figure.align-left, object.align-left {
680 | clear: left;
681 | float: left;
682 | margin-right: 1em; }
683 |
684 | img.align-right, .figure.align-right, object.align-right {
685 | clear: right;
686 | float: right;
687 | margin-left: 1em; }
688 |
689 | img.align-center, .figure.align-center, object.align-center {
690 | display: block;
691 | margin-left: auto;
692 | margin-right: auto; }
693 |
694 | .align-left {
695 | text-align: left; }
696 |
697 | .align-center {
698 | clear: both;
699 | text-align: center; }
700 |
701 | .align-right {
702 | text-align: right; }
703 |
704 | /* reset inner alignment in figures */
705 | div.align-right {
706 | text-align: inherit; }
707 |
708 | p.attribution {
709 | text-align: right;
710 | margin-left: 50%; }
711 |
712 | p.caption {
713 | font-style: italic; }
714 |
715 | p.credits {
716 | font-style: italic;
717 | font-size: smaller; }
718 |
719 | p.label {
720 | white-space: nowrap; }
721 |
722 | p.rubric {
723 | font-weight: bold;
724 | font-size: larger;
725 | color: maroon;
726 | text-align: center; }
727 |
728 | p.topic-title {
729 | font-weight: bold; }
730 |
731 | pre.address {
732 | margin-bottom: 0;
733 | margin-top: 0;
734 | font: inherit; }
735 |
736 | pre.literal-block, pre.doctest-block, pre.math, pre.code {
737 | margin-left: 2em;
738 | margin-right: 2em; }
739 |
740 | pre.code .ln {
741 | color: grey; }
742 |
743 | /* line numbers */
744 | pre.code, code {
745 | background-color: #eeeeee; }
746 |
747 | pre.code .comment, code .comment {
748 | color: #5c6576; }
749 |
750 | pre.code .keyword, code .keyword {
751 | color: #3B0D06;
752 | font-weight: bold; }
753 |
754 | pre.code .literal.string, code .literal.string {
755 | color: #0c5404; }
756 |
757 | pre.code .name.builtin, code .name.builtin {
758 | color: #352b84; }
759 |
760 | pre.code .deleted, code .deleted {
761 | background-color: #DEB0A1; }
762 |
763 | pre.code .inserted, code .inserted {
764 | background-color: #A3D289; }
765 |
766 | span.classifier {
767 | font-style: oblique; }
768 |
769 | span.classifier-delimiter {
770 | font-weight: bold; }
771 |
772 | span.option {
773 | white-space: nowrap; }
774 |
775 | span.problematic {
776 | color: #b30000; }
777 |
778 | span.section-subtitle {
779 | /* font-size relative to parent (h1..h6 element) */
780 | font-size: 80%; }
781 |
782 | span.DecNumber {
783 | color: var(--number); }
784 |
785 | span.BinNumber {
786 | color: var(--number); }
787 |
788 | span.HexNumber {
789 | color: var(--number); }
790 |
791 | span.OctNumber {
792 | color: var(--number); }
793 |
794 | span.FloatNumber {
795 | color: var(--number); }
796 |
797 | span.Identifier {
798 | color: var(--identifier); }
799 |
800 | span.Keyword {
801 | font-weight: 600;
802 | color: var(--keyword); }
803 |
804 | span.StringLit {
805 | color: var(--literal); }
806 |
807 | span.LongStringLit {
808 | color: var(--literal); }
809 |
810 | span.CharLit {
811 | color: var(--literal); }
812 |
813 | span.EscapeSequence {
814 | color: var(--escapeSequence); }
815 |
816 | span.Operator {
817 | color: var(--operator); }
818 |
819 | span.Punctuation {
820 | color: var(--punctuation); }
821 |
822 | span.Comment, span.LongComment {
823 | font-style: italic;
824 | font-weight: 400;
825 | color: var(--comment); }
826 |
827 | span.RegularExpression {
828 | color: darkviolet; }
829 |
830 | span.TagStart {
831 | color: darkviolet; }
832 |
833 | span.TagEnd {
834 | color: darkviolet; }
835 |
836 | span.Key {
837 | color: #252dbe; }
838 |
839 | span.Value {
840 | color: #252dbe; }
841 |
842 | span.RawData {
843 | color: var(--raw-data); }
844 |
845 | span.Assembler {
846 | color: #252dbe; }
847 |
848 | span.Preprocessor {
849 | color: #252dbe; }
850 |
851 | span.Directive {
852 | color: #252dbe; }
853 |
854 | span.Command, span.Rule, span.Hyperlink, span.Label, span.Reference,
855 | span.Other {
856 | color: var(--other); }
857 |
858 | /* Pop type, const, proc, and iterator defs in nim def blocks */
859 | dt pre > span.Identifier, dt pre > span.Operator {
860 | color: var(--identifier);
861 | font-weight: 700; }
862 |
863 | dt pre > span.Keyword ~ span.Identifier, dt pre > span.Identifier ~ span.Identifier,
864 | dt pre > span.Operator ~ span.Identifier, dt pre > span.Other ~ span.Identifier {
865 | color: var(--identifier);
866 | font-weight: inherit; }
867 |
868 | /* Nim sprite for the footer (taken from main page favicon) */
869 | .nim-sprite {
870 | display: inline-block;
871 | width: 51px;
872 | height: 14px;
873 | background-position: 0 0;
874 | background-size: 51px 14px;
875 | -webkit-filter: opacity(50%);
876 | background-repeat: no-repeat;
877 | background-image: var(--nim-sprite-base64);
878 | margin-bottom: 5px; }
879 |
880 | span.pragmadots {
881 | /* Position: relative frees us up to make the dots
882 | look really nice without fucking up the layout and
883 | causing bulging in the parent container */
884 | position: relative;
885 | /* 1px down looks slightly nicer */
886 | top: 1px;
887 | padding: 2px;
888 | background-color: var(--third-background);
889 | border-radius: 4px;
890 | margin: 0 2px;
891 | cursor: pointer;
892 | font-size: 0.8em;
893 | }
894 |
895 | span.pragmadots:hover {
896 | background-color: var(--hint);
897 | }
898 | span.pragmawrap {
899 | display: none;
900 | }
901 |
902 | span.attachedType {
903 | display: none;
904 | visibility: hidden;
905 | }
906 |
--------------------------------------------------------------------------------
/docs/stacks.html:
--------------------------------------------------------------------------------
1 |
2 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 | stacks
21 |
22 |
23 |
24 |
25 |
60 |
61 |
62 |
63 |
64 |
65 |
stacks
66 |
67 |
68 |
69 |
73 |
Dark Mode
74 |
75 |
76 |
77 | -
78 | Index
79 |
80 |
81 |
82 |
83 | Search:
85 |
86 |
87 | Group by:
88 |
92 |
93 |
94 | -
95 | Types
96 |
104 |
105 | -
106 | Procs
107 |
108 |
113 |
118 |
123 |
128 |
133 |
138 |
143 |
148 |
153 |
158 |
163 |
168 |
169 |
170 |
171 |
172 |
173 |
174 |
175 |
176 |
177 |
178 |
Pure Nim stack implementation based on sequences.
179 |
Example:
180 |
181 |
182 | import stacks
183 |
184 | let a = "Hello, World!"
185 | var s = Stack[char]()
186 | for letter in a:
187 | s.push(letter)
188 |
189 | var b: string
190 | while not s.isEmpty:
191 | b.add(s.pop)
192 |
193 | assert b == "!dlroW ,olleH"
194 |
195 |
196 |
197 |
198 | EStackEmpty = object of CatchableError
199 | -
200 |
201 |
202 |
203 |
204 |
205 | Stack[T] = object
206 | data: seq[T]
207 |
208 | -
209 |
210 |
211 |
212 |
213 |
214 |
215 |
216 |
217 |
218 |
219 | proc newStack[T](capacity = 8): Stack[T]
220 | -
221 |
222 | Creates a new stack. Optionally, the initial capacity can be reserved via capacity parameter.
var a = newStack[int](capacity = 64)
223 |
224 |
225 |
226 | proc len[T](s: Stack[T]): int
227 | -
228 |
229 | Returns the number of elements in the stack. Returns 0 if the stack is empty.
var a = newStack[int]()
230 | assert a.len == 0
231 | a.push(10); a.push(20)
232 | assert a.len == 2
233 |
234 |
235 |
236 | proc empty[T](s: Stack[T]): bool {...}{.deprecated: "use isEmpty() instead".}
237 | -
238 |
239 | Deprecated: use isEmpty() instead
240 |
241 |
242 |
243 |
244 |
245 |
246 | proc isEmpty[T](s: Stack[T]): bool
247 | -
248 |
249 | Returns true if stack contains no elements, false otherwise.
var a = newStack[int]()
250 | assert a.isEmpty == true
251 | a.push(10)
252 | assert a.isEmpty == false
253 |
254 |
255 |
256 | proc push[T](s: var Stack[T]; element: T)
257 | -
258 |
259 | Pushes element onto the top of the stack.
var a = newStack[int]()
260 | a.push(10)
261 |
262 |
263 |
264 | proc pop[T](s: var Stack[T]): T {...}{.raises: [EStackEmpty].}
265 | -
266 |
267 | Pops the top element from the stack. Raises EStackEmpty exception if the stack is empty.
var a = newStack[int]()
268 | a.push(10)
269 | discard a.pop()
270 | doAssertRaises(EStackEmpty, echo a.pop())
271 |
272 |
273 |
274 | proc popUnsafe[T](s: var Stack[T]): T
275 | -
276 |
277 | Pops the top element from the stack without checking if it's not empty. Make sure the stack is not empty.
var a = newStack[int]()
278 | a.push(10)
279 | check(a.popUnsafe() == 10)
280 |
281 |
282 |
283 | proc peek[T](s: Stack[T]): T {...}{.raises: [EStackEmpty].}
284 | -
285 |
286 | Peeks the top element from the stack. Raises EStackEmpty exception if the stack is empty.
var a = newStack[int]()
287 | a.push(10)
288 | check(a.peek() == 10)
289 |
290 |
291 |
292 | proc peekUnsafe[T](s: Stack[T]): T
293 | -
294 |
295 | Peeks the top element from the stack without checking if it's not empty. Make sure the stack is not empty.
var a = newStack[int]()
296 | a.push(10)
297 | check(a.peekUnsafe() == 10)
298 |
299 |
300 |
301 | proc clear[T](s: var Stack[T])
302 | -
303 |
304 | Empties the stack. Does nothing if the stack is already empty.
var a = newStack[int]()
305 | a.push(10)
306 | a.clear()
307 | assert a.isEmpty == true
308 |
309 |
310 |
311 | proc toSeq[T](s: Stack[T]): seq[T]
312 | -
313 |
314 | Returns sequence representation of a stack.
var a = newStack[int]()
315 | a.push(10); a.push(20)
316 | assert a.toSeq() == @[10, 20]
317 |
318 |
319 |
320 | proc `$`[T](s: Stack[T]): string
321 | -
322 |
323 | Returns string representation of a stack
var a = newStack[int]()
324 | a.push(10); a.push(20)
325 | assert $a == "Stack[10, 20]"
326 |
327 |
328 |
329 |
330 |
331 |
332 |
333 |
334 |
335 |
336 |
337 |
338 | Made with Nim. Generated: 2020-10-09 18:03:35 UTC
339 |
340 |
341 |
342 |
343 |
344 |
345 |
346 |
--------------------------------------------------------------------------------
/src/stacks.nim:
--------------------------------------------------------------------------------
1 | ## Pure Nim stack implementation based on sequences.
2 | ##
3 | ## **Example:**
4 | ##
5 | ## .. code-block:: Nim
6 | ## # Reverting a string using a stack
7 | ##
8 | ## import stacks
9 | ##
10 | ## let a = "Hello, World!"
11 | ## var s = Stack[char]()
12 | ## for letter in a:
13 | ## s.push(letter)
14 | ##
15 | ## var b: string
16 | ## while not s.isEmpty:
17 | ## b.add(s.pop)
18 | ##
19 | ## assert b == "!dlroW ,olleH"
20 | ##
21 |
22 | import math
23 |
24 | type EStackEmpty* = object of CatchableError
25 |
26 | type
27 | Stack* [T] = object
28 | data: seq[T]
29 |
30 | proc newStack* [T](capacity = 8): Stack[T] =
31 | ## Creates a new stack.
32 | ## Optionally, the initial capacity can be reserved via `capacity` parameter.
33 | ##
34 | ## .. code-block:: Nim
35 | ## var a = newStack[int](capacity = 64)
36 | assert isPowerOfTwo(capacity)
37 | result.data = newSeqOfCap[T](capacity)
38 |
39 | proc len* [T](s: Stack[T]): int =
40 | ## Returns the number of elements in the stack.
41 | ## Returns `0` if the stack is empty.
42 | ##
43 | ## .. code-block:: Nim
44 | ## var a = newStack[int]()
45 | ## assert a.len == 0
46 | ## a.push(10); a.push(20)
47 | ## assert a.len == 2
48 | s.data.len()
49 |
50 | proc empty* [T](s: Stack[T]): bool {.deprecated: "use isEmpty() instead".} =
51 | s.data.len() == 0
52 |
53 | proc isEmpty* [T](s: Stack[T]): bool =
54 | ## Returns `true` if stack contains no elements, `false` otherwise.
55 | ##
56 | ## .. code-block:: Nim
57 | ## var a = newStack[int]()
58 | ## assert a.isEmpty == true
59 | ## a.push(10)
60 | ## assert a.isEmpty == false
61 | s.data.len() == 0
62 |
63 | proc push* [T](s: var Stack[T], element: T) =
64 | ## Pushes `element` onto the top of the stack.
65 | ##
66 | ## .. code-block:: Nim
67 | ## var a = newStack[int]()
68 | ## a.push(10)
69 | s.data.add(element)
70 |
71 | proc pop* [T](s: var Stack[T]): T {.raises: [EStackEmpty].} =
72 | ## Pops the top element from the stack.
73 | ## Raises `EStackEmpty` exception if the stack is empty.
74 | ##
75 | ## .. code-block:: Nim
76 | ## var a = newStack[int]()
77 | ## a.push(10)
78 | ## discard a.pop()
79 | ## doAssertRaises(EStackEmpty, echo a.pop())
80 | if not s.isEmpty:
81 | result = s.data[^1]
82 | s.data.setLen s.data.len - 1
83 | else:
84 | raise newException(EStackEmpty, "Cannot pop an empty stack")
85 |
86 | proc popUnsafe* [T](s: var Stack[T]): T =
87 | ## Pops the top element from the stack without checking if it's not empty.
88 | ## Make sure the stack is not empty.
89 | ##
90 | ## .. code-block:: Nim
91 | ## var a = newStack[int]()
92 | ## a.push(10)
93 | ## check(a.popUnsafe() == 10)
94 | result = s.data[^1]
95 | s.data.setLen s.data.len - 1
96 |
97 | proc peek* [T](s: Stack[T]): T {.raises: [EStackEmpty].} =
98 | ## Peeks the top element from the stack.
99 | ## Raises `EStackEmpty` exception if the stack is empty.
100 | ##
101 | ## .. code-block:: Nim
102 | ## var a = newStack[int]()
103 | ## a.push(10)
104 | ## check(a.peek() == 10)
105 | if not s.isEmpty:
106 | result = s.data[^1]
107 | else:
108 | raise newException(EStackEmpty, "Cannot peek an empty stack")
109 |
110 | proc peekUnsafe* [T](s: Stack[T]): T =
111 | ## Peeks the top element from the stack without checking if it's not empty.
112 | ## Make sure the stack is not empty.
113 | ##
114 | ## .. code-block:: Nim
115 | ## var a = newStack[int]()
116 | ## a.push(10)
117 | ## check(a.peekUnsafe() == 10)
118 | s.data[^1]
119 |
120 | proc clear* [T](s: var Stack[T]) =
121 | ## Empties the stack. Does nothing if the stack is already empty.
122 | ##
123 | ## .. code-block:: Nim
124 | ## var a = newStack[int]()
125 | ## a.push(10)
126 | ## a.clear()
127 | ## assert a.isEmpty == true
128 | if not s.isEmpty:
129 | s.data.setLen 0
130 |
131 | proc toSeq* [T](s: Stack[T]): seq[T] =
132 | ## Returns sequence representation of a stack.
133 | ##
134 | ## .. code-block:: Nim
135 | ## var a = newStack[int]()
136 | ## a.push(10); a.push(20)
137 | ## assert a.toSeq() == @[10, 20]
138 | s.data
139 |
140 | proc `$`* [T](s: Stack[T]): string =
141 | ## Returns string representation of a stack
142 | ##
143 | ## .. code-block:: Nim
144 | ## var a = newStack[int]()
145 | ## a.push(10); a.push(20)
146 | ## assert $a == "Stack[10, 20]"
147 | result = "Stack["
148 | if not s.isEmpty():
149 | for i in 0 .. s.data.high() - 1:
150 | result &= $s.data[i]
151 | result &= ", "
152 | result &= $s.data[^1]
153 | result &= "]"
154 |
--------------------------------------------------------------------------------
/stacks.nimble:
--------------------------------------------------------------------------------
1 | # Package
2 |
3 | version = "0.4.2"
4 | author = "Max Skybin"
5 | description = "Pure Nim stack implementation based on sequences."
6 | license = "MIT"
7 | srcDir = "src"
8 |
9 | # Dependencies
10 |
11 | requires "nim >= 1.2.4"
12 |
--------------------------------------------------------------------------------
/tests/config.nims:
--------------------------------------------------------------------------------
1 | switch("path", "$projectDir/../src")
--------------------------------------------------------------------------------
/tests/test_stacks.nim:
--------------------------------------------------------------------------------
1 | # To run these tests, execute `nimble test`.
2 | import unittest
3 | import stacks
4 |
5 | test "can create an empty stack":
6 | var a = newStack[int]()
7 | check a.len() == 0
8 |
9 | test "can create an empty stack with capacity":
10 | var a = newStack[int](capacity = 32)
11 | check a.len() == 0
12 |
13 | test "can push into stack":
14 | var a = newStack[int]()
15 | a.push(10)
16 | check a.len == 1
17 |
18 | test "can pop from non-empty stack":
19 | var a = newStack[int]()
20 | a.push(10)
21 | check a.pop() == 10
22 | a.push(11)
23 | check a.popUnsafe() == 11
24 |
25 | test "can popUnsafe from non-empty stack":
26 | var a = newStack[int]()
27 | a.push(10)
28 | check a.popUnsafe() == 10
29 |
30 | test "can peek from non-empty stack":
31 | var a = newStack[int]()
32 | a.push(10)
33 | check a.peek() == 10
34 |
35 | test "can peekUnsafe from non-empty stack":
36 | var a = newStack[int]()
37 | a.push(10)
38 | check a.peekUnsafe() == 10
39 |
40 | test "pop on empty stack raises exception":
41 | var a = newStack[int]()
42 | expect EStackEmpty:
43 | discard a.pop()
44 |
45 | test "can clear stack":
46 | var a = newStack[int]()
47 | a.push(10)
48 | a.clear()
49 | check a.len() == 0
50 | check a.isEmpty() == true
51 |
52 | test "can correctly check if stack is empty":
53 | var a = newStack[int]()
54 | a.push(10)
55 | check a.isEmpty() == false
56 | a.clear()
57 | check a.isEmpty() == true
58 |
59 | test "can get sequence representation of the stack":
60 | var a = newStack[int]()
61 | a.push(10)
62 | a.push(20)
63 | a.push(30)
64 | check a.toSeq() == @[10, 20, 30]
65 |
66 | test "can get string representation of the stack":
67 | var a = newStack[int]()
68 | a.push(10)
69 | a.push(20)
70 | a.push(30)
71 | check $a == "Stack[10, 20, 30]"
72 |
--------------------------------------------------------------------------------