Discussion:
Number parsing with checks
(too old to reply)
dxf
2024-10-12 01:45:10 UTC
Permalink
The basics:

: .BAD ( -- ) cr ." Invalid item" .abort ;

: ZE? ( x -- ) if .bad then ; \ abort if non-zero
: NZ? ( x -- ) 0= ze? ; \ abort if zero
: ?ZE ( x -- x ) dup ze? ; \ check x is zero
: ?NZ ( x -- x ) dup nz? ; \ check x is non-zero

Examples:

: ?D>S ( d|ud -- n|u ) -1 0 between nz? ;
: ?RNG ( n|u lo hi -- n|u ) rot dup 2swap between nz? ;

\ Single number parsers with checking
: /DNUM ( a u -- a' 0 d|ud )
/sign >r ?nz (number) ?ze 2swap r> if dnegate then ;
: /NUM ( a u -- a' 0 n|u ) /dnum ?d>s ;
: /HEX ( a u -- a' 0 n|u ) base @ >r hex /num r> base ! ;

\ String to unsigned int with checking
: >INT ( a u -- u2 ) ?nz (number) ?ze 2drop ze? ;

where

: (NUMBER) ( a u -- ud a' u' ) 0 0 2swap >number ;

: /SIGN ( a u -- a' u' f )
dup if over c@ dup [char] + = swap [char] - =
dup >r or negate /string r> exit then 0 ;
Ruvim
2024-10-12 13:54:45 UTC
Permalink
Post by dxf
: .BAD ( -- ) cr ." Invalid item" .abort ;
: ZE? ( x -- ) if .bad then ; \ abort if non-zero
: NZ? ( x -- ) 0= ze? ; \ abort if zero
Typically, if word name ends with a question mark, the first (top)
output parameter of the word is a *flag*. And it's true for all standard
words. (though, opposite is not true)

These are better names and narrower stack diagrams:

DROP-NZ ( x\0 -- | 0 -- never )
DROP-ZE ( 0 -- | x\0 -- never )
Post by dxf
: ?ZE ( x -- x ) dup ze? ; \ check x is zero
: ?NZ ( x -- x ) dup nz? ; \ check x is non-zero
Better stack diagrams:

?ZE ( 0 -- 0 | x\0 -- never )
?NZ ( x.some\0 -- x.some | 0 -- never )

I suggest to use the data type symbol "never" for the empty data type.

See my explanation about the empty data type at
<https://github.com/ForthHub/discussion/discussions/171#discussioncomment-10882259>

(this can be discussed there, or in a new thread here)



--
Ruvim
Ruvim
2024-10-12 14:46:52 UTC
Permalink
Post by Ruvim
: .BAD ( -- )  cr ." Invalid item"  .abort ;
: ZE? ( x -- )  if .bad then ;     \ abort if non-zero
: NZ? ( x -- )  0= ze? ;           \ abort if zero
Typically, if word name ends with a question mark, the first (top)
output parameter of the word is a *flag*. And it's true for all standard
words. (though, opposite is not true)
  DROP-NZ ( x\0 --  |  0 -- never )
  DROP-ZE ( 0 --  |  x\0 -- never )
I do not like these names too.

These seem better:

?NZ-DROP
?ZE-DROP
Post by Ruvim
: ?ZE ( x -- x )  dup ze? ;        \ check x is zero
: ?NZ ( x -- x )  dup nz? ;        \ check x is non-zero
  ?ZE ( 0 -- 0  |  x\0 -- never )
  ?NZ ( x.some\0 -- x.some  |  0 -- never )
I suggest to use the data type symbol "never" for the empty data type.
See my explanation about the empty data type at <https://github.com/
ForthHub/discussion/discussions/171#discussioncomment-10882259>
(this can be discussed there, or in a new thread here)
--
Ruvim
mhx
2024-10-12 16:40:07 UTC
Permalink
[..]
Post by Ruvim
Post by Ruvim
: ZE? ( x -- )  if .bad then ;     \ abort if non-zero
: NZ? ( x -- )  0= ze? ;           \ abort if zero
Typically, if word name ends with a question mark, the first (top)
output parameter of the word is a *flag*. And it's true for all
standard words. (though, opposite is not true)
  DROP-NZ ( x\0 --  |  0 -- never )
  DROP-ZE ( 0 --  |  x\0 -- never )
I do not like these names too.
?NZ-DROP
?ZE-DROP
[..]

My convention has always been that if a word starts with
a '?', it tests and [possibly] aborts. This makes
'-DROP' unnecessary.

-marcel
Ruvim
2024-10-12 17:52:28 UTC
Permalink
Post by mhx
[..]
Post by Ruvim
Post by Ruvim
: ZE? ( x -- )  if .bad then ;     \ abort if non-zero
: NZ? ( x -- )  0= ze? ;           \ abort if zero
Typically, if word name ends with a question mark, the first (top)
output parameter of the word is a *flag*. And it's true for all
standard words. (though, opposite is not true)
   DROP-NZ ( x\0 --  |  0 -- never )
   DROP-ZE ( 0 --  |  x\0 -- never )
I do not like these names too.
     ?NZ-DROP
     ?ZE-DROP
[..]
My convention has always been that if a word starts with
a '?', it tests and [possibly] aborts. This makes
'-DROP' unnecessary.
Agreed.
Two words can be used if you need to drop, as:

?NZ DROP
?ZE DROP


--
Ruvim
Stephen Pelc
2024-10-14 14:21:20 UTC
Permalink
Post by mhx
My convention has always been that if a word starts with
a '?', it tests and [possibly] aborts. This makes
'-DROP' unnecessary.
The same convention is used by MPE, but I'm sure that there are exceptions
in our code.

Stephen
--
Stephen Pelc, ***@vfxforth.com
MicroProcessor Engineering, Ltd. - More Real, Less Time
133 Hill Lane, Southampton SO15 5AF, England
tel: +44 (0)78 0390 3612, +34 649 662 974
http://www.mpeforth.com
MPE website
http://www.vfxforth.com/downloads/VfxCommunity/
downloads
dxf
2024-10-13 01:13:32 UTC
Permalink
: .BAD ( -- )  cr ." Invalid item"  .abort ;
: ZE? ( x -- )  if .bad then ;     \ abort if non-zero
: NZ? ( x -- )  0= ze? ;           \ abort if zero
Typically, if word name ends with a question mark, the first (top) output parameter of the word is a *flag*. And it's true for all standard words. (though, opposite is not true)
It's rather similar.

ZE? NZ? destructively tests TOS
?ZE ?NZ non-destructively tests TOS

Only difference is test and action are rolled into the one function.
Ruvim
2024-10-13 02:20:55 UTC
Permalink
Post by dxf
: .BAD ( -- )  cr ." Invalid item"  .abort ;
: ZE? ( x -- )  if .bad then ;     \ abort if non-zero
: NZ? ( x -- )  0= ze? ;           \ abort if zero
Typically, if word name ends with a question mark, the first (top) output parameter of the word is a *flag*. And it's true for all standard words. (though, opposite is not true)
It's rather similar.
ZE? NZ? destructively tests TOS
But these words do not return a flag in the first output parameter. So,
their names violate the common convention.
Post by dxf
?ZE ?NZ non-destructively tests TOS
These names follow the common convention. A question mark at the
beginning of a name means that the word does something or does nothing
depending on certain conditions.

Well known nonstandard words: `?stack` `?csp` `?comp` `?exec`
Standard words: `?do` `?dup`
Post by dxf
Only difference is test and action are rolled into the one function.
--
Ruvim
dxf
2024-10-13 02:59:55 UTC
Permalink
Post by dxf
: .BAD ( -- )  cr ." Invalid item"  .abort ;
: ZE? ( x -- )  if .bad then ;     \ abort if non-zero
: NZ? ( x -- )  0= ze? ;           \ abort if zero
Typically, if word name ends with a question mark, the first (top) output parameter of the word is a *flag*. And it's true for all standard words. (though, opposite is not true)
It's rather similar.
ZE? NZ?  destructively tests TOS
But these words do not return a flag in the first output parameter. So, their names violate the common convention.
Conventions are a guide. Thankfully they're not yet a law.
Ruvim
2024-10-13 04:10:32 UTC
Permalink
Post by dxf
Post by dxf
: .BAD ( -- )  cr ." Invalid item"  .abort ;
: ZE? ( x -- )  if .bad then ;     \ abort if non-zero
: NZ? ( x -- )  0= ze? ;           \ abort if zero
Typically, if word name ends with a question mark, the first (top) output parameter of the word is a *flag*. And it's true for all standard words. (though, opposite is not true)
It's rather similar.
ZE? NZ?  destructively tests TOS
But these words do not return a flag in the first output parameter. So, their names violate the common convention.
Conventions are a guide. Thankfully they're not yet a law.
Sure. But the mentioned conventions seem good.

If you are proposing generally useful words, and their names violate a
common convention, you could probably explain why it is not worth
following that convention in this case (or in general).

Or perhaps you could add a note that these names violate a certain
convention simply because better names have not been found yet.




In general, there are two groups of words that do something or do
nothing depending on some conditions:
- group1: the words that only test some parameters (on the stack
and/or in memory);
- group2: the words that consume some parameters from the stack.

The first group is larger than the second.


In your case, you want to have a word from the first group and the
corresponding word from the second group. So, a new naming rule is
needed to distinguish these words.

The actual difference between these groups for your words is one "DUP"
or "DROP". E.g.:

: ?NZ(group1) DUP ?NZ(group2) ;

: ?NZ(group2) ?NZ(group1) DROP ;

If I had to choose only one word from these two, I would prefer the word
from the first group.

So, if the corresponding word from the second group is rarely needed, it
might not be worth introducing. Simply use "?NZ DROP" instead of an
individual word. Profit: no need to find a new naming rule.

Possible words/names for internal use:

(?NZ) ( x\0 -- | 0 -- never )
(?ZE) ( x\0 -- never | 0 -- )



--
Ruvim
dxf
2024-10-13 05:27:58 UTC
Permalink
Post by Ruvim
Post by dxf
: .BAD ( -- )  cr ." Invalid item"  .abort ;
: ZE? ( x -- )  if .bad then ;     \ abort if non-zero
: NZ? ( x -- )  0= ze? ;           \ abort if zero
Typically, if word name ends with a question mark, the first (top) output parameter of the word is a *flag*. And it's true for all standard words. (though, opposite is not true)
It's rather similar.
ZE? NZ?  destructively tests TOS
But these words do not return a flag in the first output parameter. So, their names violate the common convention.
Conventions are a guide.  Thankfully they're not yet a law.
Sure. But the mentioned conventions seem good.
If you are proposing generally useful words, and their names violate a common convention, you could probably explain why it is not worth following that convention in this case (or in general).
Convention means doing something in a consistent way unless there's a reason to do
otherwise. The standard had no qualms defining the word ? which leaves no flag.
I don't feel any less entitled coming up with names that are short and to the point.
Ruvim
2024-10-13 07:51:17 UTC
Permalink
Post by dxf
Post by Ruvim
Post by dxf
: .BAD ( -- )  cr ." Invalid item"  .abort ;
: ZE? ( x -- )  if .bad then ;     \ abort if non-zero
: NZ? ( x -- )  0= ze? ;           \ abort if zero
Typically, if word name ends with a question mark, the first (top) output parameter of the word is a *flag*. And it's true for all standard words. (though, opposite is not true)
It's rather similar.
ZE? NZ?  destructively tests TOS
But these words do not return a flag in the first output parameter. So, their names violate the common convention.
Conventions are a guide.  Thankfully they're not yet a law.
Sure. But the mentioned conventions seem good.
If you are proposing generally useful words, and their names violate a common convention, you could probably explain why it is not worth following that convention in this case (or in general).
Convention means doing something in a consistent way unless there's a reason to do
otherwise.
And what is your reason?
Post by dxf
The standard had no qualms defining the word ? which leaves no flag.
The word `?` in the standard can be explained by a historical accident
that occurred in ancient times. Moreover, this word is almost not used
in programs.

Your case cannot be explained by a historical accident ;)
Post by dxf
I don't feel any less entitled coming up with names that are short and to the point.
Feelings are not the best argument regarding names and conventions ;)


--
Ruvim
mhx
2024-10-13 09:10:04 UTC
Permalink
[..]
Post by Ruvim
Feelings are not the best argument regarding names and conventions ;)
I use conventions because they are useful, there is no need
to defend them. The original dxf code caused me to
read through all of the trivial words in the beginning
because it violated notation I take for granted.

-marcel
dxf
2024-10-14 02:26:15 UTC
Permalink
Post by Ruvim
...
Post by dxf
I don't feel any less entitled coming up with names that are short and to the point.
Feelings are not the best argument regarding names and conventions ;)
Conventions are not hard and fast rules. Making them so is what introduces
feeling and emotion.
Ruvim
2024-10-14 04:24:22 UTC
Permalink
Post by dxf
Post by Ruvim
Post by Ruvim
Post by dxf
Post by Ruvim
: .BAD ( -- )  cr ." Invalid item"  .abort ;
: ZE? ( x -- )  if .bad then ;     \ abort if non-zero
: NZ? ( x -- )  0= ze? ;           \ abort if zero
Typically, if word name ends with a question mark, the first (top)
output parameter of the word is a *flag*. And it's true for all
standard words. (though, opposite is not true)
It's rather similar.
ZE? NZ?  destructively tests TOS
But these words do not return a flag in the first output parameter.
So, their names violate the common convention.
Conventions are a guide.  Thankfully they're not yet a law.
Sure. But the mentioned conventions seem good.
If you are proposing generally useful words, and their names violate
a common convention, you could probably explain why it is not worth
following that convention in this case (or in general).
Convention means doing something in a consistent way unless there's
a reason to do otherwise.
And what is your *reason* to do otherwise in this case? ))


--
Ruvim
dxf
2024-10-14 05:08:41 UTC
Permalink
Post by Ruvim
Post by dxf
Post by Ruvim
Post by Ruvim
Post by dxf
Post by Ruvim
: .BAD ( -- )  cr ." Invalid item"  .abort ;
: ZE? ( x -- )  if .bad then ;     \ abort if non-zero
: NZ? ( x -- )  0= ze? ;           \ abort if zero
Typically, if word name ends with a question mark, the first (top)
output parameter of the word is a *flag*. And it's true for all
standard words. (though, opposite is not true)
It's rather similar.
ZE? NZ?  destructively tests TOS
But these words do not return a flag in the first output parameter.
So, their names violate the common convention.
Conventions are a guide.  Thankfully they're not yet a law.
Sure. But the mentioned conventions seem good.
If you are proposing generally useful words, and their names violate
a common convention, you could probably explain why it is not worth
following that convention in this case (or in general).
Convention means doing something in a consistent way unless there's
a reason to do otherwise.
And what is your *reason* to do otherwise in this case? ))
"names that are short and to the point"

In SwiftForth one finds -? HUH? Neither return a flag, OTOH both perform
a conditional action.
dxf
2024-10-14 10:52:31 UTC
Permalink
...
Typically, if word name ends with a question mark, the first (top) output
parameter of the word is a *flag*. And it's true for all standard words.
(though, opposite is not true)
...
These names follow the common convention. A question mark at the beginning of
a name means that the word does something or does nothing depending on certain
conditions.
Well known nonstandard words: `?stack` `?csp` `?comp` `?exec`
Standard words: `?do` `?dup`
Here is Forth Inc's convention as provided in Forth Programmer's Handbook.
It appears more flexible than what you describe above.

?name Check condition, return true if yes ?TERMINAL
Conditional operator ?DUP
Check condition, abort if bad ?STACK
Fetch contents of name and display ?N
[..]

name? Same as ?name B?

The lack of differentiation between ?NAME and NAME? is likely due to early
forth storing names as 3 characters plus count.
Loading...