[Top][All Lists]

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: Documentation

From: Jose E. Marchesi
Subject: Re: Documentation
Date: Tue, 15 Sep 2020 21:00:06 +0200
User-agent: Gnus/5.13 (Gnus v5.13) Emacs/28.0.50 (gnu/linux)

> On Tue, Sep 15, 2020 at 11:38:01AM +0200, Jose E. Marchesi wrote:
>> I think you are too optimistic regarding the current state of the
>> manual...  or maybe I'm being too pesimist!  I really wish someone would
>> help us with that.
> I'll try improve it (despite the fact that I'm not that knowledgeable about
> GNU poke and also I'm not good at writing).
> BTW do you know why the index page of HTML documentation is empty?
> It looks like a bug. This is what I get as the last lines of `index.html`:
> ```html
> <body lang="en">
> <span id="SEC_Contents"></span>
> ```

When I `make html` in doc/ I don't get an empty index.html.  How are you
generating the html documentation?

>>> /* First start with nomenclature:
>>>  *
>>>  *   - poke      The editor program (also called GNU poke)
>>>  *   - Poke      Domain-specific programming language that used by `poke`
>>>  *   - pickle    A Poke source file. The extension of filename is `.pk`
>>A pickle is not any Poke source file: it is a Poke source file that
>>implements some definited domain, like a file format (like ELF) or some
>>functional domain (like time.pk).  You may want to reflect that in the
> So a pickle is a set of related stuff (types, functions, units, ...).
> That reminds me of the definition of modules! Is this a correct 
> interpretation?
> (I know that in future we'll have modules in Poke)

Well, modules are abstractions often used to group related
functionality, but they don't absolutely have to.  We support a sort of
primitive modules with `load'.

The `pickle' point is more about what is contained in the .pk file (or
.pk files that include each other, a single pickle can be divided in
several .pk files, see pickles/dwarf-*.pk for an example.) more than
about the mechanism used to implement it.

>>> /* Array trimming: Extraction of a subset of the array */
>>> defvar arr3   = arr1[0:1];  /* arr3 == [1, 2] */
>>Probably it is worth mentioning that the provided indexes in a trim are
>>both inclusive.
> OK.
> And a comment about this feature: I really don't like this feature (using 
> closed
> ranges (intervals) instead of half-open ranges). IMHO dealing with half-open
> ranges are much more simpler.
> I guess you've made this decision because of Algol68 :D

Right :)

I have in fact considered changing it so the right extreme of the
interval is open instead of closed.  That will probably help in
calculations, considering our arrays are zero-based (unlike the Algol68
arrays, which can be configured to have different bases.)

If we are gonna change that, now is the right time, before the first
release.  What people think about it?

>>Today I moved ptime and the POSIX_Time{32,64} definitions to a pickle
>>std.pk should only be used to define "standard" language constructions,
>>such as the standard basic types.  The "standard library" of Poke is in
>>reality std.pk + pickles/*.pk.
>>... I guess :)
> Before this I treated `pickles/*.pk` files as a bunch of examples :D
> Now I know that those are part of "standard library"!
> Thanks for the clarification.
> So should I change this title "std.pk - Standard definition for poke"?
> Or just removing the DateTime stuff is enough?

I think removing the DateTime stuff is just enough.   std.pk is in the
spirit of the "standard prelude" of Algol68, i.e. a file that implement
standard _language features_, such as standard basic types.

> And what do you think about adding one-line description for each of pickles in
> `pickles` directory?

You mean in your tutorial?  Yes, why not.  I am trying to get these
pickles documented in the manual.

>>>  *   - Auto-growing memory buffer
>>>  *   - Address-space of a process
>>Not yet.  Someone should write a ptrace-based IOD :)
> Should I remove this line?
> Or just add a comment that this is not available yet?

I would just remove it.  We can always update it when we incorporate a
process IOS backend.

>>> /* To access to IO space we can map a value to some area using this syntax:
>>>  *
>>>  *     TYPE @ OFFST
>>>  * or,
>>>  *     TYPE @ IOS : OFFSET
>>>  */
>>> defvar ui32num = uint<32> @ 0#B;
>>> defvar i32num = int<32> @ 4#B;
>>> /* If we modify the `ui32num` the first 4 bytes in IO space will change. */
>>> ui32num = 0xaabbccdd;
>>Not really.  `ui32num' is a simple value (integer, offset, string) and
>>therefore it is not mapped:
>>ui32num'mapped -> 0
>>In order to perform the operation above you would need to do something
>>uint<32> @ 0#B = 0xaabbccdd;
> Interesting!
> Can I say that there are two kinds of types in Poke?
>   - Types with value semantics (like integers, offsets, strings and array of 
> them)
>   - Types with reference semantics (like structs, unions and array of them)
> So when we define a variable of a type with value semantics the value will
> be copied, and when we have a variable of a type with reference semantics, the
> "address" will be copied and we can modify the source.
> Or should I call them "simple values" and "non-simple values"?

I am using the later in the manual:

This three-steps process is necessary because in the @code{n = n + 1}
above we are modifying the value of the variable @code{n}, not the
integer actually stored at offset @var{offset} in the current IO
space.  Therefore we have to explicitly poke it back if we want the IO
space to be updated as well.

Array values (and, as we shall see, other ``composited'' values) are
different: when they are the result of the application of the map
operator, the resulting values are @dfn{mapped} themselves.

When a Poke value is mapped, updating their elements have a side
effect: the area corresponding to the updated element, in whatever IO
space it is mapped on, is updated as well!

Why is this?  The map operator, regardless of the kind of value it is
mapping, always returns a @emph{copy} of the value found stored in the
IO space.  We already saw how this worked with integers.  However, in
Poke values are copied around using a mechanism called ``shared
value''.  This means that when a composite value like an array is
copied, its elements are shared by both the original value and the new

It follows that if we wanted to change the color of some SBM pixel
stored at offset @var{offset}, we would do this:

(poke) defvar pixel = byte[3] @@ @var{offset}
(poke) a[1] = 10
@end example

There is no need to poke the array back explicitly: the side effect of
assigning 10 to a[1] is that the byte at offset @code{@var{offset}+1}
is poked.

Generally speaking, mapped values can be handled in exactly the same
way than non-mapped values.  This is actually a very central concept
in poke.  However, it is possible to check whether a given value is
mapped or not using the @code{'mapped} attribute.

As we said, @dfn{simple values} such as integers and strings are never
mapped.  Both @code{ppl} and @code{lines} are integers, therefore:

(poke) ppl'mapped
(poke) lines'mapped
@end example

However, @code{image_data} is an array that was the result of the
application of a map operator, so:

(poke) image_data'mapped
@end example

When a value is mapped, you can ask for the offset where it is mapped,
and the IO space where it is mapped, using the attributes
@code{'offset} and @code{'ios} respectively.  Therefore:

(poke) image_data'ios
(poke) image_data'offset
@end example

In other words, @code{image_data} is mapped in the IO space with id 1
(the @code{*scratch*} buffer) at offset 40 bits, or 5 bytes.  We
already knew that, because we mapped the image data ourselves, but in
other situations these attributes are most useful.  We shall see that

>>Very very nice work... once it is more complete we should include it not
>>only on the website, but also in the manual!
>>Thank you.
> Thanks! That's very good. I'll try my best to make it happen :)

Thanks :)

reply via email to

[Prev in Thread] Current Thread [Next in Thread]