John Hayes' ANS Forth test suite contains tests that look like this:
: WEIRD: CREATE DOES> 1 + DOES> 2 + ;
WEIRD: W1
W1
I'm rather at a loss as to exactly what this is supposed to do. The ANS Forth Specification on DOES> is largely impenetrable.
From reading the test suite, it looks like it's expecting the first call to DOES> to modify W1, but then that calling W1 activates the second DOES>. I assume the second one operates on the word defined by the most recent call to CREATE, but that's already been DOES>ified, so I'm not sure what that's supposed to do.
gforth passes the test suite, so the tests do seem to be valid; but my pet Forth interpreter doesn't, and I need to figure out how to make it work...
The second call to DOES> also modifies W1.
WEIRD: creates W1 with a runtime action of 1 + DOES> 2 +. The first call to W1 sets the runtime to 2 +.
This is more apparent if you change the code to print something, e.g.
: weird: create does> drop ." ONE" does> drop ." TWO" ; ok
weird: w1 ok
w1 ONE ok
w1 TWO ok
w1 TWO ok
w1 TWO ok
The explanation for this is that DOES> always operates on the latest defined word.
Related
When reading about the tick (') operator I wondered if it can be useful inside a word definition. I know that there is ['] to be used inside a definition, but I thought about using it to read the word name following invocation.
An example:
4 variable cnt
: cycle: ( arg fn -- )
'
4 cnt !
begin
cr
dup execute
-1 cnt +!
cnt # 0 = until
drop
;
I can use cycle: to repeat some word invocation, as follows.
: hello ." hello" ;
cycle: hello
Which prints hello four times, as expected.
But the following code won't define a word that prints hello four times:
: 4hello cycle: hello ;
The tick operator still expects a word from the input stream following invocation of 4hello.
Is it possible to inject it somehow when using cycle: in a word definition, so it won't "leak" outside?
Yes, it's possible. You would have to make cycle: immediate. And then also change it to postpone its actions, rather than perform them at runtime.
Postponing means to delay the actions of words. Immediate words are compiled into the current definition, and normal words are arranged to be compiled when the current definition is executing.
In this case it might look something like this.
: (cycle) 4 0 do dup execute loop drop ;
: cycle: ' postpone literal postpone (cycle) ; immediate
Note that this version no longer works outside definitions.
I would like to make matrix calculator, but I struggle a little bit, how to make an input of the program. I have commands that user can use in calculator. Some takes 1 argument, 2 arguments or 3 arguments. I was inspired by program on this website http://www.ivank.net/blogspot/matrix_pascal/matrices.pas
But I don't really understand, how the input is made. Program from the website use parse, split procedures, but I don't know, how does it work. Does it exists some website, where it is good explained (Parse in Pascal)? I would like to really understand it.
This is, how it should looks like:
command: sum X Y
command: multiply X
command: transpose X
In the sample which inspired you, all the calculation is realized by the 'procedure parse(command:String);'.
The first step consists to extract the command and all parameters by:
com := Split(command, ' ');
In your case, you will obtain for 'command: sum X Y':
Length(com) = 3
com[0] = 'sum'; com[1] = 'X'; com[2] = 'Y';
But, be carefull, the 'X' and 'Y' parameters shall not have characters between numbers.
While trying to completely understand the solution to Lua - generate sequence of numbers, the section 4.3.4 of Programming in Lua is unclear:
for i=1,f(x) do print(i) end
for i=10,1,-1 do print(i) end
The for loop has some subtleties that you should learn in order to
make good use of it. First, all three expressions are evaluated once,
before the loop starts. For instance, in the first example, f(x) is
called only once. Second, the control variable is a local variable
automatically declared by the for statement and is visible only inside
the loop. [...]
The first line of code doesn't work of course.
What is f(x) and where is it defined?
Unfortunately the documentation isn't available as a single page, making it a huge effort to search for the first occurrence. Searching for "lua f(x)" doesn't bear fruit either.
Explanation: now that I have received answers, I realize the problem was a misunderstanding. I incorrectly interpreted "f(x) is called only once" as "the line containing f(x) - for i=1,f(x) do print(i) end - will only return one value" and didn't pay enough attention to "all three expressions are evaluated once, before the loop starts".
This sentence clarifies it: expressions are evaluated once, before the loop starts.
Thus, f(x) is called only once is merely stating that the expressions will not be affected by potential changes in the loop.
For example, the following code (expressions are i=1 and x in the second line):
x=5
for i=1,x do
x = x - 1
print(i, x)
end
print(x)
will produce the following output:
1 4
2 3
3 2
4 1
5 0
0
and will not produce the following output:
1 4
2 3
3 2
2
f(x) is just a function which takes the argument x and returns a value that is used as the upper bound for the loop.
So for example, if the function f(x) calculates x² and you call it as f(3), it would return the value of 9. The resulting for loop would look like this:
for i=1, f(3) do print(i) end
which is exactly the same as
for i=1, 9 do print(i) end
I am using the interpreter directives (non ANS standard) control structures of Gforth as described in the manual section 5.13.4 Interpreter Directives. I basically want to use the loop words to create a dynamically sized word containing literals. I came up with this definition for example:
: foo
[ 10 ] [FOR]
1
[NEXT]
;
Yet this produces an Address alignment exception after the [FOR] (yes, I know you should not use a for loop in Forth at all. This is just for an easy example).
In the end it turned out that you have to write loops as one-liners in order to ensure their correct execution. So doing
: foo [ 10 [FOR] ] 1 [ [NEXT] ] ;
instead works as intended. Running see foo yields:
: foo
1 1 1 1 1 1 1 1 1 1 1 ; ok
which is exactly what I want.
Is there a way to get new lines in the word definition? The words I would like to write are way more complex, and for a presentation I would need them better formatted.
It would really be best to use an immediate word instead. For example,
: ones ( n -- ) 0 ?do 1 postpone literal loop ; immediate
: foo ( -- ten ones ) [ 10 ] ones ;
With SEE FOO resulting in the same as your example. With POSTPONE, especially with Gforth's ]] .. [[ syntax, the repeated code can be as elaborate as you like.
A multiline [FOR] would need to do four things:
Use REFILL to read in subsequent lines.
Save the read-in lines, because you'll need to evaluate them one by one to preserve line-expecting parsing behavior (such as from comments: \ ).
Stop reading in lines, and loop, when you match the terminating [NEXT].
Take care to leave >IN right after the [NEXT] so that interpretation can continue normally.
You might still run into issues with some code, like code checking SOURCE-ID.
For an example of using REFILL to parse across multiple lines, here's code from a recent posting from CLF, by Gerry:
: line, ( u1 caddr2 u2 -- u3 )
tuck here swap chars dup allot move +
;
: <text> ( "text" -- caddr u )
here 0
begin
refill
while
bl word count s" </text>" compare
while
0 >in ! source line, bl c, 1+
repeat then
;
This collects everything between <text> and a </text> that's on its own line, as with a HERE document, while also adding spaces. To save the individual lines for [FOR] in an easy way, I'd recommend leaving 0 as a sentinel on the data stack and then drop SAVE-MEM 'd lines on top of it.
x(n) is given
need x(-n+3)
so to solve it:
first advance the x(n) signal by 3 units(time)
then fold it, or make a reflection of it
are the above steps correct or is the following correct
first fold the x(n) signal
then advance the signal by 3 units
?
Yes, this is a common source of confusion when learning about signals. Here's what I usually do.
Let y[n] = x[-n+3]. Because of -n, y[n] is obviously a time-reversed version of x[n]. But the question about the shift remains.
Notice that y[3] = x[0]. Therefore, y[n] is achieved by first reflecting x[n] about n=0 and then delaying the reflected signal by 3.
For example, let x[n] be the unit step function u[n]. Draw x[n], then draw y[n].
Actually here is what I do:
Let
x(n) = {1,-1,2,4,-3,0,6,-3,-1,2,7,9,-7,5}
^
Suppose origin or n=0 is 6. Note that the ^ symbol indicates the origin. First, we find the folder sequence of x(-n) from x(n). So first we fold or we can say reverse the form of x(n), we get,
The folder sequence of x(-n) from x(n) is
x(-n) = {5,-7,9,7,2,-1,-3,6,0,-3,4,2,-1,1}
^
then shift the sequence of x(-n) towards right hand side by 3 units, we will get
x(-n+3) = {5,-7,9,7,2-1,-3,6,0,-3,4,2,-1,1}
^
Now, the sample 4 is at the origin.
Above steps are correct.
The following steps can be corrected too if these are followed like:
first fold the x(n) signal
then delay the signal by 3 units this will yield x(-n+3).