Rephrased documentation for better readability
[fifth.git] / doc / language.org
1 :PROPERTIES:
2 :ID:       da7fff9b-0b67-4843-828a-52a404d7f401
3 :END:
4
5 #+TITLE: Fifth - language
6 #+AUTHOR: Svjatoslav Agejenko
7 #+LANGUAGE: en
8
9 - [[file:5TH_ET.txt][Example Fifth source file - text editor]]
10
11 * Fifth source format
12 Fifth uses a different character table and codes than ASCII (still
13 almost similar). I call it FSCII (Fifth Standard Code for Information
14 Interchange) for example space character is not 32 but 255 instead.  I
15 plan to use mainly HEX numbers, and create new characters to represent
16 numeric values. So typical nemric characters "0123..."  is treated
17 like ordinary letters.
18 ** FSCII
19
20 |    DEC | HEX   | function                               |
21 |--------+-------+----------------------------------------|
22 | 0 - 15 | 0 - F | HEX numbers                            |
23 |    252 | FC    | backspace                              |
24 |    253 | FD    | tabulator (TAB)                        |
25 |    254 | FE    | carriage return (CR)                   |
26 |    255 | FF    | space                                  |
27 |   else |       | ordinary characters, same as in ASCII. |
28 * Fifth commands
29 ** Compilation & miscellaneous
30 #+BEGIN_VERSE
31 init    module  ( -- )
32                 First module, control is passed to on startup. Contains
33                 initialization routines. Also it is the last core module.
34                 All new modules on top of it comes as result of executing
35                 external source files.
36
37 head <name>     ( -- )  compiles new dictionary entry without specifying
38                 new module type.
39                 ex: head myentry
40
41 : <name>        ( -- )  creates new code module
42 ;               ( -- )  ends module (immideate)
43                 ex: : hello ." hi there" ;
44
45 const <name>    ( n -- ) defines new constant.
46                 ex: 2147483647 const max
47
48 :i <name>       ( -- ) same as ":" but this module will be executed
49                 immideately even in compile mode.
50                 ex: :i ( 41 scan ;
51
52 create <name>   ( -- ) same as "head" , but specify module type as data.
53                 ex: create LotoResults 5 , 13 , 52 , 12 , 11 , 3 ,
54
55 allot           ( n -- ) allocate n bytes in dictionary.
56                 ex: create MyArray 100 allot
57
58 " <string>"     ( -- ) compile string and its size into core.
59                 ex: create Mystring " This is it's contects"
60
61 str <name> <string>" ( -- ) just shorter way for defining strings.
62                 ex: str Mystring This is it's contenc"
63
64 var <name>      ( -- ) define new 32 bit variable.
65                 ex: var result
66
67 ' <module>      ( -- n ) return memory address of given entry.
68                 ex: ' init
69
70 forget <name>   ( -- ) erases from RAM given entry and all entries what was
71                 defined after it.
72                 ex: forget myprog
73
74 [               ( -- )  set interpret mode (immideate)
75 ]               ( n -- ) set compile mode and compile top stack element
76                 in as literal. Together [ .... ] cobination provides good
77                 way to compute some values only once, at compile time,
78                 rather than every time while program is running.
79                 ex: : calculate - [ 4 MyConst1 + MyConst2 * ] ;
80
81 defer <name>    ( -- ) creates new module, with jump instruction.
82                 Later address where to jump can be modified by "is" command.
83                 This provides method of foward referencing. So you can use
84                 modules what not jet exist.
85 is              ( address1 address2 -- ) address1 - where to jump, address2 -
86                 address of module created by defer command.
87                 ex:     defer dispver
88                         : run dispver ." running ..." ;
89                                ... whatever ...
90                         : (dispver ." Version 9.99 " ;
91                         ' (dispver ' dispver is
92
93                 Now if I type "run" on the screen appears:
94                         Version 9.99 running ...
95
96 asc <char>      ( -- ) reads char ascii code and treats it as literal.
97                 (immideate)
98                 ex: : BreakLine 30 do asc - emit loop ;
99                                  same as:
100                     : BreakLine 30 do    45 emit loop ;
101
102 dyninc          ( handle -- ) execute code in dynamic memory handle.
103                 automatically deallocates it when done.
104
105 include         ( filenumber -- ) execute code in specified file.
106
107 words           ( -- ) display existing blocks in core.
108
109 bye             ( -- ) exit from Fifth
110
111 fkey            ( -- c )
112                 Read one byte from input stream.
113
114 sadd            ( c addr -- )
115                 Add one byte "c" to string located at "addr" and updates
116                 string length.
117
118 scan            ( c -- )
119                 Read input stream and store it to  pad   until it finds  c  .
120                 It ignores all "c" bytes until it finds any non "c" byte.
121                 in other words:
122                                 c  is:  "
123                          input stream:  """"This is test !"aoeu idh
124                                result:  This is test !
125
126                 Is useful for breaking text lines into words.
127
128 skey            ( -- c )
129                 So called safe "fkey". Reads data from input stream
130                 but converts characters with ASCII codes: 9 13 10
131                 to spaces.
132
133 str=str?        ( adr1 adr2 -- result )
134                 Compares string at "adr1" with string at "adr2", returns
135                 true flag if they are equal or false if they are not.
136                 true = -1
137                 false = 0
138
139 find            ( -- addr )
140                 Searches whole dictionary for word in "pad". If found,
141                 returns it address, if not, returns 0.
142
143 execute         ( -- )
144                 Execute word located in "pad". Depending on "mode".
145
146 dta             ( addr -- DataAddr )
147                 Calculates address of dictionary entry data area, from
148                 entry point.
149
150 2num            ( -- num result )
151                 Attempt to convert string located in "pad" into numeric
152                 value. If succeed returns number and true as result.
153                 If not, returns whatever and false as result.
154
155 dadd            ( addr length -- )
156                 Add to dictionary data located at "addr", with specified
157                 length.
158
159 lit             ( n -- )
160                 Act with number depending on "mode". When interpreting,
161                 leaves it in stack.
162
163
164 incmod          ( addr -- )
165                 Add to dictionary data located at "addr"+1 , length is taken
166                 from "addr".
167
168 here            ( -- n )
169                 return "h" contents.
170
171 mode    var     8 bit
172                 Holds input stream parser operation mode.
173                 0 = interpreting
174                 1 = compiling
175
176 pad     var     128 bytes
177                 Holds temprorary strings.
178
179 h       var     32 bit
180                 Pointer to free byte in memory, always at the end of the
181                 dictionary. Each time when something is stored
182                 by "c," command, pointer is incareased.
183
184 lp      var     32 bit
185                 Pointer to last dictionary word. Each time when new word is
186                 compiled or erased by "forget", this pointer is updated.
187
188 modulechk       ( Dstr<filename> -- ) check if module is loaded, if not
189                 immideately load it.
190
191 ne              ( entrydata entrytype -- ) Compile new dictionary entry.
192                 It's name must be in "pad".
193 #+END_VERSE
194 ** Conditionals & control flow
195 #+BEGIN_VERSE
196 if              ( flag -- )   (immideate)
197                 "if 1.. else 2.. then" or
198                 "if 1.. then" construction. Conditional execution.
199                 Performs "1.." if "flag" was true,
200                 elseway performs "2.." if exist. Execution continues after
201                 word "then".
202                 ex: 1 if ." nonzero" else ." zero" then
203
204 >=              ( n1 n2 -- result ) true if (n1 = n2) or (n1 > n2)
205                 ex: 5 3 >= if ." first number is greater or equal" then
206
207 <=              ( n1 n2 -- result ) true if (n1 = n2) or (n1 < n2)
208 =               ( n1 n2 -- result ) true if n1 = n2
209
210 do              ( count -- )  (immideate)
211                 "do .. loop" construction. Performs ".." "count" times.
212                 In every step "count" is decareased until it is 0.
213                 ex: : test 5 do i .d loop ;
214                 result: 4 3 2 1 0
215
216 doexit         ( -- ) exit from "do .. loop"
217
218 for             ( count top -- )   (immideate)
219                 "for .. loop" construction. Performs ".." (top - count)  times.
220                 In every step "count" is incareased until it reaches "top" .
221                 ex: : test 4 10 for i .d loop ;
222                 result: 4 5 6 7 8 9
223
224 forexit         ( -- ) exit from "for .. loop"
225
226 until           ( -- )  (immideate)
227                 "until .. loop" construction. Performs ".." until flag become
228                 true. False by default. Top of return stack holds flag.
229
230 done            ( -- ) exit from "until .. loop"
231
232 #+END_VERSE
233 ** Disk & file access
234 #+BEGIN_VERSE
235 diskload ( FromDisk ToMem amount -- )
236                 Load specified abount of bytes from disk into memory.
237
238 disksave ( FromMem ToDisk amount -- )
239                 save specified abount of bytes from memory into disk.
240
241 format ( -- )   Erase all files.
242
243 fsDfilesize@ ( handle -- size )
244                 Return size of opened file.
245
246 fsDcurloc@ ( handle -- location )
247                 Return current location in file.
248
249 fsDupdated@ ( handle -- updated? )
250                 Return true if file was updated,
251                 ie. write operations occured.
252
253 fssave ( FromMem DestFileHandle amount -- )
254                 Save data to file.
255
256 fsload ( SrcFileHandle ToMem amount -- )
257                 Load data from file.
258
259 fseof ( handle -- bytesLeft )
260                 Return amount of bytes left till end of file.
261                 Useful before read operation.
262
263 fsls ( -- )     List all files and lists (directories,folders)
264                 in current path.
265
266 fslsr ( -- )    Same as "fsls" but recursively scans also sub lists.
267
268 fscl ( DynStrHand -- )
269                 Change list (path)
270
271 fscreate ( DynStrHand -- DescPnt )
272                 Create new file or list. Can create multiple lists at once.
273                 ex: when creating:
274                     "\listGAMES\listSTRATEGY\listSIMWORLD\5th-runme"
275                 and only "\listGAMES\" already exist, then
276                 "listSTRATEGY" and "listSIMWORLD" lists will be created,
277                 and empty file "5th-runme" placed in there.
278
279 fsDsave ( DynHand<data> DynStrHand<filename> -- )
280                 Create new file and save all data from dynamic memory
281                 block to it.
282
283 fsDload ( DynStr<SrcFileName> DynHand<DataDest> -- )
284                 Load whole file into dynamic memory block.
285
286 fsDloadnew ( DynStr<SrcFileName> -- DynHand<DataDest> )
287                 Load whole file into new dynamic memory block.
288 #+END_VERSE
289 ** Dynamic memory
290 #+BEGIN_VERSE
291 dynal ( size -- handle )
292                 Allocate dynamic memory block and return it's handle.
293
294 dynde ( handle -- )
295                 Deallocate dynamic memory block.
296
297 dynp ( handle -- addr )
298                 Returns pointer to memory where dynamic block
299                 data begins.
300
301 dyns ( handle -- size )
302                 Returns size of dynamic block.
303
304 dynresize ( NewSize handle -- )
305                 Nondestructively resize dynamic block.
306
307 dync@ ( addr handle )
308                 Read one byte from dynamic block.
309
310 dync! ( byte addr dynhandle )
311                 Write one byte to dynamic block.
312
313 dyn@ ( addr handle )
314                 Read 32 bit number from dynamic block.
315                 Address will spacify, whitch number, not byte.
316
317 dyn! ( 32BitNum addr dynhandle )
318                 Write 32 bit number to dynamic block.
319                 Address will spacify, whitch number, not byte.
320
321 dyncon ( size "name" -- )
322                 Allocate dynamic block with specified size, and
323                 create constant honding its handle.
324                 ex: 100 dyncon MyNewBlock
325
326 dyn. ( handle -- )
327                 Write contenc of dynamic memory block to screen.
328 #+END_VERSE
329 ** Graphics and text
330 #+BEGIN_VERSE
331 .               ( n -- ) print number on screen
332
333 d.              ( n -- ) print number on screen in decimal
334
335 ?               ( addr -- ) print 32 bit value located at addr.
336
337 ." <string>"    ( -- ) print string into screen. Immideately
338                 compiles.
339                 ex: : greeting ." Hello, World" ;
340
341 tab.            ( -- ) print tabulator
342
343 calccol         ( b g r -- c ) calculate color what best matches given
344                 Blue Green & Red values. Values must be in range 0 - 255.
345
346 imgalloc        ( xsize ysize -- imgbuf ) allocate image buffer for
347                 specified size.
348
349 imgsize         ( imgbuf -- ) print on the screen X & Y size of image
350                 buffer.
351
352 point           ( x y imgbuf -- addr ) returns memory address for specified
353                 pixel.
354
355 pset            ( color x y imgbuf -- ) set graphic point
356
357 boxf            ( x1 x2 y1 y2 imgbuf color -- ) draw filled box
358
359 cls             ( imgbuf -- ) clear image buffer
360
361 setpal          ( b g r color -- ) set palette value for specified color.
362                 values bust be in size 0 - 63.
363
364 putchar         ( char color x y imgbuf -- ) put graphic character in
365                 imagebuffer to specified (x & y) location.
366
367 scroll          ( x y imgbuf -- ) scroll in imgbuf.
368
369 scrollf         ( color x y screen -- )  scroll and fill empty space with
370                 given color.
371
372 at!             ( x y -- ) set cursor location
373 curc!           ( color -- ) set text color
374 curb!           ( solor -- ) set backround color
375
376 colnorm         ( -- ) set text color to normal
377 colneg          ( -- ) set text color to negative (selected)
378
379 dyntype         ( dynhandle -- ) display contenc of dynamic memory on screen
380 fsdisp          ( file -- ) clear screen, display file, and wait for key
381
382 type            ( addr length -- )
383                 Types on the screen string, from memory at  addr  and
384                 specified length.
385
386 write           ( addr -- )
387                 Types on the screen string, from memory at "addr"+1
388                 length is taken from "addr" .
389
390 screen  const   32 bit
391                 Holds handle of screen buffer.
392
393 copyscreen      ( SrcImgHandle DestImgHandle -- ) copy contenc of source
394                 image to destination image. Source and destination images
395                 must have same size.
396 #+END_VERSE
397 ** Math, memory & stack manipulation
398 #+BEGIN_VERSE
399 off             ( n -- ) writes 0 to given address, good for zeroing variable.
400                 ex: MyVariable off
401 on              ( n -- ) writes -1 (true flag) to given address.
402                 ex: MyVariable on
403
404 2dup            ( n1 n2 -- n1 n2 n1 n2 )
405 2drop           ( n1 n2 -- )
406 nip             ( n1 n2 -- n2 )
407 neg             ( n1 -- -n1 ) negotiate
408 bit@            ( n bit -- result ) return specified bit from n.
409                 ex: 38 2 bit@   (result will be 1)
410 to32bit         ( n1 n2 n3 n4 -- n32 ) treat 4 last stack elements as bytes
411                 and unite them into 32 bit dword. Most significant byte
412                 on top.
413                 ex: 12 76 23 11 to32bit   result: 186076172
414
415 to8bit          ( n32 -- n1 n2 n3 n4 ) break 32 bit number into 4 bytes.
416                 Useful if you need to send 32 bit numbers thru 8 bit COM
417                 port.
418                 ex: 186076172 to8bit   result: 12 76 23 11
419
420 mod             ( n1 n2 -- reminder ) divide n1 by n2 and returns reminder.
421                 ex: 12 5 mod   result: 2
422
423 bound           ( low n high -- n ) check if n is in given bounds,
424                 if not then incarease/decarease it to match bounds.
425                 ex: 5 80 15 bound    result: 15
426                     5 10 15 bound    result: 10
427                     5 -10 15 bound   result: 5
428
429 bound?          ( low n high -- result ) returns true if n is in the
430                 given bounds.
431
432 tab             ( col -- spaces) calculate amount of spaces to add
433                 ta reach next tabulation from given column.
434
435 count           ( addr -- addr+1 n )
436                 Useful for returning bytes from constantly incareasing
437                 address. Module "type" is nice example.
438
439 c,              ( n -- )
440                 store one byte at memory specified by "h". And incarease
441                 "h" by 1.
442
443 ,               ( n -- )
444                 store 32 bit number at memory specified by "h". And
445                 incarease "h" by 4.
446
447 cmove           ( addr1 addr2 n -- )
448                 copy "n" amount of bytes from memory at "addr1" to memory
449                 at "addr2".
450
451 rnd             ( limit -- result )
452                 generates random number in range 0 to "limit"-1.
453
454 abs             ( n -- |n| )
455                 returns absolute value of "n"
456 #+END_VERSE
457 ** Dynamic & static strings
458 Fifth supports both static and dynamic strings. Static strings must
459 have predefined space reserved, and string mustn't exceed this
460 length. They manipulation is faster. But they use more memory. Static
461 string memory address is used to refer to the string.
462
463 Dynamic strings can have at any time length form 0 to 0FFh, They take
464 up only memory they currently need. They are held in dynamic memory
465 blocks, so dynamic block handle is used to refer to this string.
466
467 Both types of strings are stored in the way, where first (0th) byte
468 holds current string length, following bytes are string itself.
469
470
471 #+BEGIN_VERSE
472 Dynamic:
473
474 Dstral ( -- handle )
475                 Allocate new string.
476
477 Dstrlen ( handle -- length )
478                 Return string length.
479
480 c+Dstr ( chr handle -- )
481                 Add one byte to end of the string.
482
483 c+lDstr ( chr handle -- )
484                 Add one byte to left side (beginning) of the string.
485
486 Dstr. ( handle -- )
487                 Write contec of string into screen.
488
489 Dstrsure ( size Dstr -- )
490                 Makes sure that at least rquested
491                 "size" (amount of characters) is allocated for given
492                 dynamic string.
493
494 Dstr2str ( handle address -- )
495                 Copy dyamic string into static memory space.
496
497 str2Dstr ( address handle -- )
498                 Copy static string into dyamic string.
499
500 Dstr+str ( Dstr addr -- )
501                 Add contenc of dynamic string to static string.
502
503 D" any string" ( -- Dstr )
504                 Moves specified string into dynamic string called "defDstr".
505
506 D> any_string ( -- Dstr )
507                 Moves specified string into dynamic string called "defDstr".
508                 Space marks end of string!
509
510 D>2 any_string ( -- Dstr )
511                 Moves specified string into dynamic string called "defDstr2".
512                 Space marks end of string!
513
514 Dstr+Dstr ( Dstr1 Dstr2 -- )
515                 Adds "Dstr1" to "Dstr2" and places result into "Dstr2".
516
517 Dstrclear ( Dstr -- )
518                 Clears contenc of dynamic string.
519
520 Dstr2Dstr ( Dstr1 Dstr2 -- )
521                 Moves "Dstr1" to "Dstr2".
522 Dstr ( data" name -- )
523                 Creates new dynamic string and moves specified data into it.
524                 Then creates new constant with given "name" holding created
525                 dynamic string handle.
526
527                 ex: Dstr Hello, my name is Sven!" message      \ creates it
528                     message Dstr.                              \ tests it
529
530 Dstrlscan ( char Dstr -- loc )
531                 Searches dynamic string for "char", from left to right,
532                 returns first found "char" location in string, or 0,
533                 if not found.
534
535 Dstrrscan ( char Dstr -- loc )
536                 Searches dynamic string for "char", from right to left,
537                 returns first found "char" location in string, or 0,
538                 if not found.
539
540 Dstrlscane ( char Dstr -- loc )
541                 Same as "Dstrlscan" buf returns string length+1 as location.
542 ΓΏ
543 Dstrleft ( amo Dstr -- )
544                 Only specified amount of characters from left remains
545                 in dynamic string. ie. cut right part out.
546
547 Dstrright ( amo Dstr -- )
548                 Only specified amount of characters from right remains
549                 in dynamic string. ie. cut left part out.
550
551 Dstrcutl ( amo Dstr -- )
552                 Cut specified amount of characters from left of dynamic
553                 string out.
554
555 Dstrsp ( char Dstr1 Dstr2 -- )
556                 Separate dynamic string in Dstr1 into two parts,
557                 using "char" as separator. First part will be stored in
558                 "Dstr2", second part in "Dstr1".
559                 ex: asc \                               \ ..separator
560                     D> listF\listLIB\5TH_DRVMOUSE       \ ..separate from
561                     defDstr2                            \ ..place result in
562                     Dstrsp              \ separation command
563                     defDstr Dstr.       \ will be: listLIB\5TH_DRVMOUSE
564                     defDstr2 Dstr.      \ will be: listF
565
566 Dv ( addr -- )
567                 Allocates empty dynamic string, and places it's handle
568                 into given address.
569
570 Df ( addr -- )
571                 Reads dynamic string handle from given address and
572                 deallocates (frees) it.
573
574 ex:     var mystring1
575         : testmodule
576         mystring1 Dv            \ allocates string
577
578                 <whatever>
579
580         mystring1 Df ;          \ deallocates it again when no longer needed.
581 #+END_VERSE