poke-devel
[Top][All Lists]
Advanced

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

Re: [Documentation] Learn Poke in Y Minutes


From: Mohammad-Reza Nabipoor
Subject: Re: [Documentation] Learn Poke in Y Minutes
Date: Mon, 1 Mar 2021 02:55:38 +0330

Hi, Jose.

On Sun, Feb 28, 2021 at 12:09:08PM +0100, Jose E. Marchesi wrote:
> 
> Hi Mohammad.
> 
> Fun stuff :)


Thanks :)


> 
> Would you like to maintain this in the poke source distribution doc/
> directory?
> 

Sure!
I've attached the changes at the bottom, if you think, it's OK, I'll send
the patch to add it to `doc/` directory.


> See some comments below.


Thanks for the review.


> >
> > var long_decimal = 100_000_000;
> > var long_hexadecimal = 0x1122_aabb_ccdd_eeff;
> 
> Maybe mention that _ can be used anywhere in an integer literal, in any
> numeration base?  Otherwise people may think it can only be used to
> separate hexadecimal digits.
> 


There are two examples here; one for `long_decimal` and the other for
`long_hexadecimal`.
But I also added a comment to clarify things.


> As for publishing, just let me know when you want it out and I will add
> to the poke homepage, and also publish it in applied pokology :)
> 

Thanks a lot.
Did you like the HTML output? I think green comments are more readable.


Regards,
Mohammad-Reza


---

diff --git a/learn-poke-in-y-minutes.pk b/learn-poke-in-y-minutes.pk
index e8e096b..e96ba3b 100644
--- a/learn-poke-in-y-minutes.pk
+++ b/learn-poke-in-y-minutes.pk
@@ -1,4 +1,6 @@
 
+/* Learn the Poke language in Y minutes */
+
 /* Copyright (C) 2020-2021, Mohammad-Reza Nabipoor */
 /* SPDX-License-Identifier: GPL-3.0-or-later */
 
@@ -44,7 +46,7 @@ var a_string = "hello, poke users!";
  *   - Array
  *   - Struct
  *   - Union
- *   - Function (or closure)
+ *   - Closure (or function)
  *
  * There are two categories of values in Poke:
  *   - Simple values
@@ -55,10 +57,10 @@ var a_string = "hello, poke users!";
  *     - Array
  *     - Struct
  *     - Union
- *     - Function  // FIXME not sure
+ *     - Closure
  *
  * The difference lies in the semantics of copy. Consider the following `C`
- * prgoram:
+ * program:
  *
  *   ```c
  *   void f(int);
@@ -77,7 +79,7 @@ var a_string = "hello, poke users!";
  * Simple values in Poke are like `int` in `C`. The copy makes a new disjoint
  * value. Changing the copied value will not change the original one.
  * And composite values are like `int*` in `C`. The new copy will also points
- * to the same data.
+ * to the same data (also called "copying by shared value").
  */
 
 
@@ -97,6 +99,7 @@ var ui16 = 5UH;    /* unsigned int  (16-bit) */
 var ui32 = 6U;     /* unsigned int  (32-bit) */
 var ui64 = 7UL;    /* unsigned long (64-bit) */
 
+/* Digits can be separated by `_` (underscores) to enhance readability. */
 var long_decimal = 100_000_000;
 var long_hexadecimal = 0x1122_aabb_ccdd_eeff;
 
@@ -137,14 +140,14 @@ var empty_string = "";
 
 /* Offset values
  *
- * Poke does not using integers to specify offsets in binary data, it has a
+ * Poke does not use integers to specify offsets in binary data, it has a
  * primitive type for that: offset!
  *
  * Offsets have two parts:
  *  - magnitude (an integer)
  *  - unit      (b (bit), byte (B), etc.)
  *
- * Offsets are also useful for specifying the size.
+ * Offsets are also useful for specifying sizes.
  */
 
 /* Offsets with named units */
@@ -165,8 +168,10 @@ var off_2_3 = 2#3;    /* magnitude: 2, unit: 3 bits */
  * OFF +- OFF -> OFF
  * OFF *  INT -> OFF
  * OFF /  OFF -> INT
- * OFF /^ OFF -> INT
+ * OFF /^ OFF -> INT    // ceil division
  * OFF %  OFF -> OFF
+ * OFF /  INT -> OFF
+ * OFF /^ INT -> OFF    // ceil division
  */
 var off_1_plus_2   = 1#B +  2#B;    /* 3#B  */
 var off_1_minus_2  = 1#B -  2#B;    /* -1#B */
@@ -225,8 +230,9 @@ arr6[0] = 1;        /* arr6 == [1, 2, 3] && arr1 == [-1, 2, 
3] */
 arr7[0][0] = -1;    /* arr2 == [[-1, 2], [3, 4]] */
 
 /* Making array using the constructor */
-var arr8 = string[3]("Hi");    /* arr8 == ["Hi", "Hi", "Hi"] */
-var arr9 = int<32>[]();            /* arr9 == arr4 */
+var arr8 = string[3]("Hi");     /* arr8  == ["Hi", "Hi", "Hi"] */
+var arr9 = int<32>[]();         /* arr9  == arr4; an empty array */
+var arr10 = int<32>[16#B]();    /* arr10 == [0, 0, 0, 0] */
 
 
 /* Types
@@ -277,6 +283,7 @@ var arr9 = int<32>[]();            /* arr9 == arr4 */
  *
  *   offset<int<32>,B>
  *   offset<uint<12>,Kb>
+ *   offset<uint<12>,1024>
  */
 
 /* Struct types
@@ -506,13 +513,21 @@ var hdrauto = HeaderWithInit {};
 
 
 /* Integral Structs
+ *
+ * A facility to deal with integers as a composite data.
+ * Different groups of bits of the integer can be accessed independently.
+ *
+ * Note that "integral structs" are integers, not structs. So the order of
+ * fields are independent of the underlying endianness.
+ *
+ * See http://jemarch.net/pokology-20200720.html for more info.
  */
 type IntSct = struct uint<16> /* After `struct` comes an integral type */
   {
     /* bit-width of all fields == 16 */
-    uint<4> x;
+    uint<4> x;    /* most significant nibble of the integer */
     uint<8> y;
-    uint<4> z;
+    uint<4> z;    /* least significant nibble of the integer */
   };
 var intsct = IntSct
   {
@@ -525,7 +540,6 @@ var y = intsct.y;    /* y == 0xbcUB */
 var z = intsct.z;    /* z == 0xdUN */
 /* Compiler promotes `intsct` to integer in all contexts where an integer is
  * expected.
- * Integral struct is a struct that can be interpreted as an integer.
  */
 var intsct_as_uint16 = intsct + 0H;    /* intsct_as_uint16   == 0xabcdUH */
 var intsct_as_uint16_2 = +intsct;      /* intsct_as_uint16_2 == 0xabcdUH */
@@ -573,16 +587,20 @@ fun func1 = (uint<32> arg0, uint<64> arg1) uint<32>:
     return arg0 | arg1 .>> 32;    /* `.>>` is bitwise shift right operator */
   }
 
-var three = func1 (1, 2L**33);   /* three == 3 (and `**` is power operator) */
+var three = func1 (1, 2L**33);    /* three == 3 (and `**` is power operator) */
+
+/* Alternative function call syntax */
+var four = (func1 :arg0 1 :arg1 2L**33) + 1;    /* four == 4 */
 
 fun awesome = (string name) void:
   {
     printf ("%s is awesome!\n", name);
   }
 awesome ("Poke");    /* Will print "Poke is awesome!" on terminal */
+awesome :name "Poke";
 
 var N = 10;
-fun Nsquare = int<32>:    /* No input parameter */
+fun Nsquare = int<32>:    /* No input argument */
   {
     /* The `N` variable is captured inside the `Nsquare` function */
     return N * N;
@@ -722,9 +740,24 @@ var flags3 = packet_u_3.u.alt3.flags;
 
 /* Casts
  */
-var num_u32 = 1;
+var num_u32 = 1U;
 var num_u64 = num_u32 as uint<64>;
 
+var off_12B = 1024#b as offset<int<12>,B>;    /* off_12B == 128#B */
+var off_9b = 9#b as offset<int,B>;            /* off_9b == 1#B */
+
+type CFoo = struct
+  {
+    int i;
+    long j;
+  };
+type CBar = struct
+  {
+    int i;
+  };
+var cbar_as_cfoo = CBar {i=1} as CFoo;    /* CFoo {i=1,j=0L} */
+var cfoo_as_cbar = CFoo {j=2} as CBar;    /* CBar {i=0} */
+
 
 /* Attributes
  *
@@ -776,6 +809,7 @@ var thousand = a_false_value ? 200 : 1000;
 /* Loops
  *
  *   - while
+ *   - for
  *   - for-in
  *   - try-until
  */
@@ -789,6 +823,12 @@ while (1)
 }
 /* i == 10 */
 
+for (var j = 0; j < 2; j++)
+  {
+    ++i;
+  }
+/* i == 12 */
+
 print "\nList of maintainers:\n";
 for (i in ["jemarch", "egeyar", "jmd", "positron", "darnir", "dan.cermak",
            "bruno", "ccaione", "eblake", "tim.ruehsen", "sdi1600195",
@@ -819,6 +859,7 @@ for (i in "0123456789" where i % 2 == 0)
  * output; it's like the `puts` function of C standard library.
  */
 print ("`print` is like `puts`!\n");
+print "`print` is like `puts`!\n";    /* Parentheses are optional */
 
 /* `printf` behaves like the `printf` function of C standard library:
  * one required argument of type string as the "format string" and zero or
@@ -845,6 +886,8 @@ print ("`print` is like `puts`!\n");
  * WIDTH is the width of the integral value.
  * DEPTH indicates how deep the print should recurse to print the child
  * fields. 0 means print all fields completely.
+ *
+ * Parentheses are optional around the arguments.
  */
 
 printf ("decimal (64): %i64x %u64x\n", -1, 1);
@@ -1000,6 +1043,18 @@ var cur_sz = iosize (cur_ios);
 set_endian(ENDIAN_LITTLE);    /* get_endian == ENDIAN_LITTLE */
 
 
+/* Signed Arithmetic Overflow Detection
+ *
+ * All signed arithmetic operations can raise `E_overflow` exception.
+ */
+try
+  2**33;    /* `2` is of type `int32` */
+catch if E_overflow
+  {
+    print ("Overflow detected in 2**33");
+  }
+
+
 /* std.pk - Standard definition for poke
  *
  * The following types are defined as Standard Integral Types:
@@ -1091,4 +1146,5 @@ set_endian(ENDIAN_LITTLE);    /* get_endian == 
ENDIAN_LITTLE */
  * 
https://kernel-recipes.org/en/2019/talks/gnu-poke-an-extensible-editor-for-structured-binary-data/
  * GNU poke reference documentation (Texinfo file)
  * http://jemarch.net/pokology-20200504.html
+ * http://jemarch.net/pokology-20200720.html
  */


reply via email to

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