Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Conditionals design and implementation #82

Open
iru- opened this issue May 28, 2019 · 8 comments
Open

Conditionals design and implementation #82

iru- opened this issue May 28, 2019 · 8 comments

Comments

@iru-
Copy link

iru- commented May 28, 2019

There are at least two differing semantics for IF and the words that build on it:

  1. classical: IF consumes the top of the stack and branches on false (usually 0)
    : test ( n -- ) if ." true" else ." false" then ;

  2. machineforth: IF branches on a flag external to the stack (usually the processor flags), preserving the stack contents
    : test ( n -- ) 0 <> drop if ." true" else ." false" then drop ;

What are your opinion/experience on the pros and cons of the two approaches?

@vstrakh
Copy link

vstrakh commented May 28, 2019

Using both approaches in a system on a J1 forth processor.

There's a classical 'if', branching on zero stack top and popping off the value, and custom 'c-if' I've added for my needs, branching on the carry flag not set, without popping the stack.
Helps greatly when processing strings of bytes, packed into 16-bit words. The J1 has no byte addressing, and storing bytes as words in not acceptable in tight embedded environment. So this need had to be addressed.

@iru-
Copy link
Author

iru- commented May 28, 2019

@vstrakh sorry, I didn't fully understand. How does c-if help in your case? Why is it better for you than the classifcal one?

@vstrakh
Copy link

vstrakh commented May 28, 2019

J1 is running within FPGA, using very limited resources. It has tiny stacks, originally 15 cells for data, and 17 cells for return stack. Avoiding extra constants/masks, as well as extra instructions - is crucial.

With J1 you have a memory organized as 16-bit words. To print some strings you must read the bytes, and send it to UART/whatever. The 'type' word would accept the word address and the length of string in bytes.

: type ( w-addr n -- )
    >r 2* begin
        waddr @ c-if bswap then emit 1+
    next
    drop
;

'waddr' takes the offset in bytes, shifts it right to produce the required word address, and affects carry flag, which then is used to swap the halves of the word when accessing odd bytes. The original byte offset is staying at the stack top, the fetch consumes the produced word address, but doesn't affect the carry flag.

Making the same with classical if would require more stack manipulations, more instructions to the CPU that is not extremely fast.

@cwpjr
Copy link
Member

cwpjr commented May 28, 2019 via email

@cwpjr
Copy link
Member

cwpjr commented May 28, 2019 via email

@cwpjr
Copy link
Member

cwpjr commented May 28, 2019 via email

@iru-
Copy link
Author

iru- commented May 29, 2019

@cwpjr could you elaborate on the (dis)advantages you encountered in each approach for the domain of application?

If I specialize/customize a or my forth this way, it is usually for a demonstrable advantage in a specific domain.

On Tue, May 28, 2019 at 4:49 AM iru- @.***> wrote: There are at least two differing semantics for IF and the words that build on it: 1. Classical: IF consumes the top of the stack and branches on false (usually 0). E.g. : test ( n -- ) if ." true" else ." false" then ; 2. machineforth: IF branches on a flag external to the stack (usually the processor flags), preserving the stack contents. E.g. : test ( n -- ) 0 <> drop if ." true" else ." false" then ; What are your opinion/experience on the pros and cons of the two approaches? — You are receiving this because you are subscribed to this thread. Reply to this email directly, view it on GitHub <#82?email_source=notifications&email_token=ABILVRLSNQIRUI3PEUUNA6DPXT5ZBA5CNFSM4HQBUZ62YY3PNVWWK3TUL52HS4DFUVEXG43VMWVGG33NNVSW45C7NFSM4GWF2CXQ>, or mute the thread https://github.com/notifications/unsubscribe-auth/ABILVROGAJFDCWNTJV2PB7DPXT5ZBANCNFSM4HQBUZ6Q .

@mitra42
Copy link

mitra42 commented Dec 2, 2020

Ouch - I can see the reason for this inside tight loops with bit manupulation, but please don't call it "if", its a low-level machine word, please give it a new name.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

4 participants