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