├── .eslintrc.js ├── .gitignore ├── .gitmodules ├── .npmignore ├── CONTRIBUTING.md ├── LICENSE ├── README.md ├── doc └── keyboard.md ├── examples ├── circles.html ├── donkey.html ├── editor.html ├── fonts.html ├── getput.html ├── hello_world.html ├── input.html ├── keytest.html ├── lines.html ├── mouse.html ├── paint.html ├── polargrapher.html ├── primes.html └── slides.html ├── package.json ├── test ├── array-test.js ├── basic-ops-test.js ├── basic-tester.js ├── built-in-functions-test.js ├── comment-test.js ├── const-test.js ├── copyright-test.js ├── deftypes-test.js ├── do-loop-while-test.js ├── for-loop-test.js ├── formatting-test.js ├── functions-test.js ├── if-else-test.js ├── labels-test.js ├── on-gosub-test.js ├── on-goto-test.js ├── option-base-test.js ├── primes-example-test.js ├── print-using-test.js ├── read-data-test.js ├── run-tests.sh ├── subroutines-test.js ├── swap-test.js ├── type-test.js └── while-wend-test.js ├── third_party └── install_linter │ └── package.json ├── tools ├── keyword_dump.js └── lint.sh ├── wip ├── gorillas.html └── nibbles.html └── wwwbasic.js /.eslintrc.js: -------------------------------------------------------------------------------- 1 | // Copyright 2018 Google LLC 2 | // 3 | // Licensed under the Apache License, Version 2.0 (the "License"); 4 | // you may not use this file except in compliance with the License. 5 | // You may obtain a copy of the License at 6 | // 7 | // https://www.apache.org/licenses/LICENSE-2.0 8 | // 9 | // Unless required by applicable law or agreed to in writing, software 10 | // distributed under the License is distributed on an "AS IS" BASIS, 11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | // See the License for the specific language governing permissions and 13 | // limitations under the License. 14 | 15 | 'use strict'; 16 | 17 | module.exports = { 18 | 'env': { 19 | 'browser': true, 20 | 'es6': true, 21 | 'node': true 22 | }, 23 | 'extends': 'eslint:recommended', 24 | 'parserOptions': { 25 | 'ecmaVersion': 2016 26 | }, 27 | 'rules': { 28 | 'accessor-pairs': 'error', 29 | 'array-bracket-newline': 'off', 30 | 'array-bracket-spacing': [ 31 | 'error', 32 | 'never' 33 | ], 34 | 'array-callback-return': 'error', 35 | 'array-element-newline': 'off', 36 | 'arrow-body-style': 'error', 37 | 'arrow-parens': 'error', 38 | 'arrow-spacing': 'error', 39 | 'block-scoped-var': 'off', 40 | 'block-spacing': [ 41 | 'error', 42 | 'always' 43 | ], 44 | 'brace-style': [ 45 | 'error', 46 | '1tbs', 47 | { 48 | 'allowSingleLine': true 49 | } 50 | ], 51 | 'callback-return': 'error', 52 | 'camelcase': 'off', 53 | 'capitalized-comments': 'off', 54 | 'class-methods-use-this': 'error', 55 | 'comma-dangle': 'off', 56 | 'comma-spacing': [ 57 | 'error', 58 | { 59 | 'after': true, 60 | 'before': false 61 | } 62 | ], 63 | 'comma-style': [ 64 | 'error', 65 | 'last' 66 | ], 67 | 'complexity': 'off', 68 | 'computed-property-spacing': [ 69 | 'error', 70 | 'never' 71 | ], 72 | 'consistent-return': 'error', 73 | 'consistent-this': 'error', 74 | 'curly': 'off', 75 | 'default-case': 'off', 76 | 'dot-location': 'error', 77 | 'dot-notation': [ 78 | 'error', 79 | { 80 | 'allowKeywords': false 81 | } 82 | ], 83 | 'eol-last': 'error', 84 | 'eqeqeq': 'off', 85 | 'func-call-spacing': 'error', 86 | 'func-name-matching': 'error', 87 | 'func-names': 'off', 88 | 'func-style': [ 89 | 'error', 90 | 'declaration' 91 | ], 92 | 'function-paren-newline': 'off', 93 | 'generator-star-spacing': 'error', 94 | 'global-require': 'error', 95 | 'guard-for-in': 'off', 96 | 'handle-callback-err': 'error', 97 | 'id-length': 'off', 98 | 'id-match': 'error', 99 | 'implicit-arrow-linebreak': 'error', 100 | 'indent': ['error', 2], 101 | 'indent-legacy': 'off', 102 | 'init-declarations': 'off', 103 | 'jsx-quotes': 'error', 104 | 'key-spacing': 'error', 105 | 'keyword-spacing': 'error', 106 | 'line-comment-position': 'error', 107 | 'linebreak-style': [ 108 | 'error', 109 | 'unix' 110 | ], 111 | 'lines-around-comment': 'error', 112 | 'lines-around-directive': 'error', 113 | 'lines-between-class-members': 'error', 114 | 'max-classes-per-file': 'error', 115 | 'max-depth': 'off', 116 | 'max-len': 'error', 117 | 'max-lines': 'off', 118 | 'max-lines-per-function': 'off', 119 | 'max-nested-callbacks': 'error', 120 | 'max-params': 'off', 121 | 'max-statements': 'off', 122 | 'max-statements-per-line': 'off', 123 | 'multiline-comment-style': 'off', 124 | 'multiline-ternary': [ 125 | 'error', 126 | 'never' 127 | ], 128 | 'new-parens': 'error', 129 | 'newline-after-var': 'off', 130 | 'newline-before-return': 'off', 131 | 'newline-per-chained-call': 'off', 132 | 'no-alert': 'error', 133 | 'no-array-constructor': 'error', 134 | 'no-async-promise-executor': 'error', 135 | 'no-await-in-loop': 'error', 136 | 'no-bitwise': 'off', 137 | 'no-buffer-constructor': 'error', 138 | 'no-caller': 'error', 139 | 'no-catch-shadow': 'error', 140 | 'no-cond-assign': 'off', 141 | 'no-confusing-arrow': 'error', 142 | 'no-continue': 'off', 143 | 'no-console': 'off', 144 | 'no-div-regex': 'error', 145 | 'no-duplicate-imports': 'error', 146 | 'no-else-return': 'off', 147 | 'no-empty-function': 'error', 148 | 'no-eq-null': 'off', 149 | 'no-eval': 'off', 150 | 'no-extend-native': 'error', 151 | 'no-extra-bind': 'error', 152 | 'no-extra-label': 'error', 153 | 'no-extra-parens': 'off', 154 | 'no-floating-decimal': 'error', 155 | 'no-implicit-globals': 'error', 156 | 'no-implied-eval': 'error', 157 | 'no-inline-comments': 'error', 158 | 'no-inner-declarations': [ 159 | 'error', 160 | 'functions' 161 | ], 162 | 'no-invalid-this': 'error', 163 | 'no-iterator': 'error', 164 | 'no-label-var': 'error', 165 | 'no-labels': 'off', 166 | 'no-lone-blocks': 'error', 167 | 'no-lonely-if': 'off', 168 | 'no-loop-func': 'off', 169 | 'no-magic-numbers': 'off', 170 | 'no-misleading-character-class': 'error', 171 | 'no-mixed-operators': 'off', 172 | 'no-mixed-requires': 'error', 173 | 'no-multi-assign': 'error', 174 | 'no-multi-spaces': 'error', 175 | 'no-multi-str': 'error', 176 | 'no-multiple-empty-lines': 'error', 177 | 'no-native-reassign': 'error', 178 | 'no-negated-condition': 'off', 179 | 'no-negated-in-lhs': 'error', 180 | 'no-nested-ternary': 'off', 181 | 'no-new': 'error', 182 | 'no-new-func': 'error', 183 | 'no-new-object': 'error', 184 | 'no-new-require': 'error', 185 | 'no-new-wrappers': 'error', 186 | 'no-octal-escape': 'error', 187 | 'no-param-reassign': 'off', 188 | 'no-path-concat': 'error', 189 | 'no-plusplus': 'off', 190 | 'no-process-env': 'error', 191 | 'no-process-exit': 'error', 192 | 'no-proto': 'error', 193 | 'no-prototype-builtins': 'error', 194 | 'no-redeclare': 'off', 195 | 'no-restricted-globals': 'error', 196 | 'no-restricted-imports': 'error', 197 | 'no-restricted-modules': 'error', 198 | 'no-restricted-properties': 'error', 199 | 'no-restricted-syntax': 'error', 200 | 'no-return-assign': 'error', 201 | 'no-return-await': 'error', 202 | 'no-script-url': 'error', 203 | 'no-self-compare': 'error', 204 | 'no-sequences': 'error', 205 | 'no-shadow': 'off', 206 | 'no-shadow-restricted-names': 'error', 207 | 'no-spaced-func': 'error', 208 | 'no-sync': 'off', 209 | 'no-tabs': 'error', 210 | 'no-template-curly-in-string': 'error', 211 | 'no-ternary': 'off', 212 | 'no-throw-literal': 'off', 213 | 'no-trailing-spaces': 'error', 214 | 'no-undef-init': 'error', 215 | 'no-undef': 'off', 216 | 'no-undefined': 'off', 217 | 'no-underscore-dangle': 'error', 218 | 'no-unmodified-loop-condition': 'off', 219 | 'no-unneeded-ternary': 'error', 220 | 'no-unused-vars': 'off', 221 | 'no-unused-expressions': 'error', 222 | 'no-use-before-define': 'off', 223 | 'no-useless-call': 'error', 224 | 'no-useless-computed-key': 'error', 225 | 'no-useless-concat': 'error', 226 | 'no-useless-constructor': 'error', 227 | 'no-useless-rename': 'error', 228 | 'no-useless-return': 'off', 229 | 'no-var': 'off', 230 | 'no-void': 'error', 231 | 'no-warning-comments': 'off', 232 | 'no-whitespace-before-property': 'error', 233 | 'no-with': 'error', 234 | 'nonblock-statement-body-position': 'error', 235 | 'object-curly-newline': 'error', 236 | 'object-curly-spacing': 'off', 237 | 'object-shorthand': 'off', 238 | 'one-var': 'off', 239 | 'one-var-declaration-per-line': 'off', 240 | 'operator-assignment': 'off', 241 | 'operator-linebreak': 'off', 242 | 'padded-blocks': 'off', 243 | 'padding-line-between-statements': 'error', 244 | 'prefer-arrow-callback': 'off', 245 | 'prefer-const': 'error', 246 | 'prefer-destructuring': 'off', 247 | 'prefer-numeric-literals': 'error', 248 | 'prefer-object-spread': 'error', 249 | 'prefer-promise-reject-errors': 'error', 250 | 'prefer-reflect': 'error', 251 | 'prefer-rest-params': 'error', 252 | 'prefer-spread': 'error', 253 | 'prefer-template': 'off', 254 | 'quote-props': 'off', 255 | 'quotes': ['error', 'single'], 256 | 'radix': [ 257 | 'error', 258 | 'as-needed' 259 | ], 260 | 'require-atomic-updates': 'error', 261 | 'require-await': 'error', 262 | 'require-jsdoc': 'off', 263 | 'require-unicode-regexp': 'off', 264 | 'rest-spread-spacing': 'error', 265 | 'semi': 'off', 266 | 'semi-spacing': [ 267 | 'error', 268 | { 269 | 'after': true, 270 | 'before': false 271 | } 272 | ], 273 | 'semi-style': [ 274 | 'error', 275 | 'last' 276 | ], 277 | 'sort-imports': 'error', 278 | 'sort-keys': 'off', 279 | 'sort-vars': 'off', 280 | 'space-before-blocks': 'error', 281 | 'space-before-function-paren': 'off', 282 | 'space-in-parens': [ 283 | 'error', 284 | 'never' 285 | ], 286 | 'space-infix-ops': 'error', 287 | 'space-unary-ops': 'error', 288 | 'spaced-comment': 'off', 289 | 'strict': 'error', 290 | 'switch-colon-spacing': [ 291 | 'error', 292 | { 293 | 'after': true, 294 | 'before': false 295 | } 296 | ], 297 | 'symbol-description': 'error', 298 | 'template-curly-spacing': 'error', 299 | 'template-tag-spacing': 'error', 300 | 'unicode-bom': [ 301 | 'error', 302 | 'never' 303 | ], 304 | 'valid-jsdoc': 'error', 305 | 'vars-on-top': 'off', 306 | 'wrap-regex': 'off', 307 | 'yield-star-spacing': 'error', 308 | 'yoda': [ 309 | 'error', 310 | 'never' 311 | ] 312 | } 313 | }; 314 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | .DS_Store 2 | third_party/install_linter/package-lock.json 3 | third_party/install_linter/node_modules 4 | -------------------------------------------------------------------------------- /.gitmodules: -------------------------------------------------------------------------------- 1 | [submodule "third_party/ace-builds"] 2 | path = third_party/ace-builds 3 | url = https://github.com/ajaxorg/ace-builds.git 4 | -------------------------------------------------------------------------------- /.npmignore: -------------------------------------------------------------------------------- 1 | /examples/ 2 | /test/ 3 | /tools/ 4 | /third_party/ 5 | .eslintrc.js 6 | .gitignore 7 | .gitmodules 8 | .travis.yml 9 | -------------------------------------------------------------------------------- /CONTRIBUTING.md: -------------------------------------------------------------------------------- 1 | # How to Contribute 2 | 3 | We'd love to accept your patches and contributions to this project. There are 4 | just a few small guidelines you need to follow. 5 | 6 | ## Contributor License Agreement 7 | 8 | Contributions to this project must be accompanied by a Contributor License 9 | Agreement. You (or your employer) retain the copyright to your contribution; 10 | this simply gives us permission to use and redistribute your contributions as 11 | part of the project. Head over to to see 12 | your current agreements on file or to sign a new one. 13 | 14 | You generally only need to submit a CLA once, so if you've already submitted one 15 | (even if it was for a different project), you probably don't need to do it 16 | again. 17 | 18 | ## Code reviews 19 | 20 | All submissions, including submissions by project members, require review. We 21 | use GitHub pull requests for this purpose. Consult 22 | [GitHub Help](https://help.github.com/articles/about-pull-requests/) for more 23 | information on using pull requests. 24 | 25 | ## Community Guidelines 26 | 27 | This project follows [Google's Open Source Community 28 | Guidelines](https://opensource.google.com/conduct/). 29 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | 2 | Apache License 3 | Version 2.0, January 2004 4 | http://www.apache.org/licenses/ 5 | 6 | TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION 7 | 8 | 1. Definitions. 9 | 10 | "License" shall mean the terms and conditions for use, reproduction, 11 | and distribution as defined by Sections 1 through 9 of this document. 12 | 13 | "Licensor" shall mean the copyright owner or entity authorized by 14 | the copyright owner that is granting the License. 15 | 16 | "Legal Entity" shall mean the union of the acting entity and all 17 | other entities that control, are controlled by, or are under common 18 | control with that entity. For the purposes of this definition, 19 | "control" means (i) the power, direct or indirect, to cause the 20 | direction or management of such entity, whether by contract or 21 | otherwise, or (ii) ownership of fifty percent (50%) or more of the 22 | outstanding shares, or (iii) beneficial ownership of such entity. 23 | 24 | "You" (or "Your") shall mean an individual or Legal Entity 25 | exercising permissions granted by this License. 26 | 27 | "Source" form shall mean the preferred form for making modifications, 28 | including but not limited to software source code, documentation 29 | source, and configuration files. 30 | 31 | "Object" form shall mean any form resulting from mechanical 32 | transformation or translation of a Source form, including but 33 | not limited to compiled object code, generated documentation, 34 | and conversions to other media types. 35 | 36 | "Work" shall mean the work of authorship, whether in Source or 37 | Object form, made available under the License, as indicated by a 38 | copyright notice that is included in or attached to the work 39 | (an example is provided in the Appendix below). 40 | 41 | "Derivative Works" shall mean any work, whether in Source or Object 42 | form, that is based on (or derived from) the Work and for which the 43 | editorial revisions, annotations, elaborations, or other modifications 44 | represent, as a whole, an original work of authorship. For the purposes 45 | of this License, Derivative Works shall not include works that remain 46 | separable from, or merely link (or bind by name) to the interfaces of, 47 | the Work and Derivative Works thereof. 48 | 49 | "Contribution" shall mean any work of authorship, including 50 | the original version of the Work and any modifications or additions 51 | to that Work or Derivative Works thereof, that is intentionally 52 | submitted to Licensor for inclusion in the Work by the copyright owner 53 | or by an individual or Legal Entity authorized to submit on behalf of 54 | the copyright owner. For the purposes of this definition, "submitted" 55 | means any form of electronic, verbal, or written communication sent 56 | to the Licensor or its representatives, including but not limited to 57 | communication on electronic mailing lists, source code control systems, 58 | and issue tracking systems that are managed by, or on behalf of, the 59 | Licensor for the purpose of discussing and improving the Work, but 60 | excluding communication that is conspicuously marked or otherwise 61 | designated in writing by the copyright owner as "Not a Contribution." 62 | 63 | "Contributor" shall mean Licensor and any individual or Legal Entity 64 | on behalf of whom a Contribution has been received by Licensor and 65 | subsequently incorporated within the Work. 66 | 67 | 2. Grant of Copyright License. Subject to the terms and conditions of 68 | this License, each Contributor hereby grants to You a perpetual, 69 | worldwide, non-exclusive, no-charge, royalty-free, irrevocable 70 | copyright license to reproduce, prepare Derivative Works of, 71 | publicly display, publicly perform, sublicense, and distribute the 72 | Work and such Derivative Works in Source or Object form. 73 | 74 | 3. Grant of Patent License. Subject to the terms and conditions of 75 | this License, each Contributor hereby grants to You a perpetual, 76 | worldwide, non-exclusive, no-charge, royalty-free, irrevocable 77 | (except as stated in this section) patent license to make, have made, 78 | use, offer to sell, sell, import, and otherwise transfer the Work, 79 | where such license applies only to those patent claims licensable 80 | by such Contributor that are necessarily infringed by their 81 | Contribution(s) alone or by combination of their Contribution(s) 82 | with the Work to which such Contribution(s) was submitted. If You 83 | institute patent litigation against any entity (including a 84 | cross-claim or counterclaim in a lawsuit) alleging that the Work 85 | or a Contribution incorporated within the Work constitutes direct 86 | or contributory patent infringement, then any patent licenses 87 | granted to You under this License for that Work shall terminate 88 | as of the date such litigation is filed. 89 | 90 | 4. Redistribution. You may reproduce and distribute copies of the 91 | Work or Derivative Works thereof in any medium, with or without 92 | modifications, and in Source or Object form, provided that You 93 | meet the following conditions: 94 | 95 | (a) You must give any other recipients of the Work or 96 | Derivative Works a copy of this License; and 97 | 98 | (b) You must cause any modified files to carry prominent notices 99 | stating that You changed the files; and 100 | 101 | (c) You must retain, in the Source form of any Derivative Works 102 | that You distribute, all copyright, patent, trademark, and 103 | attribution notices from the Source form of the Work, 104 | excluding those notices that do not pertain to any part of 105 | the Derivative Works; and 106 | 107 | (d) If the Work includes a "NOTICE" text file as part of its 108 | distribution, then any Derivative Works that You distribute must 109 | include a readable copy of the attribution notices contained 110 | within such NOTICE file, excluding those notices that do not 111 | pertain to any part of the Derivative Works, in at least one 112 | of the following places: within a NOTICE text file distributed 113 | as part of the Derivative Works; within the Source form or 114 | documentation, if provided along with the Derivative Works; or, 115 | within a display generated by the Derivative Works, if and 116 | wherever such third-party notices normally appear. The contents 117 | of the NOTICE file are for informational purposes only and 118 | do not modify the License. You may add Your own attribution 119 | notices within Derivative Works that You distribute, alongside 120 | or as an addendum to the NOTICE text from the Work, provided 121 | that such additional attribution notices cannot be construed 122 | as modifying the License. 123 | 124 | You may add Your own copyright statement to Your modifications and 125 | may provide additional or different license terms and conditions 126 | for use, reproduction, or distribution of Your modifications, or 127 | for any such Derivative Works as a whole, provided Your use, 128 | reproduction, and distribution of the Work otherwise complies with 129 | the conditions stated in this License. 130 | 131 | 5. Submission of Contributions. Unless You explicitly state otherwise, 132 | any Contribution intentionally submitted for inclusion in the Work 133 | by You to the Licensor shall be under the terms and conditions of 134 | this License, without any additional terms or conditions. 135 | Notwithstanding the above, nothing herein shall supersede or modify 136 | the terms of any separate license agreement you may have executed 137 | with Licensor regarding such Contributions. 138 | 139 | 6. Trademarks. This License does not grant permission to use the trade 140 | names, trademarks, service marks, or product names of the Licensor, 141 | except as required for reasonable and customary use in describing the 142 | origin of the Work and reproducing the content of the NOTICE file. 143 | 144 | 7. Disclaimer of Warranty. Unless required by applicable law or 145 | agreed to in writing, Licensor provides the Work (and each 146 | Contributor provides its Contributions) on an "AS IS" BASIS, 147 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or 148 | implied, including, without limitation, any warranties or conditions 149 | of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A 150 | PARTICULAR PURPOSE. You are solely responsible for determining the 151 | appropriateness of using or redistributing the Work and assume any 152 | risks associated with Your exercise of permissions under this License. 153 | 154 | 8. Limitation of Liability. In no event and under no legal theory, 155 | whether in tort (including negligence), contract, or otherwise, 156 | unless required by applicable law (such as deliberate and grossly 157 | negligent acts) or agreed to in writing, shall any Contributor be 158 | liable to You for damages, including any direct, indirect, special, 159 | incidental, or consequential damages of any character arising as a 160 | result of this License or out of the use or inability to use the 161 | Work (including but not limited to damages for loss of goodwill, 162 | work stoppage, computer failure or malfunction, or any and all 163 | other commercial damages or losses), even if such Contributor 164 | has been advised of the possibility of such damages. 165 | 166 | 9. Accepting Warranty or Additional Liability. While redistributing 167 | the Work or Derivative Works thereof, You may choose to offer, 168 | and charge a fee for, acceptance of support, warranty, indemnity, 169 | or other liability obligations and/or rights consistent with this 170 | License. However, in accepting such obligations, You may act only 171 | on Your own behalf and on Your sole responsibility, not on behalf 172 | of any other Contributor, and only if You agree to indemnify, 173 | defend, and hold each Contributor harmless for any liability 174 | incurred by, or claims asserted against, such Contributor by reason 175 | of your accepting any such warranty or additional liability. 176 | 177 | END OF TERMS AND CONDITIONS 178 | 179 | APPENDIX: How to apply the Apache License to your work. 180 | 181 | To apply the Apache License to your work, attach the following 182 | boilerplate notice, with the fields enclosed by brackets "[]" 183 | replaced with your own identifying information. (Don't include 184 | the brackets!) The text should be enclosed in the appropriate 185 | comment syntax for the file format. We also recommend that a 186 | file or class name and description of purpose be included on the 187 | same "printed page" as the copyright notice for easier 188 | identification within third-party archives. 189 | 190 | Copyright [yyyy] [name of copyright owner] 191 | 192 | Licensed under the Apache License, Version 2.0 (the "License"); 193 | you may not use this file except in compliance with the License. 194 | You may obtain a copy of the License at 195 | 196 | http://www.apache.org/licenses/LICENSE-2.0 197 | 198 | Unless required by applicable law or agreed to in writing, software 199 | distributed under the License is distributed on an "AS IS" BASIS, 200 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 201 | See the License for the specific language governing permissions and 202 | limitations under the License. 203 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | [![NPM Package](https://img.shields.io/npm/v/wwwbasic.svg)](https://www.npmjs.com/package/wwwbasic) 2 | 3 | # wwwBASIC 4 | 5 | wwwBASIC is an implementation of BASIC (Beginner's All-purpose Symbolic 6 | Instruction Code) designed to be easy to run on the Web. 7 | 8 | ## How to use wwwBASIC 9 | 10 | You can include wwwBASIC directly in Web pages: 11 | 12 | ```html 13 | 14 | 15 | 16 | 17 | 23 | 24 | 25 | ``` 26 | 27 | You can also import wwwBASIC as a Node.js module. 28 | 29 | Either install it via [npm](https://www.npmjs.com/): `npm install -S wwwbasic` 30 | 31 | or clone the repository: `git clone https://github.com/google/wwwbasic.git` 32 | 33 | Then run your code: 34 | ```js 35 | var basic = require('wwwbasic'); // from NPM 36 | // var basic = require('./wwwbasic.js'); // from within the cloned repository directory 37 | 38 | basic.Basic( 39 | ` 40 | PRINT "Hello World!" 41 | FOR i = 1 to 10 42 | PRINT "Counting "; i 43 | NEXT i 44 | `); 45 | ``` 46 | 47 | ## Features 48 | 49 | It supports a range of features including: 50 | * Graphics: 24-bit color, PSET, LINE, CIRCLE. 51 | * Input: INKEY$, GETMOUSE. 52 | * Source is parsed and compiled to JavaScript at load time. 53 | 54 | ## Test Suite 55 | 56 | wwwBASIC has a "work in progress" test suite. 57 | It can be run with: `./tests/run-tests.sh`. 58 | 59 | ## Examples 60 | 61 | * [Circles](https://google.github.io/wwwbasic/examples/circles.html) 62 | ([source](examples/circles.html)) - Some circles... 63 | * [DONKEY.BAS](https://google.github.io/wwwbasic/examples/donkey.html) 64 | ([source](examples/donkey.html)) - 65 | The classic "game", apparently 66 | [co-authored by Bill Gates himself](https://blog.codinghorror.com/bill-gates-and-donkey-bas/). 67 | * [GET & PUT](https://google.github.io/wwwbasic/examples/getput.html) 68 | ([source](examples/getput.html)) - Test of GET/PUT. 69 | * [Hello World](https://google.github.io/wwwbasic/examples/hello_world.html) 70 | ([source](examples/hello_world.html)) - Hello. 71 | * [Lines](https://google.github.io/wwwbasic/examples/lines.html) 72 | ([source](examples/lines.html)) - Some lines... 73 | * [Polar Grapher](https://google.github.io/wwwbasic/examples/polargrapher.html) 74 | ([source](examples/polargrapher.html)) - Draws a polar graph using trig functions. 75 | * [Primes](https://google.github.io/wwwbasic/examples/primes.html) 76 | ([source](examples/primes.html)) - Primes <3000. 77 | * [Slides](https://google.github.io/wwwbasic/examples/slides.html) 78 | ([source](examples/slides.html)) - Reveal.BAS :-) 79 | * [Editor](https://google.github.io/wwwbasic/examples/editor.html) 80 | ([source](examples/editor.html)) - Live editor using 81 | [Ace](https://ace.c9.io/). 82 | 83 | ## But Why? 84 | 85 | The immediate trigger for wwwBASIC's existence was 86 | Ed Thelen's Nike Hercules 87 | [simulator](http://ed-thelen.org/NikeSimulation.html#SimBrowser). 88 | It had been written in BASIC some time back, 89 | then ported to some unknown version of FreeBasic. 90 | However, while he had screenshots and source code, 91 | it also included a Windows .EXE to a download, 92 | and the statement, "guaranteed to be free of viruses" :-/ 93 | 94 | As it was meant to capture how something historical worked, 95 | it seemed unfortunate that something of this sort 96 | couldn't just be accessible directly on the web. 97 | Various whole system emulators that run on the web are available, 98 | but booting a whole system for a small program seemed like overkill. 99 | 100 | Hence the first goal was to get 101 | [this](http://ed-thelen.org/nike-fromBradNelsonSept26.html) to run. 102 | 103 | From there, bringing up 104 | [DONKEY.BAS](https://google.github.io/wwwbasic/examples/donkey.html) 105 | seemed a nice logical milestone. 106 | Bringing up GORILLA.BAS and NIBBLES.BAS are a current focus. 107 | 108 | ## Source Code Headers 109 | 110 | Every file containing source code must include copyright and license 111 | information. This includes any JS/CSS files that you might be serving out to 112 | browsers. (This is to help well-intentioned people avoid accidental copying that 113 | doesn't comply with the license.) 114 | 115 | Apache header: 116 | 117 | Copyright 2018 Google LLC 118 | 119 | Licensed under the Apache License, Version 2.0 (the "License"); 120 | you may not use this file except in compliance with the License. 121 | You may obtain a copy of the License at 122 | 123 | https://www.apache.org/licenses/LICENSE-2.0 124 | 125 | Unless required by applicable law or agreed to in writing, software 126 | distributed under the License is distributed on an "AS IS" BASIS, 127 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 128 | See the License for the specific language governing permissions and 129 | limitations under the License. 130 | -------------------------------------------------------------------------------- /doc/keyboard.md: -------------------------------------------------------------------------------- 1 | # Notes on BASICA keyboard 2 | 3 | Notes on BASICA keyboard as observed in an emulator. 4 | 5 | * A-Z, a-z, 0-9 = ascii 6 | * Ctrl-A-Z = chr$(1) to chr$(26) 7 | * ESCAPE = chr$(27) 8 | * BACKSPACE = chr$(8) 9 | * PrtScr = chr$(42) 10 | * F1-F10 = chr$(0) + chr$(59) thru chr$(0) + chr$(68) 11 | * Shift-F1-F10 = chr$(0) + chr$(84) thru chr$(0) + chr$(93) 12 | * Ctrl-F1-F10 = chr$(0) + chr$(94) thru chr$(0) + chr$(103) 13 | * Alt-F1-F10 = chr$(0) + chr$(104) thru chr$(0) + chr$(113) 14 | * HOME = chr$(0) + chr$(71) 15 | * LEFT = chr$(0) + chr$(75) 16 | * RIGHT = chr$(0) + chr$(77) 17 | * PGUP = chr$(0) + chr$(73) 18 | * UP = chr$(0) + chr$(72) 19 | * END = chr$(0) + chr$(79) 20 | * DOWN = chr$(0) + chr$(80) 21 | * PGDN = chr$(0) + chr$(81) 22 | * 1234567890-= = chr$(0) + chr$(120) thru chr$(0) + chr$(131) 23 | * qwertyuiop = chr$(0) + chr$(16) thru chr$(0) + chr$(25) 24 | * asdfghjkl = chr$(0) + chr$(30) thru chr$(0) + chr$(38) 25 | * zxcvbnm = chr$(0) + chr$(44) thru chr$(0) + chr$(50) 26 | * INS = chr$(0) + chr$(82) 27 | * DEL = chr$(0) + chr$(83) 28 | * TAB = chr$(9) 29 | * Shift-TAB = chr$(0) + chr$(15) 30 | -------------------------------------------------------------------------------- /examples/circles.html: -------------------------------------------------------------------------------- 1 | 16 | 17 | 18 | 45 | 46 | -------------------------------------------------------------------------------- /examples/donkey.html: -------------------------------------------------------------------------------- 1 | 16 | 17 | 18 | 19 | 20 | -------------------------------------------------------------------------------- /examples/editor.html: -------------------------------------------------------------------------------- 1 | 16 | 17 | 18 | 24 | 25 | 26 | 27 |
28 | FOR i = 1 to 10
29 |   COLOR i, 0
30 |   PRINT SPACE$(i) + "Hello world!"
31 | NEXT i
32 |
33 |
34 | 35 | 36 | 37 | 49 | 50 | 51 | -------------------------------------------------------------------------------- /examples/fonts.html: -------------------------------------------------------------------------------- 1 | 16 | 17 | 18 | 31 | 32 | -------------------------------------------------------------------------------- /examples/getput.html: -------------------------------------------------------------------------------- 1 | 16 | 17 | 18 | 48 | 49 | -------------------------------------------------------------------------------- /examples/hello_world.html: -------------------------------------------------------------------------------- 1 | 16 | 17 | 18 | 26 | 27 | -------------------------------------------------------------------------------- /examples/input.html: -------------------------------------------------------------------------------- 1 | 16 | 17 | 18 | 32 | 33 | -------------------------------------------------------------------------------- /examples/keytest.html: -------------------------------------------------------------------------------- 1 | 16 | 17 | 18 | 31 | 32 | -------------------------------------------------------------------------------- /examples/lines.html: -------------------------------------------------------------------------------- 1 | 16 | 17 | 18 | 31 | 32 | -------------------------------------------------------------------------------- /examples/mouse.html: -------------------------------------------------------------------------------- 1 | 16 | 17 | 18 | 35 | 36 | -------------------------------------------------------------------------------- /examples/paint.html: -------------------------------------------------------------------------------- 1 | 16 | 17 | 18 | 27 | 28 | -------------------------------------------------------------------------------- /examples/polargrapher.html: -------------------------------------------------------------------------------- 1 | 16 | 17 | 18 | 72 | -------------------------------------------------------------------------------- /examples/primes.html: -------------------------------------------------------------------------------- 1 | 16 | 17 | 18 | 43 | -------------------------------------------------------------------------------- /examples/slides.html: -------------------------------------------------------------------------------- 1 | 16 | 17 | 18 | 100 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "wwwbasic", 3 | "version": "1.0.0", 4 | "description": "An implementation of BASIC designed to be easy to run on the Web", 5 | "keywords": [ 6 | "BASIC" 7 | ], 8 | "homepage": "https://github.com/google/wwwbasic#readme", 9 | "bugs": { 10 | "url": "https://github.com/google/wwwbasic/issues" 11 | }, 12 | "license": "Apache-2.0", 13 | "author": { 14 | "name": "Brad Nelson", 15 | "email": "flagxor@gmail.com", 16 | "url": "http://flagxor.com/" 17 | }, 18 | "main": "wwwbasic.js", 19 | "directories": { 20 | "example": "examples", 21 | "test": "test", 22 | "tools": "tools" 23 | }, 24 | "repository": { 25 | "type": "git", 26 | "url": "git+https://github.com/google/wwwbasic.git" 27 | }, 28 | "scripts": { 29 | "test": "./test/run-tests.sh" 30 | } 31 | } 32 | -------------------------------------------------------------------------------- /test/array-test.js: -------------------------------------------------------------------------------- 1 | // Copyright 2018 Google LLC 2 | // 3 | // Licensed under the Apache License, Version 2.0 (the "License"); 4 | // you may not use this file except in compliance with the License. 5 | // You may obtain a copy of the License at 6 | // 7 | // https://www.apache.org/licenses/LICENSE-2.0 8 | // 9 | // Unless required by applicable law or agreed to in writing, software 10 | // distributed under the License is distributed on an "AS IS" BASIS, 11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | // See the License for the specific language governing permissions and 13 | // limitations under the License. 14 | 15 | 'use strict'; 16 | 17 | var basic_test = require('./basic-tester.js'); 18 | 19 | basic_test.BASIC_TEST('Array', '2d', ` 20 | x = 123 21 | DIM a(17,11) AS SINGLE 22 | addr = VARPTR(a) 23 | y = 456 24 | z = 789 25 | w = 100 26 | FOR i = 0 to 17 27 | FOR j = 0 to 11 28 | a(i, j) = i + j * 1000 29 | NEXT j 30 | NEXT i 31 | FOR i = 0 to 17 32 | FOR j = 0 to 11 33 | IF a(i, j) <> i + j * 1000 THEN 34 | PRINT "FAIL", i, j, a(i, j) 35 | END 36 | END IF 37 | NEXT j 38 | NEXT i 39 | PRINT VARPTR(a) - addr 40 | PRINT x 41 | PRINT y 42 | PRINT z 43 | PRINT w 44 | PRINT "ok" 45 | `, ` 46 | 0 47 | 123 48 | 456 49 | 789 50 | 100 51 | ok 52 | `); 53 | 54 | basic_test.BASIC_TEST('Array', '1dInit', ` 55 | DIM a(10) = {10,9,8,7,6,5,4,3,2,1,0} 56 | FOR i = 0 to 10 57 | IF a(i) <> 10 - i THEN 58 | PRINT "FAIL","FAIL", i, a(i) 59 | END 60 | END IF 61 | NEXT i 62 | PRINT "ok" 63 | `, ` 64 | ok 65 | `); 66 | 67 | basic_test.BASIC_TEST('Array', 'String', ` 68 | DIM a$(10) 69 | FOR i = 0 to 10 70 | a$(i) = str$(i+1) 71 | NEXT i 72 | FOR i = 0 to 10 73 | IF val(a$(i)) <> i + 1 THEN 74 | PRINT "FAIL", i 75 | END IF 76 | NEXT i 77 | PRINT "ok" 78 | `, ` 79 | ok 80 | `); 81 | 82 | basic_test.BASIC_TEST('Array', 'InSub', ` 83 | TYPE Stuff 84 | x as INTEGER 85 | y as INTEGER 86 | z as INTEGER 87 | END TYPE 88 | 89 | DIM SHARED foo(1 to 80, 1 to 50) AS Stuff 90 | 91 | SUB Bar(a, b, c) 92 | FOR i = 1 to 80 93 | FOR j = 1 to 50 94 | foo(i, j).x = a 95 | foo(i, j).y = b 96 | foo(i, j).z = c 97 | NEXT j 98 | NEXT i 99 | PRINT "done" 100 | END SUB 101 | 102 | FUNCTION Check(a, b, c) 103 | FOR i = 1 to 80 104 | FOR j = 1 to 50 105 | IF foo(i, j).x <> a OR foo(i, j).y <> b OR foo(i, j).z <> c THEN 106 | Check = 0 107 | EXIT FUNCTION 108 | END IF 109 | NEXT j 110 | NEXT i 111 | Check = -1 112 | END FUNCTION 113 | 114 | SUB Baz 115 | Bar 1, 2, 3 116 | PRINT Check(1, 2, 3) 117 | PRINT Check(2, 3, 4) 118 | PRINT Check(1, 2, 3) 119 | foo(1, 1).z = 10 120 | PRINT Check(1, 2, 3) 121 | Bar 1, 2, 3 122 | PRINT Check(1, 2, 3) 123 | END SUB 124 | 125 | Baz 126 | PRINT "hi" 127 | `, ` 128 | done 129 | -1 130 | 0 131 | -1 132 | 0 133 | done 134 | -1 135 | hi 136 | `); 137 | 138 | basic_test.BASIC_TEST('Array', 'InSubArg', ` 139 | TYPE Stuff 140 | x as INTEGER 141 | y as INTEGER 142 | z as INTEGER 143 | END TYPE 144 | 145 | DIM foo1(1 to 80, 1 to 50) AS Stuff 146 | DIM foo2(1 to 80, 1 to 50) AS Stuff 147 | 148 | SUB Bar(foo() as Stuff, a, b, c) 149 | FOR i = 1 to 80 150 | FOR j = 1 to 50 151 | foo(i, j).x = a 152 | foo(i, j).y = b 153 | foo(i, j).z = c 154 | NEXT j 155 | NEXT i 156 | PRINT "done" 157 | END SUB 158 | 159 | FUNCTION Check(foo() as Stuff, a, b, c) 160 | FOR i = 1 to 80 161 | FOR j = 1 to 50 162 | IF foo(i, j).x <> a OR foo(i, j).y <> b OR foo(i, j).z <> c THEN 163 | Check = 0 164 | EXIT FUNCTION 165 | END IF 166 | NEXT j 167 | NEXT i 168 | Check = -1 169 | END FUNCTION 170 | 171 | SUB Baz 172 | Bar foo1(), 1, 2, 3 173 | Bar foo2(), 5, 6, 7 174 | PRINT Check(foo1(), 1, 2, 3) 175 | PRINT Check(foo1(), 2, 3, 4) 176 | PRINT Check(foo1(), 1, 2, 3) 177 | foo1(1, 1).z = 10 178 | PRINT Check(foo1(), 1, 2, 3) 179 | Bar foo2(), 5, 6, 7 180 | Bar foo1(), 1, 2, 3 181 | PRINT Check(foo1(), 1, 2, 3) 182 | PRINT Check(foo2(), 5, 6, 7) 183 | END SUB 184 | 185 | Baz 186 | PRINT "hi" 187 | `, ` 188 | done 189 | done 190 | -1 191 | 0 192 | -1 193 | 0 194 | done 195 | done 196 | -1 197 | -1 198 | hi 199 | `); 200 | 201 | -------------------------------------------------------------------------------- /test/basic-ops-test.js: -------------------------------------------------------------------------------- 1 | // Copyright 2018 Google LLC 2 | // 3 | // Licensed under the Apache License, Version 2.0 (the "License"); 4 | // you may not use this file except in compliance with the License. 5 | // You may obtain a copy of the License at 6 | // 7 | // https://www.apache.org/licenses/LICENSE-2.0 8 | // 9 | // Unless required by applicable law or agreed to in writing, software 10 | // distributed under the License is distributed on an "AS IS" BASIS, 11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | // See the License for the specific language governing permissions and 13 | // limitations under the License. 14 | 15 | 'use strict'; 16 | 17 | var basic_test = require('./basic-tester.js'); 18 | 19 | basic_test.BASIC_TEST('BasicOps', 'Negate', ` 20 | PRINT -123 21 | `, ` 22 | -123 23 | `); 24 | 25 | basic_test.BASIC_TEST('BasicOps', 'FourOps', ` 26 | PRINT -123+123 27 | PRINT -123-123 28 | PRINT 1+2*4 29 | PRINT 1+2/4 30 | `, ` 31 | 0 32 | -246 33 | 9 34 | 1.5 35 | `); 36 | 37 | basic_test.BASIC_TEST('BasicOps', 'Power', ` 38 | PRINT 2^3 39 | `, ` 40 | 8 41 | `); 42 | 43 | basic_test.BASIC_TEST('BasicOps', 'PowerNeg', ` 44 | PRINT -2^4 45 | `, ` 46 | -16 47 | `); 48 | 49 | basic_test.BASIC_TEST('BasicOps', 'Precidence1', ` 50 | PRINT 2^4*3 51 | `, ` 52 | 48 53 | `); 54 | 55 | basic_test.BASIC_TEST('BasicOps', 'Precidence2', ` 56 | PRINT 3*2^4 57 | `, ` 58 | 48 59 | `); 60 | 61 | basic_test.BASIC_TEST('BasicOps', 'Let', ` 62 | LET x = 2 63 | LET y = 3 64 | PRINT x * y 65 | `, ` 66 | 6 67 | `); 68 | 69 | basic_test.BASIC_TEST('BasicOps', 'Mod', ` 70 | LET x = 5 71 | LET y = 3 72 | PRINT x mod y 73 | `, ` 74 | 2 75 | `); 76 | 77 | basic_test.BASIC_TEST('BasicOps', 'FloorDivide', ` 78 | LET x = 7 79 | LET y = 3 80 | PRINT x \\ y 81 | `, ` 82 | 2 83 | `); 84 | 85 | basic_test.BASIC_TEST('BasicOps', 'Not', ` 86 | DEFINT A-Z 87 | CONST TRUE = -1 88 | CONST FALSE = NOT TRUE 89 | foo = TRUE 90 | bar = FALSE 91 | PRINT foo = TRUE 92 | PRINT foo = FALSE 93 | PRINT bar = TRUE 94 | PRINT bar = FALSE 95 | PRINT TRUE 96 | PRINT FALSE 97 | `, ` 98 | -1 99 | 0 100 | 0 101 | -1 102 | -1 103 | 0 104 | `); 105 | 106 | -------------------------------------------------------------------------------- /test/basic-tester.js: -------------------------------------------------------------------------------- 1 | // Copyright 2018 Google LLC 2 | // 3 | // Licensed under the Apache License, Version 2.0 (the "License"); 4 | // you may not use this file except in compliance with the License. 5 | // You may obtain a copy of the License at 6 | // 7 | // https://www.apache.org/licenses/LICENSE-2.0 8 | // 9 | // Unless required by applicable law or agreed to in writing, software 10 | // distributed under the License is distributed on an "AS IS" BASIS, 11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | // See the License for the specific language governing permissions and 13 | // limitations under the License. 14 | 15 | 'use strict'; 16 | 17 | var basic = require('../wwwbasic.js'); 18 | 19 | function BASIC_TEST(suite, name, code, expected_log, expected_error) { 20 | const full_name = suite + '.' + name; 21 | console.log('...... ' + full_name); 22 | 23 | function StripLeading(s) { 24 | if (s[0] == '\n') { 25 | return s.substr(1); 26 | } else { 27 | return s; 28 | } 29 | } 30 | 31 | code = StripLeading(code); 32 | expected_log = StripLeading(expected_log); 33 | if (expected_error !== undefined) { 34 | expected_error = StripLeading(expected_error); 35 | } 36 | 37 | let result_log = ''; 38 | let result_error = ''; 39 | const console_log = console.log; 40 | const console_error = console.error; 41 | try { 42 | console.log = function(msg) { 43 | result_log += msg + '\n'; 44 | }; 45 | console.error = function(msg) { 46 | result_error += msg + '\n'; 47 | }; 48 | basic.Basic(code); 49 | if (result_log != expected_log || 50 | (expected_error !== undefined && result_error != expected_error)) { 51 | throw 'Result:\n' + result_log + 52 | '\nExpected:\n' + expected_log + 53 | '\nResult error:\n' + result_error + 54 | '\nExpected error:\n' + expected_error; 55 | } 56 | } finally { 57 | console.log = console_log; 58 | console.error = console_error; 59 | } 60 | console.log('[ OK ]'); 61 | } 62 | 63 | exports.BASIC_TEST = BASIC_TEST; 64 | -------------------------------------------------------------------------------- /test/built-in-functions-test.js: -------------------------------------------------------------------------------- 1 | // Copyright 2018 Google LLC 2 | // 3 | // Licensed under the Apache License, Version 2.0 (the "License"); 4 | // you may not use this file except in compliance with the License. 5 | // You may obtain a copy of the License at 6 | // 7 | // https://www.apache.org/licenses/LICENSE-2.0 8 | // 9 | // Unless required by applicable law or agreed to in writing, software 10 | // distributed under the License is distributed on an "AS IS" BASIS, 11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | // See the License for the specific language governing permissions and 13 | // limitations under the License. 14 | 15 | 'use strict'; 16 | 17 | var basic_test = require('./basic-tester.js'); 18 | 19 | basic_test.BASIC_TEST('BuiltInFunctions', 'Log', ` 20 | PRINT LOG(1) 21 | PRINT LOG(8) / LOG(2) 22 | PRINT LOG(EXP(11)) 23 | `, ` 24 | 0 25 | 3 26 | 11 27 | `); 28 | 29 | basic_test.BASIC_TEST('BuiltInFunctions', 'Chr$', ` 30 | PRINT CHR$(42) 31 | PRINT CHR$(65) 32 | PRINT CHR$(97) 33 | `, ` 34 | * 35 | A 36 | a 37 | `); 38 | 39 | basic_test.BASIC_TEST('BuiltInFunctions', 'Ucase$', ` 40 | PRINT UCASE$("hello") 41 | PRINT UCASE$("Hello") 42 | PRINT UCASE$("123") 43 | `, ` 44 | HELLO 45 | HELLO 46 | 123 47 | `); 48 | 49 | basic_test.BASIC_TEST('BuiltInFunctions', 'Lcase$', ` 50 | PRINT LCASE$("hello") 51 | PRINT LCASE$("Hello") 52 | PRINT LCASE$("HI123") 53 | `, ` 54 | hello 55 | hello 56 | hi123 57 | `); 58 | 59 | basic_test.BASIC_TEST('BuiltInFunctions', 'Lcase$', ` 60 | PRINT SQR(64) 61 | PRINT SQR(4) 62 | `, ` 63 | 8 64 | 2 65 | `); 66 | 67 | basic_test.BASIC_TEST('BuiltInFunctions', 'Int', ` 68 | PRINT INT(89.91) 69 | PRINT INT(-11.12) 70 | `, ` 71 | 89 72 | -12 73 | `); 74 | 75 | basic_test.BASIC_TEST('BuiltInFunctions', 'Abs', ` 76 | PRINT ABS(88) 77 | PRINT ABS(-11) 78 | PRINT ABS(-11.25) 79 | PRINT ABS(0) 80 | `, ` 81 | 88 82 | 11 83 | 11.25 84 | 0 85 | `); 86 | 87 | basic_test.BASIC_TEST('BuiltInFunctions', 'Sin', ` 88 | PRINT SIN(0) 89 | `, ` 90 | 0 91 | `); 92 | 93 | basic_test.BASIC_TEST('BuiltInFunctions', 'Cos', ` 94 | PRINT COS(0) 95 | `, ` 96 | 1 97 | `); 98 | 99 | basic_test.BASIC_TEST('BuiltInFunctions', 'Tan', ` 100 | PRINT TAN(0) 101 | `, ` 102 | 0 103 | `); 104 | 105 | basic_test.BASIC_TEST('BuiltInFunctions', 'Exp', ` 106 | PRINT EXP(0) 107 | PRINT LOG(EXP(11)) 108 | `, ` 109 | 1 110 | 11 111 | `); 112 | 113 | basic_test.BASIC_TEST('BuiltInFunctions', 'Str$', ` 114 | PRINT STR$(123) + "aa" 115 | `, ` 116 | 123aa 117 | `); 118 | 119 | basic_test.BASIC_TEST('BuiltInFunctions', 'Str$Neg', ` 120 | PRINT STR$(-123) + "aa" 121 | `, ` 122 | -123aa 123 | `); 124 | 125 | basic_test.BASIC_TEST('BuiltInFunctions', 'Atan2', ` 126 | PRINT ATAN2(0, 1) 127 | `, ` 128 | 0 129 | `); 130 | 131 | basic_test.BASIC_TEST('BuiltInFunctions', 'Mid$', ` 132 | PRINT MID$("ABCDEFG", 2, 3) 133 | PRINT MID$("ABCDEFG", 1, 3) 134 | PRINT MID$("ABCDEFG", 3) 135 | PRINT MID$("ABCDEFG", 2, 2) 136 | `, ` 137 | BCD 138 | ABC 139 | CDEFG 140 | BC 141 | `); 142 | 143 | basic_test.BASIC_TEST('BuiltInFunctions', 'Mid$Statement', ` 144 | A$="hello" 145 | MID$(A$, 2, 2) = "xyz" 146 | PRINT A$ 147 | MID$(A$, 3) = "a" 148 | PRINT A$ 149 | `, ` 150 | hxylo 151 | hxalo 152 | `); 153 | 154 | basic_test.BASIC_TEST('BuiltInFunctions', 'Mid$StatementArray', ` 155 | DIM A$(10) 156 | A$(2)="hello" 157 | MID$(A$(2), 2, 2) = "xyz" 158 | PRINT A$(2) 159 | MID$(A$(2), 3) = "a" 160 | PRINT A$(2) 161 | `, ` 162 | hxylo 163 | hxalo 164 | `); 165 | 166 | basic_test.BASIC_TEST('BuiltInFunctions', 'Left$', ` 167 | PRINT LEFT$("ABCDEFG", 3) 168 | `, ` 169 | ABC 170 | `); 171 | 172 | basic_test.BASIC_TEST('BuiltInFunctions', 'Right$', ` 173 | PRINT RIGHT$("ABCDEFG", 3) 174 | `, ` 175 | EFG 176 | `); 177 | 178 | basic_test.BASIC_TEST('BuiltInFunctions', 'Instr', ` 179 | PRINT INSTR("hello", "el") 180 | PRINT INSTR("hello", "mo") 181 | `, ` 182 | 2 183 | 0 184 | `); 185 | 186 | basic_test.BASIC_TEST('BuiltInFunctions', 'Fix', ` 187 | PRINT FIX(45.67) 188 | PRINT FIX(-2.89) 189 | `, ` 190 | 45 191 | -2 192 | `); 193 | 194 | basic_test.BASIC_TEST('BuiltInFunctions', 'Int', ` 195 | PRINT INT(45.67) 196 | PRINT INT(-2.89) 197 | `, ` 198 | 45 199 | -3 200 | `); 201 | 202 | basic_test.BASIC_TEST('BuiltInFunctions', 'CInt', ` 203 | PRINT CINT(45.67) 204 | PRINT CINT(-2.89) 205 | `, ` 206 | 46 207 | -3 208 | `); 209 | -------------------------------------------------------------------------------- /test/comment-test.js: -------------------------------------------------------------------------------- 1 | // Copyright 2022 Google LLC 2 | // 3 | // Licensed under the Apache License, Version 2.0 (the "License"); 4 | // you may not use this file except in compliance with the License. 5 | // You may obtain a copy of the License at 6 | // 7 | // https://www.apache.org/licenses/LICENSE-2.0 8 | // 9 | // Unless required by applicable law or agreed to in writing, software 10 | // distributed under the License is distributed on an "AS IS" BASIS, 11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | // See the License for the specific language governing permissions and 13 | // limitations under the License. 14 | 15 | 'use strict'; 16 | 17 | var basic_test = require('./basic-tester.js'); 18 | 19 | basic_test.BASIC_TEST('Comment', 'Comments', ` 20 | REM This is a test! 21 | 'This is a test 22 | REM 23 | ' 24 | PRINT "hello"'This is a test 25 | PRINT "done" 26 | `, ` 27 | hello 28 | done 29 | `); 30 | -------------------------------------------------------------------------------- /test/const-test.js: -------------------------------------------------------------------------------- 1 | // Copyright 2018 Google LLC 2 | // 3 | // Licensed under the Apache License, Version 2.0 (the "License"); 4 | // you may not use this file except in compliance with the License. 5 | // You may obtain a copy of the License at 6 | // 7 | // https://www.apache.org/licenses/LICENSE-2.0 8 | // 9 | // Unless required by applicable law or agreed to in writing, software 10 | // distributed under the License is distributed on an "AS IS" BASIS, 11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | // See the License for the specific language governing permissions and 13 | // limitations under the License. 14 | 15 | 'use strict'; 16 | 17 | var basic_test = require('./basic-tester.js'); 18 | 19 | basic_test.BASIC_TEST('Const', 'AllocationLayout', ` 20 | CONST foo=314159 21 | CONST bar=100000 22 | DIM gap(100) 23 | FOR i = 0 to 100 24 | gap(i) = 0 25 | NEXT i 26 | PRINT foo 27 | PRINT bar 28 | `, ` 29 | 314159 30 | 100000 31 | `); 32 | 33 | -------------------------------------------------------------------------------- /test/copyright-test.js: -------------------------------------------------------------------------------- 1 | // Copyright 2018 Google LLC 2 | // 3 | // Licensed under the Apache License, Version 2.0 (the "License"); 4 | // you may not use this file except in compliance with the License. 5 | // You may obtain a copy of the License at 6 | // 7 | // https://www.apache.org/licenses/LICENSE-2.0 8 | // 9 | // Unless required by applicable law or agreed to in writing, software 10 | // distributed under the License is distributed on an "AS IS" BASIS, 11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | // See the License for the specific language governing permissions and 13 | // limitations under the License. 14 | 15 | 'use strict'; 16 | 17 | var fs = require('fs'); 18 | 19 | const EXCLUDED_FILENAMES = [ 20 | '.git', 21 | '.gitignore', 22 | '.gitmodules', 23 | '.npmignore', 24 | 'third_party', 25 | '.DS_Store', 26 | '.eslintrc.js', 27 | 'package.json', 28 | 'package-lock.json', 29 | 'CONTRIBUTING.md', 30 | 'LICENSE', 31 | 'README.md', 32 | 'keyboard.md', 33 | ]; 34 | 35 | const COPYRIGHT_LINE = /Copyright 20[0-9]+ Google LLC/; 36 | 37 | const LICENSE_LINES = 38 | ` 39 | Licensed under the Apache License, Version 2.0 (the "License"); 40 | you may not use this file except in compliance with the License. 41 | You may obtain a copy of the License at 42 | 43 | https://www.apache.org/licenses/LICENSE-2.0 44 | 45 | Unless required by applicable law or agreed to in writing, software 46 | distributed under the License is distributed on an "AS IS" BASIS, 47 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 48 | See the License for the specific language governing permissions and 49 | limitations under the License. 50 | `.split('\n'); 51 | 52 | console.log('Copyright header test...'); 53 | 54 | function CheckDir(path) { 55 | var files = fs.readdirSync(path); 56 | files.forEach(function(file) { 57 | if (EXCLUDED_FILENAMES.indexOf(file) >= 0) { 58 | return; 59 | } 60 | if (fs.statSync(path + file).isDirectory()) { 61 | CheckDir(path + file + '/'); 62 | } else { 63 | var data = fs.readFileSync(path + file, 'utf8'); 64 | if (data.search(COPYRIGHT_LINE) < 0) { 65 | throw 'Missing copyright line in: ' + path + file; 66 | } 67 | for (var i = 0; i < LICENSE_LINES.length; ++i) { 68 | if (data.indexOf(LICENSE_LINES[i]) < 0) { 69 | throw 'Missing license line in: ' + path + file; 70 | } 71 | } 72 | } 73 | }); 74 | } 75 | 76 | CheckDir('./'); 77 | console.log('[ OK ]'); 78 | -------------------------------------------------------------------------------- /test/deftypes-test.js: -------------------------------------------------------------------------------- 1 | // Copyright 2018 Google LLC 2 | // 3 | // Licensed under the Apache License, Version 2.0 (the "License"); 4 | // you may not use this file except in compliance with the License. 5 | // You may obtain a copy of the License at 6 | // 7 | // https://www.apache.org/licenses/LICENSE-2.0 8 | // 9 | // Unless required by applicable law or agreed to in writing, software 10 | // distributed under the License is distributed on an "AS IS" BASIS, 11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | // See the License for the specific language governing permissions and 13 | // limitations under the License. 14 | 15 | 'use strict'; 16 | 17 | var basic_test = require('./basic-tester.js'); 18 | 19 | basic_test.BASIC_TEST('DefTypes', 'Double', ` 20 | DEFDBL A-Z 21 | x = 3 / 2 22 | print x 23 | `, ` 24 | 1.5 25 | `); 26 | 27 | basic_test.BASIC_TEST('DefTypes', 'Single', ` 28 | DEFSNG A-Z 29 | x = 3 / 2 30 | print x 31 | `, ` 32 | 1.5 33 | `); 34 | 35 | basic_test.BASIC_TEST('DefTypes', 'Integer', ` 36 | DEFINT A-Z 37 | x = 3 / 2 38 | print x 39 | `, ` 40 | 1 41 | `); 42 | 43 | basic_test.BASIC_TEST('DefTypes', 'Long', ` 44 | DEFLNG A-Z 45 | x = 3 / 2 46 | print x 47 | `, ` 48 | 1 49 | `); 50 | 51 | basic_test.BASIC_TEST('DefTypes', 'String', ` 52 | DEFSTR A-Z 53 | x = "hello" 54 | print x 55 | `, ` 56 | hello 57 | `); 58 | 59 | basic_test.BASIC_TEST('DefTypes', 'BadRange', ` 60 | DEFSTR Z-A 61 | `, ` 62 | `, ` 63 | Invalid variable range at line 2 64 | `); 65 | 66 | basic_test.BASIC_TEST('DefTypes', 'Multiple', ` 67 | DEFINT A-Z 68 | DEFDBL A-B, Y-Z 69 | a = 3/2 70 | y = 3/2 71 | print a 72 | print y 73 | `, ` 74 | 1.5 75 | 1.5 76 | `); 77 | 78 | -------------------------------------------------------------------------------- /test/do-loop-while-test.js: -------------------------------------------------------------------------------- 1 | // Copyright 2018 Google LLC 2 | // 3 | // Licensed under the Apache License, Version 2.0 (the "License"); 4 | // you may not use this file except in compliance with the License. 5 | // You may obtain a copy of the License at 6 | // 7 | // https://www.apache.org/licenses/LICENSE-2.0 8 | // 9 | // Unless required by applicable law or agreed to in writing, software 10 | // distributed under the License is distributed on an "AS IS" BASIS, 11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | // See the License for the specific language governing permissions and 13 | // limitations under the License. 14 | 15 | 'use strict'; 16 | 17 | var basic_test = require('./basic-tester.js'); 18 | 19 | basic_test.BASIC_TEST('DoLoopWhile', 'OneToFive', ` 20 | i = 1 21 | DO 22 | PRINT i 23 | i = i + 1 24 | LOOP WHILE i <= 5 25 | `, ` 26 | 1 27 | 2 28 | 3 29 | 4 30 | 5 31 | `); 32 | 33 | basic_test.BASIC_TEST('DoLoopWhile', 'SixToOne', ` 34 | i = 6 35 | DO 36 | PRINT i 37 | i = i - 1 38 | LOOP WHILE i > 0 39 | `, ` 40 | 6 41 | 5 42 | 4 43 | 3 44 | 2 45 | 1 46 | `); 47 | 48 | basic_test.BASIC_TEST('DoLoopWhile', 'LoopUntilSixToOne', ` 49 | i = 6 50 | DO 51 | PRINT i 52 | i = i - 1 53 | LOOP UNTIL i = 0 54 | `, ` 55 | 6 56 | 5 57 | 4 58 | 3 59 | 2 60 | 1 61 | `); 62 | 63 | basic_test.BASIC_TEST('DoLoopWhile', 'LoopSideBySide', ` 64 | i = 6 65 | DO 66 | PRINT i 67 | i = i - 1 68 | LOOP UNTIL i = 0 69 | DO 70 | PRINT i 71 | i = i + 1 72 | LOOP UNTIL i = 4 73 | `, ` 74 | 6 75 | 5 76 | 4 77 | 3 78 | 2 79 | 1 80 | 0 81 | 1 82 | 2 83 | 3 84 | `); 85 | 86 | basic_test.BASIC_TEST('DoLoopWhile', 'JustDoLoop', ` 87 | i = 6 88 | DO 89 | PRINT i 90 | i = i - 1 91 | IF i = 0 THEN GOTO done 92 | LOOP 93 | done: 94 | `, ` 95 | 6 96 | 5 97 | 4 98 | 3 99 | 2 100 | 1 101 | `); 102 | 103 | -------------------------------------------------------------------------------- /test/for-loop-test.js: -------------------------------------------------------------------------------- 1 | // Copyright 2018 Google LLC 2 | // 3 | // Licensed under the Apache License, Version 2.0 (the "License"); 4 | // you may not use this file except in compliance with the License. 5 | // You may obtain a copy of the License at 6 | // 7 | // https://www.apache.org/licenses/LICENSE-2.0 8 | // 9 | // Unless required by applicable law or agreed to in writing, software 10 | // distributed under the License is distributed on an "AS IS" BASIS, 11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | // See the License for the specific language governing permissions and 13 | // limitations under the License. 14 | 15 | 'use strict'; 16 | 17 | var basic_test = require('./basic-tester.js'); 18 | 19 | basic_test.BASIC_TEST('ForLoop', 'OneToTen', ` 20 | FOR i = 1 to 10 21 | PRINT i 22 | NEXT i 23 | `, ` 24 | 1 25 | 2 26 | 3 27 | 4 28 | 5 29 | 6 30 | 7 31 | 8 32 | 9 33 | 10 34 | `); 35 | 36 | basic_test.BASIC_TEST('ForLoop', 'OneToTenStep2', ` 37 | FOR i = 1 to 10 STEP 2 38 | PRINT i 39 | NEXT i 40 | `, ` 41 | 1 42 | 3 43 | 5 44 | 7 45 | 9 46 | `); 47 | 48 | basic_test.BASIC_TEST('ForLoop', 'OneToTenStep3', ` 49 | FOR i = 1 to 10 STEP 3 50 | PRINT i 51 | NEXT i 52 | `, ` 53 | 1 54 | 4 55 | 7 56 | 10 57 | `); 58 | 59 | basic_test.BASIC_TEST('ForLoop', 'TenToOneStepMinusOne', ` 60 | FOR i = 10 to 1 STEP -1 61 | PRINT i 62 | NEXT i 63 | `, ` 64 | 10 65 | 9 66 | 8 67 | 7 68 | 6 69 | 5 70 | 4 71 | 3 72 | 2 73 | 1 74 | `); 75 | 76 | basic_test.BASIC_TEST('ForLoop', 'Nested3', ` 77 | FOR i = 1 to 3 78 | FOR j = 1 to 3 79 | PRINT i; " "; j 80 | NEXT j 81 | NEXT i 82 | `, ` 83 | 1 1 84 | 1 2 85 | 1 3 86 | 2 1 87 | 2 2 88 | 2 3 89 | 3 1 90 | 3 2 91 | 3 3 92 | `); 93 | 94 | -------------------------------------------------------------------------------- /test/formatting-test.js: -------------------------------------------------------------------------------- 1 | // Copyright 2018 Google LLC 2 | // 3 | // Licensed under the Apache License, Version 2.0 (the "License"); 4 | // you may not use this file except in compliance with the License. 5 | // You may obtain a copy of the License at 6 | // 7 | // https://www.apache.org/licenses/LICENSE-2.0 8 | // 9 | // Unless required by applicable law or agreed to in writing, software 10 | // distributed under the License is distributed on an "AS IS" BASIS, 11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | // See the License for the specific language governing permissions and 13 | // limitations under the License. 14 | 15 | 'use strict'; 16 | 17 | var basic_test = require('./basic-tester.js'); 18 | 19 | basic_test.BASIC_TEST('Formatting', 'CRLF', 20 | 'FOR i = 1 TO 3\r\n' + 21 | ' PRINT i\r\n' + 22 | 'NEXT i\r\n' 23 | , ` 24 | 1 25 | 2 26 | 3 27 | `); 28 | 29 | basic_test.BASIC_TEST('Formatting', 'Tabs', 30 | 'FOR i = 1 TO 3\n' + 31 | '\tPRINT i\n' + 32 | 'NEXT i\n' 33 | , ` 34 | 1 35 | 2 36 | 3 37 | `); 38 | 39 | -------------------------------------------------------------------------------- /test/functions-test.js: -------------------------------------------------------------------------------- 1 | // Copyright 2018 Google LLC 2 | // 3 | // Licensed under the Apache License, Version 2.0 (the "License"); 4 | // you may not use this file except in compliance with the License. 5 | // You may obtain a copy of the License at 6 | // 7 | // https://www.apache.org/licenses/LICENSE-2.0 8 | // 9 | // Unless required by applicable law or agreed to in writing, software 10 | // distributed under the License is distributed on an "AS IS" BASIS, 11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | // See the License for the specific language governing permissions and 13 | // limitations under the License. 14 | 15 | 'use strict'; 16 | 17 | var basic_test = require('./basic-tester.js'); 18 | 19 | basic_test.BASIC_TEST('Functions', 'Classic', ` 20 | DEF FNdist(x, y) = SQR(x^2 + y^2) 21 | a = 3 22 | b = 4 23 | PRINT FNdist(a, b) 24 | `, ` 25 | 5 26 | `); 27 | 28 | basic_test.BASIC_TEST('Functions', 'ClassicArgless', ` 29 | a$ = "hello" 30 | b$ = "..." 31 | DEF fnfoo$ = a$ + b$ 32 | print fnfoo$ 33 | a$ = "there" 34 | print fnfoo$ 35 | `, ` 36 | hello... 37 | there... 38 | `); 39 | 40 | basic_test.BASIC_TEST('Functions', 'NewStyle', ` 41 | FUNCTION Dist(x, y) 42 | Dist = SQR(x^2 + y^2) 43 | END FUNCTION 44 | a = 3 45 | b = 4 46 | PRINT Dist(a, b) 47 | `, ` 48 | 5 49 | `); 50 | 51 | basic_test.BASIC_TEST('Functions', 'CallLayers', ` 52 | FUNCTION Inc(x) 53 | Inc = x + 1 54 | END FUNCTION 55 | PRINT Inc(Inc(Inc(Inc(3)))) 56 | `, ` 57 | 7 58 | `); 59 | 60 | basic_test.BASIC_TEST('Functions', 'DefLayers', ` 61 | FUNCTION Baz(x) 62 | Baz = x * 2 63 | END FUNCTION 64 | 65 | FUNCTION Bar(x) 66 | Bar = Baz(x) * 3 67 | END FUNCTION 68 | 69 | FUNCTION Foo(x) 70 | Foo = Bar(x) * 5 71 | END FUNCTION 72 | 73 | a = 1 74 | PRINT Foo(a) 75 | `, ` 76 | 30 77 | `); 78 | 79 | basic_test.BASIC_TEST('Functions', 'RecursiveImplicit', ` 80 | FUNCTION Factorial(n) 81 | IF n = 0 OR n = 1 THEN 82 | Factorial = 1 83 | ELSE 84 | Factorial = n * Factorial(n - 1) 85 | END IF 86 | END FUNCTION 87 | 88 | a = 4 89 | PRINT Factorial(a) 90 | `, ` 91 | 24 92 | `); 93 | 94 | basic_test.BASIC_TEST('Functions', 'RecursiveExplicit', ` 95 | FUNCTION Factorial(n AS INTEGER) AS INTEGER 96 | IF n = 0 OR n = 1 THEN 97 | Factorial = 1 98 | ELSE 99 | Factorial = n * Factorial(n - 1) 100 | END IF 101 | END FUNCTION 102 | 103 | a = 4 104 | PRINT Factorial(a) 105 | `, ` 106 | 24 107 | `); 108 | 109 | basic_test.BASIC_TEST('Functions', 'RecursiveExplicitWithLocal', ` 110 | FUNCTION Factorial(n AS INTEGER) AS INTEGER 111 | IF n = 0 OR n = 1 THEN 112 | Factorial = 1 113 | ELSE 114 | temp = n * Factorial(n - 1) 115 | Factorial = temp 116 | END IF 117 | END FUNCTION 118 | 119 | a = 4 120 | PRINT Factorial(a) 121 | `, ` 122 | 24 123 | `); 124 | 125 | basic_test.BASIC_TEST('Functions', 'Predeclare', ` 126 | DECLARE FUNCTION Adder(x AS INTEGER, y AS INTEGER) AS INTEGER 127 | PRINT Adder(1, 2) 128 | FUNCTION Adder(x AS INTEGER, y AS INTEGER) AS INTEGER 129 | Adder = x + y 130 | END FUNCTION 131 | `, ` 132 | 3 133 | `); 134 | 135 | basic_test.BASIC_TEST('Functions', 'ByRef', ` 136 | FUNCTION Changer(x as INTEGER) 137 | x = 2 138 | Changer = 3 139 | END FUNCTION 140 | a = 1 141 | PRINT Changer(a) 142 | PRINT a 143 | `, ` 144 | 3 145 | 2 146 | `); 147 | 148 | basic_test.BASIC_TEST('Functions', 'Multi', ` 149 | FUNCTION Plus1(x as INTEGER) 150 | Plus1 = x + 1 151 | END FUNCTION 152 | PRINT Plus1(3) + Plus1(4) + Plus1(6) 153 | `, ` 154 | 16 155 | `); 156 | 157 | basic_test.BASIC_TEST('Functions', 'TreeSize', ` 158 | FUNCTION TreeSize(n) 159 | IF n = 1 THEN 160 | TreeSize = 1 161 | ELSE 162 | TreeSize = TreeSize(n - 1) + TreeSize(n - 1) + 1 163 | END IF 164 | END FUNCTION 165 | PRINT TreeSize(5) 166 | `, ` 167 | 31 168 | `); 169 | 170 | basic_test.BASIC_TEST('Subroutines', 'Depth', ` 171 | a = stackdepth() 172 | b = basedepth() 173 | 174 | FUNCTION Foo(a$) 175 | b$ = a$ 176 | print "Foo sp: "; stackdepth() - a 177 | print "Foo bp: "; basedepth() - b 178 | Foo = 1 179 | END FUNCTION 180 | 181 | FUNCTION Bar() 182 | print "Bar sp: "; stackdepth() - a 183 | print "Bar bp: "; basedepth() - b 184 | Bar = Foo("hi") 185 | print "Bar sp: "; stackdepth() - a 186 | print "Bar bp: "; basedepth() - b 187 | END FUNCTION 188 | 189 | print "Root sp: "; stackdepth() - a 190 | print "Root bp: "; basedepth() - b 191 | PRINT Bar() 192 | print "Root sp: "; stackdepth() - a 193 | print "Root bp: "; basedepth() - b 194 | `, ` 195 | Root sp: 0 196 | Root bp: 0 197 | Bar sp: 32 198 | Bar bp: 8 199 | Foo sp: 72 200 | Foo bp: 40 201 | Bar sp: 32 202 | Bar bp: 8 203 | 1 204 | Root sp: 0 205 | Root bp: 0 206 | `); 207 | 208 | -------------------------------------------------------------------------------- /test/if-else-test.js: -------------------------------------------------------------------------------- 1 | // Copyright 2018 Google LLC 2 | // 3 | // Licensed under the Apache License, Version 2.0 (the "License"); 4 | // you may not use this file except in compliance with the License. 5 | // You may obtain a copy of the License at 6 | // 7 | // https://www.apache.org/licenses/LICENSE-2.0 8 | // 9 | // Unless required by applicable law or agreed to in writing, software 10 | // distributed under the License is distributed on an "AS IS" BASIS, 11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | // See the License for the specific language governing permissions and 13 | // limitations under the License. 14 | 15 | 'use strict'; 16 | 17 | var basic_test = require('./basic-tester.js'); 18 | 19 | basic_test.BASIC_TEST('IfElse', 'SingleThen', ` 20 | i = 1 21 | x = 0 22 | FOR i = 1 TO 5 23 | IF i = 4 THEN x = i 24 | NEXT i 25 | PRINT x 26 | `, ` 27 | 4 28 | `); 29 | 30 | basic_test.BASIC_TEST('IfElse', 'SingleThenColon', ` 31 | i = 1 32 | x = 0 33 | FOR i = 1 TO 5 34 | IF i = 4 THEN x = i : x = 9 35 | NEXT i 36 | PRINT x 37 | `, ` 38 | 9 39 | `); 40 | 41 | basic_test.BASIC_TEST('IfElse', 'SingleThenEndIf', ` 42 | i = 1 43 | x = 0 44 | FOR i = 1 to 5 45 | IF i = 4 THEN : x = i END IF 46 | NEXT i 47 | PRINT x 48 | `, ` 49 | 4 50 | `); 51 | 52 | basic_test.BASIC_TEST('IfElse', 'SingleThenElseEndIf', ` 53 | i = 1 54 | x = 0 55 | y = 0 56 | FOR i = 1 to 5 57 | IF i = 4 THEN : x = i ELSE : y = i END IF 58 | NEXT i 59 | PRINT x 60 | PRINT y 61 | `, ` 62 | 4 63 | 5 64 | `); 65 | basic_test.BASIC_TEST('IfElse', 'MultiThenEndIf', ` 66 | i = 1 67 | x = 0 68 | FOR i = 1 to 5 69 | IF i = 4 THEN 70 | x = i 71 | END IF 72 | NEXT i 73 | PRINT x 74 | `, ` 75 | 4 76 | `); 77 | 78 | basic_test.BASIC_TEST('IfElse', 'MultiThenElseEndIf', ` 79 | i = 1 80 | x = 0 81 | y = 0 82 | FOR i = 1 to 5 83 | IF i = 4 THEN 84 | x = i 85 | ELSE 86 | y = i 87 | END IF 88 | NEXT i 89 | PRINT x 90 | PRINT y 91 | `, ` 92 | 4 93 | 5 94 | `); 95 | 96 | basic_test.BASIC_TEST('IfElse', 'MultiThenElseElseIfEndIf', ` 97 | i = 1 98 | x = 0 99 | y = 0 100 | z = 0 101 | FOR i = 1 to 5 102 | IF i = 4 THEN 103 | x = i 104 | ELSEIF i = 2 THEN 105 | z = i 106 | ELSEIF i = 3 THEN 107 | z = i 108 | ELSE 109 | y = i 110 | END IF 111 | NEXT i 112 | PRINT x 113 | PRINT y 114 | PRINT z 115 | `, ` 116 | 4 117 | 5 118 | 3 119 | `); 120 | 121 | basic_test.BASIC_TEST('IfElse', 'LessMultiThenElseElseIfEndIf', ` 122 | pz = 0 123 | IF pz < 1 Then 124 | pz = 1 125 | ELSEIF PZ > 80000/3 Then 126 | pz = 80000/3 127 | END IF 128 | PRINT pz 129 | `, ` 130 | 1 131 | `); 132 | 133 | -------------------------------------------------------------------------------- /test/labels-test.js: -------------------------------------------------------------------------------- 1 | // Copyright 2018 Google LLC 2 | // 3 | // Licensed under the Apache License, Version 2.0 (the "License"); 4 | // you may not use this file except in compliance with the License. 5 | // You may obtain a copy of the License at 6 | // 7 | // https://www.apache.org/licenses/LICENSE-2.0 8 | // 9 | // Unless required by applicable law or agreed to in writing, software 10 | // distributed under the License is distributed on an "AS IS" BASIS, 11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | // See the License for the specific language governing permissions and 13 | // limitations under the License. 14 | 15 | 'use strict'; 16 | 17 | var basic_test = require('./basic-tester.js'); 18 | 19 | basic_test.BASIC_TEST('Labels', 'LabelSimpleLoop', ` 20 | i = 1 21 | Again: 22 | PRINT i 23 | i = i + 1 24 | IF i <> 5 THEN GOTO Again 25 | PRINT "done" 26 | `, ` 27 | 1 28 | 2 29 | 3 30 | 4 31 | done 32 | `); 33 | 34 | basic_test.BASIC_TEST('Labels', 'LineNumberSimpleLoop', ` 35 | 10 i = 1 36 | 20 PRINT i 37 | 30 i = i + 1 38 | 40 IF i <> 5 THEN GOTO 20 39 | 50 PRINT "done" 40 | `, ` 41 | 1 42 | 2 43 | 3 44 | 4 45 | done 46 | `); 47 | 48 | -------------------------------------------------------------------------------- /test/on-gosub-test.js: -------------------------------------------------------------------------------- 1 | // Copyright 2018 Google LLC 2 | // 3 | // Licensed under the Apache License, Version 2.0 (the "License"); 4 | // you may not use this file except in compliance with the License. 5 | // You may obtain a copy of the License at 6 | // 7 | // https://www.apache.org/licenses/LICENSE-2.0 8 | // 9 | // Unless required by applicable law or agreed to in writing, software 10 | // distributed under the License is distributed on an "AS IS" BASIS, 11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | // See the License for the specific language governing permissions and 13 | // limitations under the License. 14 | 15 | 'use strict'; 16 | 17 | var basic_test = require('./basic-tester.js'); 18 | 19 | basic_test.BASIC_TEST('OnGosub', 'TwoSubroutines', ` 20 | FOR i%=1 TO 2 21 | ON i% GOSUB One, Two 22 | NEXT i% 23 | PRINT "done" 24 | END 25 | One: 26 | PRINT i% 27 | RETURN 28 | Two: 29 | PRINT i% 30 | RETURN 31 | `, ` 32 | 1 33 | 2 34 | done 35 | `); 36 | 37 | basic_test.BASIC_TEST('OnGosub', 'SubroutineAtLines', ` 38 | 10 FOR i=1 TO 2 39 | 20 ON i GOSUB 60,80 40 | 30 NEXT i 41 | 40 PRINT "done" 42 | 50 END 43 | 60 PRINT "1" 44 | 70 RETURN 45 | 80 PRINT "2" 46 | 90 RETURN 47 | `, ` 48 | 1 49 | 2 50 | done 51 | `); 52 | 53 | basic_test.BASIC_TEST('OnGosub', 'OutOfRange', ` 54 | ON 0 GOSUB a,b 55 | ON 5 GOSUB a,b 56 | ON 3 GOSUB a,b,c 57 | PRINT "done" 58 | END 59 | a: 60 | PRINT "a" 61 | RETURN 62 | b: 63 | PRINT "b" 64 | RETURN 65 | `, ` 66 | done 67 | `); 68 | 69 | -------------------------------------------------------------------------------- /test/on-goto-test.js: -------------------------------------------------------------------------------- 1 | // Copyright 2018 Google LLC 2 | // 3 | // Licensed under the Apache License, Version 2.0 (the "License"); 4 | // you may not use this file except in compliance with the License. 5 | // You may obtain a copy of the License at 6 | // 7 | // https://www.apache.org/licenses/LICENSE-2.0 8 | // 9 | // Unless required by applicable law or agreed to in writing, software 10 | // distributed under the License is distributed on an "AS IS" BASIS, 11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | // See the License for the specific language governing permissions and 13 | // limitations under the License. 14 | 15 | 'use strict'; 16 | 17 | var basic_test = require('./basic-tester.js'); 18 | 19 | basic_test.BASIC_TEST('OnGoto', 'JumpInOrder', ` 20 | x = 1 21 | ON x GOTO a,b,c 22 | END 23 | a: 24 | PRINT "1" 25 | x = x + 1 26 | ON x GOTO a,b,c 27 | END 28 | b: 29 | PRINT "2" 30 | ON x+1 GOTO a,b,c 31 | END 32 | c: 33 | PRINT "3" 34 | PRINT "done" 35 | END 36 | `, ` 37 | 1 38 | 2 39 | 3 40 | done 41 | `); 42 | 43 | basic_test.BASIC_TEST('OnGoto', 'OutOfRange', ` 44 | ON 5 GOTO a,b 45 | PRINT "done" 46 | END 47 | a: 48 | END 49 | b: 50 | END 51 | `, ` 52 | done 53 | `); 54 | 55 | -------------------------------------------------------------------------------- /test/option-base-test.js: -------------------------------------------------------------------------------- 1 | // Copyright 2018 Google LLC 2 | // 3 | // Licensed under the Apache License, Version 2.0 (the "License"); 4 | // you may not use this file except in compliance with the License. 5 | // You may obtain a copy of the License at 6 | // 7 | // https://www.apache.org/licenses/LICENSE-2.0 8 | // 9 | // Unless required by applicable law or agreed to in writing, software 10 | // distributed under the License is distributed on an "AS IS" BASIS, 11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | // See the License for the specific language governing permissions and 13 | // limitations under the License. 14 | 15 | 'use strict'; 16 | 17 | var basic_test = require('./basic-tester.js'); 18 | 19 | basic_test.BASIC_TEST('OptionBase', 'Zero', ` 20 | OPTION BASE 0 21 | DIM a(10) 22 | FOR i = 0 to 10 23 | a(i) = i + 1 24 | NEXT i 25 | t = 0 26 | FOR i = 0 to 10 27 | t = t + a(i) 28 | NEXT i 29 | PRINT t 30 | `, ` 31 | 66 32 | `); 33 | 34 | basic_test.BASIC_TEST('OptionBase', 'One', ` 35 | OPTION BASE 1 36 | DIM a(10) 37 | FOR i = 1 to 10 38 | a(i) = i + 1 39 | NEXT i 40 | t = 0 41 | FOR i = 1 to 10 42 | t = t + a(i) 43 | NEXT i 44 | PRINT t 45 | `, ` 46 | 65 47 | `, ` 48 | `); 49 | 50 | basic_test.BASIC_TEST('OptionBase', 'Bad', ` 51 | OPTION BASE 2 52 | `, ` 53 | `, ` 54 | Unexpected option base "2" at line 1 55 | `); 56 | 57 | 58 | -------------------------------------------------------------------------------- /test/primes-example-test.js: -------------------------------------------------------------------------------- 1 | // Copyright 2018 Google LLC 2 | // 3 | // Licensed under the Apache License, Version 2.0 (the "License"); 4 | // you may not use this file except in compliance with the License. 5 | // You may obtain a copy of the License at 6 | // 7 | // https://www.apache.org/licenses/LICENSE-2.0 8 | // 9 | // Unless required by applicable law or agreed to in writing, software 10 | // distributed under the License is distributed on an "AS IS" BASIS, 11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | // See the License for the specific language governing permissions and 13 | // limitations under the License. 14 | 15 | 'use strict'; 16 | 17 | var basic_test = require('./basic-tester.js'); 18 | 19 | function First3000Primes() { 20 | var expected_primes = [2]; 21 | main: for (var i = 3; i <= 300; i += 2) { 22 | for (var j = 3; j < i; ++j) { 23 | if (i % j == 0) { 24 | continue main; 25 | } 26 | } 27 | expected_primes.push(i); 28 | } 29 | return expected_primes; 30 | } 31 | 32 | basic_test.BASIC_TEST('PrimesExample', 'Test', ` 33 | DECLARE FUNCTION GetLengthOfNumber(n) 34 | 35 | PRINT 2; " "; 36 | FOR i = 3 TO 300 STEP 2 37 | numLength = GetLengthOfNumber(i) + 1 38 | FOR j = 3 TO i / numLength STEP 2 39 | IF i MOD j = 0 THEN GOTO NotPrime 40 | NEXT j 41 | PRINT i; " "; 42 | NotPrime: 43 | NEXT i 44 | PRINT 45 | PRINT "done" 46 | END 47 | 48 | FUNCTION GetLengthOfNumber(n) 49 | digits = 1 50 | WHILE digits > 9 51 | digits = digits + 1 52 | n = n / 10 53 | WEND 54 | GetLengthOfNumber = digits 55 | END FUNCTION 56 | `, 57 | First3000Primes().join(' ') + ' \ndone\n'); 58 | 59 | -------------------------------------------------------------------------------- /test/print-using-test.js: -------------------------------------------------------------------------------- 1 | // Copyright 2018 Google LLC 2 | // 3 | // Licensed under the Apache License, Version 2.0 (the "License"); 4 | // you may not use this file except in compliance with the License. 5 | // You may obtain a copy of the License at 6 | // 7 | // https://www.apache.org/licenses/LICENSE-2.0 8 | // 9 | // Unless required by applicable law or agreed to in writing, software 10 | // distributed under the License is distributed on an "AS IS" BASIS, 11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | // See the License for the specific language governing permissions and 13 | // limitations under the License. 14 | 15 | 'use strict'; 16 | 17 | var basic_test = require('./basic-tester.js'); 18 | 19 | basic_test.BASIC_TEST('PrintUsing', 'SimpleDecimal', ` 20 | PRINT USING "abc #.#### def"; 1.23 21 | `, ` 22 | abc 1.2300 def 23 | `); 24 | 25 | basic_test.BASIC_TEST('PrintUsing', 'CommaSimpleDecimal', ` 26 | PRINT USING "abc ##,###.#### def"; 8989.23 27 | `, ` 28 | abc 8,989.2300 def 29 | `); 30 | 31 | basic_test.BASIC_TEST('PrintUsing', 'CommaUnusedSimpleDecimal', ` 32 | PRINT USING "abc ##,###.#### def"; 989.23 33 | `, ` 34 | abc 989.2300 def 35 | `); 36 | 37 | basic_test.BASIC_TEST('PrintUsing', 'SimpleInteger', ` 38 | PRINT USING "abc ##### def"; 8989.23 39 | `, ` 40 | abc 8989 def 41 | `); 42 | 43 | basic_test.BASIC_TEST('PrintUsing', 'CommaSimpleInteger', ` 44 | PRINT USING "abc ##,### def"; 8989.23 45 | `, ` 46 | abc 8,989 def 47 | `); 48 | 49 | basic_test.BASIC_TEST('PrintUsing', 'CommaUnusedSimpleInteger', ` 50 | PRINT USING "abc ##,### def"; 989.23 51 | `, ` 52 | abc 989 def 53 | `); 54 | 55 | basic_test.BASIC_TEST('PrintUsing', 'Overflow', ` 56 | PRINT USING "abc ##,### def"; 123456 57 | `, ` 58 | abc ****** def 59 | `); 60 | 61 | basic_test.BASIC_TEST('PrintUsing', 'Multiple', ` 62 | PRINT USING "abc ##,### def ##,### ghi"; 123456; 23456 63 | PRINT USING "abc #,### def ##,### ghi"; 1456; 23456 64 | `, ` 65 | abc ****** def 23,456 ghi 66 | abc 1,456 def 23,456 ghi 67 | `); 68 | 69 | -------------------------------------------------------------------------------- /test/read-data-test.js: -------------------------------------------------------------------------------- 1 | // Copyright 2018 Google LLC 2 | // 3 | // Licensed under the Apache License, Version 2.0 (the "License"); 4 | // you may not use this file except in compliance with the License. 5 | // You may obtain a copy of the License at 6 | // 7 | // https://www.apache.org/licenses/LICENSE-2.0 8 | // 9 | // Unless required by applicable law or agreed to in writing, software 10 | // distributed under the License is distributed on an "AS IS" BASIS, 11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | // See the License for the specific language governing permissions and 13 | // limitations under the License. 14 | 15 | 'use strict'; 16 | 17 | var basic_test = require('./basic-tester.js'); 18 | 19 | basic_test.BASIC_TEST('ReadData', 'NumbersSingleLine', ` 20 | FOR i = 1 to 5 21 | READ x 22 | PRINT x 23 | NEXT i 24 | DATA 11, 15, 19, 33, 6 25 | `, ` 26 | 11 27 | 15 28 | 19 29 | 33 30 | 6 31 | `); 32 | 33 | basic_test.BASIC_TEST('ReadData', 'NumbersMultiLine', ` 34 | FOR i = 1 to 3 35 | READ x, y 36 | PRINT x; ", "; y 37 | NEXT i 38 | DATA 11, 15, 19, 33, 6 39 | DATA 3 40 | `, ` 41 | 11, 15 42 | 19, 33 43 | 6, 3 44 | `); 45 | 46 | basic_test.BASIC_TEST('ReadData', 'Strings', ` 47 | FOR i = 1 to 4 48 | READ a$ 49 | PRINT "|"; a$; "|" 50 | NEXT i 51 | DATA this is , a test, " of , strings " 52 | DATA that's it 53 | `, ` 54 | |this is| 55 | |a test| 56 | | of , strings | 57 | |that's it| 58 | `); 59 | 60 | basic_test.BASIC_TEST('ReadData', 'Restore', ` 61 | FOR i = 1 to 3 62 | READ x 63 | PRINT x 64 | NEXT i 65 | RESTORE 101 66 | FOR i = 1 to 2 67 | READ x 68 | PRINT x 69 | NEXT i 70 | 100 DATA 123 71 | 101 DATA 234 72 | 102 DATA 345 73 | `, ` 74 | 123 75 | 234 76 | 345 77 | 234 78 | 345 79 | `); 80 | 81 | -------------------------------------------------------------------------------- /test/run-tests.sh: -------------------------------------------------------------------------------- 1 | #! /bin/bash 2 | # Copyright 2018 Google LLC 3 | # 4 | # Licensed under the Apache License, Version 2.0 (the "License"); 5 | # you may not use this file except in compliance with the License. 6 | # You may obtain a copy of the License at 7 | # 8 | # https://www.apache.org/licenses/LICENSE-2.0 9 | # 10 | # Unless required by applicable law or agreed to in writing, software 11 | # distributed under the License is distributed on an "AS IS" BASIS, 12 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | # See the License for the specific language governing permissions and 14 | # limitations under the License. 15 | 16 | set -e 17 | 18 | # Move to root of project. 19 | SCRIPT_DIR="$(cd "$(dirname "$0")" && pwd -P)" 20 | cd ${SCRIPT_DIR}/.. 21 | 22 | # Run tests. 23 | for x in $(ls ./test/*-test.js); do 24 | node $x 25 | done 26 | 27 | # Run linter. 28 | echo "Linting..." 29 | ./tools/lint.sh 30 | echo "[ OK ]" 31 | 32 | # Make sure keyword dumper runs. 33 | echo "Keyword dumping..." 34 | ./tools/keyword_dump.js >/dev/null 35 | echo "[ OK ]" 36 | 37 | # Test packaging. 38 | echo "Test packaging..." 39 | npm publish --dry-run >/dev/null 2>/dev/null 40 | echo "[ OK ]" 41 | -------------------------------------------------------------------------------- /test/subroutines-test.js: -------------------------------------------------------------------------------- 1 | // Copyright 2018 Google LLC 2 | // 3 | // Licensed under the Apache License, Version 2.0 (the "License"); 4 | // you may not use this file except in compliance with the License. 5 | // You may obtain a copy of the License at 6 | // 7 | // https://www.apache.org/licenses/LICENSE-2.0 8 | // 9 | // Unless required by applicable law or agreed to in writing, software 10 | // distributed under the License is distributed on an "AS IS" BASIS, 11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | // See the License for the specific language governing permissions and 13 | // limitations under the License. 14 | 15 | 'use strict'; 16 | 17 | var basic_test = require('./basic-tester.js'); 18 | 19 | basic_test.BASIC_TEST('Subroutines', 'Simple', ` 20 | SUB MyPrint(x AS INTEGER, y AS DOUBLE) 21 | PRINT x; " oh "; y 22 | END SUB 23 | MyPrint 123, 12.5 24 | CALL MyPrint(456, 2.5) 25 | `, ` 26 | 123 oh 12.5 27 | 456 oh 2.5 28 | `); 29 | 30 | basic_test.BASIC_TEST('Subroutines', 'Predeclare', ` 31 | DECLARE SUB MyPrint(x AS INTEGER) 32 | MyPrint 123 33 | CALL MyPrint(456) 34 | SUB MyPrint(x AS INTEGER) 35 | PRINT x 36 | END SUB 37 | `, ` 38 | 123 39 | 456 40 | `); 41 | 42 | basic_test.BASIC_TEST('Subroutines', 'NoArgsNestedWithLocal', ` 43 | DECLARE SUB DumpIt() 44 | SUB DumpIt() 45 | x = 1 46 | PRINT "hello there" 47 | END SUB 48 | SUB DoIt2() 49 | PRINT "a" 50 | DumpIt 51 | PRINT "b" 52 | DumpIt 53 | PRINT "c" 54 | END SUB 55 | DoIt2 56 | `, ` 57 | a 58 | hello there 59 | b 60 | hello there 61 | c 62 | `); 63 | 64 | basic_test.BASIC_TEST('Subroutines', 'StringArg1', ` 65 | SUB MyPrint(msg$) 66 | PRINT "|"; msg$; "|" 67 | END SUB 68 | level = 5 69 | MyPrint "Hello there " + STR$(level) + " It" 70 | `, ` 71 | |Hello there 5 It| 72 | `); 73 | 74 | basic_test.BASIC_TEST('Subroutines', 'StringArg2', ` 75 | SUB MyPrint(spaces, msg$) 76 | PRINT SPACE$(spaces); msg$ 77 | END SUB 78 | myPrint 2, "Hello there" 79 | `, ` 80 | Hello there 81 | `); 82 | 83 | basic_test.BASIC_TEST('Subroutines', 'NestedWithStrings', ` 84 | SUB Func1(a$) 85 | PRINT a$ 86 | END SUB 87 | SUB Func2(t, a$) 88 | Func1 STR$(t) + a$ 89 | END SUB 90 | Func2 2, "hi" 91 | `, ` 92 | 2hi 93 | `); 94 | 95 | basic_test.BASIC_TEST('Subroutines', 'NestedWithStringsAndDecl', ` 96 | DECLARE SUB Func1 (text$) 97 | DECLARE SUB Func2 (t, text$) 98 | SUB Func1(text$) 99 | PRINT text$ 100 | END SUB 101 | SUB Func2(t, text$) 102 | Func1 STR$(t) + text$ 103 | END SUB 104 | Func2 3, "hi" + STR$(5) + "there" 105 | `, ` 106 | 3hi 5there 107 | `); 108 | 109 | basic_test.BASIC_TEST('Subroutines', 'ByRef', ` 110 | SUB MySwap(x as INTEGER, y as INTEGER) 111 | t = x 112 | x = y 113 | y = t 114 | END SUB 115 | a = 2 116 | b = 3 117 | MySwap a, b 118 | PRINT a 119 | PRINT b 120 | `, ` 121 | 3 122 | 2 123 | `); 124 | 125 | basic_test.BASIC_TEST('Subroutines', 'Depth', ` 126 | a = stackdepth() 127 | b = basedepth() 128 | 129 | SUB Foo(a$) 130 | b$ = a$ 131 | print "Foo sp: "; stackdepth() - a 132 | print "Foo bp: "; basedepth() - b 133 | END SUB 134 | 135 | SUB Bar 136 | print "Bar sp: "; stackdepth() - a 137 | print "Bar bp: "; basedepth() - b 138 | Foo "hi" 139 | print "Bar sp: "; stackdepth() - a 140 | print "Bar bp: "; basedepth() - b 141 | END SUB 142 | 143 | print "Root sp: "; stackdepth() - a 144 | print "Root bp: "; basedepth() - b 145 | Bar 146 | print "Root sp: "; stackdepth() - a 147 | print "Root bp: "; basedepth() - b 148 | `, ` 149 | Root sp: 0 150 | Root bp: 0 151 | Bar sp: 24 152 | Bar bp: 8 153 | Foo sp: 64 154 | Foo bp: 32 155 | Bar sp: 24 156 | Bar bp: 8 157 | Root sp: 0 158 | Root bp: 0 159 | `); 160 | 161 | -------------------------------------------------------------------------------- /test/swap-test.js: -------------------------------------------------------------------------------- 1 | // Copyright 2022 Google LLC 2 | // 3 | // Licensed under the Apache License, Version 2.0 (the "License"); 4 | // you may not use this file except in compliance with the License. 5 | // You may obtain a copy of the License at 6 | // 7 | // https://www.apache.org/licenses/LICENSE-2.0 8 | // 9 | // Unless required by applicable law or agreed to in writing, software 10 | // distributed under the License is distributed on an "AS IS" BASIS, 11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | // See the License for the specific language governing permissions and 13 | // limitations under the License. 14 | 15 | 'use strict'; 16 | 17 | var basic_test = require('./basic-tester.js'); 18 | 19 | basic_test.BASIC_TEST('Swap', 'SwapNumbers', ` 20 | x = 1 21 | y = 100 22 | swap x, y 23 | print x 24 | print y 25 | print "done" 26 | `, ` 27 | 100 28 | 1 29 | done 30 | `); 31 | 32 | basic_test.BASIC_TEST('Swap', 'SwapStrings', ` 33 | a$ = "hello" 34 | b$ = "there" 35 | swap a$, b$ 36 | print a$ 37 | print b$ 38 | print "done" 39 | `, ` 40 | there 41 | hello 42 | done 43 | `); 44 | -------------------------------------------------------------------------------- /test/type-test.js: -------------------------------------------------------------------------------- 1 | // Copyright 2018 Google LLC 2 | // 3 | // Licensed under the Apache License, Version 2.0 (the "License"); 4 | // you may not use this file except in compliance with the License. 5 | // You may obtain a copy of the License at 6 | // 7 | // https://www.apache.org/licenses/LICENSE-2.0 8 | // 9 | // Unless required by applicable law or agreed to in writing, software 10 | // distributed under the License is distributed on an "AS IS" BASIS, 11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | // See the License for the specific language governing permissions and 13 | // limitations under the License. 14 | 15 | 'use strict'; 16 | 17 | var basic_test = require('./basic-tester.js'); 18 | 19 | basic_test.BASIC_TEST('Type', 'InvalidType', ` 20 | DIM x AS SINGLE 21 | PRINT x.y 22 | `, ` 23 | `, ` 24 | Not a struct type at line 2 25 | `); 26 | 27 | basic_test.BASIC_TEST('Type', 'InvalidField', ` 28 | TYPE vector 29 | x AS SINGLE 30 | y AS SINGLE 31 | END TYPE 32 | 33 | DIM v AS vector 34 | PRINT v.z 35 | `, ` 36 | `, ` 37 | Invalid field name at line 7 38 | `); 39 | 40 | basic_test.BASIC_TEST('Type', 'Simple', ` 41 | TYPE vector 42 | x AS SINGLE 43 | y AS SINGLE 44 | END TYPE 45 | 46 | DIM u AS vector 47 | DIM v AS vector 48 | 49 | u.x = 1 50 | u.y = 2 51 | v.x = 3 52 | v.y = 4 53 | 54 | PRINT u.x 55 | PRINT u.y 56 | PRINT v.x 57 | PRINT v.y 58 | `, ` 59 | 1 60 | 2 61 | 3 62 | 4 63 | `); 64 | 65 | basic_test.BASIC_TEST('Type', 'Array', ` 66 | TYPE vector 67 | x AS SINGLE 68 | y AS SINGLE 69 | END TYPE 70 | 71 | DIM points(10) AS vector 72 | 73 | FOR i = 1 to 10 74 | points(i).x = i 75 | points(i).y = i + 1 76 | NEXT i 77 | 78 | total = 0 79 | FOR i = 1 to 10 80 | total = total + points(i).x 81 | NEXT i 82 | 83 | PRINT total 84 | `, ` 85 | 55 86 | `); 87 | 88 | -------------------------------------------------------------------------------- /test/while-wend-test.js: -------------------------------------------------------------------------------- 1 | // Copyright 2018 Google LLC 2 | // 3 | // Licensed under the Apache License, Version 2.0 (the "License"); 4 | // you may not use this file except in compliance with the License. 5 | // You may obtain a copy of the License at 6 | // 7 | // https://www.apache.org/licenses/LICENSE-2.0 8 | // 9 | // Unless required by applicable law or agreed to in writing, software 10 | // distributed under the License is distributed on an "AS IS" BASIS, 11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | // See the License for the specific language governing permissions and 13 | // limitations under the License. 14 | 15 | 'use strict'; 16 | 17 | var basic_test = require('./basic-tester.js'); 18 | 19 | basic_test.BASIC_TEST('WhileWend', 'OneToFive', ` 20 | i = 1 21 | WHILE i <= 5 22 | PRINT i 23 | i = i + 1 24 | WEND 25 | `, ` 26 | 1 27 | 2 28 | 3 29 | 4 30 | 5 31 | `); 32 | 33 | basic_test.BASIC_TEST('DoLoopWhile', 'WhileNone', ` 34 | i = 6 35 | WHILE i <= 5 36 | PRINT i 37 | i = i + 1 38 | WEND 39 | `, ` 40 | `); 41 | 42 | -------------------------------------------------------------------------------- /third_party/install_linter/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "install_linter", 3 | "version": "1.0.0", 4 | "description": "", 5 | "main": "index.js", 6 | "scripts": { 7 | "test": "echo \"Error: no test specified\" && exit 1" 8 | }, 9 | "keywords": [], 10 | "author": "", 11 | "license": "ISC", 12 | "devDependencies": { 13 | "eslint": "^7.0.0" 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /tools/keyword_dump.js: -------------------------------------------------------------------------------- 1 | #! /usr/bin/env node 2 | // Copyright 2018 Google LLC 3 | // 4 | // Licensed under the Apache License, Version 2.0 (the "License"); 5 | // you may not use this file except in compliance with the License. 6 | // You may obtain a copy of the License at 7 | // 8 | // https://www.apache.org/licenses/LICENSE-2.0 9 | // 10 | // Unless required by applicable law or agreed to in writing, software 11 | // distributed under the License is distributed on an "AS IS" BASIS, 12 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | // See the License for the specific language governing permissions and 14 | // limitations under the License. 15 | 16 | 'use strict'; 17 | 18 | var fs = require('fs'); 19 | var path = require('path'); 20 | 21 | var root_dir = path.dirname(__dirname); 22 | var source_file = path.join(root_dir, 'wwwbasic.js'); 23 | var source = fs.readFileSync(source_file, 'utf8'); 24 | 25 | var p; 26 | var keywords = {}; 27 | 28 | // Gather Skip('FOO'); 29 | var re = /Skip\('([^']+)'\)/g; 30 | while ((p = re.exec(source)) !== null) { 31 | keywords[p[1]] = 1; 32 | } 33 | 34 | // Gather tok == 'FOO' 35 | var re = /tok == '([^']+)'/g; 36 | while ((p = re.exec(source)) !== null) { 37 | keywords[p[1]] = 1; 38 | } 39 | 40 | // Dump unique ones. 41 | var output = []; 42 | for (var keyword in keywords) { 43 | output.push(keyword); 44 | } 45 | output.sort(); 46 | for (var i = 0; i < output.length; ++i) { 47 | console.log(output[i]); 48 | } 49 | -------------------------------------------------------------------------------- /tools/lint.sh: -------------------------------------------------------------------------------- 1 | #! /bin/bash 2 | # Copyright 2018 Google LLC 3 | # 4 | # Licensed under the Apache License, Version 2.0 (the "License"); 5 | # you may not use this file except in compliance with the License. 6 | # You may obtain a copy of the License at 7 | # 8 | # https://www.apache.org/licenses/LICENSE-2.0 9 | # 10 | # Unless required by applicable law or agreed to in writing, software 11 | # distributed under the License is distributed on an "AS IS" BASIS, 12 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | # See the License for the specific language governing permissions and 14 | # limitations under the License. 15 | 16 | set -e 17 | 18 | # Move to root of project. 19 | SCRIPT_DIR="$(cd "$(dirname "$0")" && pwd -P)" 20 | cd ${SCRIPT_DIR}/.. 21 | 22 | LINTER_DIR=./third_party/install_linter 23 | ESLINT=${LINTER_DIR}/node_modules/.bin/eslint 24 | 25 | # Install or update eslint as needed. 26 | OLD_PWD=$(pwd) 27 | cd ${LINTER_DIR} 28 | npm update 29 | cd ${OLD_PWD} 30 | 31 | # Lint it. 32 | ${ESLINT} $* \ 33 | --ignore-pattern '!.eslintrc.js' \ 34 | .eslintrc.js wwwbasic.js test/ tools/ 35 | -------------------------------------------------------------------------------- /wip/gorillas.html: -------------------------------------------------------------------------------- 1 | 16 | 17 | 18 | 19 | 20 | -------------------------------------------------------------------------------- /wip/nibbles.html: -------------------------------------------------------------------------------- 1 | 16 | 17 | 18 | 19 | 20 | --------------------------------------------------------------------------------