Posted to tcl by Stu at Tue Jun 04 14:23:35 GMT 2024view raw

  1. $cat README
  2.  
  3. <?pragma elide on?>
  4.  
  5. pTycl is a variation on Python syntax.
  6.  
  7. Blocks:
  8. Braces are used to delimit multi-line blocks, like in C.
  9.  
  10. Comments:
  11. Lines where the first non-whitespace characters are "//"
  12. are pTycl comments and will not appear in the output.
  13.  
  14. Self:
  15. The character "$" will be replaced by "self" only in places
  16. where it is clear that "self" is what is wanted.
  17.  
  18. Carets:
  19. The character "^" will be replaced by "return" only in places
  20. where it is clear that "return" is what is wanted.
  21.  
  22. Mefods:
  23. Methods written with "mef" instead of "def" will be rewritten
  24. with "def" and "self" will be added as the first parameter.
  25. Use "maf" for "async def".
  26.  
  27. Lambdas:
  28. pTycl:
  29. | a b c | some_code_here(a,b,c) |
  30. becomes Python:
  31. lambda a,b,c:some_code_here(a,b,c)
  32.  
  33. Pragmas:
  34. Pragmas are of the form "<?pragma name args ...?>" and must be on a line by themselves.
  35. Available pragmas:
  36. elide Do not process or output lines. Default: off.
  37. comment Add a comment char "#" to the beginning of each line. Default: off.
  38. braces Turn on/off brace processing. Default: on.
  39. carets Turn on/off caret processing. Default: on.
  40. lambdas Turn on/off lamba processing. Default: on.
  41. m_fs Turn on/off mef/maf processing. Default: on.
  42. self Turn on/off self processing or set "self". Default: on, "self".
  43.  
  44.  
  45. Notes:
  46. The reference implementation of the preprocessor is the Tcl version.
  47.  
  48. Input is processed line by line using regular expressions and string replacement.
  49. With the exception of multi-line blocks, all code can be written as normal Python.
  50. There is no actual parsing.
  51.  
  52. This will work:
  53. if True {
  54. print('t')
  55. }
  56. This will not work:
  57. if True { print('t') }
  58. When writing such things on one line, use straight Python syntax:
  59. if True : print('t')
  60.  
  61. Normal Python multi-line blocks will not work;
  62. pTycl and Python can't be mixed in that way.
  63.  
  64. Anything pTycl is semi-intentionally designed to be a syntax error in Python.
  65. This was done to help prevent wrongness slipping-through unnoticed.
  66. For example, "<?praga elide off?>" will be ignored because pTycl doesn't
  67. understand it, so it will pass through to Python, where it will be an error.
  68.  
  69.  
  70. Example:
  71.  
  72. <?pragma elide off?>
  73.  
  74. // This is a pTycl program
  75. # This line will be in the output
  76. // This line won't
  77.  
  78. class Thing {
  79.  
  80. // For starters, we don't have to indent inside the class.
  81.  
  82. // "self" will be added automatically to a "mefod".
  83. // Braces are used to enclose the method body.
  84. // "$" is used for self.
  85. mef __init__ () {
  86. $num = 4
  87. }
  88.  
  89. // A mefod that takes a parameter and returns something.
  90. mef add_num1 (num) {
  91. ^ $num + num
  92. }
  93.  
  94. // Same but with regular "def" and "$" (self)
  95. def add_num2 ($, num) {
  96. ^ self.num + num
  97. }
  98.  
  99. // A mefod with a lambda
  100. mef lamda_add_num (num) {
  101. ^ | n | num + n |
  102. }
  103.  
  104. // Indenting
  105. mef indenting (some, unused, args) {
  106. if some == unused or args is None {
  107. ^ do_some_thing(args)
  108. } elif args is not None and args[0] == 4 {
  109. ^ $me_do_something(some)
  110. } elif args is None {
  111. notice here
  112. that even
  113. with the messed-up indenting {
  114. if the braces are {
  115. balanced
  116. for example {
  117. here
  118. }
  119. then
  120. things
  121. will
  122. work
  123. out
  124. } else {
  125. things could get messy
  126. }
  127. }
  128. } else {
  129. try {
  130. unused += args
  131. } except Exception as ex {
  132. print(ex)
  133. } else {
  134. for i in range(unused) {
  135. print($add_num1(i))
  136. }
  137. }
  138. }
  139. }
  140.  
  141.  
  142. } # class Thing (this is just a comment after the close brace. This whole line will be gone.)
  143.  
  144. # EOF
  145. // EOF
  146.  
  147. #---------------------------------
  148.  
  149. $ ptycl < README
  150.  
  151. # This line will be in the output
  152.  
  153. class Thing:
  154.  
  155.  
  156. def __init__ (self):
  157. self.num = 4
  158.  
  159. def add_num1 (self, num):
  160. return self.num + num
  161.  
  162. def add_num2 (self, num):
  163. return self.num + num
  164.  
  165. def lamda_add_num (self, num):
  166. return lambda n:num + n
  167.  
  168. def indenting (self, some, unused, args):
  169. if some == unused or args is None:
  170. return do_some_thing(args)
  171. elif args is not None and args[0] == 4:
  172. return self.me_do_something(some)
  173. elif args is None:
  174. notice here
  175. that even
  176. with the messed-up indenting:
  177. if the braces are:
  178. balanced
  179. for example:
  180. here
  181. then
  182. things
  183. will
  184. work
  185. out
  186. else:
  187. things could get messy
  188. else:
  189. try:
  190. unused += args
  191. except Exception as ex:
  192. print(ex)
  193. else:
  194. for i in range(unused):
  195. print(self.add_num1(i))
  196.