├── .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,iVBORw0KGgoAAAANSUhEUgAAAN4AAAA9CAYAAADCt9ebAAAACXBIWXMAAAsTAAALEwEAmpwYAAAFFmlUWHRYTUw6Y29tLmFkb2JlLnhtcAAAAAAAPD94cGFja2V0IGJlZ2luPSLvu78iIGlkPSJXNU0wTXBDZWhpSHpyZVN6TlRjemtjOWQiPz4gPHg6eG1wbWV0YSB4bWxuczp4PSJhZG9iZTpuczptZXRhLyIgeDp4bXB0az0iQWRvYmUgWE1QIENvcmUgNS42LWMxNDggNzkuMTY0MDM2LCAyMDE5LzA4LzEzLTAxOjA2OjU3ICAgICAgICAiPiA8cmRmOlJERiB4bWxuczpyZGY9Imh0dHA6Ly93d3cudzMub3JnLzE5OTkvMDIvMjItcmRmLXN5bnRheC1ucyMiPiA8cmRmOkRlc2NyaXB0aW9uIHJkZjphYm91dD0iIiB4bWxuczp4bXA9Imh0dHA6Ly9ucy5hZG9iZS5jb20veGFwLzEuMC8iIHhtbG5zOmRjPSJodHRwOi8vcHVybC5vcmcvZGMvZWxlbWVudHMvMS4xLyIgeG1sbnM6cGhvdG9zaG9wPSJodHRwOi8vbnMuYWRvYmUuY29tL3Bob3Rvc2hvcC8xLjAvIiB4bWxuczp4bXBNTT0iaHR0cDovL25zLmFkb2JlLmNvbS94YXAvMS4wL21tLyIgeG1sbnM6c3RFdnQ9Imh0dHA6Ly9ucy5hZG9iZS5jb20veGFwLzEuMC9zVHlwZS9SZXNvdXJjZUV2ZW50IyIgeG1wOkNyZWF0b3JUb29sPSJBZG9iZSBQaG90b3Nob3AgMjEuMCAoV2luZG93cykiIHhtcDpDcmVhdGVEYXRlPSIyMDE5LTEyLTAzVDAxOjAzOjQ4KzAxOjAwIiB4bXA6TW9kaWZ5RGF0ZT0iMjAxOS0xMi0wM1QwMjoyODo0MSswMTowMCIgeG1wOk1ldGFkYXRhRGF0ZT0iMjAxOS0xMi0wM1QwMjoyODo0MSswMTowMCIgZGM6Zm9ybWF0PSJpbWFnZS9wbmciIHBob3Rvc2hvcDpDb2xvck1vZGU9IjMiIHBob3Rvc2hvcDpJQ0NQcm9maWxlPSJzUkdCIElFQzYxOTY2LTIuMSIgeG1wTU06SW5zdGFuY2VJRD0ieG1wLmlpZDozMzM0ZjAxYS0yMDExLWE1NGQtOTVjNy1iOTgxMDFlMDFhMmEiIHhtcE1NOkRvY3VtZW50SUQ9InhtcC5kaWQ6MzMzNGYwMWEtMjAxMS1hNTRkLTk1YzctYjk4MTAxZTAxYTJhIiB4bXBNTTpPcmlnaW5hbERvY3VtZW50SUQ9InhtcC5kaWQ6MzMzNGYwMWEtMjAxMS1hNTRkLTk1YzctYjk4MTAxZTAxYTJhIj4gPHhtcE1NOkhpc3Rvcnk+IDxyZGY6U2VxPiA8cmRmOmxpIHN0RXZ0OmFjdGlvbj0iY3JlYXRlZCIgc3RFdnQ6aW5zdGFuY2VJRD0ieG1wLmlpZDozMzM0ZjAxYS0yMDExLWE1NGQtOTVjNy1iOTgxMDFlMDFhMmEiIHN0RXZ0OndoZW49IjIwMTktMTItMDNUMDE6MDM6NDgrMDE6MDAiIHN0RXZ0OnNvZnR3YXJlQWdlbnQ9IkFkb2JlIFBob3Rvc2hvcCAyMS4wIChXaW5kb3dzKSIvPiA8L3JkZjpTZXE+IDwveG1wTU06SGlzdG9yeT4gPC9yZGY6RGVzY3JpcHRpb24+IDwvcmRmOlJERj4gPC94OnhtcG1ldGE+IDw/eHBhY2tldCBlbmQ9InIiPz4PsixkAAAJ5klEQVR4nO2dfbBUZR3HP3vvxVD0zo0ACXxBuQMoQjJ1DfMl0NIhNcuSZqQhfGt6UWtK06xJexkrmywVRTQlHCIdtclC0zBJvYIvvEUgZpc3XyC7RVbKlQu1/fHdbc+uu2fPOfs85+y55/nMnBl2z+5zfnc5v/M8z+8119XVRYroAG4HfgvMT1YUR4MMAa4HLkhakCRoSVqAELwLeBY4C7gF+D6QS1QiR1ROAJ4Dzk9akKQwoXhtwL4GxvHjU8AKoNPz3leAu4HBFq+bAyZZHD9rDAK+BywDDklYlkQxoXhfAtYAEw2MVckQYBHwU6or99nA08BBFq49GngUeBIYaWH8rNEJdAOXA60Jy5I4jSreSOBKYDzwBPCJhiUqcSjwe2BWnc9NLnxuvMFrnwqsAqYBBwBfNzh2FpmNfs9jkhakWcg1aFxZiH5UL3cDnwf+Xue7BwFjgFHAOwuv24tyob3cO0LIshP4EbCn8Pq/wKvA9sLxMvCvOmPsA1yDZnHv/nEv2mM+F0IeR4m8z7lM7tMbUbzj0CxX7YfbAXwaWFJ4PRrNIu9FS9KJyEIZN68CG4DnkRJtLBw7gHHAYuDdNb77EDAjBhkHIk7xKoiqeK3IwjilzuceQJvoZjdQ/AMZaeoZiWYgBXSEwyleBW0Rv3cR9ZUO4LSI48fN2wN+bi5wJNBvUZaBSCaVy48oxpVhwDdMC5ISxpJRh6/DLGEUrxXt29YBQ+2IkwquR76ofZIWxJFegireNLSnm48skFmmDfmiVgJHJyuKI620ADOpbWEcDPwYOZKD7OmyxCTkXL+wzueOiEEWR8poQb60V4A7kLm/yFjgKeALuM1xLfYDbkX+zEGe98cAX0Oui6viF8vR7OS6urragW2UZr21wK+Aiwlu7XPoN3sYOAd4H6WH1SnA0qSEcjQnRT/e1bgnsw16kGPez4/lyCBF48oNwL+TFGSAsgCndI4qFBVvJ0owdZhjL3CnxfHzBo8+YBMyol0CHBijrKbHS/LoA7Yio9sPgJNr/QHekLGR6MffL+KP4SjnHmQxtoXNmbQP+CHyV75hYDzTIWNpWkU8iR5mq71vVsZqXgtcFqNQ/wG2IOtfD8oi6AX+Ujj+isKz8sBrnu+1okyGdmD/wnEgcDClTIdRyJRvI1cvCMciq7At4rj5eoCPAusbHCfLigda/VyKgi+AtyreMGAzykGzQQ/wO+BxSlkCuy1dq8hw5OieUjimYT+x9bHCdWwS1823Ez1EXmhgjKwrXpHzkduuanbCtzGX+NkPPAj8GincNkPjNkIO5dadUjiOB95m+BonopQpm8R58/0JJbHWy2eshVM8sRvdbyurKV4Hmoka2WA/iwwLP6d+QmzSdKC92GzK/W9R+Q3woQbHCELcN991wJcjftcpXolngKm18vFmoVonYcgDv0Qz5pqGREuOTuA8lPYUZbndh0LJNpkUqgZx33xvomim7RG+6xSvnOm1gqQXoyiMoKxFs8VZpFfpQHvQK4HDUPnAsBa9bxGP0tUjF+IYCkxFew+/G3owdq20pgjzt3uPRscs/o43IaOhH2f4ZaAPRyZQP6vgbuCbyGext87F0sgIZFI/N8BnlwBnolovcWAjq/uzwM0+55cBJ0UYN84ZL+rfbnLMM4FfUDv7Z1XlCe8FetETbleNL7+CZrnvMjCVDuTOOA84Hf+96ga0PC8qXY50FQsuMg+41+d8p885R4n7gdt8zo+qvDkmUF4fZQXwEbS+99KDMhlWkw0eALqQglXyDDCdcovf+4lv5jPNXJ9zWc/FDMMdPudGVCreRlTWwVtWbynwYVQQCFSp61Q042WJLUjB1nneuw8tvXo97x1Lugvg+j1Mo9boySLVHtJFWqsthx5GlbSGeN5bigrHdqPl52Zj4qWLXvTQWY4KOX2ccgPMBLRcuy9+0YzhguXN4GuYq2Zc2R/NZg+hfYt3/9ZCepdQthmB4vIWIYOTbWyWzGt2Y0izG1fqjlltxnsdpbPMRMmd3lqTTumqMw7FZY5G5mSHw5dalreiRWYGWjbZ7gYUlFa0xOtIWA4vk1E6zWEoI+FvyYrjSAO1FG8DCmQGKd+DJFsGogWVVFiP/GWbga9Svg9NgtPQvnd04fUNCcriSBF+vqZ5nn9PQ+Xs4q401oI6EP0R+BkyXoAeAtcgBfwidnvkVaMVFTO6n1JoWTfqiONw1MVP8e6l3GVwOPJZXW5VItGGiuduAu5CZdOrMQJ1CHqpIFccS+LxaD/3Hcr7vF0Xw7UdAwQ/xduLGkJ6aUMhVAuwU006B3wM+ZLmozJ5QRhWkGs9yjKw1fhwDsq8eE/F+y+i1CeHIxD1wppupXrA5xyUOjQHMzU3cyjTeS2aaaN2Fzoc1bhch3xspuqBTkDulQVUz1q4mYEbNuewQD3FexGFS1VjOLoRHwOOinj9HAooXY2CSidHHKeSI5GFcRWNdSxqR7VH1iHHeTV24R+X53C8hSCBvPPqnD8B+AOygn6OYAm0ORSGthLl8B0d4DtRmIKsoMsJF1U/Hi1dt6DusIN8PrsIlUdwOAITpDFlC6q3MTbgmHm011qGepOvQSXPipyOCujW6rxqk0dRWYsVFe8PRSn5JxWOoEvdfOGzfnF5tnCRK+bGi33MoB1hL0U5d1H5J5oVD6A5mp8sQS6KSWh5e0jEcR4BPmhKqJA4xTM3XuxjBlW8DuRacDU3y0myNbNTPHPjxT5m0GTN15A/zVFiI+HKYzgc/ydMlrRfgmQWuYn0F91xJEQYxVuDnMcOrQAWJi2EI72ErQviwqLEQpQ+5XBEIqzi3YWLwF+BMiMcjshEqYR1Gdk1KmxBsaR9SQviSDdRFK8fxVU+YliWZmcbcq7vSFoQR/qJWvuxD0WgLDYoSzPzAqowtjVhORwDhEaKru4GPoliGgcyy4Hj0DLT4TBCo9WO88jQ8Bns97lLghvRTOfqqDiMYqrM+HyUYdBtaLykeRmlK12C9rQOh1FM1vd/HqUIzaT5e+LVoh/VxByHShs6HFaw0VjjHhTxP5d0LT+fRnu5q3HuAodlbHW02Q5cDByM+sw1642cRylCx6PeZiuTFScUFxK+f19QovaRS+t4tsasxhvABbZbSfUCV6CM7qtQl6Fm4E1U22UqcAYqvZ42fgJMxH6vdYc5nkBlSW6Pq4fbS6hb6jg0u9yGug7FyS5U1+UcVBbwbFSuMM1sQ1bXK4A9CcviqM0e9H80HdUxCpwIa4McygA/GfgAcCJqmGKKXUixupEv7nHsLc2agWNQ0d9OzC+PHNHIo1XeLCoe8kkqXiUtwKFoWXoEKqk3BpWLaC8cXsV8HT1J+tFTZKvn+DMqFZi1knvtyKg1O2lBHADcCVxEedNSAP4HJcsr0NNWHVUAAAAASUVORK5CYII="); 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 | 82 |
83 | Search: 85 |
86 |
87 | Group by: 88 | 92 |
93 | 173 | 174 |
175 |
176 |
177 | 178 |

Pure Nim stack implementation based on sequences.

179 |

Example:

180 |
# Reverting a string using a stack
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 |

Types

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 |

Procs

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 | 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 | --------------------------------------------------------------------------------