1# RETRO: a Modern, Pragmatic Forth 2 3Welcome to RETRO, my personal take on the Forth language. This 4is a modern system primarily targeting desktop, mobile, and 5servers, though it can also be used on some larger (ARM, MIPS32) 6embedded systems. 7 8The language is Forth. It is untyped, uses a stack to pass data 9between functions called words, and a dictionary which tracks 10the word names and data structures. 11 12But it's not a traditional Forth. RETRO draws influences from 13many sources and takes a unique approach to the language. 14 15RETRO has a large vocabulary of words. Keeping a copy of the 16Glossary on hand is highly recommended as you learn to use RETRO. 17 18This book will hopefully help you develop a better understanding 19of RETRO and how it works. 20 21# Obtaining RETRO 22 23## Stable Releases 24 25I periodically make stable releases. This will typically happen 26quarterly. 27 28- http://forthworks.com/retro 29- http://forth.works 30 31## Snapshots 32 33A lot of development happens between releases. I make snapshots 34of my working source tree nightly (and often more often). 35 36The latest snapshot can be downloaded from the following stable 37URLs: 38 39* http://forthworks.com/retro/r/latest.tar.gz 40* gopher://forthworks.com/9/retro/r/latest.tar.gz 41 42## Fossil Repository 43 44I use a Fossil repository to manage development. To obtain a 45copy of the repository install Fossil and: 46 47 fossil clone http://forthworks.com:8000 retro.fossil 48 mkdir retro 49 cd retro 50 fossil open /path/to/retro.fossil 51 52See the Fossil documentation for details on using Fossil to 53keep your local copy of the repository current. 54 55This will let you stay current with my latest changes faster 56than the snapshots, but you may occasionally encounter bigger 57problems as some commits may be in a partially broken state. 58 59If you have problems, check the version of Fossil you are 60using. I am currently using Fossil 2.10, you may experience 61issues checking out or cloning if using older versions. 62 63## git Repository 64 65There is now a read-only mirror of the fossil repository 66provided via git. This is hosted on sr.ht. 67 68 git clone https://git.sr.ht/~crc_/retroforth 69 70## Notes 71 72I personally recommend using either a recent snapshot or a 73build from one of the repositories. This will reflect the 74latest system as I use it, and are normally reliable as I 75run them daily for my production systems. 76 77# Building on BSD, Linux, macOS, and other Unix Targets 78 79RETRO is well supported on BSD (tested on FreeBSD, NetBSD, 80OpenBSD), Linux, and macOS systems. It should build on any 81of these without issue. 82 83## Requirements 84 85- c compiler & linker 86- standard headers 87- make 88 89## Process 90 91For a standard 32-bit system: 92 93Run `make` 94 95For a 64-bit system: 96 97Run `make OPTIONS=-DBIT64` 98 99This will build the toolchain and then the main `retro` 100executable. 101 102## Executables 103 104In the `bin/` directory, you should see the following: 105 106 retro 107 retro-unu 108 retro-muri 109 retro-extend 110 retro-embedimage 111 retro-describe 112 113## Test The Build 114 115You can conduct a quick test of the build by running `bin/retro`: 116 117 ./bin/retro 118 119Exit by typing `bye` and pressing enter. 120 121## Installation 122 123You can install Retro globally on BSD systems (and possibly Linux) 124by doing: 125 126 doas make install 127 128or: 129 130 sudo make install 131 132## Platform Specific Notes 133 134In addition to the 64-bit build, it is possible to override the 135image size, address stack depth, and data stack depth by defining 136the appropriate elements. 137 138E.g., for a 64-bit build with: 139 140 4,000,000 cells of memory 141 4,000 item limit on data stack 142 500 item limit on address stack 143 144Run `make OPTIONS="-DBIT64 -DIMAGE_SIZE=4000000 -DSTACK_DEPTH=4000 -DADDRESSES=500"` 145 146 147### Haiku 148 149To build on Haiku, you need to link with the *network* library. 150E.g.: 151 152 make LDFLAGS=-lnetwork 153 154### Unix 155 156On Unix, you can optionally enable the sockets device (and thus the socket 157words) by building with `-DENABLE_SOCKETS`. 158 159 make OPTIONS="-DENABLE_SOCKETS" 160 161## Issues 162 163If you run into any build issues, please send details to 164crc@forth.works so I can work on addressing them as quickly 165as possible. 166 167# Building RETRO on Windows 168 169It is possible to build RETRO on Windows, though a few of the 170extensions are not supported: 171 172- no `unix:` words 173- no `gopher:` words 174 175This is currently more difficult than on a Unix host. If you have 176Windows 10 and WSL, it may be better to build under that (using 177the Unix instructions). 178 179## Setup Build Environment 180 181RETRO on Windows is built with TCC. 182 183Go to http://download.savannah.gnu.org/releases/tinycc/ 184 185Download the *winapi-full* and *tcc-xxxx-bin* packages for your 186system. Decompress them, copy the headers from the winapi 187package into the tcc directory. 188 189## Prepare Source 190 191Copy the `source/interfaces/retro-windows.c` and the 192`source/interfaces/retro-windows.c` to the directory you setup 193tcc into. 194 195## Build 196 197Building will require use of the command line. Assuming that 198tcc.exe is in the current directory along with the RETRO sources: 199 200 tcc retro-windows.c -o retro.exe 201 202# Building Alternative Systems 203 204In addition to the C implementation, there are a few other 205interfaces that can be built. 206 207## Requirements 208 209- c compiler (tested: clang, tcc, gcc) 210- make 211- standard unix shell 212 213## retro-repl 214 215A basic interactive system can be built by using: 216 217 make bin/retro-repl 218 219This requires a copy of `ngaImage` to be in the current 220directory. 221 222## Barebones 223 224This is a minimal version of the `retro-repl`. It keeps the C 225portion as short as possible, making it a useful starting point 226for new interfaces. 227 228To build: 229 230 make bin/retro-barebones 231 232## retro-compiler 233 234This is a turnkey compiler. It can compile a new executable 235bundling a Retro VM and image. 236 237Requirements: 238 239- BSD or Linux 240- objcopy in $PATH 241 242To build: 243 244 make bin/retro-compiler 245 246Example use: 247 2481. Given a source file like "Hello.forth": 249 250 ~~~ 251 :hello 'hello_world! s:put nl ; 252 ~~~ 253 2542. Use: 255 256 ./bin/retro-compiler Hello.forth hello 257 258The first argument is the source file, the second is the 259word to run on startup. 260 2613. Run the generated `a.out` 262 263Limits: 264 265This only supports the core words ('all' interface) and the 266file i/o words. Support for other I/O extensions will be 267added in the future. 268 269## Pascal 270 271There is a Pascal version of `retro-repl`. 272 273Dependencies: 274 275- freepascal 276 277Building: 278 279 cd vm/nga-pascal 280 fpc listener.lpr 281 282This will require a copy of the `ngaImage` in the 283current directory. 284 285## Python: retro.py 286 287This is an implementation of `retro-repl` in Python. As 288with `retro-repl` it requires the `ngaImage` in the current 289directory when starting. 290 291## C#: retro.cs 292 293This is an implementation of `retro-repl` in C#. As with 294`retro-repl` it requires the `ngaImage` in the current 295directory when starting. 296 297Building: 298 299 cd vm\nga-csharp 300 csc retro.cs 301 302You'll need to make sure your path has the CSC.EXE in it, 303or provide a full path to it. Something like this should 304reveal the path to use: 305 306 dir /s %WINDIR%\CSC.EXE 307 308I've only tested building this using Microsoft's .NET tools. 309It should also build and run under Mono. 310 311# Advanced Builds 312 313## Custom Image 314 315For users of BSD, Linux, macOS, you can customize the image at 316build time. 317 318In the top level directory is a `package` directory containing 319a file named `list.forth`. You can add files to compile into 320your system by adding them to the `list.forth` and rebuilding. 321 322Example: 323 324If you have wanted to include the NumbersWithoutPrefixes.forth 325example, add: 326 327 ~~~ 328 'example/NumbersWithoutPrefixes.forth include 329 ~~~ 330 331To the start of the `list.forth` file and then run `make` again. 332The newly built `bin/retro` will now include your additions. 333 334# Starting RETRO 335 336RETRO can be run for scripting or interactive use. 337 338## Interactive 339 340To start it interactively, run: `retro` without any command line 341arguments, or with `-i`, `-s`, or `-i,c`. 342 343Starting the interactive system: 344 345``` 346retro 347``` 348 349Or: 350 351``` 352retro -i 353``` 354 355This should be sufficient for most uses. 356 357Starting the interactive system (without displaying the 358startup banner): 359 360``` 361retro -s 362``` 363 364## Using In a Pipe 365 366If using a Unix shell and piping input between processes, you 367will probably want to use `-s` to suppress the startup messages 368and `Ok` prompt that normally appear. 369 370E.g., 371 372``` 373echo "'lol s:put nl" | retro -s 374``` 375 376## Running A Program In A File 377 378You can run code in a file very easily. This is simply: 379 380``` 381retro filename 382``` 383 384You can follow the filename with any arguments that it may need. 385These will be accessible to the program via the `script:arguments` 386and `script:get-argument` words. 387 388Source files must be written in Unu format. 389 390## Scripting 391 392You can use RETRO to write scripts. Add a shebang: 393 394``` 395#!/usr/bin/env retro 396``` 397 398And make the file executable. 399 400Source files must be written in Unu format. 401 402## Command Line Arguments 403 404For a summary of the full command line arguments available: 405 406 Scripting Usage: 407 408 retro filename [script arguments...] 409 410 Interactive Usage: 411 412 retro [-h] [-i] [-c] [-s] [-f filename] [-t] 413 414 -h Display this help text 415 -i Interactive mode (line buffered) 416 -s Suppress the startup text 417 -f filename Run the contents of the specified file 418 -t Run tests (in ``` blocks) in any loaded files 419 420# Basic Interactions 421 422Start RETRO in interactive mode: 423 424``` 425retro -i 426``` 427 428You should see something similar to this: 429 430 RETRO 12 (2019.6) 431 8388608 MAX, TIB @ 1025, Heap @ 9374 432 433At this point you are at the *listener*, which reads and 434processes your input. You are now set to begin exploring 435RETRO. 436 437To exit, run `bye`: 438 439``` 440bye 441``` 442 443# Unu: Simple, Literate Source Files 444 445RETRO is written in a literate style. Most of the sources 446are in a format called Unu. This allows easy mixing of 447commentary and code blocks, making it simple to document 448the code. 449 450As an example, 451 452 # Determine The Average Word Name Length 453 454 To determine the average length of a word name two values 455 are needed. First, the total length of all names in the 456 Dictionary: 457 458 ~~~ 459 #0 [ d:name s:length + ] d:for-each 460 ~~~ 461 462 And then the number of words in the Dictionary: 463 464 ~~~ 465 #0 [ drop n:inc ] d:for-each 466 ~~~ 467 468 With these, a simple division is all that's left. 469 470 ~~~ 471 / 472 ~~~ 473 474 Finally, display the results: 475 476 477 ~~~ 478 'Average_name_length:_%n\n s:format s:put 479 ~~~ 480 481This illustrates the format. Only code in the fenced blocks 482(between \~~~ pairs) get extracted and run. 483 484(Note: this only applies to source files; fences are not used 485when entering code interactively). 486 487## On The Name 488 489The name Unu comes from the Maori language, where it means: 490 491 (verb) (-hia) pull out, withdraw, draw out, extract. 492 Taken from https://maoridictionary.co.nz/ 493 494# RETRO's Markdown Syntax 495 496I use a variation of Markdown for writing documentation and 497when commenting code written in RETRO. The syntax is 498described below. 499 500## Basic Syntax 501 502### Headings 503 504Headings start with one or more number (`#`) signs. The 505number of number signs should correspond to the heading 506level. 507 508 # Heading 1 509 ## Heading 2 510 ### Heading 3 511 #### Heading 4 512 513My Markdown does not support the alternate underline 514format for headings. 515 516### Paragraphs & Line Breaks 517 518To create paragraphs, use a blank line to separate one or 519more lines of text. 520 521Do not add spaces or tabs at the start of a paragraph as 522this may cause the Markdown tools to interpret the line 523improperly. 524 525Line breaks are entered at the end of each line. 526 527### Emphasis 528 529#### Bold 530 531To make text bold, surround it with asterisks. 532 533 The *bold* word. 534 535#### Italic 536 537To make text italic, surround it with front slashes. 538 539 The /italic words/. 540 541#### Underline 542 543To underline text, surround it with underscores. 544 545 Underline _some text_. 546 547### Horizontal Rules 548 549Horizontal rules can be inserted by starting a line with a 550sequence of four or more dashes (`-`) or four or more alternating 551dash and plus (`-+-+`) characters. 552 553 ---- 554 555## Lists 556 557Lists start with a `-` or `*`, followed by a space, then the item 558text. Additionally, nested lists starting with two spaces before 559the list marker can be used. 560 561 - this is a list item 562 - so is this 563 564 - this will be indented 565 - likewise 566 567 - back to the standard level 568 569## Code 570 571### Code Blocks 572 573Code blocks start and end with ~~~ on a line by themselves. 574 575 Sum the values. 576 577 ~~~ 578 { #10 #20 #13 #4 #22 } #0 [ + ] a:reduce 579 ~~~ 580 581You can also denote code by starting the line with four spaces. 582 583 This line will be treated as code. 584 585### Test Blocks 586 587Unit testing blocks start and end with ``` on a line by 588themselves. 589 590 ``` 591 { #10 #20 #13 #4 #22 } #0 [ + ] a:reduce 592 ``` 593 594### Inline Code 595 596To mark a sequence as inline code, surround it with backticks. 597 598 For instance, look at the value in `Compiler` to see if 599 the colon compiler is active. 600 601## Escaping 602 603You can preceed a character with a backslash (\\) to have it 604not be processed as a Markdown element. 605 606# A Quick Tutorial 607 608Programming in RETRO is all about creating words to solve 609the problem at hand. Words operate on data, which can be 610kept in memory or on the stack. 611 612Let's look at this by solving a small problem: writing a 613word to determine if a string is a palindrome. 614 615A palindrome is a phrase which reads the same backward 616and forward. 617 618We first need a string to look at. Starting with something 619easy: 620 621``` 622'anna 623``` 624 625Looking in the Glossary, there is a `s:reverse` word for 626reversing a string. We can find `dup` to copy a value, and 627`s:eq?` to compare two strings. So testing: 628 629``` 630'anna dup s:reverse s:eq? 631``` 632 633This yields -1 (`TRUE`) as expected. So we can easily 634name it: 635 636``` 637:palindrome? dup s:reverse s:eq? ; 638``` 639 640Naming uses the `:` sigil to add a new word to the dictionary. 641The words that make up the definition are then placed, with a 642final word (`;`) ending the definition. We can then use this: 643 644``` 645'anna palindrome? 646``` 647 648Once defined there is no difference between our new word and 649any of the words already provided by the RETRO system. 650 651# Syntax 652 653RETRO has more syntax than a traditional Forth due to ideas 654borrowed from ColorForth and some design decisions. This has 655some useful traits, and helps to make the language more 656consistent. 657 658## Tokens 659 660Input is divided into a series of whitespace delimited tokens. 661Each of these is then processed individually. There are no 662parsing words in RETRO. 663 664Tokens may have a single character *sigil*, which RETRO will 665use to decide how to process the token. 666 667## Sigils 668 669Sigils are single characters added to the start of a token 670to guide the compiler. The use of these is a major way in 671which RETRO differs from traditional Forth. 672 673When a token is passed to `interpret`, RETRO first takes the 674initial character and looks to see if there is a word that 675matches this. If so, it will pass the rest of the token to 676that word to handle. 677 678In a traditional Forth, the interpret process is something 679like: 680 681 get token 682 is token in the dictionary? 683 yes: 684 is it immediate? 685 yes: call the word. 686 no: are we interpreting? 687 yes: call the word 688 no: compile a call to the word 689 no: 690 is it a number? 691 yes: are we interpreting? 692 yes: push the number to the stack 693 no: compile the number as a literal 694 no: report an error ("not found") 695 696In RETRO, the interpret process is basically: 697 698 get token 699 does the first character match a `sigil:` word? 700 yes: pass the token to the sigil handler 701 no: is token a word in the dictionary? 702 yes: push the XT to the stack and call the 703 class handler 704 no: report an error ("not found") 705 706All of the actual logic for how to deal with tokens is moved 707to the individual sigil handlers, and the logic for handling 708words is moved to word class handlers. 709 710This means that sigils are used for a lot of things. Numbers? 711Handled by a `#` sigil. Strings? Use the `'` sigil. Comments? 712Use `(`. Making a new word? Use the `:` sigil. 713 714The major sigils are: 715 716 | Sigil | Used For | 717 | ------ | ----------------------------- | 718 | @ | Fetch from variable | 719 | ! | Store into variable | 720 | & | Pointer to named item | 721 | # | Numbers | 722 | $ | ASCII characters | 723 | ' | Strings | 724 | ( | Comments | 725 | : | Define a word | 726 727The individual sigils will be covered in more detail in the 728later chapters on working with different data types. 729 730## Word Classes 731 732Word classes are words which take a pointer and do something 733with it. These are covered in detail in their own chapter, 734but essentially they decide *how* to execute or compile specific 735types of words. 736 737 738# Additional Tools 739 740In addition to the core `retro` binary, the `bin` directory 741will contain a few other tools. 742 743## retro 744 745This is the main RETRO binary. 746 747## retro-describe 748 749This is a program that looks up entries in the Glossary. 750 751At the command line, you can use it like: 752 753 retro-describe s:for-each 754 755You can pass multiple word names to it: 756 757 retro-describe s:for-each nl d:words 758 759## retro-embedimage 760 761This is a program which generates a C file with the ngaImage 762contents. It's used when building `retro`. 763 764 retro-embedimage ngaImage 765 766The output is written to stdout; redirect it as needed. 767 768## retro-extend 769 770This is a program which compiles code into the ngaImage. 771It's used when building `retro` and when you want to make a 772standalone image with custom additions. 773 774Example command line: 775 776 retro-extend ngaImage example/rot13.forth 777 778Pass the image name as the first argument, and then file names 779as subsequent ones. Do *not* use this for things relying on I/O 780apart from the basic console output as it doesn't emulate other 781devices. If you need to load in things that rely on using the 782optional I/O devices, see the **Advanced Builds** chapter. 783 784## retro-muri 785 786This is the assembler for Nga. It's used to build the initial 787RETRO kernel and can be used by other tools as well. 788 789 retro-muri retro.muri 790 791## retro-tags and retro-locate 792 793These tools are intended to be used together. The first tool, 794`retro-tags`, will recursively scan the current directory for 795RETRO source files and extract the locations of words defined 796in them. These will be written to disk in a `tags` file, using 797the standard ctags format. 798 799`retro-locate` takes a word name, and returns the location(s) 800where it is defined. This requires a `tags` file to be present. 801 802Create the `tags` file: 803 804 retro-tags 805 806Locate a word: 807 808 retro-locate n:square 809 810## retro-unu 811 812This is the literate source extraction tool for RETRO. It 813is used in building `retro`. 814 815Example usage: 816 817 retro-unu literate/RetroForth.md 818 819Output is written to stdout; redirect as neeeded. 820 821# The Optional Retro Compiler 822 823In addition to the base system, users of RETRO on Unix hosts 824with ELF executables can build and use the `retro-compiler` 825to generate turnkey executables. 826 827## Requirements 828 829- Unix host 830- ELF executable support 831- `objcopy` in the $PATH 832 833## Building 834 835 make bin/retro-compiler 836 837## Installing 838 839Copy `bin/retro-compiler` to somewhere in your $PATH. 840 841## Using 842 843`retro-compiler` takes two arguments: the source file to 844compile and the name of the word to use as the main entry 845point. 846 847Example: 848 849Given a `hello.forth`: 850 851 ~~~ 852 :hello 'Hello_World! s:put nl ; 853 ~~~ 854 855Use: 856 857 retro-compiler hello.forth hello 858 859The compiler will generate an `a.out` file which you can 860then rename. 861 862## Known Limitations 863 864This does not provide the scripting support for command line 865arguments that the standard `retro` interface offers. 866 867A copy of `objcopy` needs to be in the path for compilation 868to work. 869 870The current working directory must be writable. 871 872This only supports hosts using ELF executables. 873 874The output file name is fixed to `a.out`. 875 876RETRO(1) General Commands Manual RETRO(1) 877 878RETRO 879 retro - a modern, pragmatic forth development system 880 881SYNOPSIS 882 retro [-h] [-i] [-t] [-f filename] [-u filename] [-r filename] 883 [filename script-args] 884 885DESCRIPTION 886 RETRO is a modern, pragmatic Forth drawing influences from many sources. 887 It's clean, elegant, tiny, and easy to grasp and adapt to various uses. 888 889 retro is the main interface for interacting with Retro. It provides both 890 an interactive and a scripting model. 891 892OPTIONS 893 -h Display a help screen. 894 895 -i Start Retro in interactive mode. 896 897 -s Start Retro in interactive mode and supress the startup message. 898 899 -t Run any test blocks in the loaded files. 900 901 -f filename 902 Run any code blocks in the specified file. 903 904 -u filename 905 Load and use the specified image file rather than the integral 906 one. 907 908 -r filename 909 Load and run the code in the specified image file rather than 910 the integral one. 911 912 filename script-args 913 Run code blocks in a single file. Pass script-args to the code 914 being run. 915 916AUTHORS 917 Charles Childers <crc@forthworks.com> 918 919OpenBSD 6.4 September 2019 OpenBSD 6.4 920 921RETRO-DESCRIBE(1) General Commands Manual RETRO-DESCRIBE(1) 922 923RETRO-DESCRIBE 924 retro-describe - a modern, pragmatic forth development system 925 926SYNOPSIS 927 retro-describe wordname [additional wordnames] 928 929DESCRIPTION 930 RETRO is a modern, pragmatic Forth drawing influences from many sources. 931 It's clean, elegant, tiny, and easy to grasp and adapt to various uses. 932 933 retro-describe is a tool for looking up the description and stack 934 comments for words in the core language and extensions. It will write 935 output to stdout. 936 937AUTHORS 938 Charles Childers <crc@forthworks.com> 939 940OpenBSD 6.4 May 2019 OpenBSD 6.4 941 942RETRO-DOCUMENT(1) General Commands Manual RETRO-DOCUMENT(1) 943 944RETRO-DOCUMENT 945 retro-document - a modern, pragmatic forth development system 946 947SYNOPSIS 948 retro-document filename 949 950DESCRIPTION 951 RETRO is a modern, pragmatic Forth drawing influences from many sources. 952 It's clean, elegant, tiny, and easy to grasp and adapt to various uses. 953 954 retro-document is a tool for generating a listing of the descriptions and 955 stack comments for all standard word used in a source file. It will write 956 output to stdout. 957 958AUTHORS 959 Charles Childers <crc@forthworks.com> 960 961OpenBSD 6.4 May 2019 OpenBSD 6.4 962 963RETRO-EMBEDIMAGE(1) General Commands Manual RETRO-EMBEDIMAGE(1) 964 965RETRO-EMBEDIMAGE 966 retro-embedimage - a modern, pragmatic forth development system 967 968SYNOPSIS 969 retro-embedimage [filename] 970 971DESCRIPTION 972 RETRO is a modern, pragmatic Forth drawing influences from many sources. 973 It's clean, elegant, tiny, and easy to grasp and adapt to various uses. 974 975 retro-embedimage loads the specified image (or `ngaImage` from the 976 current directory if none is specified). It converts this into C code 977 that can be compiled for inclusion in a RETRO executable. It will write 978 the output to stdout. 979 980AUTHORS 981 Charles Childers <crc@forthworks.com> 982 983OpenBSD 6.4 February 2019 OpenBSD 6.4 984 985RETRO-EXTEND(1) General Commands Manual RETRO-EXTEND(1) 986 987RETRO-EXTEND 988 retro-extend - a modern, pragmatic forth development system 989 990SYNOPSIS 991 retro-extend image filename [filenames] 992 993DESCRIPTION 994 RETRO is a modern, pragmatic Forth drawing influences from many sources. 995 It's clean, elegant, tiny, and easy to grasp and adapt to various uses. 996 997 retro-extend is a tool to load additional code into an image file. It 998 takes the name of an image file and one or more source files to load into 999 the image. After completion the image file will be updated with the 1000 changes. 1001 1002 1003CAVEATS 1004 retro-extend only emulates the minimal console output device. If the 1005 source files require additional I/O to be present, the extend process 1006 will likely fail to work correctly. 1007 1008 1009AUTHORS 1010 Charles Childers <crc@forthworks.com> 1011 1012OpenBSD 6.4 January 2021 OpenBSD 6.4 1013 1014RETRO-LOCATE(1) General Commands Manual RETRO-LOCATE(1) 1015 1016RETRO-LOCATE 1017 retro-locate - a modern, pragmatic forth development system 1018 1019SYNOPSIS 1020 retro-locate wordname 1021 1022DESCRIPTION 1023 RETRO is a modern, pragmatic Forth drawing influences from many sources. 1024 It's clean, elegant, tiny, and easy to grasp and adapt to various uses. 1025 1026 retro-locate searches the tags file generated by retro-tags for the 1027 desired word name. Any matches are displayed, along with the line number. 1028 1029AUTHORS 1030 Charles Childers <crc@forthworks.com> 1031 1032OpenBSD 6.6 January 2020 OpenBSD 6.6 1033 1034RETRO-MURI(1) General Commands Manual RETRO-MURI(1) 1035 1036RETRO-MURI 1037 retro-muri - a modern, pragmatic forth development system 1038 1039SYNOPSIS 1040 retro-muri filename 1041 1042DESCRIPTION 1043 RETRO is a modern, pragmatic Forth drawing influences from many sources. 1044 It's clean, elegant, tiny, and easy to grasp and adapt to various uses. 1045 1046 retro-muri is an assembler for Nga, the virtual machine at the heart of 1047 Retro. It is used to build the image file containing the actual Retro 1048 language. 1049 1050 This will extract the code blocks in the specified file and generate an 1051 image file named `ngaImage`. 1052 1053AUTHORS 1054 Charles Childers <crc@forthworks.com> 1055 1056OpenBSD 6.4 February 2019 OpenBSD 6.4 1057 1058RETRO-TAGS(1) General Commands Manual RETRO-TAGS(1) 1059 1060RETRO-TAGS 1061 retro-tags - a modern, pragmatic forth development system 1062 1063SYNOPSIS 1064 retro-tags 1065 1066DESCRIPTION 1067 RETRO is a modern, pragmatic Forth drawing influences from many sources. 1068 It's clean, elegant, tiny, and easy to grasp and adapt to various uses. 1069 1070 retro-tags is a tool for extracting code from fenced blocks in literate 1071 sources and generating a tags file compatible with ctags. 1072 1073AUTHORS 1074 Charles Childers <crc@forthworks.com> 1075 1076OpenBSD 6.4 August 2019 OpenBSD 6.4 1077 1078# Naming Conventions 1079 1080Word names in RETRO generally follow the following conventions. 1081 1082## General Guidelines 1083 1084* Readability is important 1085* Be consistent 1086* Don't use a sigil as the first character of a name 1087* Don't use underscores in word names 1088* Use short names for indices 1089* Word names start with a `-` for "not" 1090* Words returning a flag end in ? 1091 1092## Typical Format 1093 1094The word names will generally follow a form like: 1095 1096 [namespace:]name 1097 1098The `namespace:` is optional, but recommended for consistency 1099with the rest of the system and to make it easier to identify 1100related words. 1101 1102## Case 1103 1104Word names are lowercase, with a dash (-) for compound names. 1105 1106 hello 1107 drop-pair 1108 s:for-each 1109 1110Variables use TitleCase, with no dash between compound names. 1111 1112 Base 1113 Heap 1114 StringBuffers 1115 1116Constants are UPPERCASE, with a dash (-) for compound names. 1117 1118 TRUE 1119 FALSE 1120 f:PI 1121 MAX-STRING-LENGTH 1122 1123## Namespaces 1124 1125Words are grouped into broad namespaces by attaching a short 1126prefix string to the start of a name. 1127 1128The common namespaces are: 1129 1130 | Prefix | Contains | 1131 | ------- | ------------------------------------------------------ | 1132 | a: | Words operating on simple arrays | 1133 | ASCII: | ASCII character constants for control characters | 1134 | buffer: | Words for operating on a simple linear LIFO buffer | 1135 | c: | Words for operating on ASCII character data | 1136 | class: | Contains class handlers for words | 1137 | d: | Words operating on the Dictionary | 1138 | err: | Words for handling errors | 1139 | io: | General I/O words | 1140 | n: | Words operating on numeric data | 1141 | sigil: | Contains sigil handlers | 1142 | s: | Words operating on string data | 1143 | v: | Words operating on variables | 1144 | file: | File I/O words | 1145 | f: | Floating Point words | 1146 | unix: | Unix system call words | 1147 1148## Tips 1149 1150### Don't Start Names With Sigil Characters 1151 1152Avoid using a sigil as the first character of a word name. RETRO 1153will look for sigils first, this will prevent direct use of 1154the work in question. 1155 1156To find a list of sigil characters, do: 1157 1158 'sigil: d:words-with 1159 1160### Don't Use Underscores 1161 1162Underscores in strings are replaced by spaces. This is problematic, 1163especially with variables. Consider: 1164 1165 'test_name var 1166 #188 !test_name 1167 1168In this, the string for the name is converted to "test name". The 1169store in the second line will not add the space, so resolves to an 1170incorrect address. 1171 1172I personally recommend avoiding the use of underscores in any word 1173names. 1174 1175# The Return Stack 1176 1177RETRO has two stacks. The primary one is used to pass data 1178between words. The second one primarily holds return addresses. 1179 1180Each time a word is called, the next address is pushed to 1181the return stack. 1182 1183# Stack Diagrams 1184 1185Most words in RETRO have a stack comment. These look like: 1186 1187 (-) 1188 (nn-n) 1189 1190As with all comments, a stack comment begins with `(` and 1191should end with a `)`. There are two parts to the comment. 1192On the left side of the `-` is what the word *consumes*. On 1193the right is what it *leaves*. 1194 1195RETRO uses a short notation, with one character per value 1196taken or left. In general, the following symbols represent 1197certain types of values. 1198 1199 | Notation | Represents | 1200 | ------------------- | ----------------------- | 1201 | b, n, m, o, x, y, z | generic numeric values | 1202 | s | string | 1203 | v | variable | 1204 | p, a | pointers | 1205 | q | quotation | 1206 | d | dictionary header | 1207 | f | `TRUE` or `FALSE` flag. | 1208 1209In the case of something like `(xyz-m)`, RETRO expects z to be 1210on the top of the stack, with y below it and x below the y 1211value. And after execution, a single value (m) will be left on 1212the stack. 1213 1214Words with no stack effect have a comment of (-) 1215 1216# Working With Arrays 1217 1218RETRO offers a number of words for operating on statically sized 1219arrays. 1220 1221## Namespace 1222 1223The words operating on arrays are kept in an `a:` namespace. 1224 1225## Creating Arrays 1226 1227The easiest way to create an array is to wrap the values in a 1228`{` and `}` pair: 1229 1230``` 1231{ #1 #2 #3 #4 } 1232{ 'this 'is 'an 'array 'of 'strings } 1233{ 'this 'is 'a 'mixed 'array #1 #2 #3 } 1234``` 1235 1236You can also make an array from a quotation which returns 1237values and the number of values to store in the a: 1238 1239``` 1240[ #1 #2 #3 #3 ] a:counted-results 1241[ #1 #2 #3 #3 ] a:make 1242``` 1243 1244## Accessing Elements 1245 1246You can access a specific value with `a:th` and `fetch` or 1247`store`: 1248 1249``` 1250{ #1 #2 #3 #4 } #3 a:th fetch 1251``` 1252 1253## Find The Length 1254 1255Use `a:length` to find the size of the array. 1256 1257``` 1258{ #1 #2 #3 #4 } a:length 1259``` 1260 1261## Duplicate 1262 1263Use `a:dup` to make a copy of an a: 1264 1265``` 1266{ #1 #2 #3 #4 } a:dup 1267``` 1268 1269## Filtering 1270 1271RETRO provides `a:filter` which extracts matching values 1272from an array. This is used like: 1273 1274``` 1275{ #1 #2 #3 #4 #5 #6 #7 #8 } [ n:even? ] a:filter 1276``` 1277 1278The quote will be passed each value in the array and should 1279return TRUE or FALSE. Values that lead to TRUE will be collected 1280into a new array. 1281 1282## Mapping 1283 1284`a:map` applies a quotation to each item in an array and 1285constructs a new array from the returned values. 1286 1287Example: 1288 1289``` 1290{ #1 #2 #3 } [ #10 * ] a:map 1291``` 1292 1293## Reduce 1294 1295`a:reduce` takes an array, a starting value, and a quote. It 1296executes the quote once for each item in the array, passing the 1297item and the value to the quote. The quote should consume both 1298and return a new value. 1299 1300``` 1301{ #1 #2 #3 } #0 [ + ] a:reduce 1302``` 1303 1304## Search 1305 1306RETRO provides `a:contains?` and `a:contains-string?` 1307to search an array for a value (either a number or string) and 1308return either TRUE or FALSE. 1309 1310``` 1311#100 { #1 #2 #3 } a:contains? 1312'test { 'abc 'def 'test 'ghi } a:contains-string? 1313``` 1314 1315## Implementation 1316 1317In memory, an array is a count followed by the values. As an 1318example, if you have an array: 1319 1320 { #10 #20 #30 } 1321 1322In memory this would be setup as: 1323 1324 | Offset | Value | 1325 | ------ | ----- | 1326 | 000 | 3 | 1327 | 001 | 10 | 1328 | 002 | 20 | 1329 | 003 | 30 | 1330 1331You can construct one on the fly by keeping a pointer to 1332`here` and using `,` to place the values. E.g., 1333 1334 here [ #3 , #10 , #20 , #30 , ] dip 1335 1336An example of this can be seen in this excerpt from an example 1337(*example/Primes.forth*): 1338 1339 :create-set (-a) 1340 here #3000 , #2 #3002 [ dup , n:inc ] times drop ; 1341 1342# Working With Assembly Language 1343 1344RETRO runs on a virtual machine called Nga. It provides a 1345standard assembler for this called *Muri*. 1346 1347Muri is a simple, multipass model that's not fancy, but 1348suffices for RETRO's needs. 1349 1350## Assembling A Standalone File 1351 1352A small example (*test.muri*) 1353 1354 ~~~ 1355 i liju.... 1356 r main 1357 : c:put 1358 i liiire.. 1359 i 0 1360 : main 1361 i lilica.. 1362 d 97 1363 i liju.... 1364 r main 1365 ~~~ 1366 1367Assembling it: 1368 1369 retro-muri test.muri 1370 1371So breaking down: Muri extracts the assembly code blocks to 1372assemble, then proceeds to do the assembly. Each source line 1373starts with a directive, followed by a space, and then ending 1374with a value. 1375 1376The directives are: 1377 1378 : value is a label 1379 i value is an instruction bundle 1380 d value is a numeric value 1381 r value is a reference 1382 s value is a string to inline 1383 1384Instructions for Nga are provided as bundles. Each memory 1385location can store up to four instructions. And each instruction 1386gets a two character identifier. 1387 1388From the list of instructions: 1389 1390 0 nop 5 push 10 ret 15 fetch 20 div 25 zret 1391 1 lit 6 pop 11 eq 16 store 21 and 26 halt 1392 2 dup 7 jump 12 neq 17 add 22 or 27 ienum 1393 3 drop 8 call 13 lt 18 sub 23 xor 28 iquery 1394 4 swap 9 ccall 14 gt 19 mul 24 shift 29 iinvoke 1395 1396This reduces to: 1397 1398 0 .. 5 pu 10 re 15 fe 20 di 25 zr 1399 1 li 6 po 11 eq 16 st 21 an 26 ha 1400 2 du 7 ju 12 ne 17 ad 22 or 27 ie 1401 3 dr 8 ca 13 lt 18 su 23 xo 28 iq 1402 4 sw 9 cc 14 gt 19 mu 24 sh 29 ii 1403 1404Most are just the first two letters of the instruction name. I 1405use `..` instead of `no` for `NOP`, and the first letter of 1406each I/O instruction name. So a bundle may look like: 1407 1408 dumure.. 1409 1410(This would correspond to `dup multiply return nop`). 1411 1412## Runtime Assembler 1413 1414RETRO also has a runtime variation of Muri that can be used 1415when you need to generate more optimal code. So one can write: 1416 1417 :n:square dup * ; 1418 1419Or: 1420 1421 :n:square \dumure.. ; 1422 1423The second one will be faster, as the entire definition is one 1424bundle, which reduces memory reads and decoding by 2/3. 1425 1426Doing this is less readable, so I only recommend doing so after 1427you have finalized working RETRO level code and determined the 1428best places to optimize. 1429 1430The runtime assembler has the following directives: 1431 1432 i value is an instruction bundle 1433 d value is a numeric value 1434 r value is a reference 1435 1436Additionally, in the runtime assembler, these are reversed: 1437 1438 'dudumu.. i 1439 1440Instead of: 1441 1442 i dudumu.. 1443 1444The runtime assembler also provides three sigils for use in 1445inlining machine code into a definition. These are: 1446 1447 \ Treat token as an assembly sequence 1448 ` Treat token as a numeric value 1449 ^ Treat token as a reference 1450 1451E.g., instead of doing something like: 1452 1453 :n:square as{ 'dumu.... i }as ; 1454 :test as{ 'lilica.... i #22 d 'n:square r }as ; 1455 1456Just write: 1457 1458 :n:square \dumu.... ; 1459 :test \lilica.. `22 ^n:square ; 1460 1461# Working With a Buffer 1462 1463RETRO provides words for operating on a linear memory area. 1464This can be useful in building strings or custom data 1465structures. 1466 1467## Namespace 1468 1469Words operating on the buffer are kept in the `buffer:` 1470namespace. 1471 1472## Implementation 1473 1474A buffer is a linear sequence of memory. The buffer words 1475provide a means of incrementally storing and retrieving 1476values from it. 1477 1478The buffer words keep track of the start and end of the 1479buffer. They also ensure that an `ASCII:NULL` is written 1480after the last value, which make using them for string 1481data easy. 1482 1483## Limitations 1484 1485Only one buffer can be active at a time. RETRO provides a 1486`buffer:preserve` combinator to allow using a second one 1487before returning to the prior one. 1488 1489## Set The Active Buffer 1490 1491To set a buffer as the active one use `buffer:set`. This takes 1492an address. 1493 1494The buffer will be assumed to be empty. The initial value will 1495be set to ASCII:NULL. 1496 1497## Add Value 1498 1499Use `buffer:add` to append a value to the buffer. This takes 1500a single value and will also add an ASCII:NULL after the end 1501of the buffer. 1502 1503## Fetch Last Value 1504 1505To return the last value in the buffer you can use `buffer:get`. 1506This removes the value and sets an ASCII:NULL in the memory 1507location the returned value occupied. 1508 1509## Get Data About The Buffer 1510 1511RETRO provides `buffer:start` to get the initial address in 1512the buffer, `buffer:end` to get the last address (ignoring the 1513ASCII:NULL), and `buffer:size` to return the number of values 1514in the buffer. 1515 1516## Reset 1517 1518You can reset a buffer to the empty state using `buffer:empty`. 1519 1520## Example 1521 1522To begin, create a memory region to use as a buffer. 1523 1524``` 1525'Test d:create #1025 allot 1526``` 1527 1528Then you can set this as the current buffer: 1529 1530``` 1531&Test buffer:set 1532``` 1533 1534When a buffer is set, the vocabulary sets an internal 1535index to the first address in it. This will be 1536incremented when you add data and decremented when you 1537remove data. 1538 1539Let's add some stuff using `buffer:add`: 1540 1541``` 1542#100 buffer:add 1543#200 buffer:add 1544#300 buffer:add 1545``` 1546 1547And then retrieve the values: 1548 1549``` 1550buffer:get n:put nl 1551buffer:get n:put nl 1552buffer:get n:put nl 1553``` 1554 1555You can remove all values using `buffer:empty`: 1556 1557``` 1558#100 buffer:add 1559#200 buffer:add 1560#300 buffer:add 1561buffer:empty 1562``` 1563 1564And ask the buffer how many items it contains: 1565 1566``` 1567buffer:size n:put nl 1568#100 buffer:add 1569#200 buffer:add 1570#300 buffer:add 1571buffer:size n:put nl 1572buffer:empty 1573``` 1574 1575The other functions are `buffer:start`, which returns 1576the address of the buffer, `buffer:end`, which returns 1577the address of the last value, and `buffer:preserve`. 1578The first is easy to demo: 1579 1580``` 1581buffer:start Test eq? n:put nl 1582``` 1583 1584The last one is useful. Only one buffer is ever active 1585at a given time. The `buffer:preserve` combinator lets 1586you execute a word, saving and restoring the current 1587buffer indexes. So the word could assign and use a new 1588buffer and this will reset the previous one after 1589control returns. 1590 1591There are a few notes that need to be considered. The 1592preserve combinator saves the start and current index 1593but *not* the contents. If the word you call uses the 1594same buffer, the contents will remain altered. 1595 1596Finally, the buffer words have one interesting trait: 1597they store an ASCII NULL after adding each item to the 1598buffer. This lets one use them to build strings easily. 1599 1600``` 1601Test buffer:set 1602$h buffer:add 1603$e buffer:add 1604$l buffer:add 1605$l buffer:add 1606$o buffer:add 1607$, buffer:add 1608#32 buffer:add 1609$w buffer:add 1610$o buffer:add 1611$r buffer:add 1612$l buffer:add 1613$d buffer:add 1614buffer:start s:put nl 1615``` 1616 1617# Working With Characters 1618 1619RETRO provides words for working with ASCII characters. 1620 1621## Sigil 1622 1623Character constants are returned using the `$` sigil. 1624 1625## Namespace 1626 1627Words operating on characters are in the `c:` namespace. 1628 1629## Classification 1630 1631RETRO provides a number of words to determine if a character 1632fits into predefined groups. 1633 1634The primary words for this are: 1635 1636* `c:consonant?` 1637* `c:digit?` 1638* `c:letter?` 1639* `c:lowercase?` 1640* `c:uppercase?` 1641* `c:visible?` 1642* `c:vowel?` 1643* `c:whitespace?` 1644 1645There are also corresponding "not" forms: 1646 1647* `c:-consonant?` 1648* `c:-digit?` 1649* `c:-lowercase?` 1650* `c:-uppercase?` 1651* `c:-visible?` 1652* `c:-vowel?` 1653* `c:-whitespace?` 1654 1655All of these take a character and return either a `TRUE` or 1656`FALSE` flag. 1657 1658## Conversions 1659 1660A few words are provided to convert case. Each takes a character 1661and returns the modified character. 1662 1663* `c:to-lower` 1664* `c:to-number` 1665* `c:to-upper` 1666* `c:toggle-case` 1667 1668RETRO also has `c:to-string`, which takes a character and 1669creates a new temporary string with the character. 1670 1671## I/O 1672 1673Characters can be displayed using `c:put`. 1674 1675``` 1676$a c:put 1677``` 1678 1679With the default system on BSD, Linux, and macOS (and other 1680Unix style hosts), `c:get` is provided to read input. This 1681may be buffered, depending on the host. 1682 1683# Defining Words 1684 1685Words are named functions. To start a word, preceed it's name 1686with a colon. Follow this by the definition, and end with a 1687semicolon. 1688 1689E.g., 1690 1691 :do-nothing ; 1692 :square dup * ; 1693 1694# Working With The Dictionary 1695 1696The Dictionary is a linked list containing the dictionary 1697headers. 1698 1699## Namespace 1700 1701Words operating on the dictionary are in the `d:` namespace. 1702 1703## Variables 1704 1705`Dictionary` is a variable holding a pointer to the most recent 1706header. 1707 1708## Header Structure 1709 1710Each entry follows the following structure: 1711 1712 Offset Contains 1713 ------ --------------------------- 1714 0000 Link to Prior Header 1715 0001 Link to XT 1716 0002 Link to Class Handler 1717 0003+ Word name (null terminated) 1718 1719RETRO provides words for accessing the fields in a portable 1720manner. It's recommended to use these to allow for future 1721revision of the header structure. 1722 1723## Accessing Fields 1724 1725Given a pointer to a header, you can use `d:xt`, `d:class`, 1726and `d:name` to access the address of each specific field. 1727There is no `d:link`, as the link will always be the first 1728field. 1729 1730## Shortcuts For The Latest Header 1731 1732RETRO provides several words for operating on the most recent 1733header. 1734 1735`d:last` returns a pointer to the latest header. `d:last.xt` 1736will give the contents of the `d:xt` field for the latest 1737header. There are also `d:last.class` and `d:last.name`. 1738 1739## Adding Headers 1740 1741Two words exist for making new headers. The easy one is 1742`d:create`. This takes a string for the name and makes a 1743new header with the class set to `class:data` and the XT 1744field pointing to `here`. 1745 1746Example: 1747 1748``` 1749'Base d:create 1750``` 1751 1752The other is `d:add-header`. This takes a string, a pointer 1753to the class handler, and a pointer for the XT field and 1754builds a new header using these. 1755 1756Example: 1757 1758``` 1759'Base &class:data #10000 d:add-header 1760``` 1761 1762## Searching 1763 1764RETRO provides two words for searching the dictionary. 1765 1766`d:lookup` takes a string and tries to find it in the 1767dictionary. It will return a pointer to the dictionary header 1768or a value of zero if the word was not found. 1769 1770`d:lookup-xt` takes a pointer and will return the dictionary 1771header that has this as the `d:xt` field, or zero if no match 1772is found. 1773 1774## Iteration 1775 1776You can use the `d:for-each` combinator to iterate over all 1777entries in the dictionary. For instance, to display the names 1778of all words: 1779 1780``` 1781[ d:name s:put sp ] d:for-each 1782``` 1783 1784For each entry, this combinator will push a pointer to the 1785entry to the stack and call the quotation. 1786 1787## Listing Words 1788 1789Most Forth systems provide WORDS for listing the names of all 1790words in the dictionary. RETRO does as well, but this is named 1791`d:words`. 1792 1793This isn't super useful as looking through several hundred 1794names is annoying. RETRO also provides `d:words-with` to help 1795in filtering the results. 1796 1797Example: 1798 1799``` 1800'class: d:words-with 1801``` 1802 1803 1804# Working With Floating Point 1805 1806Some RETRO systems include support for floating point numbers. 1807When present, this is built over the system `libm` using the 1808C `double` type. 1809 1810Floating point values are typically 64 bit IEEE 754 double 1811precision (1 bit for the sign, 11 bits for the exponent, and 1812the remaining 52 bits for the value), i.e. 15 decimal digits 1813of precision. 1814 1815## Sigil 1816 1817Floating point numbers start with a `.` 1818 1819Examples: 1820 1821 Token Value 1822 .1 1.0 1823 .0.5 0.5 1824 .-.4 -0.4 1825 .1.3 1.3 1826 1827## Namespace 1828 1829Floating point words are in the `f:` namespace. There is also 1830a related `e:` namespace for *encoded values*, which allows 1831storing of floats in standard memory. 1832 1833## Operation 1834 1835Floating point values exist on a separate stack, and are bigger 1836than the standard memory cells, so can not be directly stored 1837and fetched from memory. 1838 1839The floating point system also provides an alternate stack that 1840can be used to temporarily store values. 1841 1842The following words exist for arranging values on the floating 1843point stack. These are direct analogs to the non-prefiexd words 1844for dealing with the data stack. 1845 1846- `f:nip` 1847- `f:over` 1848- `f:depth` 1849- `f:drop` 1850- `f:drop-pair` 1851- `f:dup` 1852- `f:dup-pair` 1853- `f:dump-stack` 1854- `f:tuck` 1855- `f:swap` 1856- `f:rot` 1857 1858For the secondary floating point stack, the following words are 1859provided: 1860 1861- `f:push` 1862- `f:pop` 1863- `f:adepth` 1864- `f:dump-astack` 1865 1866## Constants 1867 1868 | Name | Returns | 1869 | -------- | ----------------- | 1870 | `f:E` | Euler's number | 1871 | `f:-INF` | Negative infinity | 1872 | `f:INF` | Positive infinity | 1873 | `f:NAN` | Not a Number | 1874 | `f:PI` | PI | 1875 1876## Comparisons 1877 1878The basic set of comparators are the same as those for 1879operating on integers. These are: 1880 1881- `f:-eq?` 1882- `f:between?` 1883- `f:eq?` 1884- `f:gt?` 1885- `f:lt?` 1886- `f:negative?` 1887- `f:positive?` 1888- `f:case` 1889 1890There are also a few additions for comparing to special values 1891like infinity and NaN. 1892 1893- `f:-inf?` 1894- `f:inf?` 1895- `f:nan?` 1896 1897## Basic Math 1898 1899- `f:*` 1900- `f:+` 1901- `f:-` 1902- `f:/` 1903- `f:abs` 1904- `f:floor` 1905- `f:inc` 1906- `f:limit` 1907- `f:max` 1908- `f:min` 1909- `f:negate` 1910- `f:power` 1911- `f:ceiling` 1912- `f:dec` 1913- `f:log` 1914- `f:sqrt` 1915- `f:square` 1916- `f:round` 1917- `f:sign` 1918- `f:signed-sqrt` 1919- `f:signed-square` 1920 1921## Geometry 1922 1923RETRO provides a small number of words for doing geometric 1924related calculations. 1925 1926| Word | Returns | 1927| -------- | ------------ | 1928| `f:acos` | arc cosine | 1929| `f:asin` | arc sine | 1930| `f:atan` | arc tangent | 1931| `f:cos` | cosine | 1932| `f:sin` | sine | 1933| `f:tan` | tangent | 1934 1935## Storage and Retrieval 1936 1937By leveraging the encoded value functions, RETRO is able to 1938allow storage of floating point values in memory. This does 1939have a tradeoff in accuracy as the memory cells are considerably 1940smaller than a full floating point size. 1941 1942You can use `f:fetch` to fetch a floating point value and 1943`f:store` to store one. 1944 1945If you need more precision, try Kiyoshi Yoneda's FloatVar 1946example (`example/FloatVar.forth`), which includes words to 1947store and retrieve values using multiple cells. 1948 1949- `f:to-number` 1950- `f:to-string` 1951 1952## I/O 1953 1954The floating point vocabulary has a single I/O word, `f:put`, 1955for the display of floating point numbers. 1956 1957## Encoded Values 1958 1959RETRO provides a means of encoding and decoding floating point 1960values into standard integer cells. This is based on the paper 1961"Encoding floating point values to shorter integers" by Kiyoshi 1962Yoneda and Charles Childers. 1963 1964- `f:E1` 1965- `f:to-e` 1966- `e:-INF` 1967- `e:-inf?` 1968- `e:INF` 1969- `e:MAX` 1970- `e:MIN` 1971- `e:NAN` 1972- `e:clip` 1973- `e:inf?` 1974- `e:max?` 1975- `e:min?` 1976- `e:n?` 1977- `e:nan?` 1978- `e:put` 1979- `e:to-f` 1980- `e:zero?` 1981 1982# Working With Files 1983 1984On Unix and Windows systems RETRO provides a set of words for 1985working with files. As a pragmatic choice these are mostly 1986modeled after the file functions in libc. 1987 1988The file words are in the `file:` namespace. 1989 1990## File Access Modes 1991 1992You can open a file for various operations. The functionality 1993allowed depends on the file access mode. Valid modes in RETRO 1994are: 1995 1996 file:A Open for appending; file pointer set to end of file 1997 file:R Open for reading; file pointer set to start of file 1998 file:R+ Open for reading and writing 1999 file:W Open for writing 2000 2001## Opening A File 2002 2003To open a file, pass the file name and a file mode to `file:open`. 2004 2005 '/etc/motd file:R file:open 2006 2007On a successful open this will return a file handle greater than 2008zero. 2009 2010Additionally, RETRO provides a few other forms for opening files. 2011 2012To open a file for reading: 2013 2014 '/etc/motd file:open-for-reading 2015 2016This will return the size of the file (as NOS) and the file handle 2017(as TOS). 2018 2019To open a file for writing: 2020 2021 '/tmp/test file:open-for-writing 2022 2023This returns the file handle. 2024 2025To open a file for append operations: 2026 2027 '/tmp/test file:open-for-append 2028 2029As with `file:open-for-reading`, this returns both the size of 2030the file and the file handle. 2031 2032## Closing A File 2033 2034To close a file, pass the file handle to `file:close`. 2035 2036 '/etc/motd file:A file:open file:close 2037 2038## Reading From A File 2039 2040To read a byte from an open file, pass the file handle to the 2041`file:read` word. 2042 2043 @FID file:read n:put 2044 2045To read a line from a file, pass the file handle to the word 2046`file:read-line`. 2047 2048 @FID file:read-line s:put 2049 2050The line is read into a temporary string buffer. Move the 2051text to a safe place if you aren't using it quickly or if 2052the length of the line is bigger than the size of a temporary 2053string. 2054 2055## Writing To A File 2056 2057To write a byte to a file, pass it and the file handle to 2058`file:write`. 2059 2060 $h @FID file:write 2061 $e @FID file:write 2062 $l @FID file:write 2063 $l @FID file:write 2064 $o @FID file:write 2065 2066Though cells are 32 or 64 bits in size, only the byte value will 2067be written to the file. 2068 2069## Deleting Files 2070 2071You can delete a file by passing the file name to `file:delete`. 2072 2073 /tmp/test file:delete 2074 2075## Check For File Existance 2076 2077Use `file:exists?` to detect the existance of a file. Pass it a 2078file name and it will return `TRUE` if existing or `FALSE` if 2079it does not. 2080 2081 '/etc/motd file:exists? 2082 2083This will also return `TRUE` if the filename is a directory. 2084 2085## Flush Caches 2086 2087Use `file:flush` to flush the system caches for a file. Pass a 2088file handle to this. 2089 2090 @FID file:flush 2091 2092## Seek A Position Within A File 2093 2094You can use `file:seek` to move the internal file pointer 2095for a given file. Pass this the new location and a file. 2096 2097 #100 @FID file:seek 2098 2099The location for the file pointer is a fixed offset from the 2100start of the file, not a relative offset. 2101 2102## Get The Current Position Within A File 2103 2104To find the current value of the file pointer within a file 2105just pass the file handle to `file:tell`. 2106 2107 @FID file:tell 2108 2109This returns a number that is the number of bytes into the file 2110that the file pointer is currently at. 2111 2112## Determine The Size Of A File 2113 2114Use `file:size` to return the size of a file. Pass this a file 2115handle and it will return the size of a file, or 0 if empty. If 2116the file is a directory, it returns -1. 2117 2118 @FID file:size 2119 2120## Reading An Entire File 2121 2122If you want to read an entire file into memory you can use 2123`file:slurp`. This takes the starting address of a memory 2124region and the name of the file. 2125 2126 here '/etc/motd file:slurp 2127 2128Take care that the memory buffer is large enough for the file 2129being read or you will run into problems. 2130 2131## Writing A String To A File 2132 2133If you have a string that you want to write to a file, replacing 2134any existing contents, you can use `file:spew`. This takes the 2135string to write and a file name. 2136 2137 'hello_world '/tmp/test.txt file:spew 2138 2139## Iterating Over A File, Line By Line 2140 2141You can easily iterate over each line in a file using the word 2142`file:for-each-line`. This will take a file name and a quote, 2143read each line into a temporary string, then pass this string to 2144the quote. 2145 2146 '/etc/motd [ s:put nl ] file:for-each-line 2147 2148# Loops 2149 2150RETRO provides several words for creating loops. 2151 2152## Unconditional Loops 2153 2154An unconditional loop begins with `repeat` and ends with `again`. 2155 2156 :test repeat #1 n:put sp again ; 2157 test 2158 2159Unconditional loops must be inside a definition or quote. To exit 2160one of these, use `0;`, `-if;` or `if;`. 2161 2162 :test #100 repeat 0; dup n:put sp n:dec again ; 2163 test 2164 2165 :test #100 repeat dup #50 eq? [ 'done! s:put nl ] if; n:dec again ; 2166 test 2167 2168You can also achieve this via recursion: 2169 2170 :test 0; dup n:put sp n:dec test ; 2171 #100 test 2172 2173Be careful with recursion as the virtual machine will have a limited 2174amount of space for the address stack and recursing too many times 2175can cause a stack overflow. 2176 2177## Conditional Loops 2178 2179There are two conditional looping combinators: `while` and `until`. 2180Both take a quote and execute it, checking a returned flag to decide 2181when to stop running. 2182 2183 #0 [ dup n:put sp n:inc dup #10 eq? ] until 2184 #10 [ dup n:put sp n:dec dup n:-zero? ] while 2185 2186## Counted Loops 2187 2188There are two combinators for counted loops. These are `times` and 2189`indexed-times`. 2190 2191 #0 #10 [ dup n:put sp n:inc ] times nl 2192 #10 [ I n:put sp ] indexed-times 2193 2194The `indexed-times` provides an index via the `I`, `J`, and 2195`K` words. `I` will be the index of the current loop, with `J` and 2196`K` being the indexes of the next two older loops. 2197 2198The loop indexes can be accessed outside the loop body: 2199 2200 :display I n:square n:put sp ; 2201 :squares [ display ] indexed-times nl ; 2202 #100 squares 2203 2204## Tradeoffs 2205 2206The unconditional loop form is more efficient as it's just a 2207simple jump operation. The `times` counted loops are a little 2208slower, but can be cleaner and more readable in many cases. The 2209`indexed-times` form is significantly slower than the other 2210two forms. 2211 2212# Working With Numbers 2213 2214Numbers in RETRO are signed integers. 2215 2216## Sigil 2217 2218All numbers start with a `#` sigil. 2219 2220## Namespace 2221 2222Most words operating on numbers are in the `n:` namespace. 2223 2224## Range of Values 2225 2226A default RETRO system with 32 bit cells provides a range of 2227-2,147,483,648 to 2,147,483,647. For 64 bit systems, the range 2228will be -9,223,372,036,854,775,807 to 9,223,372,036,854,775,806. 2229 2230You can check the range your VM and image support using: 2231 2232 n:MIN 2233 n:MAX 2234 2235These will return the limits for your system. 2236 2237## Comparisons 2238 2239RETRO provides a number of comparison words for numeric values. 2240 2241The basic comparators are: 2242 2243 -eq? 2244 eq? 2245 lt? 2246 lteq? 2247 gt? 2248 gteq? 2249 2250Additionally RETRO also provides: 2251 2252 n:-zero? 2253 n:between? 2254 n:even? 2255 n:negative? 2256 n:odd? 2257 n:positive? 2258 n:strictly-positive? 2259 n:zero? 2260 2261## Basic Operations 2262 2263 + 2264 - 2265 * 2266 / 2267 mod 2268 /mod 2269 n:abs 2270 n:dec 2271 n:inc 2272 n:limit 2273 n:max 2274 n:min 2275 n:negate 2276 n:pow 2277 n:sqrt 2278 n:square 2279 2280## Conversions 2281 2282You can convert a number to a string with `n:to-string` or 2283to a floating point value with `n:to-float`. 2284 2285 #123 n:to-float f:put 2286 2287 #123 n:to-string s:put 2288 2289## Display 2290 2291To display a number, use `n:put`. 2292 2293 #123 n:put 2294 2295# Working With Pointers 2296 2297## Sigil 2298 2299Pointers are returned by the `&` sigil. 2300 2301## Examples 2302 2303``` 2304'Base var 2305&Base fetch 2306#10 &Base store 2307 2308#10 &n:inc call 2309``` 2310 2311## Notes 2312 2313The use of `&` to get a pointer to a data structure (with a 2314word class of `class:data`) is not required. I like to use it 2315anyway as it makes my intent a little clearer. 2316 2317Pointers are useful with combinators. Consider: 2318 2319``` 2320:abs dup n:negative? [ n:negate ] if ; 2321``` 2322 2323Since the target quote body is a single word, it is more 2324efficient to use a pointer instead: 2325 2326``` 2327:abs dup n:negative? &n:negate if ; 2328``` 2329 2330The advantages are speed (saves a level of call/return by 2331avoiding the quotation) and size (for the same reason). 2332This may be less readable though, so consider the balance 2333of performance to readability when using this approach. 2334 2335# Quotations 2336 2337Quotes are anonymous functions. RETRO uses these as the basis for 2338executable flow control and combinatorial logic. 2339 2340## Using Quotations 2341 2342To make a quotation, surround the code with square brackets. E.g., 2343 2344 #1 #2 eq? [ 'No_match s:put nl ] -if 2345 2346Quotes can be nested: 2347 2348 [ #3 [ #4 ] dip ] call 2349 2350After creation, a pointer to the quotation is left on the stack 2351(or is compiled into the current definition). 2352 2353## Combinators 2354 2355Words operating on quotations are called combinators; these are 2356discussed in *Using Combinators*. 2357 2358## Implementation 2359 2360A quotation is compiled as: 2361 2362 ... code before quotation ... 2363 i liju.... (if_compiling_only) 2364 d address after quotation (if_compiling_only) 2365 ... code for quotation 2366 i re...... (this_is_where_the_quote_ends) 2367 i li...... 2368 d address of code for quotation 2369 ... code after quotation .... 2370 2371## Other Notes 2372 2373Quotations are used heavily in RETRO. They give the source a 2374feel that's different from traditional Forth, and allow for 2375a more consistent syntax. 2376 2377For instance, in a traditional Forth, you might have some 2378conditionals: 2379 2380 IF ... THEN 2381 IF ... ELSE ... THEN 2382 IF ... EXIT THEN 2383 2384RETRO uses conditional combinators for these: 2385 2386 [ ... ] if 2387 [ ... ] [ ... ] choose 2388 [ ... ] if; 2389 2390Or loops: 2391 2392 FOR ... NEXT 2393 2394Is replaced by: 2395 2396 [ ... ] times 2397 2398This can also extend to stack flow. Sequences like: 2399 2400 >R ... >R 2401 DUP >R ... >R 2402 2403Become: 2404 2405 [ ... ] dip 2406 [ ... ] sip 2407 2408And forms like: 2409 2410 1 2 3 * swap 3 * swap 2411 2412Can be replaced with a combinator like: 2413 2414 #1 #2 [ #3 * ] bi@ 2415 2416While there is a different set of words to learn, I find that 2417overall there's less noise from low level stack shuffling words 2418and the added consistency with regards to overall syntax has 2419been nice as I was never fond of the multiple forms that existed 2420in traditional Forth. 2421 2422# Sockets 2423 2424On Unix hosts, RETRO provides an optional set of words for using 2425network sockets. 2426 2427## Create a Socket 2428 2429To create a new socket, just run: 2430 2431 socket:create 2432 2433This will return a socket handle. 2434 2435## Bind To A Port 2436 2437To bind to a port, pass the port number and socket handle 2438to `socket:bind`. The port should be a string. This will return 24390 if successful, -1 if not successful, and an error code. 2440 2441 '9998 @Sock socket:bind 2442 2443## Configure To Allow Incoming Connections 2444 2445To prepare a socket for incoming connections use socket:listen. This 2446will take a backlog count and a socket handle. It returns a flag 2447(0 success, -1 failed) and an error code. 2448 2449 #3 @Sock socket:listen 2450 2451## Accept Connections 2452 2453To accept connections pass the socket handle to `socket:accept`. 2454This returns a new socket for the connection and an error code. 2455 2456 @Sock socket:accept 2457 2458## Make A Connection 2459 2460To connect to a server using the socket: 2461 2462 'forth.works '70 socket:configure 2463 @Sock socket:connect 2464 2465`socket:connect` will return a status code and an error code. 2466 2467## Writing To A Socket 2468 2469To write a string to a socket, use `socket:send`. This will 2470take a string and a socket handle and will return the number 2471of bytes sent and an error code. 2472 2473 'test @Sock socket:send 2474 2475## Reading From A Socket 2476 2477To read data from a socket pass an address, a maximum number of 2478bytes, and the socket handle to `socket:recv`. This will return 2479the number of bytes received and an error code. The bytes will 2480be stored in memory starting at the specified address. 2481 2482 here #1024 @Sock socket:recv 2483 2484## Close a Socket 2485 2486To close a socket, pass the socket handle to `socket:close`. 2487 2488 @Socket socket:close 2489 2490# Unix Scripting 2491 2492RETRO on Unix hosts is designed to play well with scripting. 2493 2494Shebang 2495 2496To run an entire program directly, start the file with the standard 2497shebang and make the file executable: 2498 2499 #!/usr/bin/env retro 2500 2501This requires the retro binary to be in your path. 2502 2503## Arguments 2504 2505RETRO provides several words in the `script:` namespace for accessing 2506command line arguments. 2507 2508The number of arguments can be accessed via `script:arguments`. This 2509will return a number with the arguments, other than the script name. 2510 2511 script:arguments '%n_arguments_passed\n s:format s:put 2512 2513To retreive an argument, pass the argument number to `script:get-argument`: 2514 2515 script:arguments [ I script:get-argument s:put nl ] indexed-times 2516 2517And to get the name of the script, use `script:name`. 2518 2519 script:name s:put 2520 2521## Mixing 2522 2523With use of the Unu literate format, it's possible to mix both shell 2524and RETRO code into a single script. As an example, this is a bit of 2525shell that runs itself via retro for each .retro file in the current 2526directory tree: 2527 2528 #!/bin/sh 2529 2530 # shell part 2531 find . -name '*.retro' -print0 | xargs -0 -n 1 retro $0 2532 exit 2533 2534 # retro part 2535 2536 This will scan a source file and do something with it: 2537 2538 ~~~ 2539 ... do stuff ... 2540 ~~~ 2541 2542# Working With Strings 2543 2544Strings in RETRO are NULL terminated sequences of values 2545representing characters. Being NULL terminated, they can't 2546contain a NULL (ASCII 0). 2547 2548The character words in RETRO are built around ASCII, but 2549strings can contain UTF8 encoded data if the host platform 2550allows. Words like `s:length` will return the number of bytes, 2551not the number of logical characters in this case. 2552 2553## Sigil 2554 2555Strings begin with a single `'`. 2556 2557 'Hello 2558 'This_is_a_string 2559 'This_is_a_much_longer_string_12345_67890_!!! 2560 2561RETRO will replace spaces with underscores. If you need both 2562spaces and underscores in a string, escape the underscores and 2563use `s:format`: 2564 2565 'This_has_spaces_and_under\_scored_words. s:format 2566 2567## Namespace 2568 2569Words operating on strings are in the `s:` namespace. 2570 2571## Lifetime 2572 2573At the interpreter, strings get allocated in a rotating buffer. 2574This is used by the words operating on strings, so if you need 2575to keep them around, use `s:keep` or `s:copy` to move them to 2576more permanent storage. 2577 2578In a definition, the string is compiled inline and so is in 2579permanent memory. 2580 2581You can manually manage the string lifetime by using `s:keep` 2582to place it into permanent memory or `s:temp` to copy it to 2583the rotating buffer. 2584 2585## Mutability 2586 2587Strings are mutable. If you need to ensure that a string is 2588not altered, make a copy before operating on it or see the 2589individual glossary entries for notes on words that may do 2590this automatically. 2591 2592## Searching 2593 2594RETRO provides four words for searching within a string. 2595 2596* `s:contains-char?` 2597* `s:contains-string?` 2598* `s:index-of` 2599* `s:index-of-string` 2600 2601## Comparisons 2602 2603* `s:eq?` 2604* `s:case` 2605 2606## Extraction 2607 2608To obtain a new string containing the first `n` characters from 2609a source string, use `s:left`: 2610 2611 'Hello_World #5 s:left 2612 2613To obtain a new string containing the last `n` characters from 2614a source string, use `s:right`: 2615 2616 'Hello_World #5 s:right 2617 2618If you need to extract data from the middle of the string, use 2619`s:substr`. This takes a string, the offset of the first 2620character, and the number of characters to extract. 2621 2622 'Hello_World #3 #5 s:substr 2623 2624## Joining 2625 2626You can use `s:append` or `s:prepend` to merge two strings. 2627 2628 'First 'Second s:append 2629 'Second 'First s:prepend 2630 2631## Tokenization 2632 2633* `s:tokenize` 2634* `s:tokenize-on-string` 2635* `s:split` 2636* `s:split-on-string` 2637 2638## Conversions 2639 2640To convert the case of a string, RETRO provides `s:to-lower` 2641and `s:to-upper`. 2642 2643`s:to-number` is provided to convert a string to an integer 2644value. This has a few limitations: 2645 2646- only supports decimal 2647- non-numeric characters will result in incorrect values 2648 2649## Cleanup 2650 2651RETRO provides a handful of words for cleaning up strings. 2652 2653`s:chop` will remove the last character from a string. This 2654is done by replacing it with an ASCII:NULL. 2655 2656`s:trim` removes leading and trailing whitespace from a string. 2657For more control, there is also `s:trim-left` and `s:trim-right` 2658which let you trim just the leading or trailing end as desired. 2659 2660## Combinators 2661 2662* `s:for-each` 2663* `s:filter` 2664* `s:map` 2665 2666## Other 2667 2668* `s:evaluate` 2669* `s:copy` 2670* `s:reverse` 2671* `s:hash` 2672* `s:length` 2673* `s:replace` 2674* `s:format` 2675* `s:empty` 2676 2677## Controlling The Temporary Buffers 2678 2679As dicussed in the Lifetime subsection, temporary strings are 2680allocated in a rotating buffer. The details of this can be 2681altered by updating two variables. 2682 2683 | Variable | Holds | 2684 | ------------- | ---------------------------------------- | 2685 | TempStrings | The number of temporary strings | 2686 | TempStringMax | The maximum length of a temporary string | 2687 2688For example, to increase the number of temporary strings to 268948: 2690 2691 #48 !TempStrings 2692 2693The defaults are: 2694 2695 | Variable | Default | 2696 | ------------- | ------- | 2697 | TempStrings | 32 | 2698 | TempStringMax | 512 | 2699 2700It's also important to note that altering these will affect 2701the memory map for all temporary buffers. Do not use anything 2702already in the buffers after updating these or you will risk 2703data corruption and possible crashes. 2704 2705# Using Combinators 2706 2707A combinator is a function that consumes functions as input. 2708They are used heavily by the RETRO system. 2709 2710## Types of Combinators 2711 2712Combinators are divided into three primary types: compositional, 2713execution flow, and data flow. 2714 2715## Compositional 2716 2717A compositional combinator takes elements from the stack and 2718returns a new quote. 2719 2720`curry` takes a value and a quote and returns a new quote 2721applying the specified quote to the specified value. As an 2722example, 2723 2724``` 2725:acc (n-) here swap , [ dup v:inc fetch ] curry ; 2726``` 2727 2728This would create an accumulator function, which takes an 2729initial value and returns a quote that will increase the 2730accumulator by 1 each time it is invoked. It will also return 2731the latest value. So: 2732 2733``` 2734#10 acc 2735dup call n:put 2736dup call n:put 2737dup call n:put 2738``` 2739 2740## Execution Flow 2741 2742Combinators of this type execute other functions. 2743 2744### Fundamental 2745 2746`call` takes a quote and executes it immediately. 2747 2748``` 2749[ #1 n:put ] call 2750&words call 2751``` 2752 2753### Conditionals 2754 2755RETRO provides three primary combinators for use with 2756conditional execution of quotes. These are `choose`, `if`, 2757and `-if`. 2758 2759`choose` takes a flag and two quotes from the stack. If the 2760flag is true, the first quote is executed. If false, the 2761second quote is executed. 2762 2763``` 2764#-1 [ 'true s:put ] [ 'false s:put ] choose 2765 #0 [ 'true s:put ] [ 'false s:put ] choose 2766``` 2767 2768`if` takes a flag and one quote from the stack. If the flag is 2769true, the quote is executed. If false, the quote is discarded. 2770 2771``` 2772#-1 [ 'true s:put ] if 2773 #0 [ 'true s:put ] if 2774``` 2775 2776`-if` takes a flag and one quote from the stack. If the flag is 2777false, the quote is executed. If true, the quote is discarded. 2778 2779``` 2780#-1 [ 'false s:put ] -if 2781 #0 [ 'false s:put ] -if 2782``` 2783 2784RETRO also provides `case` and `s:case` for use when you have 2785multiple values to check against. This is similar to a `switch` 2786in C. 2787 2788`case` takes two numbers and a quote. The initial value is 2789compared to the second one. If they match, the quote is 2790executed. If false, the quote is discarded and the initial 2791value is left on the stack. 2792 2793Additionally, if the first value was matched, `case` will exit 2794the calling function, but if false, it returns to the calling 2795function. 2796 2797`s:case` works the same way, but for strings instead of simple 2798values. 2799 2800``` 2801:test (n-) 2802 #1 [ 'Yes s:put ] case 2803 #2 [ 'No s:put ] case 2804 drop 'No idea s:put ; 2805``` 2806 2807### Looping 2808 2809Several combinators are available for handling various looping 2810constructs. 2811 2812`while` takes a quote from the stack and executes it repeatedly 2813as long as the quote returns a true flag on the stack. This flag 2814must be well formed and equal -1 or 0. 2815 2816``` 2817#10 [ dup n:put sp n:dec dup 0 -eq? ] while 2818``` 2819 2820`times` takes a count and quote from the stack. The quote will 2821be executed the number of times specified. No indexes are pushed 2822to the stack. 2823 2824``` 2825#1 #10 [ dup n:put sp n:inc ] times drop 2826``` 2827 2828There is also a `indexed-times` variation that provides 2829access to the loop index (via `I`) and parent loop indexes 2830(via `J` and `K`). 2831 2832``` 2833#10 [ I n:put sp ] indexed-times 2834``` 2835 2836## Data Flow 2837 2838These combinators exist to simplify stack usage in various 2839circumstances. 2840 2841### Preserving 2842 2843Preserving combinators execute code while preserving portions 2844of the data stack. 2845 2846`dip` takes a value and a quote, moves the value off the main 2847stack temporarily, executes the quote, and then restores the 2848value. 2849 2850``` 2851#10 #20 [ n:inc ] dip 2852``` 2853 2854Would yield the following on the stack: 2855 2856``` 285711 20 2858``` 2859 2860`sip` is similar to `dip`, but leaves a copy of the original 2861value on the stack during execution of the quote. So: 2862 2863``` 2864#10 [ n:inc ] sip 2865``` 2866 2867Leaves us with: 2868 2869``` 287011 10 2871``` 2872 2873### Cleave 2874 2875Cleave combinators apply multiple quotations to a single value 2876or set of values. 2877 2878`bi` takes a value and two quotes, it then applies each quote to 2879a copy of the value. 2880 2881``` 2882#100 [ n:inc ] [ n:dec ] bi 2883``` 2884 2885`tri` takes a value and three quotes. It then applies each quote 2886to a copy of the value. 2887 2888``` 2889#100 [ n:inc ] [ n:dec ] [ dup * ] tri 2890``` 2891 2892### Spread 2893 2894Spread combinators apply multiple quotations to multiple values. 2895The asterisk suffixed to these function names signifies that 2896they are spread combinators. 2897 2898`bi*` takes two values and two quotes. It applies the first 2899quote to the first value and the second quote to the second 2900value. 2901 2902``` 2903#1 #2 [ n:inc ] [ #2 * ] bi* 2904``` 2905 2906`tri*` takes three values and three quotes, applying the 2907first quote to the first value, the second quote to the 2908second value, and the third quote to the third value. 2909 2910``` 2911#1 #2 #3 [ n:inc ] [ #2 * ] [ n:dec ] tri* 2912``` 2913 2914### Apply 2915 2916Apply combinators apply a single quotation to multiple values. 2917The @ sign suffixed to these function names signifies that they 2918are apply combinators. 2919 2920`bi@` takes two values and a quote. It then applies the quote to 2921each value. 2922 2923``` 2924#1 #2 [ n:inc ] bi@ 2925``` 2926 2927`tri@` takes three values and a quote. It then applies the quote 2928to each value. 2929 2930``` 2931#1 #2 #3 [ n:inc ] tri@ 2932``` 2933 2934RETRO also provides `for-each` combinators for various data 2935structures. The exact usage of these varies; consult the 2936Glossary and relevant chapters for more details on these. 2937 2938# Word Classes 2939 2940Word classes are one of the two elements at the heart of 2941RETRO's interpreter. 2942 2943There are different types of words in a Forth system. At a 2944minimum there are data words, regular words, and immediate 2945words. There are numerous approaches to dealing with this. 2946 2947In RETRO I define special words which receive a pointer and 2948decide how to deal with it. These are grouped into a `class:` 2949namespace. 2950 2951## How It Works 2952 2953When a word is found in the dictionary, RETRO will push a 2954pointer to the definition (the `d:xt` field) to the stack 2955and then call the word specified by the `d:class` field. 2956 2957The word called is responsible for processing the pointer 2958passed to it. 2959 2960As a simple case, let's look at `immediate` words. These are 2961words which will always be called when encountered. A common 2962strategy is to have an immediacy bit which the interpreter 2963will look at, but RETRO uses a class for this. The class is 2964defined: 2965 2966``` 2967:class:immediate (a-) call ; 2968``` 2969 2970Or a normal word. These should be called at interpret time 2971or compiled into definitions. The handler for this can look 2972like: 2973 2974``` 2975:class:word (a-) compiling? [ compile:call ] [ call ] choose ; 2976``` 2977 2978## Using Classes 2979 2980The ability to add new classes is useful. If I wanted to add 2981a category of word that preserves an input value, I could do 2982it with a class: 2983 2984``` 2985:class:duplicating (a-) 2986 compiling? [ &dup compile:call ] [ &dup dip ] choose 2987 class:word ; 2988 2989:duplicating &class:duplicating reclass ; 2990 2991:. n:put nl ; duplicating 2992#100 . . . 2993``` 2994 2995# Checking The Version 2996 2997RETRO releases add and change things. You can use the `Version` 2998variable to determine the version in use and react accordingly. 2999 3000``` 3001@Version #201906 eq? [ 'Needs_2019.6! s:put nl bye ] if 3002``` 3003 3004This can be also be used to conditionally load compatibility files: 3005 3006``` 3007(If_newer_than_2016.6,_load_aliases_for_renamed_words) 3008@Version #201906 gt? [ 'Renamed_2019.6.forth include ] if 3009``` 3010 3011## Version Number Format 3012 3013The version is a six digit number encoding the year and month of 3014the release. So: 3015 3016 201901 is 2019.1 3017 201906 is 2019.6 3018 201911 is 2019.11 3019 3020A `#100 /mod` will suffice to split these if needed. 3021 3022# Errors 3023 3024RETRO does only minimal error checking. 3025 3026## Non-Fatal 3027 3028A non-fatal error will be reported on *word not found* during 3029interactive or compile time. Note that this only applies to 3030calls: if you try to get a pointer to an undefined word, the 3031returned pointer will be zero. 3032 3033## Fatal 3034 3035A number of conditions are known to cause fatal errors. The 3036main ones are stack overflow, stack underflow, and division 3037by zero. 3038 3039On these, RETRO will generally exit. For stack depth issues, 3040the VM will attempt to display an error prior to exiting. 3041 3042In some cases, the VM may get stuck in an endless loop. If this 3043occurs, try using CTRL+C to kill the process, or kill it using 3044whatever means your host system provides. 3045 3046## Rationale 3047 3048Error checks are useful, but slow - especially on a minimal 3049system like RETRO. The overhead of doing depth or other checks 3050adds up quickly. 3051 3052As an example, adding a depth check to `drop` increases the 3053time to use it 250,000 times in a loop from 0.16 seconds to 30541.69 seconds. 3055 3056 3057# Lexical Scope 3058 3059RETRO has a single dictionary, but does provide a means of using 3060lexical scope to keep this dictionary clean. 3061 3062## Example 3063 3064``` 3065{{ 3066 'A var 3067 :++A &A v:inc ; 3068---reveal--- 3069 :B ++A ++A @A n:put nl ; 3070}} 3071``` 3072 3073In this example, the lexical namespace is created with `{{`. A 3074variable (`A`) and word (`++A`) are defined. Then a marker is 3075set with `---reveal---`. Another word (`B`) is defined, and the 3076lexical area is closed with `}}`. 3077 3078The headers between `{{` and `---reveal---` are then hidden from 3079the dictionary, leaving only the headers between `---reveal---` 3080and `}}` exposed. 3081 3082## Notes 3083 3084This only affects word visibility within the scoped area. As an 3085example: 3086 3087``` 3088:a #1 ; 3089 3090{{ 3091 :a #2 ; 3092---reveal--- 3093 :b 'a s:evaluate n:put ; 3094}} 3095``` 3096 3097In this, after `}}` closes the area, the `:a #2 ;` is hidden and 3098the `s:evaluate` will find the `:a #1 ;` when `b` is run. 3099 3100# The Stacks 3101 3102The stacks are a defining feature of Forth. They are are used 3103to pass data between words and to track return addresses for 3104function calls. 3105 3106RETRO always has two stacks, and optionally (if built with 3107floating point support) a third. 3108 3109## Data Stack 3110 3111This is the primary stack. Values are placed here, passed to 3112words which consume them and then return results. When I 3113refer to "the stack", this is the one I mean. Learning to use 3114the stack is a crucial part to making effective use of RETRO. 3115 3116### Placing Values On The Stack 3117 3118Values can be placed on the stack directly. 3119 3120 | Example | Action | 3121 | -------------- | ---------------------------------------- | 3122 | `#300123` | Push the number `300123` to the stack | 3123 | `$h` | Push the ASCII code for `h` to the stack | 3124 | `'hello_world` | Push a pointer to a string to the stack | 3125 | `&fetch` | Push the address of `fetch` to the stack | 3126 3127### Reordering The Stack 3128 3129RETRO provides a number of *shufflers* for reordering items 3130on the stack. 3131 3132Some of the most common ones are: 3133 3134 | Word | Before | After | 3135 | ------- |--------- | -------- | 3136 | dup | #1 | #1 #1 | 3137 | drop | #1 #2 | #1 | 3138 | swap | #1 #2 | #2 #1 | 3139 | over | #1 #2 | #1 #2 #1 | 3140 | tuck | #1 #2 | #2 #1 #2 | 3141 | nip | #1 #2 | #2 | 3142 | rot | #1 #2 #3 | #3 #1 #2 | 3143 3144You can use `push` and `pop` to move values to and from the 3145address stack. Make sure you `pop` them back before the word 3146ends or RETRO will crash. These two words can not be used 3147at the interpreter. 3148 3149There is also a special one, `reorder`, which allows for big 3150stack restructuring. This is slow but can be very useful. 3151 3152As an example, let's say we have four values: 3153 3154 #1 #2 #3 #4 3155 3156And we want them to become: 3157 3158 #4 #3 #2 #1 3159 3160Doing this with the basic shufflers is difficult. You could end 3161up with something similar to: 3162 3163 swap rot push rot pop swap 3164 3165But with `reorder`, you can just express the before and after 3166states: 3167 3168 'abcd 'dcba reorder 3169 3170### Resetting The Stack 3171 3172If you need to quickly empty the stack, use `reset`. 3173 3174### Get The Stack Depth 3175 3176To find out how many items are on the stack, use `depth`. 3177 3178### Displaying The Stack 3179 3180You can display the stack by running `dump-stack`. 3181 3182### Data Flow Combinators 3183 3184RETRO provides *combinators* for working with data order on 3185the stack. These are covered in a later chapter and are worth 3186learning to use as they can help provide a cleaner, more 3187structured means of working. 3188 3189### Tips 3190 3191The stack is *not* an array in addressable memory. Don't try 3192to treat it like one. 3193 3194## Address Stack 3195 3196This stack primarily holds return addresses for function calls. 3197You normally won't need to directly interact with this stack, 3198but you can use `push` and `pop` to move values between the 3199data stack and this. 3200 3201## Floating Point Stack 3202 3203If you are using a build with floating point support a third 3204stack will be present. Floating point values are kept and 3205passed between words using this. 3206 3207See the Floating Point chapter for more details on this. 3208 3209## Tips 3210 3211I recommend keeping the data stack shallow. Don't try to juggle 3212too much; it's better to factor definitions into shorter ones 3213that deal with simpler parts of the stack values than to have 3214a big definition with a lot of complex shuffling. 3215 3216## Notes 3217 3218The standard system is configured with a very deep data stack 3219(around 2,000 items) and an address stack that is 3x deeper. 3220In actual use, your programs are unlikely to ever need this, 3221but if you do, keep the limits in mind. 3222 3223# Internals: Nga Virtual Machine 3224 3225## Overview 3226 3227At the heart of RETRO is a simple MISC (minimal instruction 3228set computer) processor for a dual stack architecture. 3229 3230This is a very simple and straightforward system. There are 323130 instructions. The memory is a linear array of signed 32 3232bit values. And there are two stacks: one for data and one 3233for return addresses. 3234 3235## Instruction Table 3236 3237 | Stacks | 3238 | Opcode | Muri | Full Name | Data | Address | 3239 | ------ | ---- | ------------------ | ----- | ------- | 3240 | 0 | .. | nop | - | - | 3241 | 1 | li | lit | -n | - | 3242 | 2 | du | dup | n-nn | - | 3243 | 3 | dr | drop | n- | - | 3244 | 4 | sw | swap | xy-yx | - | 3245 | 5 | pu | push | n- | -n | 3246 | 6 | po | pop | -n | n- | 3247 | 7 | ju | jump | a- | - | 3248 | 8 | ca | call | a- | -A | 3249 | 9 | cc | conditional call | af- | -A | 3250 | 10 | re | return | - | A- | 3251 | 11 | eq | equality | xy-f | - | 3252 | 12 | ne | inequality | xy-f | - | 3253 | 13 | lt | less than | xy-f | - | 3254 | 14 | gt | greater than | xy-f | - | 3255 | 15 | fe | fetch | a-n | - | 3256 | 16 | st | store | na- | - | 3257 | 17 | ad | addition | xy-n | - | 3258 | 18 | su | subtraction | xy-n | - | 3259 | 19 | mu | multiplication | xy-n | - | 3260 | 20 | di | divide & remainder | xy-rq | - | 3261 | 21 | an | bitwise and | xy-n | - | 3262 | 22 | or | bitwise or | xy-n | - | 3263 | 23 | xo | bitwise xor | xy-n | - | 3264 | 24 | sh | shift | xy-n | - | 3265 | 25 | zr | zero return | n-? | - | 3266 | 26 | ha | halt | - | - | 3267 | 27 | ie | i/o enumerate | -n | - | 3268 | 28 | iq | i/o query | n-xy | - | 3269 | 29 | ii | i/o invoke | ...n- | - | 3270 3271## Encoding 3272 3273Up to four instructions can be packed into each memory cell. 3274 3275As an example, 3276 3277 Opcode 4 Opcode 3 Opcode 2 Opcode 1 3278 00000000:00000000:00000000:00000000 3279 3280If we have a bundle of `duliswst`, it would look like: 3281 3282 st sw li du 3283 00010000:00000100:00000001:00000010 3284 3285Each `li` should have a value in the following cell(s). These 3286values will be pushed to the stack. E.g., `lili....` and 32871, 2: 3288 3289 00000000:00000000:00000001:00000001 3290 00000000 00000000 00000000 00000001 (1) 3291 00000000 00000000 00000000 00000010 (2) 3292 3293## Shifts 3294 3295`sh` performs a bitwise arithmetic shift operation. 3296 3297This takes two values: 3298 3299 xy 3300 3301And returns a single one: 3302 3303 z 3304 3305If y is positive, this shifts `x` right by `y` bits. If negative, 3306it shifts left. 3307 3308## Queries: Memory, Stacks 3309 3310The `fe` instruction allows queries of some data related to 3311the Nga VM state. These are returned by reading from negative 3312addresses: 3313 3314 | Address | Returns | 3315 | ------- | ---------------------- | 3316 | -1 | Data stack depth | 3317 | -2 | Address stack depth | 3318 | -3 | Maximum Image Size | 3319 | -4 | Minimum Integer Value | 3320 | -5 | Maximum Integer Value | 3321 3322## I/O Devices 3323 3324Nga provides three instructions for interacting with I/O devices. 3325These are: 3326 3327 ie i/o enumerate returns the number of attached devices 3328 iq i/o query returns information about a device 3329 ii i/o interact invokes an interaction with a device 3330 3331As an example, with an implementation providing an output source, 3332a block storage system, and keyboard: 3333 3334 ie will return `3` since there are three i/o devices 3335 0 iq will return 0 0, since the first device is a screen (0) 3336 with a version of 0 3337 1 iq will return 1 3, since the second device is a block 3338 storage (3), with a version of 1 3339 2 iq will return 0 1, since the third device is a keyboard 3340 (1), with a version of 0 3341 3342In this case, some interactions can be defined: 3343 3344 : c:put 3345 i liiire.. 3346 d 0 3347 3348 : c:get 3349 i liiire.. 3350 d 2 3351 3352Setup the stack, push the device ID to the stack, and then use 3353`ii` to invoke the interaction. 3354 3355A RETRO system requires one I/O device (a generic output for a 3356single character). This must be the first device, and must have 3357a device ID of 0. 3358 3359All other devices are optional and can be specified in any order. 3360 3361The currently supported and reserved device identifiers are: 3362 3363 | ID | Device Type | Notes | 3364 | ---- | ---------------- | -------------------------- | 3365 | 0000 | Generic Output | Always present as device 0 | 3366 | 0001 | Keyboard | | 3367 | 0002 | Floating Point | | 3368 | 0003 | Block Storage | Raw, 1024 cell blocks | 3369 | 0004 | Filesystem | Unix-style Files | 3370 | 0005 | Network: Gopher | Make gopher requests | 3371 | 0006 | Network: HTTP | Make HTTP requests | 3372 | 0007 | Network: Sockets | | 3373 | 0008 | Syscalls: Unix | | 3374 | 0009 | Scripting Hooks | | 3375 | 0010 | Random Number | | 3376 3377This list may be revised in the future. The only guaranteed 3378stable indentifier is 0000 for generic output. 3379 3380# Internals: Interface Layers 3381 3382Nga provides a virtual processor and an extensible way of adding 3383I/O devices, but does not provide any I/O itself. Adding I/O is 3384the responsability of the *interface layer*. 3385 3386An interface layer will wrap Nga, providing at least one I/O 3387device (a generic output target), and a means of interacting 3388with the *retro image*. 3389 3390It's expected that this layer will be host specific, adding any 3391system interactions that are needed via the I/O instructions. 3392The image will typically be extended with words to use these. 3393 3394 3395 3396# Internals: I/O 3397 3398RETRO provides three words for interacting with I/O. These are: 3399 3400 io:enumerate returns the number of attached devices 3401 io:query returns information about a device 3402 io:invoke invokes an interaction with a device 3403 3404As an example, with an implementation providing an output source, 3405a block storage system, and keyboard: 3406 3407 io:enumerate will return `3` since there are three 3408 i/o devices 3409 #0 io:query will return 0 0, since the first device 3410 is a screen (type 0) with a version of 0 3411 #1 io:query will return 1 3, since the second device is 3412 block storage (type 3), with a version of 1 3413 #2 io:query will return 0 1, since the last device is a 3414 keyboard (type 1), with a version of 0 3415 3416In this case, some interactions can be defined: 3417 3418 :c:put #0 io:invoke ; 3419 :c:get #2 io:invoke ; 3420 3421Setup the stack, push the device ID, and then use `io:invoke` 3422to invoke the interaction. 3423 3424A RETRO system requires one I/O device (a generic output for a 3425single character). This must be the first device, and must have 3426a device ID of 0. 3427 3428All other devices are optional and can be specified in any 3429order. 3430 3431 3432# I/O Devices 3433 3434I/O devices on Nga are exposed via three instructions: 3435 3436 ie enumerate i/o devices 3437 iq query i/o device 3438 ii invoke i/o interaction 3439 3440All devices are registered with the VM. How this occurs is 3441implementation dependent. 3442 3443## Counting Devices 3444 3445Use the `ie` instruction to return the number of attached devices. 3446 3447 i ie...... 3448 3449Upon running, the stack will contain the number of devices. You 3450can then query these by passing the device number to `iq`. 3451 3452## Query Devices 3453 3454Use `iq` to query an attached device. This will return two values, 3455a device identifer and a revision number. 3456 3457The device identifier will be the top value on the stack. 3458 3459## Invoking a Device 3460 3461You can trigger an I/O operation by passing the device number to 3462the `ii` instruction. 3463 3464E.g., to display a character (ASCII code 98 in this case): 3465 3466 i liliii.. 3467 d 98 3468 d 0 3469 3470Be sure to pass the device number, not the device identifier. 3471 3472## Device Identifiers 3473 3474Ultimately device identifiers are implementation-specific, but the 3475most common system (Nga on Unix) provides or reserves the following: 3476 3477 ID | Device Type | Notes | 3478 -----+------------------+----------------------------+ 3479 0000 | Generic Output | Always present as device 0 | 3480 0001 | Keyboard | | 3481 0002 | Floating Point | | 3482 0003 | Block Storage | Raw, 1024 cell blocks | 3483 0004 | Filesystem | Unix-style Files | 3484 0005 | Clock | | 3485 0006 | | | 3486 0007 | Network: Sockets | | 3487 0008 | Syscalls: Unix | | 3488 0009 | Scripting Hooks | | 3489 0010 | Random Number | | 3490 1000 | Image Saving | | 3491 3492It must be noted here that nothing forces devices to use these 3493identifiers, and one must take care to use an Nga implementation 3494that provides the devices they need. 3495 3496## Device Revisions 3497 3498Over time, the functionality a device provides may change. To allow 3499detection of this, the query functionality provides a revision number. 3500Your code can use this to ensure that the device provided supports 3501the level of functionality you need. 3502 3503## Nga/Retro-Unix Device Details 3504 3505### 0000: Generic Output 3506 3507Supported by all Nga implementations. This is required to be the 3508first device, and is the only one guaranteed to be provided. It 3509consumes a value from the stack, writing to to the host-specific 3510output. (This does not need to be a screen). 3511 3512### 0001: Keyboard 3513 3514Read and return a keypress. 3515 3516Consumes no data, returns a single value representing the 3517character that was read. 3518 3519No subcommands are defined. 3520 3521### 0002: Floating Point 3522 3523The current revision is 1. 3524 3525It currently provides: 3526 3527 n:to-float (n-_f:-n) 3528 s:to-float (s-_f:-n) 3529 f:to-number (f:a-__-n) 3530 f:to-string (f:n-__-s) 3531 f:+ (f:ab-c) 3532 f:- (f:ab-c) 3533 f:* (f:ab-c) 3534 f:/ (f:ab-c) 3535 f:floor (f:ab-c) 3536 f:ceiling (f:f-f) 3537 f:sqrt (f:f-f) 3538 f:eq? (f:ab-c) 3539 f:-eq? (f:ab-c) 3540 f:lt? (f:ab-c) 3541 f:gt? (f:ab-c) 3542 f:depth (-n) 3543 f:dup (f:a-aa) 3544 f:drop (f:a-) 3545 f:swap (f:ab-ba) 3546 f:log (f:ab-c) 3547 f:power (f:ab-c) 3548 f:sin (f:f-f) 3549 f:cos (f:f-f) 3550 f:tan (f:f-f) 3551 f:asin (f:f-f) 3552 f:acos (f:f-f) 3553 f:atan (f:f-f) 3554 f:push (f:f-) 3555 f:pop (f:-f) 3556 f:adepth (-n) 3557 3558### 0003: Block Storage 3559 3560Reserved for future use. 3561 3562### 0004: Filesystem 3563 3564Currently at revision 0. 3565 3566This implements a device providing traditional Unix-like files. 3567 3568Takes a value indicating an operation, and each operation takes 3569additional values. 3570 3571 | Operation | Stack | Action | 3572 | --------- | ----- | -------------------------------- | 3573 | 0 | sm-h | Open a file | 3574 | 1 | h- | Close a file | 3575 | 2 | h-c | Read a byte from a file | 3576 | 3 | ch- | Write a byte to a file | 3577 | 4 | h-n | Return current pointer into file | 3578 | 5 | nh- | Move pointer in a file | 3579 | 6 | h-n | Return the size of a file | 3580 | 7 | s- | Delete a file | 3581 | 8 | h- | Flush pending writes | 3582 3583### 0010: Random Number Generator 3584 3585This is currently at revision 0. 3586 3587On invocation, this returns a random number. 3588 3589## Implementation Details (C) 3590 3591On the C implementation, each I/O device has the needed support 3592functions defined, then a query function and invocation function 3593defined. 3594 3595As an example, to add a device that has two functions, I might do: 3596 3597 void one() { 3598 stack_push(100); 3599 } 3600 3601 void two() { 3602 stack_push(200); 3603 } 3604 3605 Handler device_actions[] = { 3606 one, two 3607 } 3608 3609 void io_device() { 3610 device_actions[stack_pop()](); 3611 } 3612 3613 void query_device() { 3614 stack_push(0); /* Revision */ 3615 stack_push(1234); /* Device ID */ 3616 } 3617 3618Then add pointers to `io_device` to `IO_deviceHandlers` and 3619`query_device` to `IO_queryHandlers` and increase the `NUM_DEVICES` 3620by one. 3621 3622You will then need to write a set of Retro words to use the new 3623device. 3624 3625 :device:one #1 #1234 io:scan-for io:invoke ; 3626 :device:two #2 #1234 io:scan-for io:invoke ; 3627 3628Rebuild the VM, adding these to image. 3629 3630# Internals: The Retro Image 3631 3632The actual RETRO language is stored as a memory image for Nga. 3633 3634## Format 3635 3636The image file is a flat, linear sequence of signed 32-bit 3637values. Each value is stored in little endian format. The 3638size is not fixed. An interface should check when loading to 3639ensure that the physical image is not larger than the emulated 3640memory. 3641 3642## Header 3643 3644The image will start with two cells. The first is a liju.... 3645instruction, the second is the target address for the jump. 3646This serves to skip over the rest of the data and reach the 3647actual entry point. 3648 3649This is followed by a pointer to the most recent dictionary 3650header, a pointer to the next free address in memory, and 3651then the RETRO version number. 3652 3653 | Offset | Contains | 3654 | ------ | --------------------------- | 3655 | 0 | lit call nop nop | 3656 | 1 | Pointer to main entry point | 3657 | 2 | Dictionary | 3658 | 3 | Heap | 3659 | 4 | RETRO version | 3660 3661The actual code starts after this header. 3662 3663The version number is the year and month. As an example, 3664the 12.2019.6 release will have a version number of 3665`201906`. 3666 3667## Layout 3668 3669Assuming an Nga built with 524287 cells of memory: 3670 3671 | RANGE | CONTAINS | 3672 | --------------- | ---------------------------- | 3673 | 0 - 1024 | RETRO Core kernel | 3674 | 1025 - 1535 | token input buffer | 3675 | 1536 + | start of heap space | 3676 | ............... | free memory for your use | 3677 | 506879 | buffer for string evaluate | 3678 | 507904 | temporary strings (32 * 512) | 3679 | 524287 | end of memory | 3680 3681The buffers at the end of memory will resize when specific 3682variables related to them are altered. 3683 3684# Calling Retro from C 3685 3686The C implementation of Retro provides several functions for 3687interacting with code written in Retro. 3688 3689## Dictionary 3690 3691The dictionary is a linked list, with a pointer to the most 3692recent entry stored in address 2. 3693 3694You can access the fields for each entry using: 3695 3696 d_link 3697 d_xt 3698 d_class 3699 d_name 3700 3701Each takes a dictionary header address (the "dictionary token") 3702and returns a pointer to the Retro address for the desired data. 3703 3704To find a dictionary token, use `d_lookup`. This takes the address 3705of the dictionary to search (`memory[2]` in most cases) and the 3706name of the word to find. 3707 3708There is also `d_xt_for()` which takes a name and a dictionary 3709pointer and returns the execution token for the specified word. 3710 3711## Strings 3712 3713Like C, Retro uses NUL terminated strings. But, since all 3714addressing is 32-bit (or 64-bit, depending on your configuration), 3715some conversion is needed. 3716 3717To get a C version of a string, use `string_extract()`. This takes 3718a Retro address and returns a pointer to a C string. 3719 3720Example: 3721 3722 // Get the name of the most recently defined word 3723 string_extract(d_name(memory[2])); 3724 3725To push a C string into Retro memory, use `string_inject()`. This 3726takes a C string and a Retro address. 3727 3728 // Copy a string to the TIB buffer 3729 string_inject("hello", 1024); 3730 3731## Stack 3732 3733You can push values to the stack with `stack_push()` and pop them 3734off with `stack_pop()`. 3735 3736## Interacting 3737 3738If you have a word named `hello` that you wish to run: 3739 3740 execute(d_xt_for("hello", memory[2])); 3741 3742If you want to evaluate a token as if it was typed into a Retro 3743listener: 3744 3745 string_inject("token", 1024); 3746 stack_push(1024); 3747 execute("interpret", memory[2]); 3748 3749The `interpret` word handles things like sigils, so this is 3750needed if you want to run something that needs those. 3751 3752# Historical Papers and Notes 3753 3754## On the Naming of RETRO 3755 3756Taken from http://lists.tunes.org/archives/tunes-lll/1999-July/000121.html 3757 3758On Fri, Jul 30, 1999 at 07:43:54PM -0400, Paul Dufresne wrote: 3759 3760> My brother did found it funny that Retro is called like that. 3761> For him retro means going back (generally in time) so this 3762> does not looks like a name of a OS to come. So he'd like to 3763> know from where the name came. 3764 3765Heheh, here's the story: When I started playing with OS stuff 3766last year (not seriously), I was reading about some old things 3767like FORTH and ITS, dating back to the 1960's and 70's. The 3768past few years in America, there's been a revival of disco 3769music (along with bell bottoms, platform shoes, and all that 3770crap) and they call it "retro". Now, my OS was named by 3771musicians.. I was telling a fellow musician about my ideas, 3772how it would be cool to have a small OS that isn't bloated and 3773unmanageable like Windows... go back to the 70's and resurrect 3774a line of software that died out. He goes "hmm.. sounds kinda 3775retro.." 3776 3777I think it sounds kinda rebellious, which is a Good Thing now 3778that everybody hates the M$ empire. :) It seems like other 3779people are as sick of the future as I am. Look at TUNES, the 3780idea there isn't to make some great new invention, just take 3781some decades-old ideas and combine them in one OS. The first 3782time I saw Knuth's "Art of Computer Programming" in the library 3783I thought "god that looks old.. 1973!!! nevermind.." Now it's 3784my programming bible. Find me something better published in 3785the 90's.. if such a thing exists, it'll be like a needle in a 3786haystack. "Newer" doesn't necessarily mean "better". 3787 3788 New cars = flimsier 3789 New farming methods = more devastating 3790 New version of Netscape = more bloat, more bullshit 3791 3792One thing is better now: computer hardware. Give me 70's 3793software on 90's and 00's hardware :) 3794 3795- Tom Novelli <tcn@tunes.org> 3796 3797 3798## The Design Philosophy of RETRO Native Forth 3799 3800Computer software is a technology in its infancy, a mere fifty years 3801old. The last 25 years in particular have seen an explosion in the 3802software business. However, software has seen little innovation while 3803hardware technology has improved phenomenally (notwithstanding the advent 3804of lousy slave-made parts). Proven software techniques of forty years ago 3805have yet to reach widespread use, in deference to the "latest and 3806greatest" proprietary solutions of dubious value. Thanks to agressive 3807marketing, we make huge investments in these dead-end technologies 3808(through our businesses and governments, if not personally) and we end up 3809with a reliance on a heap of complicated, error-prone, poorly understood 3810junk software. 3811 3812Complexity will dominate the software industry for the foreseeable 3813future. The Retro philosophy is a simple alternative for those willing to 3814make a clean break with legacy software. A Retro system can communicate 3815with other systems, but it won't run much legacy software, especially 3816proprietary software without source code. An emulation layer could be 3817added, but doing so would defeat the purpose of a simple operating system. 3818I think TCP/IP support is all the compatibility that's needed. 3819 3820At first Retro will appeal to computer hobbyists and electronic 3821engineers. Once the rough edges are smoothed out, it could catch on with 3822ordinary folks who don't like waiting five minutes just to check their 3823email (not to mention the long hours of setup and maintenance). Game 3824programmers who take their craft seriously may also be interested. 3825Businesses might even see a use for it, if the managers decide it's more 3826cost-effective to carefully design software for specific needs, rather 3827than buying off-the-shelf crap and spending countless manhours working 3828around the bugs. Since it's not practical for businesses to make a clean 3829break, my advice is to run Retro (and its ilk) on separate machines 3830connected by a network. Retro is efficient enough to run on older 3831machines that would otherwise sit idle, being too slow for the latest 3832Microsoft bloatware (or Linux, for that matter). 3833 3834I strive to avoid the extraneous. That applies even to proven 3835technologies, if I don't need them. If my computer isn't set up for 3836people to log in over the network, I don't want security features; they 3837just get in the way. If I'm only running programs I wrote, I should be 3838able to run them with full access to the hardware; I don't need protection 3839from viruses. If I download something I don't trust, then I can run it in 3840an isolated process, which is customary with Unix and kin. But that's not 3841core functionality. All that's needed is the flexibility to add things 3842like security, graphical interfaces, and distributed processing - if the 3843need ever arises. 3844 3845In programming languagues, I was misled. It's the Tower of Babel all 3846over again. The thousands of languages in existence all fall into a 3847handful of archetypes: Assembler, LISP, FORTRAN and FORTH represent the 3848earliest descendants of nearly all languages. I hesitate to name a 3849definitive "object-oriented" language, and here's why: Object-Oriented 3850programming is just a technique, and any language will suffice, even 3851Assembler. The complexites of fancy languages like Ada and C++ are a 3852departure from reality -- the reality of the actual physical machine. 3853When it all boils down, even LISP, FORTRAN and FORTH are only extensions 3854of the machine. 3855 3856I chose FORTH as the "native tongue" of Retro. LISP, FORTRAN, and 3857other languages can be efficiently implemented as extensions of FORTH, but 3858the reverse isn't so efficient. Theoretically all languages are 3859equivalent, but when design time, compilation time, and complexity are 3860accounted for, FORTH is most efficient. FORTH also translates most 3861directly to the hardware. (In fact, FORTH has been implemented in 3862hardware; these "stack machines" are extremely efficient.) FORTH is also 3863the easiest language to implement from scratch - a major concern when 3864you're trying to make a clean break. So with simplicity in mind, FORTH 3865was the obvious choice. 3866 3867I'm perfectly happy working with text only, and I go to great lengths 3868to avoid using the standard graphical environments, which have major 3869problems: windows, pulldown menus, and mice. Windows can't share the 3870screen nicely; that idea is hopeless. Pulldowns are tedious. Mice get in 3871the way of typing without reducing the need for it; all they give me is 3872tendonitis. Their main use is for drawing. 3873 3874Some of my favorite interfaces: Telix, Telegard BBS, Pine, Pico, Lynx, 3875and ScreamTracker. All "hotkey" interfaces where you press a key or two 3876to perform an action. Usually the important commands are listed at the 3877bottom of the screen, or at least on a help screen. The same principles 3878apply to graphical interfaces: use the full screen, except for a status 3879and menu area on one edge. Resist the temptation to clutter up the 3880screen. 3881 3882As for switching between programs, the Windows methods suck; the only 3883thing worse is Unix job control (jobs, fg, and such). The Linux method is 3884tolerable: Alt-Arrows, Alt-F1, Alt-F2, etc. Still, things could be 3885better: F11 and F12 cycle back and forth through all open programs; Alt-F1 3886assigns the currently selected program to F1, and likewise for the other 3887function keys. Programs just won't use function keys - Control and Alt 3888combinations are less awkward and easier to remember, besides. I'll also 3889want a "last channel" key and a "task list" key; maybe I'll borrow those 3890stupid Win95 keys. The Pause key will do like it says - pause the current 3891program - and Ctrl-Pause (Break) will kill it. 3892 3893One more thing: consistency. I like programs to look different so I 3894can tell them apart, but the keys should be the same as much as possible. 3895Keys should be configured in one place, for all programs. Finally, 3896remember the most consistent interface, one of the few constants 3897throughout the history of computing - the text screen and keyboard, and 3898the teletypewriter before that. Don't overlook it. 3899 3900More to come, maybe... :) 3901 3902"If it's on line, it's a work in progress." 3903 3904Tom Novelli, 3/4/2000 3905 3906## Metacompilation and Assembly 3907 3908RETRO 10 and 11 were written in themselves using a metacompiler. 3909I had been fascinated by this idea for a long time and was able 3910to explore it heavily. While I still find it to be a good idea, 3911the way I ended up doing it was problematic. 3912 3913The biggest issue I faced was that I wanted to do this in one 3914step, where loading the RETRO source would create a new image 3915in place of the old one, switch to the new one, and then load 3916the higher level parts of the language over this. In retrospect, 3917this was a really bad idea. 3918 3919My earlier design for RETRO was very flexible. I allowed almost 3920everything to be swapped out or extended at any time. This made 3921it extremely easy to customize the language and environment, but 3922made it crucial to keep track of what was in memory and what had 3923been patched so that the metacompiler wouldn't refer to anything 3924in the old image during the relocation and control change. It 3925was far too easy to make a mistake, discover that elements of 3926the new image were broken, and then have to go and revert many 3927changes to try to figure out what went wrong. 3928 3929This was also complicated by the fact that I built new images 3930as I worked, and, while a new image could be built from the last 3931built one, it wasn't always possible to build a new image from 3932the prior release version. (Actually, it was often worse - I 3933failed to check in every change as I went, so often even the 3934prior commits couldn't rebuild the latest images). 3935 3936For RETRO 12 I wanted to avoid this problem, so I decided to go 3937back to writing the kernel ("Rx") in assembly. I actually wrote 3938a Machine Forth dialect to generate the initial assembly, before 3939eventually hand tuning the final results to its current state. 3940 3941I could (and likely will eventually) write the assembler in 3942RETRO, but the current one is in C, and is built as part of the 3943standard toolchain. 3944 3945My VM actually has two assemblers. The older one is Naje. This 3946was intended to be fairly friendly to work with, and handles 3947many of the details of packing instructions for the user. Here 3948is an example of a small program in it: 3949 3950 :square 3951 dup 3952 mul 3953 ret 3954 :main 3955 lit 35 3956 lit &square 3957 call 3958 end 3959 3960The other assembler is Muri. This is a far more minimalistic 3961assembler, but I've actually grown to prefer it. The above 3962example in Muri would become: 3963 3964 i liju.... 3965 r main 3966 : square 3967 i dumure.. 3968 : main 3969 i lilica.. 3970 d 35 3971 r square 3972 i en...... 3973 3974In Muri, each instruction is reduced to two characters, and the 3975bundlings are listed as part of an instruction bundle (lines 3976starting with `i`). This is less readable if you aren't very 3977familiar with Nga's assembly and packing rules, but allows a 3978very quick, efficient way of writing assembly for those who are. 3979 3980I eventually rewrote the kernel in the Muri style as it's what 3981I prefer, and since there's not much need to make changes in it. 3982 3983## The Path to Self Hosting 3984 3985RETRO is an image based Forth system running on a lightweight 3986virtual machine. This is the story of how that image is made. 3987 3988The first RETRO to use an image based approach was RETRO 10. 3989The earliest images were built using a compiler written in 3990Toka, an earlier experimental stack language I had written. 3991It didn't take long to want to drop the dependency on Toka, 3992so I rewrote the image compiler in RETRO and then began 3993development at a faster pace. 3994 3995RETRO 11 was built using the last RETRO 10 image and an 3996evolved version of the metacompiler. This worked well, but 3997I eventually found it to be problematic. 3998 3999One of the issues I faced was the inability to make a new 4000image from the prior stable release. Since I develop and 4001test changes incrementally, I reached a point where the 4002current metacompiler and image required each other. This 4003wasn't a fatal flaw, but it was annoying. 4004 4005Perhaps more critical was the fragility of the system. In 4006R11 small mistakes could result in a corrupt image. The test 4007suite helped identify some of these, but there were a few 4008times I was forced to dig back through the version control 4009history to recover a working image. 4010 4011The fragile nature was amplified by some design decisions. 4012In R11, after the initial kernel was built, it would be 4013moved to memory address 0, then control would jump into the 4014new kernel to finish building the higher level parts. 4015 4016Handling this was a tricky task. In R11 almost everything 4017could be revectored, so the metacompiler had to ensure that 4018it didn't rely on anything in the old image during the move. 4019This caused a large number of issues over R11's life. 4020 4021So on to RETRO 12. I decided that this would be different. 4022First, the kernel would be assembly, with an external tool 4023to generate the core image. The kernel is in `Rx.md` and the 4024assembler is `Muri`. To load the standard library, I wrote a 4025second tool, `retro-extend`. This separation has allowed me 4026many fewer headaches as I can make changes more easily and 4027rebuild from scratch when necessary. 4028 4029But I miss self-hosting. So last fall I decided to resolve 4030this. And today I'm pleased to say that it is now done. 4031 4032There are a few parts to this. 4033 4034**Unu**. I use a Markdown variation with fenced code blocks. 4035The tool I wrote in C to extract these is called `unu`. For 4036a self hosting RETRO, I rewrote this as a combinator that 4037reads in a file and runs another word against each line in the 4038file. So I could display the code block contents by doing: 4039 4040 'filename [ s:put nl ] unu 4041 4042This made it easier to implement the other tools. 4043 4044**Muri**. This is my assembler. It's minimalistic, fast, and 4045works really well for my purposes. RETRO includes a runtime 4046version of this (using `as{`, `}as`, `i`, `d`, and `r`), so 4047all I needed for this was to write a few words to parse the 4048lines and run the corresponding runtime words. As with the C 4049version, this is a two pass assembler. 4050 4051Muri generates a new `ngaImage` with the kernel. To create a 4052full image I needed a way to load in the standard library and 4053I/O extensions. 4054 4055This is handled by **retro-extend**. This is where it gets 4056more complex. I implemented the Nga virtual machine in RETRO 4057to allow this to run the new image in isolation from the 4058host image. The new ngaImage is loaded, the interpreter is 4059located, and each token is passed to the interpreter. Once 4060done, the new image is written to disk. 4061 4062So at this point I'm pleased to say that I can now develop 4063RETRO using only an existing copy of RETRO (VM+image) and 4064tools (unu, muri, retro-extend, and a line oriented text 4065editor) written in RETRO. 4066 4067This project has delivered some additional side benefits. 4068During the testing I was able to use it to identify a few 4069bugs in the I/O extensions, and the Nga-in-RETRO will replace 4070the older attempt at this in the debugger, allowing a safer 4071testing environment. 4072 4073What issues remain? 4074 4075The extend process is *slow*. On my main development server 4076(Linode 1024, OpenBSD 6.4, 64-bit) it takes a bit over five 4077minutes to complete loading the standard library, and a few 4078additional depending on the I/O drivers selected. 4079 4080Most of the performance issues come from running Nga-in-RETRO 4081to isolate the new image from the host one. It'd be possible 4082to do something a bit more clever (e.g., running a RETRO 4083instance using the new image via a subprocess and piping in 4084the source, or doing relocations of the data), but this is 4085less error prone and will work on all systems that I plan to 4086support (including, with a few minor adjustments, the native 4087hardware versions [assuming the existance of mass storage]). 4088 4089Sources: 4090 4091**Unu** 4092 4093- http://forth.works/c8820f85e0c52d32c7f9f64c28f435c0 4094- gopher://forth.works/0/c8820f85e0c52d32c7f9f64c28f435c0 4095 4096**Muri** 4097 4098- http://forth.works/09d6c4f3f8ab484a31107dca780058e3 4099- gopher://forth.works/0/09d6c4f3f8ab484a31107dca780058e3 4100 4101**retro-extend** 4102 4103- http://forth.works/c812416f397af11db58e97388a3238f2 4104- gopher://forth.works/0/c812416f397af11db58e97388a3238f2 4105 4106## Sigils as a Language Element 4107 4108A big change in RETRO 12 was the elimination of the traditional 4109parser from the language. This was a sacrifice due to the lack 4110of an I/O model. RETRO has no way to know *how* input is given 4111to the `interpret` word, or whether anything else will ever be 4112passed into it. 4113 4114And so `interpret` operates only on the current token. The core 4115language does not track what came before or attempt to guess at 4116what might come in the future. 4117 4118This leads into the sigils. RETRO 11 had a complicated system 4119for sigils, with different types of sigilss for words that 4120parsed ahead (e.g., strings) and words that operated on the 4121current token (e.g., `@`). RETRO 12 eliminates all of these in 4122favor of just having a single sigil model. 4123 4124The first thing `interpret` does is look to see if the first 4125character in a token matches a `sigil:` word. If it does, it 4126passes the rest of the token as a string pointer to the sigil 4127specific handler to deal with. If there is no valid sigil 4128found, it tries to find it in the dictionary. Assuming that it 4129finds the words, it passes the `d:xt` field to the handler that 4130`d:class` points to. Otherwise it calls `err:notfound`. 4131 4132This has an important implication: *words can not reliably 4133have names that start with a sigil character.* 4134 4135It also simplifies things. Anything that would normally parse 4136becomes a sigil handler. So creating a new word? Use the `:` 4137sigil. Strings? Use `'`. Pointers? Try `&`. And so on. E.g., 4138 4139 In ANS | In RETRO 4140 : foo ... ; | :foo ... ; 4141 ' foo | &foo 4142 : bar ... ['] foo ; | :bar ... &foo ; 4143 s" hello world!" | 'hello_world! 4144 4145If you are familiar with ColorForth, sigils are a similar 4146idea to colors, but can be defined by the user as normal words. 4147 4148After doing this for quite a while I rather like it. I can see 4149why Chuck Moore eventually went towards ColorForth as using 4150color (or sigils in my case) does simplify the implementation 4151in many ways. 4152 4153## On The Kernel Wordset 4154 4155In implementing the RETRO 12 kernel (called RETRO Core, and 4156defined in `image/retro.muri`) I had to decide on what functionality 4157would be needed. It was important to me that this be kept clean 4158and minimalistic, as I didn't want to spend a lot of time 4159changing it as time progressed. It's far nicer to code at the 4160higher level, where the RETRO language is fully functional, as 4161opposed to writing more assembly code. 4162 4163So what made it in? 4164 4165Primitives 4166 4167These are words that map directly to Nga instructions. 4168 4169 dup drop swap call eq? -eq? lt? gt? 4170 fetch store + - * /mod and or 4171 xor shift push pop 0; 4172 4173Memory 4174 4175 fetch-next store-next , s, 4176 4177Strings 4178 4179 s:to-number s:eq? s:length 4180 4181Flow Control 4182 4183 choose if -if repeat again 4184 4185Compiler & Interpreter 4186 4187 Compiler Heap ; [ ] Dictionary 4188 d:link d:class d:xt d:name d:add-header 4189 class:word class:primitive class:data class:macro 4190 sigil:: sigil:# sigil:& sigil:$ 4191 interpret d:lookup err:notfound 4192 4193Assembler 4194 4195 i d r 4196 4197I *could* slightly reduce this. The $ sigil could be defined in 4198higher level code, and I don't strictly *need* to expose the 4199`fetch-next` and `store-next` here. But since the are already 4200implemented as dependencies of the words in the kernel, it would 4201be a bit wasteful to redefine them later in higher level code. 4202 4203A recent change was the addition of the assembler into the 4204kernel. This allows the higher levels to use assembly as needed, 4205which gives more flexibility and allows for more optimal code 4206in the standard library. 4207 4208With these words the rest of the language can be built up. Note 4209that the RETRO kernel does not provide any I/O words. It's assumed 4210that the RETRO interfaces will add these as best suited for the 4211systems they run on. 4212 4213There is another small bit. All images start with a few key 4214pointers in fixed offsets of memory. These are: 4215 4216 | Offset | Contains | 4217 | ------ | --------------------------- | 4218 | 0 | lit call nop nop | 4219 | 1 | Pointer to main entry point | 4220 | 2 | Dictionary | 4221 | 3 | Heap | 4222 | 4 | RETRO version identifier | 4223 4224An interface can use the dictionary pointer and knowledge of the 4225dictionary format for a specific RETRO version to identify the 4226location of essential words like `interpret` and `err:notfound` 4227when implementing the user facing interface. 4228 4229## On The Evolution Of Ngaro Into Nga 4230 4231When I decided to begin work on what became RETRO 12, I knew 4232the process would involve updating Ngaro, the virtual machine 4233that RETRO 10 and 11 ran on. 4234 4235Ngaro rose out of an earlier experimental virtual machine I had 4236written back in 2005-2006. This earlier VM, called Maunga, was 4237very close to what Ngaro ended up being, though it had a very 4238different approach to I/O. (All I/O in Maunga was intended to be 4239memory mapped; Ngaro adopted a port based I/O system). 4240 4241Ngaro itself evolved along with RETRO, gaining features like 4242automated skipping of NOPs and a LOOP opcode to help improve 4243performance. But the I/O model proved to be a problem. When I 4244created Ngaro, I had the idea that I would always be able to 4245assume a console/terminal style environment. The assumption was 4246that all code would be entered via the keyboard (or maybe a 4247block editor), and that proved to be the fundamental flaw as 4248time went on. 4249 4250As RETRO grew it was evident that the model had some serious 4251problems. Need to load code from a file? The VM and language had 4252functionality to pretend it was being typed in. Want to run on 4253something like a browser, Android, or iOS? The VM would need to 4254be implemented in a way that simulates input being typed into 4255the VM via a simulated keyboard. And RETRO was built around this. 4256I couldn't change it because of a promise to maintain, as much 4257as possible, source compatibility for a period of at least five 4258years. 4259 4260When the time came to fix this, I decided at the start to keep 4261the I/O model separate from the core VM. I also decided that the 4262core RETRO language would provide some means of interpreting 4263code without requiring an assumption that a traditional terminal 4264was being used. 4265 4266So Nga began. I took the opportunity to simplify the instruction 4267set to just 26 essential instructions, add support for packing 4268multiple instructions per memory location (allowing a long due 4269reduction in memory footprint), and to generally just make a far 4270simpler design. 4271 4272I've been pleased with Nga. On its own it really isn't useful 4273though. So with RETRO I embed it into a larger framework that 4274adds some basic I/O functionality. The *interfaces* handle the 4275details of passing tokens into the language and capturing any 4276output. They are free to do this in whatever model makes most 4277sense on a given platform. 4278 4279So far I've implemented: 4280 4281 - a scripting interface, reading input from a file and 4282 offering file i/o, gopher, and reading from stdin, and 4283 sending output to stdout. 4284 - an interactive interface, built around ncurses, reading 4285 input from stdin, and displaying output to a scrolling 4286 buffer. 4287 - an iOS interface, built around a text editor, directing 4288 output to a separate interface pane. 4289 - an interactive block editor, using a gopher-based block 4290 data store. Output is displayed to stdout, and input is 4291 done via the blocks being evaluated or by reading from 4292 stdin. 4293 4294In all cases, the only common I/O word that has to map to an 4295exposed instruction is `putc`, to display a single character to 4296some output device. There is no requirement for a traditional 4297keyboard input model. 4298 4299By doing this I was able to solve the biggest portability issue 4300with the RETRO 10/11 model, and make a much simpler, cleaner 4301language in the end. 4302 4303## RETRO 11 (2011 - 2019): A Look Back 4304 4305So it's now been about five years since the last release of RETRO 430611. While I still see some people obtaining and using it, I've 4307moved on to the twelth generation of RETRO. It's time for me to 4308finally retire RETRO 11. 4309 4310As I prepare to do so, I thought I'd take a brief look back. 4311 4312RETRO 11 began life in 2011. It grew out of RETRO 10, which was 4313the first version of RETRO to not be written in x86 assembly 4314language. For R10 and R11, I wrote a portable virtual machine 4315(with numerous implementations) and the Forth dialect was kept 4316in an image file which ran on the VM. 4317 4318RETRO 10 worked, but was always a bit too sloppy and changed 4319drastically between releases. The major goal of RETRO 11 was to 4320provide a stable base for a five year period. In retrospect, 4321this was mostly achieved. Code from earlier releases normally 4322needed only minor adjustments to run on later releases, though 4323newer releases added significantly to the language. 4324 4325There were seven releases. 4326 4327- Release 11.0: 2011, July 4328- Release 11.1: 2011, November 4329- Release 11.2: 2012, January 4330- Release 11.3: 2012, March 4331- Release 11.4: 2012, July 4332- Release 11.5: 2013, March 4333- Release 11.6: 2014, August 4334 4335Development was fast until 11.4. This was the point at which I 4336had to slow down due to RSI problems. It was also the point 4337which I started experiencing some problems with the metacompiler 4338(as discussed previously). 4339 4340RETRO 11 was flexible. All colon definitions were setup as hooks, 4341allowing new functionality to be layered in easily. This allowed 4342the later releases to add things like vocabularies, search order, 4343tab completion, and keyboard remapping. This all came at a cost 4344though: later things could use the hooks to alter behavior of 4345existing words, so it was necessary to use a lot of caution to 4346ensure that the layers didn't break the earlier code. 4347 4348The biggest issue was the I/O model. RETRO 11 and the Ngaro VM 4349assumed the existence of a console environment. All input was 4350required to be input at the keyboard, and all output was to be 4351shown on screen. This caused some problems. Including code from 4352a file required some tricks, temporarily rewriting the keyboard 4353input function to read from the file. It also became a major 4354issue when I wrote the iOS version. The need to simulate the 4355keyboard and console complicated everything and I had to spend 4356a considerable amount of effort to deal with battery performance 4357resulting from the I/O polling and wait states. 4358 4359But on the whole it worked well. I used RETRO 11.6 until I started 4360work on RETRO 12 in late 2016, and continued running some tools 4361written in R11 until the first quarter of last year. 4362 4363The final image file was 23,137 cells (92,548 bytes). This was 4364bloated by keeping some documentation (stack comments and short 4365descriptions) in the image, which started in 11.4. This contained 4366269 words. 4367 4368I used RETRO 11 for a wide variety of tasks. A small selection of 4369things that were written includes: 4370 4371- a pastebin 4372- front end to ii (irc client) 4373- small explorations of interactive fiction 4374- irc log viewer 4375- tool to create html from templates 4376- tool to automate creation of an SVCD from a set of photos 4377- tools to generate reports from data sets for my employer 4378 4379In the end, I'm happy with how RETRO 11 turned out. I made some 4380mistakes in embracing too much complexity, but despite this it 4381was a successful system for many years. 4382 4383# Security Concerns 4384 4385The standard RETRO is not a good choice for applications 4386needing to be highly secure. 4387 4388## Runtime Checks 4389 4390The RETRO system performs only minimal checks. It will not 4391load an image larger than the max set at build time. And 4392stack over/underflow are checked for as code executes. 4393 4394The system does not attempt to validate anything else, it's 4395quite easy to crash. 4396 4397## Isolation 4398 4399The VM itself and the core code is self contained. Nga does 4400not make use of malloc/free, and uses only standard system 4401libraries. It's possible for buffer overruns within the image 4402(overwriting Nga code), but the RETRO image shouldn't leak 4403into the C portions. 4404 4405I/O presents a bigger issue. Anything involving I/O, especially 4406with the `unix:` words, may be a vector for attacks. 4407 4408## Future Direction 4409 4410I'm not planning to add anything to the *image* side as, for me, 4411the performance hit due to added checks is bigger than the 4412benefits. 4413 4414The story is different on the VM side. I've already begun taking 4415steps to address some of the issues, using functions that check 4416for overruns with strings and doing some minor testing for these 4417conditions. I will be gradually addressing the various I/O 4418related extensions, though it's unlikely to ever be fully guarded 4419against attacks. 4420 4421## Rationale 4422 4423RETRO is, primarily, a personal system. I'm running code I wrote 4424to solve problems I face. On the occasions where I run code sent 4425to me by others, I read it carefully first and then run inside a 4426sandboxed environment if I'm worried about anything in it. 4427 4428### On The Use Of Underscores In Word Names 4429 4430In brief: don't use underscores in word names. 4431 4432There is a good reason for this, and it has to do with how RETRO 4433processes strings. By default, underscores in strings are replaced 4434by spaces. This is problematic when dealing with words like `var`, 4435`const`, and `d:create` which take word names as strings. 4436 4437Consider: 4438 4439 :hello_msg 'hello_user ; 4440 'test_name var 4441 #188 !test_name 4442 4443In the first case, the `:` sigil handles the token, so the 4444underscore is not remapped to a space, creating a word name as 4445`hello_msg`. But in the second, the `'` sigil remaps the 4446underscore to a space, giving a variable name of `test name`. 4447In the third line, the name lookup will fail as `test_name` is 4448not defined, so the store will be done to an incorrect address. 4449 4450Because of this, it's best to avoid underscores in names. 4451 4452Having covered this, if you do need to use them for some reason, 4453you can replace `d:add-header` with a version that remaps spaces 4454back to underscores before creating the header. The following 4455will allow for this. 4456 4457 ~~~ 4458 {{ 4459 :fields @Dictionary , (link) , (xt) , (class) ; 4460 :invalid-name? dup ASCII:SPACE s:contains-char? ; 4461 :rewrite [ ASCII:SPACE [ $_ ] case ] s:map ; 4462 :entry here &call dip !Dictionary ; 4463 [ [ fields invalid-name? &rewrite if s, (name) ] entry ] 4464 }} 4465 4466 #1793 &d:add-header store 4467 &d:add-header n:inc store 4468 ~~~ 4469 4470Additional Note: 4471 4472Some version of RETRO have included the above patch. The last 4473release that will include this by default is 2020.4 as it is 4474not needed by the majority of users. If you want to keep it in 4475your system, you will need to load it yourself or add it to 4476your `package/list.forth` (for Unix users) before building. 4477 4478# The Code It Yourself Manifesto 4479 4480We use software for our everyday needs because we want to get 4481something done. We have goals to achieve and things to do. 4482 4483The software we use is coded by brave programmers that have 4484their own goals. Most of the time there is an overlap between 4485their goals and ours. 4486 4487Over time these will diverge. 4488 4489This means that the tools we depend on grow features we don't 4490use or understand. There will be bugs in these code parts which 4491will prevent us from reaching our goals. 4492 4493So we are at a fork in the road: 4494 4495- We have the choice of trying to understand the code and 4496 fix it. 4497- We have the choice of trying another program, whose 4498 creator's goals are closer to ours. 4499- We also have the choice of coding the software ourself. 4500 4501All but the last path mean endless seeking, evaluating and 4502further deviation from our goals. Therefore we replace programs 4503we do not understand fully with our own implementation. 4504 4505The followers of the Code It Yourself Manifesto believe in 4506these things: 4507 4508- We implement it according to our own goals. 4509- We make mistakes and learn from them. 4510- We learn how our tools we depend on need to work. 4511- We gain a deep understanding of our problem domain. 4512- We still embrace sharing of ideas and code. 4513 4514Sharing is only possible if we are excellent developers to 4515each other. The next developer reading our code will be us 4516in a not so distant future. Coding It Ourselves means we will 4517document our code, clearly stating the goal of the software 4518we write. 4519 4520Together we enjoy the diversity of implementations and ideas. 4521 4522We encourage our colleagues to 4523 4524**Code It Yourself.** 4525 4526---- 4527 4528Written by Christian Kellermann on 2016-01-12, licensed under 4529a CreativeCommonsAttribution-ShareAlike3.0UnportedLicense. 4530 4531Original text taken from 4532http://pestilenz.org/~ckeen/blog/posts/ciy-manifesto.html 4533 4534# Deprecation Policy 4535 4536As RETRO evolves, some words will become obsolete and no longer be 4537needed. In each release, these will be marked as deprecated in the 4538glossary. Any deprecated words will be removed in the next quarterly 4539release. 4540 4541E.g., if 2020.1 had deprecated words, these would be removed in the 45422020.4 release. Any words made deprecated in between 2020.1 and 45432020.4 would be removed in the 2020.7 release. 4544 4545The text in these files is Copyright (c) 2018-2020 by 4546Charles Childers. 4547 4548To the extent possible under law, Charles Childers has 4549waived all copyright and related or neighboring rights 4550to the RETRO Documentation. This work is published from: 4551United States. 4552 4553The historical papers are Copyright (c) 1999-2000 by 4554Tom Novelli. 4555 4556## Legal Text 4557 4558See https://creativecommons.org/publicdomain/zero/1.0/legalcode 4559 4560The laws of most jurisdictions throughout the world automatically confer 4561exclusive Copyright and Related Rights (defined below) upon the creator 4562and subsequent owner(s) (each and all, an "owner") of an original work 4563of authorship and/or a database (each, a "Work"). 4564 4565Certain owners wish to permanently relinquish those rights to a Work for 4566the purpose of contributing to a commons of creative, cultural and 4567scientific works ("Commons") that the public can reliably and without 4568fear of later claims of infringement build upon, modify, incorporate in 4569other works, reuse and redistribute as freely as possible in any form 4570whatsoever and for any purposes, including without limitation commercial 4571purposes. These owners may contribute to the Commons to promote the 4572ideal of a free culture and the further production of creative, cultural 4573and scientific works, or to gain reputation or greater distribution for 4574their Work in part through the use and efforts of others. 4575 4576For these and/or other purposes and motivations, and without any 4577expectation of additional consideration or compensation, the person 4578associating CC0 with a Work (the "Affirmer"), to the extent that he or 4579she is an owner of Copyright and Related Rights in the Work, voluntarily 4580elects to apply CC0 to the Work and publicly distribute the Work under 4581its terms, with knowledge of his or her Copyright and Related Rights in 4582the Work and the meaning and intended legal effect of CC0 on those 4583rights. 4584 45851. Copyright and Related Rights. A Work made available under CC0 may be 4586protected by copyright and related or neighboring rights ("Copyright and 4587Related Rights"). Copyright and Related Rights include, but are not 4588limited to, the following: 4589 4590- the right to reproduce, adapt, distribute, perform, display, 4591 communicate, and translate a Work; 4592 4593- moral rights retained by the original author(s) and/or performer(s); 4594 4595- publicity and privacy rights pertaining to a person's image or 4596 likeness depicted in a Work; 4597 4598- rights protecting against unfair competition in regards to a Work, 4599 subject to the limitations in paragraph 4(a), below; 4600 4601- rights protecting the extraction, dissemination, use and reuse of data 4602 in a Work; 4603 4604- database rights (such as those arising under Directive 96/9/EC of the 4605 European Parliament and of the Council of 11 March 1996 on the legal 4606 protection of databases, and under any national implementation thereof, 4607 including any amended or successor version of such directive); and 4608 4609- other similar, equivalent or corresponding rights throughout the world 4610 based on applicable law or treaty, and any national implementations 4611 thereof. 4612 46132. Waiver. To the greatest extent permitted by, but not in contravention 4614of, applicable law, Affirmer hereby overtly, fully, permanently, 4615irrevocably and unconditionally waives, abandons, and surrenders all of 4616Affirmer's Copyright and Related Rights and associated claims and causes 4617of action, whether now known or unknown (including existing as well as 4618future claims and causes of action), in the Work (i) in all territories 4619worldwide, (ii) for the maximum duration provided by applicable law or 4620treaty (including future time extensions), (iii) in any current or 4621future medium and for any number of copies, and (iv) for any purpose 4622whatsoever, including without limitation commercial, advertising or 4623promotional purposes (the "Waiver"). Affirmer makes the Waiver for the 4624benefit of each member of the public at large and to the detriment of 4625Affirmer's heirs and successors, fully intending that such Waiver shall 4626not be subject to revocation, rescission, cancellation, termination, or 4627any other legal or equitable action to disrupt the quiet enjoyment of 4628the Work by the public as contemplated by Affirmer's express Statement 4629of Purpose. 4630 46313. Public License Fallback. Should any part of the Waiver for any reason 4632be judged legally invalid or ineffective under applicable law, then the 4633Waiver shall be preserved to the maximum extent permitted taking into 4634account Affirmer's express Statement of Purpose. In addition, to the 4635extent the Waiver is so judged Affirmer hereby grants to each affected 4636person a royalty-free, non transferable, non sublicensable, non 4637exclusive, irrevocable and unconditional license to exercise Affirmer's 4638Copyright and Related Rights in the Work (i) in all territories 4639worldwide, (ii) for the maximum duration provided by applicable law or 4640treaty (including future time extensions), (iii) in any current or 4641future medium and for any number of copies, and (iv) for any purpose 4642whatsoever, including without limitation commercial, advertising or 4643promotional purposes (the "License"). The License shall be deemed 4644effective as of the date CC0 was applied by Affirmer to the Work. Should 4645any part of the License for any reason be judged legally invalid or 4646ineffective under applicable law, such partial invalidity or 4647ineffectiveness shall not invalidate the remainder of the License, and 4648in such case Affirmer hereby affirms that he or she will not (i) 4649exercise any of his or her remaining Copyright and Related Rights in the 4650Work or (ii) assert any associated claims and causes of action with 4651respect to the Work, in either case contrary to Affirmer's express 4652Statement of Purpose. 4653 46544. Limitations and Disclaimers. 4655 4656No trademark or patent rights held by Affirmer are waived, abandoned, 4657surrendered, licensed or otherwise affected by this document. 4658 4659Affirmer offers the Work as-is and makes no representations or 4660warranties of any kind concerning the Work, express, implied, statutory 4661or otherwise, including without limitation warranties of title, 4662merchantability, fitness for a particular purpose, non infringement, or 4663the absence of latent or other defects, accuracy, or the present or 4664absence of errors, whether or not discoverable, all to the greatest 4665extent permissible under applicable law. 4666 4667Affirmer disclaims responsibility for clearing rights of other persons 4668that may apply to the Work or any use thereof, including without 4669limitation any person's Copyright and Related Rights in the Work. 4670Further, Affirmer disclaims responsibility for obtaining any necessary 4671consents, permissions or other rights required for any use of the Work. 4672 4673Affirmer understands and acknowledges that Creative Commons is not a 4674party to this document and has no duty or obligation with respect to 4675this CC0 or use of the Work. 4676 4677---- 4678 4679The Code It Yourself Manifesto is Copyright (c) 2016 by 4680Christian Kellermann and is used under the 4681Attribution-ShareAlike 3.0 Unported (CC BY-SA 3.0) license. 4682 4683This license reads: 4684 4685THE WORK (AS DEFINED BELOW) IS PROVIDED UNDER THE TERMS OF THIS CREATIVE 4686COMMONS PUBLIC LICENSE ("CCPL" OR "LICENSE"). THE WORK IS PROTECTED BY 4687COPYRIGHT AND/OR OTHER APPLICABLE LAW. ANY USE OF THE WORK OTHER THAN AS 4688AUTHORIZED UNDER THIS LICENSE OR COPYRIGHT LAW IS PROHIBITED. 4689 4690BY EXERCISING ANY RIGHTS TO THE WORK PROVIDED HERE, YOU ACCEPT AND AGREE 4691TO BE BOUND BY THE TERMS OF THIS LICENSE. TO THE EXTENT THIS LICENSE MAY 4692BE CONSIDERED TO BE A CONTRACT, THE LICENSOR GRANTS YOU THE RIGHTS 4693CONTAINED HERE IN CONSIDERATION OF YOUR ACCEPTANCE OF SUCH TERMS AND 4694CONDITIONS. 4695 46961. Definitions 4697 4698"Adaptation" means a work based upon the Work, or upon the Work and 4699other pre-existing works, such as a translation, adaptation, derivative 4700work, arrangement of music or other alterations of a literary or 4701artistic work, or phonogram or performance and includes cinematographic 4702adaptations or any other form in which the Work may be recast, 4703transformed, or adapted including in any form recognizably derived from 4704the original, except that a work that constitutes a Collection will not 4705be considered an Adaptation for the purpose of this License. For the 4706avoidance of doubt, where the Work is a musical work, performance or 4707phonogram, the synchronization of the Work in timed-relation with a 4708moving image ("synching") will be considered an Adaptation for the 4709purpose of this License. 4710 4711"Collection" means a collection of literary or artistic works, such as 4712encyclopedias and anthologies, or performances, phonograms or 4713broadcasts, or other works or subject matter other than works listed in 4714Section 1(f) below, which, by reason of the selection and arrangement of 4715their contents, constitute intellectual creations, in which the Work is 4716included in its entirety in unmodified form along with one or more other 4717contributions, each constituting separate and independent works in 4718themselves, which together are assembled into a collective whole. A work 4719that constitutes a Collection will not be considered an Adaptation (as 4720defined below) for the purposes of this License. 4721 4722"Creative Commons Compatible License" means a license that is listed at 4723https://creativecommons.org/compatiblelicenses that has been approved by 4724Creative Commons as being essentially equivalent to this License, 4725including, at a minimum, because that license: (i) contains terms that 4726have the same purpose, meaning and effect as the License Elements of 4727this License; and, (ii) explicitly permits the relicensing of 4728adaptations of works made available under that license under this 4729License or a Creative Commons jurisdiction license with the same License 4730Elements as this License. 4731 4732"Distribute" means to make available to the public the original and 4733copies of the Work or Adaptation, as appropriate, through sale or other 4734transfer of ownership. 4735 4736"License Elements" means the following high-level license attributes as 4737selected by Licensor and indicated in the title of this License: 4738Attribution, ShareAlike. 4739 4740"Licensor" means the individual, individuals, entity or entities that 4741offer(s) the Work under the terms of this License. 4742 4743"Original Author" means, in the case of a literary or artistic work, the 4744individual, individuals, entity or entities who created the Work or if 4745no individual or entity can be identified, the publisher; and in 4746addition (i) in the case of a performance the actors, singers, 4747musicians, dancers, and other persons who act, sing, deliver, declaim, 4748play in, interpret or otherwise perform literary or artistic works or 4749expressions of folklore; (ii) in the case of a phonogram the producer 4750being the person or legal entity who first fixes the sounds of a 4751performance or other sounds; and, (iii) in the case of broadcasts, the 4752organization that transmits the broadcast. 4753 4754"Work" means the literary and/or artistic work offered under the terms 4755of this License including without limitation any production in the 4756literary, scientific and artistic domain, whatever may be the mode or 4757form of its expression including digital form, such as a book, pamphlet 4758and other writing; a lecture, address, sermon or other work of the same 4759nature; a dramatic or dramatico-musical work; a choreographic work or 4760entertainment in dumb show; a musical composition with or without words; 4761a cinematographic work to which are assimilated works expressed by a 4762process analogous to cinematography; a work of drawing, painting, 4763architecture, sculpture, engraving or lithography; a photographic work 4764to which are assimilated works expressed by a process analogous to 4765photography; a work of applied art; an illustration, map, plan, sketch 4766or three-dimensional work relative to geography, topography, 4767architecture or science; a performance; a broadcast; a phonogram; a 4768compilation of data to the extent it is protected as a copyrightable 4769work; or a work performed by a variety or circus performer to the extent 4770it is not otherwise considered a literary or artistic work. 4771 4772"You" means an individual or entity exercising rights under this License 4773who has not previously violated the terms of this License with respect 4774to the Work, or who has received express permission from the Licensor to 4775exercise rights under this License despite a previous violation. 4776 4777"Publicly Perform" means to perform public recitations of the Work and 4778to communicate to the public those public recitations, by any means or 4779process, including by wire or wireless means or public digital 4780performances; to make available to the public Works in such a way that 4781members of the public may access these Works from a place and at a place 4782individually chosen by them; to perform the Work to the public by any 4783means or process and the communication to the public of the performances 4784of the Work, including by public digital performance; to broadcast and 4785rebroadcast the Work by any means including signs, sounds or images. 4786 4787"Reproduce" means to make copies of the Work by any means including 4788without limitation by sound or visual recordings and the right of 4789fixation and reproducing fixations of the Work, including storage of a 4790protected performance or phonogram in digital form or other electronic 4791medium. 4792 47932. Fair Dealing Rights. Nothing in this License is intended to reduce, 4794limit, or restrict any uses free from copyright or rights arising from 4795limitations or exceptions that are provided for in connection with the 4796copyright protection under copyright law or other applicable laws. 4797 47983. License Grant. Subject to the terms and conditions of this License, 4799Licensor hereby grants You a worldwide, royalty-free, non-exclusive, 4800perpetual (for the duration of the applicable copyright) license to 4801exercise the rights in the Work as stated below: 4802 4803- to Reproduce the Work, to incorporate the Work into one or more 4804 Collections, and to Reproduce the Work as incorporated in the 4805 Collections; 4806 4807- to create and Reproduce Adaptations provided that any such Adaptation, 4808 including any translation in any medium, takes reasonable steps to 4809 clearly label, demarcate or otherwise identify that changes were made to 4810 the original Work. For example, a translation could be marked "The 4811 original work was translated from English to Spanish," or a modification 4812 could indicate "The original work has been modified."; 4813 4814- to Distribute and Publicly Perform the Work including as incorporated in 4815 Collections; and, 4816 4817- to Distribute and Publicly Perform Adaptations. 4818 4819For the avoidance of doubt: 4820 4821Non-waivable Compulsory License Schemes. In those jurisdictions in which 4822the right to collect royalties through any statutory or compulsory 4823licensing scheme cannot be waived, the Licensor reserves the exclusive 4824right to collect such royalties for any exercise by You of the rights 4825granted under this License; 4826 4827Waivable Compulsory License Schemes. In those jurisdictions in which the 4828right to collect royalties through any statutory or compulsory licensing 4829scheme can be waived, the Licensor waives the exclusive right to collect 4830such royalties for any exercise by You of the rights granted under this 4831License; and, 4832 4833Voluntary License Schemes. The Licensor waives the right to collect 4834royalties, whether individually or, in the event that the Licensor is a 4835member of a collecting society that administers voluntary licensing 4836schemes, via that society, from any exercise by You of the rights 4837granted under this License. 4838 4839The above rights may be exercised in all media and formats whether now 4840known or hereafter devised. The above rights include the right to make 4841such modifications as are technically necessary to exercise the rights 4842in other media and formats. Subject to Section 8(f), all rights not 4843expressly granted by Licensor are hereby reserved. 4844 48454. Restrictions. The license granted in Section 3 above is expressly 4846made subject to and limited by the following restrictions: 4847 4848You may Distribute or Publicly Perform the Work only under the terms of 4849this License. You must include a copy of, or the Uniform Resource 4850Identifier (URI) for, this License with every copy of the Work You 4851Distribute or Publicly Perform. You may not offer or impose any terms on 4852the Work that restrict the terms of this License or the ability of the 4853recipient of the Work to exercise the rights granted to that recipient 4854under the terms of the License. You may not sublicense the Work. You 4855must keep intact all notices that refer to this License and to the 4856disclaimer of warranties with every copy of the Work You Distribute or 4857Publicly Perform. When You Distribute or Publicly Perform the Work, You 4858may not impose any effective technological measures on the Work that 4859restrict the ability of a recipient of the Work from You to exercise the 4860rights granted to that recipient under the terms of the License. This 4861Section 4(a) applies to the Work as incorporated in a Collection, but 4862this does not require the Collection apart from the Work itself to be 4863made subject to the terms of this License. If You create a Collection, 4864upon notice from any Licensor You must, to the extent practicable, 4865remove from the Collection any credit as required by Section 4(c), as 4866requested. If You create an Adaptation, upon notice from any Licensor 4867You must, to the extent practicable, remove from the Adaptation any 4868credit as required by Section 4(c), as requested. 4869 4870You may Distribute or Publicly Perform an Adaptation only under the 4871terms of: (i) this License; (ii) a later version of this License with 4872the same License Elements as this License; (iii) a Creative Commons 4873jurisdiction license (either this or a later license version) that 4874contains the same License Elements as this License (e.g., 4875Attribution-ShareAlike 3.0 US)); (iv) a Creative Commons Compatible 4876License. If you license the Adaptation under one of the licenses 4877mentioned in (iv), you must comply with the terms of that license. If 4878you license the Adaptation under the terms of any of the licenses 4879mentioned in (i), (ii) or (iii) (the "Applicable License"), you must 4880comply with the terms of the Applicable License generally and the 4881following provisions: (I) You must include a copy of, or the URI for, 4882the Applicable License with every copy of each Adaptation You Distribute 4883or Publicly Perform; (II) You may not offer or impose any terms on the 4884Adaptation that restrict the terms of the Applicable License or the 4885ability of the recipient of the Adaptation to exercise the rights 4886granted to that recipient under the terms of the Applicable License; 4887(III) You must keep intact all notices that refer to the Applicable 4888License and to the disclaimer of warranties with every copy of the Work 4889as included in the Adaptation You Distribute or Publicly Perform; (IV) 4890when You Distribute or Publicly Perform the Adaptation, You may not 4891impose any effective technological measures on the Adaptation that 4892restrict the ability of a recipient of the Adaptation from You to 4893exercise the rights granted to that recipient under the terms of the 4894Applicable License. This Section 4(b) applies to the Adaptation as 4895incorporated in a Collection, but this does not require the Collection 4896apart from the Adaptation itself to be made subject to the terms of the 4897Applicable License. 4898 4899If You Distribute, or Publicly Perform the Work or any Adaptations or 4900Collections, You must, unless a request has been made pursuant to 4901Section 4(a), keep intact all copyright notices for the Work and 4902provide, reasonable to the medium or means You are utilizing: (i) the 4903name of the Original Author (or pseudonym, if applicable) if supplied, 4904and/or if the Original Author and/or Licensor designate another party or 4905parties (e.g., a sponsor institute, publishing entity, journal) for 4906attribution ("Attribution Parties") in Licensor's copyright notice, 4907terms of service or by other reasonable means, the name of such party or 4908parties; (ii) the title of the Work if supplied; (iii) to the extent 4909reasonably practicable, the URI, if any, that Licensor specifies to be 4910associated with the Work, unless such URI does not refer to the 4911copyright notice or licensing information for the Work; and (iv) , 4912consistent with Ssection 3(b), in the case of an Adaptation, a credit 4913identifying the use of the Work in the Adaptation (e.g., "French 4914translation of the Work by Original Author," or "Screenplay based on 4915original Work by Original Author"). The credit required by this Section 49164(c) may be implemented in any reasonable manner; provided, however, 4917that in the case of a Adaptation or Collection, at a minimum such credit 4918will appear, if a credit for all contributing authors of the Adaptation 4919or Collection appears, then as part of these credits and in a manner at 4920least as prominent as the credits for the other contributing authors. 4921For the avoidance of doubt, You may only use the credit required by this 4922Section for the purpose of attribution in the manner set out above and, 4923by exercising Your rights under this License, You may not implicitly or 4924explicitly assert or imply any connection with, sponsorship or 4925endorsement by the Original Author, Licensor and/or Attribution Parties, 4926as appropriate, of You or Your use of the Work, without the separate, 4927express prior written permission of the Original Author, Licensor and/or 4928Attribution Parties. 4929 4930Except as otherwise agreed in writing by the Licensor or as may be 4931otherwise permitted by applicable law, if You Reproduce, Distribute or 4932Publicly Perform the Work either by itself or as part of any Adaptations 4933or Collections, You must not distort, mutilate, modify or take other 4934derogatory action in relation to the Work which would be prejudicial to 4935the Original Author's honor or reputation. Licensor agrees that in those 4936jurisdictions (e.g. Japan), in which any exercise of the right granted 4937in Section 3(b) of this License (the right to make Adaptations) would be 4938deemed to be a distortion, mutilation, modification or other derogatory 4939action prejudicial to the Original Author's honor and reputation, the 4940Licensor will waive or not assert, as appropriate, this Section, to the 4941fullest extent permitted by the applicable national law, to enable You 4942to reasonably exercise Your right under Section 3(b) of this License 4943(right to make Adaptations) but not otherwise. 4944 49455. Representations, Warranties and Disclaimer 4946 4947UNLESS OTHERWISE MUTUALLY AGREED TO BY THE PARTIES IN WRITING, LICENSOR 4948OFFERS THE WORK AS-IS AND MAKES NO REPRESENTATIONS OR WARRANTIES OF ANY 4949KIND CONCERNING THE WORK, EXPRESS, IMPLIED, STATUTORY OR OTHERWISE, 4950INCLUDING, WITHOUT LIMITATION, WARRANTIES OF TITLE, MERCHANTIBILITY, 4951FITNESS FOR A PARTICULAR PURPOSE, NONINFRINGEMENT, OR THE ABSENCE OF 4952LATENT OR OTHER DEFECTS, ACCURACY, OR THE PRESENCE OF ABSENCE OF ERRORS, 4953WHETHER OR NOT DISCOVERABLE. SOME JURISDICTIONS DO NOT ALLOW THE 4954EXCLUSION OF IMPLIED WARRANTIES, SO SUCH EXCLUSION MAY NOT APPLY TO YOU. 4955 49566. Limitation on Liability. EXCEPT TO THE EXTENT REQUIRED BY APPLICABLE 4957LAW, IN NO EVENT WILL LICENSOR BE LIABLE TO YOU ON ANY LEGAL THEORY FOR 4958ANY SPECIAL, INCIDENTAL, CONSEQUENTIAL, PUNITIVE OR EXEMPLARY DAMAGES 4959ARISING OUT OF THIS LICENSE OR THE USE OF THE WORK, EVEN IF LICENSOR HAS 4960BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. 4961 49627. Termination 4963 4964This License and the rights granted hereunder will terminate 4965automatically upon any breach by You of the terms of this License. 4966Individuals or entities who have received Adaptations or Collections 4967from You under this License, however, will not have their licenses 4968terminated provided such individuals or entities remain in full 4969compliance with those licenses. Sections 1, 2, 5, 6, 7, and 8 will 4970survive any termination of this License. Subject to the above terms and 4971conditions, the license granted here is perpetual (for the duration of 4972the applicable copyright in the Work). Notwithstanding the above, 4973Licensor reserves the right to release the Work under different license 4974terms or to stop distributing the Work at any time; provided, however 4975that any such election will not serve to withdraw this License (or any 4976other license that has been, or is required to be, granted under the 4977terms of this License), and this License will continue in full force and 4978effect unless terminated as stated above. 8. Miscellaneous 4979 4980Each time You Distribute or Publicly Perform the Work or a Collection, 4981the Licensor offers to the recipient a license to the Work on the same 4982terms and conditions as the license granted to You under this License. 4983 4984Each time You Distribute or Publicly Perform an Adaptation, Licensor 4985offers to the recipient a license to the original Work on the same terms 4986and conditions as the license granted to You under this License. 4987 4988If any provision of this License is invalid or unenforceable under 4989applicable law, it shall not affect the validity or enforceability of 4990the remainder of the terms of this License, and without further action 4991by the parties to this agreement, such provision shall be reformed to 4992the minimum extent necessary to make such provision valid and 4993enforceable. 4994 4995No term or provision of this License shall be deemed waived and no 4996breach consented to unless such waiver or consent shall be in writing 4997and signed by the party to be charged with such waiver or consent. 4998 4999This License constitutes the entire agreement between the parties with 5000respect to the Work licensed here. There are no understandings, 5001agreements or representations with respect to the Work not specified 5002here. Licensor shall not be bound by any additional provisions that may 5003appear in any communication from You. This License may not be modified 5004without the mutual written agreement of the Licensor and You. 5005 5006The rights granted under, and the subject matter referenced, in this 5007License were drafted utilizing the terminology of the Berne Convention 5008for the Protection of Literary and Artistic Works (as amended on 5009September 28, 1979), the Rome Convention of 1961, the WIPO Copyright 5010Treaty of 1996, the WIPO Performances and Phonograms Treaty of 1996 and 5011the Universal Copyright Convention (as revised on July 24, 1971). These 5012rights and subject matter take effect in the relevant jurisdiction in 5013which the License terms are sought to be enforced according to the 5014corresponding provisions of the implementation of those treaty 5015provisions in the applicable national law. If the standard suite of 5016rights granted under applicable copyright law includes additional rights 5017not granted under this License, such additional rights are deemed to be 5018included in the License; this License is not intended to restrict the 5019license of any rights under applicable law. 5020 5021