Shop Learn
TACHYON O/S V3.0 JUNO - Furiously Fast Forth, FAT32+LAN+VGA+RS485+OBEX ROMS+FP+LMM+++ - Page 89 — Parallax Forums

TACHYON O/S V3.0 JUNO - Furiously Fast Forth, FAT32+LAN+VGA+RS485+OBEX ROMS+FP+LMM+++

18687899192109

Comments

  • In my statemachinery I have the need to get the name of a word whose cfa I have. I know it is possible but my babysteps are still very wiggly. Maybe someone will give me his hand - I'm looking for the CFA>NFA word definition in the following code snippet which has yet to be implemented and I'm to tired to implement it myself (now 1:00 am and getting up at 5:00 am and my better half is asking for end of project ...).
    WORD mynfa
    WORD mycfa
    pub .NFA ( nfa -- )
      DUP C@ SWAP 1+ SWAP CTYPE     \ print name of given nfa to console
    	;
    \ uncomment following lines to get the idea
    \ pub CFA>NFA ( cfa -- nfa )
    \   DROP NFA' TERMINAL mynfa W! mynfa W@     \ currently simulated
    \ 	( and to be filled )
    \ 	;
    pub CFA>NFA ( cfa -- nfa )
    	( here is the missed code )
    	;
    ' TERMINAL mycfa W!
    ( now we have cfa ... )
    mycfa W@ CFA>NFA mynfa W!
    mynfa W@ CR .NFA
    
    Thanks for your help you great(!) forumistas.
  • The tick symbol ' will return with the CFA (execute) address of the following word, isn't that what you want?

    ' .VER .WORD 1AB9 ok
    $1AB9 CALL Propeller .:.:--TACHYON--:.:. Forth V29160613.0000

    My patient better half gave up a long time ago asking me :) Well, she still asks me, it's just that she doesn't expect much :)
  • two things have to be said. First: no this is not what I wanted. I'm on CFA>NFA. The iteration through the dictionary for me is such a great thing that I thought I should ask before needing so much time.
    The tick symbol ' will return with the CFA (execute) address of the following word, isn't that what you want?' .VER .WORD 1AB9 ok$1AB9 CALL Propeller .:.:--TACHYON--:.:. Forth V29160613.0000My patient better half gave up a long time ago asking me :) Well, she still asks me, it's just that she doesn't expect much :)
    second: I'm sure your better half is knowing or feeling that there is something of real value which you must publish and share with others to make it flourish. Alone this work can't be done. Now I will progress CFA>NFA :)
  • Still not got forward with CFA>NFA .
    After some research in this thread - for other newbies:
    - ATR :: ATtRibute - attribute
    - ATRS :: ATtRibuteS - attributes
    - HATR :: Header ATtRibute
    - CFA :: Code Field Address
    - NFA :: Name Field Address
    - PFA :: Parameter Field Address
    I think these should be explained in Tachyon glossary.

  • Let's re-post this as a start.

    I was thinking during all these posts that I must do something about the use and definition of NFA CFA PFA as they are in traditional Forth but mean something not quite the same in Tachyon. The trouble is that I do have the two bytes in the name header which usually are the byte code(s) to compile or they could be in some cases a 16-bit pointer to the bytecodes to execute. What do I call this field? Then there is the actual code itself, be it in cog as PASM or in hub as bytecode, what do I call this? :)

    NFA is probably ok but just remembering that the name space is separate from code space. Now putting aside for the moment the two bytes in the header that are the compilation codes we have the actual code which is either PASM in the cog (opcode) or bytecode in the hub. When we do a tick of an opcode it returns with its address in the cog in the range of $00..$FF or $100..$1FF in the case of XOP access to the second 256 longs in the cog. Okay, that's fine but some words are comprised of 2 opcodes as we allow 2 bytes in the header to represent the code. A example is NIP which rather than consuming precious cog memory for code is simply defined as SWAP DROP and an attribute in the header tells Tachyon to compile these two bytes. Now if we were to find the tick (code address) of NIP we would get something but not what we were expecting, it is more of an unresolved situation. I would like to think of CFA more as a "Compile Field Address" taking into account the attribute as well while the PASM or byte code is either machine code or VM code so it is still a "Code Field Address" or CFA. Whereas PFA referred to the parameters that immediately followed the code field header in traditional Forths, so those parameters could be a constant, a structure, or more typically CFAs of Forth words to execute.

    Looking at NIP we have.
    ' NIP .WORD 2F26 ok
    NFA' NIP $10 DUMP 
    0000_6A0D:   03 4E 49 50  86 1F 11 03   41 44 4F 86  1E D1 02 32   .NIP....ADO....2 ok
    ' SWAP .WORD 001F ok
    ' DROP .WORD 0011 ok
    
    where we can see the 2 compilation codes just after the name and attribute $86

    Compare this with a definition that uses NIP:
    : MYTEST NIP PRINT" HELLO" . ;  ok
    ' MYTEST $10 DUMP 
    0000_3BBA:   1F 11 C1 64  48 45 4C 4C   4F 00 C1 67  0C 72 3B BA   ...dHELLO..g.r;. ok
    NFA' MYTEST $10 DUMP 
    0000_55C9:   06 4D 59 54  45 53 54 82   BE 49 05 53  54 41 52 53   .MYTEST..I.STARS ok
    
    Very first two bytecodes that are compiled are SWAP ($1F) and DROP ($11) which are the PASM addresses or opcodes which represent NIP. The C1 following that is a CALL to a vector via the index 64 that then looks up the address that points to the actual bytecode to execute for PRINT" after which we can see the null terminated string followed by another call C1 67 which is . or PRINT and then 0C which is the EXIT opcode.

    Great, but this is not straightforward threaded Forth. Perhaps CFA can mean the code address to execute and we can still use PFA to point to the header code bytes which are compiled. If PFA is too confusing because of traditional PFA meaning then I would favor CCA for Compilation Code Address so using as an example:
    NFA' PRINT" 10 DUMP 
    0000_6584:   06 50 52 49  4E 54 22 A2   C1 71 05 50  52 49 4E 54   .PRINT"..q.PRINT ok
    
    At present we can say:
    NFA' PRINT" 10 DUMP 
    0000_6584:   06 50 52 49  4E 54 22 A2   C1 71 05 50  52 49 4E 54   .PRINT"..q.PRINT ok
    NFA' PRINT" NFA>CFA .WORD 658C ok
    
    which actually finds the CCA which then needs to be converted to the CFA. At present the CFA and PFA are jumbled, my bad. But then CCA should really point to the preceding attribute to ascertain the correct interpretation of the following two compilation code bytes. Now if you go to TF2 it is a lot simpler again but the P1 is awkward to implement a traditional Forth in and the result would be less than satisfactory so therefore the awkwardness is in the implementation so that the result is a Forth that is more than satisfactory.





  • MJBMJB Posts: 1,235
    proplem wrote: »
    Still not got forward with CFA>NFA .
    After some research in this thread - for other newbies:
    - ATR :: ATtRibute - attribute
    - ATRS :: ATtRibuteS - attributes
    - HATR :: Header ATtRibute
    - CFA :: Code Field Address
    - NFA :: Name Field Address
    - PFA :: Parameter Field Address
    I think these should be explained in Tachyon glossary.

    why don't you just use
    ' .VER >PFA  PFA>NFA 20 DUMP
    
  • I think the OP wants to lookup the NFA from the CFA inside his state machine for some reason. Maybe he has a CFA and is gonna execute a call but wants to know what Word this is before the call. I can't come up with a proper use case here. Let's hear from the OP.

    MJB wrote: »
    proplem wrote: »
    Still not got forward with CFA>NFA .
    After some research in this thread - for other newbies:
    - ATR :: ATtRibute - attribute
    - ATRS :: ATtRibuteS - attributes
    - HATR :: Header ATtRibute
    - CFA :: Code Field Address
    - NFA :: Name Field Address
    - PFA :: Parameter Field Address
    I think these should be explained in Tachyon glossary.

    why don't you just use
    ' .VER >PFA  PFA>NFA 20 DUMP
    

  • D.P wrote: »
    I think the OP wants to lookup the NFA from the CFA inside his state machine for some reason. Maybe he has a CFA and is gonna execute a call but wants to know what Word this is before the call. I can't come up with a proper use case here. Let's hear from the OP.

    why don't you just use
    ' .VER >PFA  PFA>NFA 20 DUMP
    

    D.P is pointing the right direction and mjb's suggest seemed well but didn't do it.
    I have a CFA and want to get to the NFA - reusing and prefixing a one liner mjb's answer
    pub .NFA ( nfa -- ) DUP C@ SWAP 1+ SWAP CTYPE ;
    ' .VER CFA>NFA .NFA
    
    is what I need to do and if I had CFA>NFA this should output
    .VER ok
    
  • Just try the perhaps misnamed PFA>NFA.
    ' .VER .WORD 1AB9 ok
    $1AB9 PFA>NFA QD 
    0000_6E3D:   2E 56 45 52  82 C0 50 07   54 41 43 48  59 4F 4E 82   .VER..P.TACHYON.
    0000_6E4D:   C0 8F 04 40  50 41 44 82   C0 5A 04 48  4F 4C 44 82   ...@PAD..Z.HOLD. ok
    $1AB9 PFA>NFA PRINT$ .VER ok
    

    As you can see this actually returns with the start of the string in the name field but if you want the actual NFA just do a 1- so that we could say:
    : CFA>NFA  PFA>NFA 1- ;
    

  • MJBMJB Posts: 1,235
    edited 2016-07-13 09:00
    proplem wrote: »
    D.P wrote: »
    I think the OP wants to lookup the NFA from the CFA inside his state machine for some reason. Maybe he has a CFA and is gonna execute a call but wants to know what Word this is before the call. I can't come up with a proper use case here. Let's hear from the OP.

    why don't you just use
    ' .VER >PFA  PFA>NFA 20 DUMP
    

    D.P is pointing the right direction and mjb's suggest seemed well but didn't do it.
    I have a CFA and want to get to the NFA - reusing and prefixing a one liner mjb's answer
    pub .NFA ( nfa -- ) DUP C@ SWAP 1+ SWAP CTYPE ;
    ' .VER CFA>NFA .NFA
    
    is what I need to do and if I had CFA>NFA this should output
    .VER ok
    
    you were asking to start from CFA, but I didn't realize that ' returns the PFA instead (should have tested it).
    thats why I proposed:

    from Tachyon2.7.spin:
    ' : >PFA  ( cfa -- pfa )
    
    and from EXTEND.fth
    pub PFA>NFA ( pfa -- nfa \ find the nfa else false )
    
    so both together should do the job from CFA to NFA.

    But maybe you really want something different.

    Like print the name of the link in your table, which is the PFA, that ou can CALL.
    So you need PFA>NFA as Peter pointed out.

    And then there is the length byte in front of the real name string that you have to take into account.
  • shame on me - it is so easy and the result is so elegant.
    $1AB9 PFA>NFA PRINT$ .VER ok
    
    was what I wanted. The following is the output of my statemachine sending an AT command via serial interface and the incoming response OK with state transitions,state timer and state counter.
    'sIdle PNS AST ' RUN +POLL 
    RESET-->sIdle (t: 91234ms/r: 0) ok
    
    0000_4254:   00 00 00 00  00 00 00 00   00 00 00 00  00 00 00 00   ................
    sIdle-->sSendAT (t: 434ms/r: 1)
    sSendAT-->sIdle (t: 4ms/r: 1)
    0000_4254:   4F 4B 00 00  00 00 00 00   00 00 00 00  00 00 00 00   OK..............
    sIdle-->sSendAT (t: 1434ms/r: 7739)
    sSendAT-->sIdle (t: 3ms/r: 1)
    0000_4254:   4F 4B 4F 4B  00 00 00 00   00 00 00 00  00 00 00 00   OKOK............
    sIdle-->sSendAT (t: 1434ms/r: 7738)
    sSendAT-->sIdle (t: 4ms/r: 1)
    0000_4254:   4F 4B 4F 4B  4F 4B 00 00   00 00 00 00  00 00 00 00   OKOKOK..........
    sIdle-->sSendAT (t: 1434ms/r: 7738)
    sSendAT-->sIdle (t: 4ms/r: 1)
    0000_4254:   4F 4B 4F 4B  4F 4B 4F 4B   00 00 00 00  00 00 00 00   OKOKOKOK........
    sIdle-->sSendAT (t: 1434ms/r: 7739)
    

    This is a great success for me. Thank you very very much for your help altogether.
  • MJBMJB Posts: 1,235
    proplem wrote: »
    shame on me - it is so easy and the result is so elegant.
    $1AB9 PFA>NFA PRINT$ .VER ok
    
    was what I wanted. The following is the output of my statemachine sending an AT command via serial interface and the incoming response OK with state transitions,state timer and state counter.
    'sIdle PNS AST ' RUN +POLL 
    RESET-->sIdle (t: 91234ms/r: 0) ok
    
    0000_4254:   00 00 00 00  00 00 00 00   00 00 00 00  00 00 00 00   ................
    sIdle-->sSendAT (t: 434ms/r: 1)
    sSendAT-->sIdle (t: 4ms/r: 1)
    0000_4254:   4F 4B 00 00  00 00 00 00   00 00 00 00  00 00 00 00   OK..............
    sIdle-->sSendAT (t: 1434ms/r: 7739)
    sSendAT-->sIdle (t: 3ms/r: 1)
    0000_4254:   4F 4B 4F 4B  00 00 00 00   00 00 00 00  00 00 00 00   OKOK............
    sIdle-->sSendAT (t: 1434ms/r: 7738)
    sSendAT-->sIdle (t: 4ms/r: 1)
    0000_4254:   4F 4B 4F 4B  4F 4B 00 00   00 00 00 00  00 00 00 00   OKOKOK..........
    sIdle-->sSendAT (t: 1434ms/r: 7738)
    sSendAT-->sIdle (t: 4ms/r: 1)
    0000_4254:   4F 4B 4F 4B  4F 4B 4F 4B   00 00 00 00  00 00 00 00   OKOKOKOK........
    sIdle-->sSendAT (t: 1434ms/r: 7739)
    

    This is a great success for me. Thank you very very much for your help altogether.
    If you have some code to show/share the community will benefit and grow ...


  • The code isn't yet so far to publish. There have some things to be done and I want to put it into a package/module more precise two modules.
  • Hi proplem,
    I appreciate the feedback even on little things so I can continue to improve Tachyon not only under the hood but also from a programmer's perspective, especially someone who is starting out, So be prepared for some changes in this regard as even that PFA>NFA will be renamed due to the fact that it is not really a PFA or NFA but a name like >NAME is perhaps more suitable as it translates a code address to a name address.

    Also I will standardize on the field names overall so that:
    CFA = starting address of the bytecode if => $0200 or the PASM code in the cog if < $200.
    NFA = starting address of the name field which points to the count byte followed by the name etc.
    HAA = Header attribute address with also signifies what to do with the two compilation code bytes following.

    PFA will no longer be used or applicable although there are actual parameter fields in constants etc which is simply the CFA +1.
  • MJBMJB Posts: 1,235
    @Peter Did you see my emails or did they end up in spam?

  • Peter JakackiPeter Jakacki Posts: 10,193
    edited 2016-07-16 08:26
    Just checked spam
    nospam.png

    So the only emails I saw were in regards to TFTE.fth which uses Tachyon's built-in SPI instructions and in that regard the X,Y byte variables are fine for character positions rather than raw pixel positions IIRC. I'm not sure that I have tested the new code yet though.

    The other was SPIWRX but even though I allowed for an opcode entry I haven't used or implemented this method yet and maybe I might not either.

    Finally I am happy if you can make CREATE DOES> work with some suitable examples too :) Perhaps the one technical question from you that I discern might need to be answered is "--- how do we get the address of the last definition to put the 3 bytes CALL16 (+ EXIT ??) there ?". If we use @NAMES to return with the pointer to the latest definition which in itself is an NFA we can easily work from there with NFA>CFA.
    600 x 96 - 7K
  • MJBMJB Posts: 1,235
    edited 2016-07-16 15:28
    Thanks
    Just checked spam
    So the only emails I saw were in regards to TFTE.fth which uses Tachyon's built-in SPI instructions and in that regard the X,Y byte variables are fine for character positions rather than raw pixel positions IIRC. I'm not sure that I have tested the new code yet though.
    thanks - missed the char vs. pixel distinction
    The other was SPIWRX but even though I allowed for an opcode entry I haven't used or implemented this method yet and maybe I might not either.
    SPIWRX is there, great for arbitrary transfer length up to 32!, and shifting can be done before as desired, right/left.
    So great flexibility. Your new patch approach covers variable length and variable but not generic shifting.
    Sure - this can be compensated for.
    To make SPIWRX match SPIRDX and use 'spicnt' @SPICNT as COGREG to specify count as in the SPIRDX version 'ACC' just needs to be replaced with 'spicnt' in SPIWRX (and before). Then all is fine.
    Currently just storing the length in 11 COGREG! (aka ACC) is a workaround to @SPICNT COGREG!
    EDIT: Attention - this is a special thing: using the ACC works only in special circumstances!
    each X/YCALL or inline constant will mess up the ACC value.

    And for SPIWRX there is no vector defined.
    but this can be easily done with:
    ALIAS SPIWR SPIWRX
    NFA' SPIWRX C++
    

    Finally I am happy if you can make CREATE DOES> work with some suitable examples too :) Perhaps the one technical question from you that I discern might need to be answered is "--- how do we get the address of the last definition to put the 3 bytes CALL16 (+ EXIT ??) there ?". If we use @NAMES to return with the pointer to the latest definition which in itself is an NFA we can easily work from there with NFA>CFA.
    sounds you think the proposed approach could work with the Tachyon model then.
    missed @NAMES ... so many words around ;-) thanks




  • Hi there,
    (Tachyon) FORTH is really a language of enormous efficiency. As I'm always interested in reusing learned lessons I would like to (learn) program more in Forth. In a windows environment I'm looking for a solution to do some database access to a postgres database. I searched shortly and it seems that there are not many matches for these topics (search was "forth windows postgres"). Forth is a niche language.

    Before I spend more time in researching do you have experience with a forth in a windows/linux(/android/ios) environment which suits well with the tachyon paradigms and which you recommend?
  • I want to optimize something and to learn these [COMPILE] GRAB IMMEDIATE DOES> matters. Currently I have to do the following for all of my defined states:
    ' sUndef == 'sMyState
    State sMyState ." in my state" ;
    

    I would like to make this look like this:
    State sMyState ." in my state" ;
    
    So the `State´ word should CREATE the 'sMyState CONSTANT at compile time. Can someone help on how to do this?
    BTW: I already read an older post about ALIAS but didn't understand it and my head is smoking :-)
  • Peter JakackiPeter Jakacki Posts: 10,193
    edited 2016-07-16 13:33
    @proplem

    ALIAS simply creates a new name in the dictionary but copies the attributes and the two code compilation bytes into this new name so that the new name behaves exactly like the old one: ALIAS <old> <new>
    Notice the identical attributes and compilation codes 82 BF AB. btw, there is no overhead in using an alias other than the extra name space.
    ALIAS DUMP D  ok
    NFA' DUMP 10 D 
    0000_60A6:   04 44 55 4D  50 82 BF AB   05 44 55 4D  50 4C 82 C0   .DUMP....DUMPL.. ok
    NFA' D 10 D 
    0000_4D75:   01 44 82 BF  AB 02 51 56   A2 BD B9 09  3F 41 55 54   .D....QV....?AUT ok
    

    IMMEDIATE words
    Most immediate words are used to modify the way Forth compiles so that an IF is immediate and compiles an equivalent JZ type of instruction with a dummy branch while leaving the address to the dummy branch on the stack along with a check flag, in this case $1F :) Likewise THEN is an immediate word which simply checks the top of the stack for the $1F flag and if true uses the address of the IF to calculate and update the IF branch offset.

    Look at this incomplete compilation so that we can see the $1F flag (merged with the address).
    HERE .WORD 4C24 ok
    : DEMO IF ;  ok
    HERE .WORD 4C27 ok
    .S  Data Stack (1)
    $001F.4C26 - 2051110 ok
    ' DEMO 10 DUMP 
    0000_4C24:   CC 00 0C 72  4C 24 73 0A   BF AB 0C 0C  0C 0C 00 00   ...rL$s......... ok
    

    Resetting and completing that exact same definition:
    : DEMO IF PRINT" QUITE TRUE" THEN ;  ok
    ' DEMO $10 DUMP 
    0000_4C24:   CC 0D C0 64  51 55 49 54   45 20 54 52  55 45 00 0C   ...dQUITE TRUE..
    

    Notice now that instead of CC 00 we have CC 0D which says JZ +0D which ends up jumping to the last byte in this line 0C which is the EXIT opcode. So immediate words are useful in extending the compiler itself. Look to the end of this post for a sneaky trick based on this knowledge.

    GRAB is an immediate word which if we need it compiled we then need to force the compilation with [COMPILE] which itself is an immediate word. Where it is useful is when we want to grab parameters that have already been compiled but are needed for these immediate words to wreak their havoc. Here is an example taken from my terse command mode:
    --- table building word
    : AS ( ch -- ) IMMEDIATE 	[COMPILE] ' [COMPILE] GRAB SWAP  BL - 2* tcodes + W! ;
    
    In action I may assign a code vector to a single terse command character in this manner:
    'D' AS DUMP
    
    When AS executed immediately it needed the value 'D' which unfortunately had already been compiled, but no problem, we run GRAB which executes anything that has been compiled in this definition while reseting the compilation address which all results in 'D' being made available on the stack. Now along with the tick address of DUMP also on the stack we simply store that address into the tcodes table using 'D' as an index ('D'-$20)*2.

    I will get back to you in another post on how to implement State to automatically create a constant.


    sneaky trick: How to get a definition to jump to a definition that hasn't been created yet?
    : DEMO IF PRINT" QUITE TRUE" ;  ok
    : DEMO2 THEN PRINT" BUT THE REST IS ANOTHER STORY" ;  ok
    
    running it:
    TRUE DEMO QUITE TRUE ok
    FALSE DEMO BUT THE REST IS ANOTHER STORY ok
    

  • Excellent, more info like this please, when you have time of course.
    Dang, I can't find the
    : like   ." button" ;
    
  • proplemproplem Posts: 233
    edited 2016-07-16 16:37
    @Peter: thanks for the explanation - I'm continuously wiggling forward.

    I want to output something like this:
    :HELLO ." Hello \"Tachyon\"" ;
    Hello "Tachyon" ok
    
    Is there a way?
  • proplem wrote: »
    @Peter: thanks for the explanation - I'm continuously wiggling forward.

    I want to output something like this:
    :HELLO ." Hello \"Tachyon\"" ;
    Hello "Tachyon" ok
    
    Is there a way?
    : hello  CR ." Hello " 34 EMIT ." Tachyon" 34 EMIT ;  ok
    hello 
    Hello "Tachyon" ok
    

  • Thanks D.P, that'll work although I thought of concatenating at compile time.
    D.P wrote: »
    proplem wrote: »
    :HELLO ." Hello \"Tachyon\"" ;
    Hello "Tachyon" ok
    
    Is there a way?
    : hello  CR ." Hello " 34 EMIT ." Tachyon" 34 EMIT ;  ok
    hello 
    Hello "Tachyon" ok
    
    Coming from traditional languages doing it so it feels wrong but maybe I have to change my mind to be more forthish.
  • Traditional languages are typically compiled on PCs correct? The source code may be preprocessed and lex'd, syntax checked, maybe semantics, and go through multiple passes correct? There is none of that with Tachyon which compiles on the Prop as each character is received from the serial stream. In this case though we could indeed process these special sequences but where do you stop and given the single pass nature of the serial stream there must be some limitations. Rather than trying to be smart and end up complicating something we could be happy that Forth is not syntax sensitive and what we type is what it compiles.

    We can enter character literals enclosed by 'c' (or older method "c").
    : HELLO PRINT" Hello " '"' EMIT PRINT" Tachyon" '"' EMIT ;

    Interestingly I have thought about using escape sequences but I know that I would probably end up allowing for decimal and hex values etc and once again where do I stop. However I may just play with it a little sometime and if it maintains the KISS principle I may incorporate it.
  • Mike GreenMike Green Posts: 23,045
    edited 2016-07-16 22:32
    Probably the simplest way to make escape sequences work would be to create a "pseudo-input device" that can be substituted for whatever input vector is in use and saves the original input vector to use for its input and to use to restore the original source later. This device would have to have a single character buffer for backing up. The original input device vector and the string terminator character would have to be provided to the setup word which would be called from words like " or ." or PRINT". Once the non-escaped terminator is found, the original input vector could be restored.
  • Peter JakackiPeter Jakacki Posts: 10,193
    edited 2016-07-16 23:01
    I added a simple escape sequence to the print word as a test and all it does is allow you to use a backslash as a single character escape. I may add more later.
    ." hello \"tachyon\"" hello "tachyon" ok

    It was so simple I should have done this a long time ago :)
  • Mike Green wrote: »
    Probably the simplest way to make escape sequences work would be to create a "pseudo-input device" that can be substituted for whatever input vector is in use and saves the original input vector to use for its input and to use to restore the original source later. This device would have to have a single character buffer for backing up. The original input device vector and the string terminator character would have to be provided to the setup word which would be called from words like " or ." or PRINT". Once the non-escaped terminator is found, the original input vector could be restored.

    Would you like to give that a go Mike and see what you come up with? It only needs to be tested on the ." word which is _PRSTR_ on line 1905 in the PASM source.

  • MJBMJB Posts: 1,235
    Mike Green wrote: »
    Probably the simplest way to make escape sequences work would be to create a "pseudo-input device" that can be substituted for whatever input vector is in use and saves the original input vector to use for its input and to use to restore the original source later. This device would have to have a single character buffer for backing up. The original input device vector and the string terminator character would have to be provided to the setup word which would be called from words like " or ." or PRINT". Once the non-escaped terminator is found, the original input vector could be restored.
    actually - if you can type those strange characters e.g. via ALTxyz on windows Tachyon just takes them and compiles them. Even a $00 will be compiled, but will function as end of string when processing / e.g. printing it.
    The only really SPECIAL character is " itself, which defines end of string. To handle this an escape mechanism is needed.
    And of course you might not see the strange characters on the listing ;-)

    e.g. in the following definition of
    pub test3 ." Hello <cr>World<cr>this is line 3"
    since the <cr> is performed by the terminal, the previousterminal output text is overwritten.
    But it is compiled correctly. Printing the text also results in the overwriting then.
    So in test4 I also enter <lf> with windows ALT010 on numeric keyboard.
    As you can see on the second dump it is correctly compiled and also correctly executed/printed.
      ok
    this is line 3" ;  ok
      ok
    this is line 3 ok
      ok
    ' test3  20 DUMP
    0000_5A53:   C4 5A 48 65  6C 6C 6F 20   0D 57 6F 72  6C 64 0D 74   .ZHello .World.t
    0000_5A63:   68 69 73 20  69 73 20 6C   69 6E 65 20  33 00 0F 76   his is line 3..v ok
    pub test4 ." Hello
    World
    thi is line 3" ;  ok
    test4 Hello
    World
    thi is line 3 ok
    ' test4 20 DUMP
    0000_5A72:   C4 5A 48 65  6C 6C 6F 0D   0A 57 6F 72  6C 64 0D 0A   .ZHello..World..
    0000_5A82:   74 68 69 20  69 73 20 6C   69 6E 65 20  33 00 0F 76   thi is line 3..v ok
    
    
    Interresting, what you can do ;-)

    On the other hand it is all a question of priority.
    If you look at the huge C libraries for string handling and printing .. great if you have gigBytes of memory.
    But if you have 32k to run the OS+SD+File+NW+Application+ ...
    then rarely used functionality should not bloat the basic system.
    And if you need a special escapedString, than just define a new '' in addition to " or something
    you like and make it handle escaped strings.

    With the modular loading of EXTEND which I started to implement, but which is not fully
    done yet (the handling of dependencies between modules needs some work) such extra MODULES can be loaded if the application really needs it - to keep the basic system LEAN & FAST.

    btw: this little snipped is the Tachyon string compiler ... 29 bytes !!!!
    ' PRINT" HELLO WORLD"	Compile a literal print string - no length restriction - any codes can be included except the delimiter "
    _PSTR_	byte	_BYTE,XCALL,XCALL,xBCOMP,_BYTE,xPRTSTR,XCALL,xBCOMP
    COMPSTR
    pslp	byte	XCALL,xWKEY,DUP,XCALL,xQEMIT		' echo string
    	byte	DUP,_BYTE,$22,EQ,_IF,05,DROP,_0,XCALL,xBCOMP,EXIT
    	byte	XCALL,xBCOMP,_AGAIN,@ps01-@pslp
    ps01	'''
    
    
    

  • Peter JakackiPeter Jakacki Posts: 10,193
    edited 2016-07-17 03:04
    I've upgraded the kernel so that we can have \n \r \t \$xx or any other character after the \ as passthrough.
    ." hello \"tachyon\"\r\nnew line\$05"
    
    hello "tachyon"
    new line ok
    Minicom2.7
    

    btw, the same applies to string literals such as " hello \"tachyon\"" PRINT$
Sign In or Register to comment.