easycoder 250103.2__tar.gz → 250105.1__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.

Potentially problematic release.


This version of easycoder might be problematic. Click here for more details.

Files changed (146) hide show
  1. {easycoder-250103.2 → easycoder-250105.1}/PKG-INFO +19 -5
  2. {easycoder-250103.2 → easycoder-250105.1}/README.md +18 -4
  3. {easycoder-250103.2 → easycoder-250105.1}/doc/core/README.md +1 -1
  4. {easycoder-250103.2 → easycoder-250105.1}/doc/core/keywords/import.md +6 -0
  5. {easycoder-250103.2 → easycoder-250105.1}/doc/core/keywords/load.md +1 -1
  6. easycoder-250105.1/doc/core/keywords/lock.md +15 -0
  7. easycoder-250105.1/doc/core/keywords/module.md +17 -0
  8. {easycoder-250103.2 → easycoder-250105.1}/doc/core/keywords/multiply.md +1 -1
  9. {easycoder-250103.2 → easycoder-250105.1}/doc/core/keywords/read.md +1 -1
  10. easycoder-250105.1/doc/core/keywords/release.md +15 -0
  11. {easycoder-250103.2 → easycoder-250105.1}/doc/core/keywords/replace.md +1 -1
  12. {easycoder-250103.2 → easycoder-250105.1}/doc/core/keywords/return.md +1 -1
  13. easycoder-250105.1/doc/core/keywords/run.md +15 -0
  14. {easycoder-250103.2 → easycoder-250105.1}/doc/core/keywords/save.md +1 -1
  15. {easycoder-250103.2 → easycoder-250105.1}/doc/core/keywords/truncate.md +1 -1
  16. easycoder-250105.1/doc/core/keywords/unlock.md +15 -0
  17. {easycoder-250103.2 → easycoder-250105.1}/doc/core/keywords/variable.md +1 -1
  18. {easycoder-250103.2 → easycoder-250105.1}/easycoder/__init__.py +1 -1
  19. {easycoder-250103.2 → easycoder-250105.1}/easycoder/ec_compiler.py +3 -0
  20. {easycoder-250103.2 → easycoder-250105.1}/easycoder/ec_core.py +203 -17
  21. {easycoder-250103.2 → easycoder-250105.1}/easycoder/ec_graphics.py +40 -12
  22. {easycoder-250103.2 → easycoder-250105.1}/easycoder/ec_program.py +98 -51
  23. {easycoder-250103.2 → easycoder-250105.1}/easycoder/ec_renderer.py +3 -1
  24. {easycoder-250103.2 → easycoder-250105.1}/easycoder/ec_value.py +1 -1
  25. {easycoder-250103.2 → easycoder-250105.1}/scripts/benchmark.ecs +1 -0
  26. {easycoder-250103.2 → easycoder-250105.1}/scripts/fizzbuzz.ecs +1 -0
  27. {easycoder-250103.2 → easycoder-250105.1}/scripts/hello.ecs +1 -0
  28. {easycoder-250103.2 → easycoder-250105.1}/scripts/points.ecs +2 -1
  29. {easycoder-250103.2 → easycoder-250105.1}/scripts/tests.ecs +2 -0
  30. {easycoder-250103.2 → easycoder-250105.1}/LICENSE +0 -0
  31. {easycoder-250103.2 → easycoder-250105.1}/doc/README.md +0 -0
  32. {easycoder-250103.2 → easycoder-250105.1}/doc/core/conditions/boolean.md +0 -0
  33. {easycoder-250103.2 → easycoder-250105.1}/doc/core/conditions/empty.md +0 -0
  34. {easycoder-250103.2 → easycoder-250105.1}/doc/core/conditions/ends.md +0 -0
  35. {easycoder-250103.2 → easycoder-250105.1}/doc/core/conditions/even.md +0 -0
  36. {easycoder-250103.2 → easycoder-250105.1}/doc/core/conditions/exists.md +0 -0
  37. {easycoder-250103.2 → easycoder-250105.1}/doc/core/conditions/greater.md +0 -0
  38. {easycoder-250103.2 → easycoder-250105.1}/doc/core/conditions/hasProperty.md +0 -0
  39. {easycoder-250103.2 → easycoder-250105.1}/doc/core/conditions/includes.md +0 -0
  40. {easycoder-250103.2 → easycoder-250105.1}/doc/core/conditions/is.md +0 -0
  41. {easycoder-250103.2 → easycoder-250105.1}/doc/core/conditions/less.md +0 -0
  42. {easycoder-250103.2 → easycoder-250105.1}/doc/core/conditions/list.md +0 -0
  43. {easycoder-250103.2 → easycoder-250105.1}/doc/core/conditions/none.md +0 -0
  44. {easycoder-250103.2 → easycoder-250105.1}/doc/core/conditions/not.md +0 -0
  45. {easycoder-250103.2 → easycoder-250105.1}/doc/core/conditions/numeric.md +0 -0
  46. {easycoder-250103.2 → easycoder-250105.1}/doc/core/conditions/object.md +0 -0
  47. {easycoder-250103.2 → easycoder-250105.1}/doc/core/conditions/odd.md +0 -0
  48. {easycoder-250103.2 → easycoder-250105.1}/doc/core/conditions/starts.md +0 -0
  49. {easycoder-250103.2 → easycoder-250105.1}/doc/core/conditions/string.md +0 -0
  50. {easycoder-250103.2 → easycoder-250105.1}/doc/core/keywords/add.md +0 -0
  51. {easycoder-250103.2 → easycoder-250105.1}/doc/core/keywords/append.md +0 -0
  52. {easycoder-250103.2 → easycoder-250105.1}/doc/core/keywords/assert.md +0 -0
  53. {easycoder-250103.2 → easycoder-250105.1}/doc/core/keywords/begin.md +0 -0
  54. {easycoder-250103.2 → easycoder-250105.1}/doc/core/keywords/clear.md +0 -0
  55. {easycoder-250103.2 → easycoder-250105.1}/doc/core/keywords/close.md +0 -0
  56. {easycoder-250103.2 → easycoder-250105.1}/doc/core/keywords/create.md +0 -0
  57. {easycoder-250103.2 → easycoder-250105.1}/doc/core/keywords/debug.md +0 -0
  58. {easycoder-250103.2 → easycoder-250105.1}/doc/core/keywords/decrement.md +0 -0
  59. {easycoder-250103.2 → easycoder-250105.1}/doc/core/keywords/delete.md +0 -0
  60. {easycoder-250103.2 → easycoder-250105.1}/doc/core/keywords/divide.md +0 -0
  61. {easycoder-250103.2 → easycoder-250105.1}/doc/core/keywords/exit.md +0 -0
  62. {easycoder-250103.2 → easycoder-250105.1}/doc/core/keywords/file.md +0 -0
  63. {easycoder-250103.2 → easycoder-250105.1}/doc/core/keywords/fork.md +0 -0
  64. {easycoder-250103.2 → easycoder-250105.1}/doc/core/keywords/get.md +0 -0
  65. {easycoder-250103.2 → easycoder-250105.1}/doc/core/keywords/go.md +0 -0
  66. {easycoder-250103.2 → easycoder-250105.1}/doc/core/keywords/gosub.md +0 -0
  67. {easycoder-250103.2 → easycoder-250105.1}/doc/core/keywords/if.md +0 -0
  68. {easycoder-250103.2 → easycoder-250105.1}/doc/core/keywords/increment.md +0 -0
  69. {easycoder-250103.2 → easycoder-250105.1}/doc/core/keywords/index.md +0 -0
  70. {easycoder-250103.2 → easycoder-250105.1}/doc/core/keywords/init.md +0 -0
  71. {easycoder-250103.2 → easycoder-250105.1}/doc/core/keywords/input.md +0 -0
  72. {easycoder-250103.2 → easycoder-250105.1}/doc/core/keywords/negate.md +0 -0
  73. {easycoder-250103.2 → easycoder-250105.1}/doc/core/keywords/open.md +0 -0
  74. {easycoder-250103.2 → easycoder-250105.1}/doc/core/keywords/pop.md +0 -0
  75. {easycoder-250103.2 → easycoder-250105.1}/doc/core/keywords/post.md +0 -0
  76. {easycoder-250103.2 → easycoder-250105.1}/doc/core/keywords/print.md +0 -0
  77. {easycoder-250103.2 → easycoder-250105.1}/doc/core/keywords/push.md +0 -0
  78. {easycoder-250103.2 → easycoder-250105.1}/doc/core/keywords/put.md +0 -0
  79. {easycoder-250103.2 → easycoder-250105.1}/doc/core/keywords/script.md +0 -0
  80. {easycoder-250103.2 → easycoder-250105.1}/doc/core/keywords/set.md +0 -0
  81. {easycoder-250103.2 → easycoder-250105.1}/doc/core/keywords/split.md +0 -0
  82. {easycoder-250103.2 → easycoder-250105.1}/doc/core/keywords/stack.md +0 -0
  83. {easycoder-250103.2 → easycoder-250105.1}/doc/core/keywords/stop.md +0 -0
  84. {easycoder-250103.2 → easycoder-250105.1}/doc/core/keywords/system.md +0 -0
  85. {easycoder-250103.2 → easycoder-250105.1}/doc/core/keywords/take.md +0 -0
  86. {easycoder-250103.2 → easycoder-250105.1}/doc/core/keywords/toggle.md +0 -0
  87. {easycoder-250103.2 → easycoder-250105.1}/doc/core/keywords/wait.md +0 -0
  88. {easycoder-250103.2 → easycoder-250105.1}/doc/core/keywords/while.md +0 -0
  89. {easycoder-250103.2 → easycoder-250105.1}/doc/core/keywords/write.md +0 -0
  90. {easycoder-250103.2 → easycoder-250105.1}/doc/core/values/arg.md +0 -0
  91. {easycoder-250103.2 → easycoder-250105.1}/doc/core/values/args.md +0 -0
  92. {easycoder-250103.2 → easycoder-250105.1}/doc/core/values/cos.md +0 -0
  93. {easycoder-250103.2 → easycoder-250105.1}/doc/core/values/datime.md +0 -0
  94. {easycoder-250103.2 → easycoder-250105.1}/doc/core/values/decode.md +0 -0
  95. {easycoder-250103.2 → easycoder-250105.1}/doc/core/values/element.md +0 -0
  96. {easycoder-250103.2 → easycoder-250105.1}/doc/core/values/elements.md +0 -0
  97. {easycoder-250103.2 → easycoder-250105.1}/doc/core/values/empty.md +0 -0
  98. {easycoder-250103.2 → easycoder-250105.1}/doc/core/values/encode.md +0 -0
  99. {easycoder-250103.2 → easycoder-250105.1}/doc/core/values/error.md +0 -0
  100. {easycoder-250103.2 → easycoder-250105.1}/doc/core/values/files.md +0 -0
  101. {easycoder-250103.2 → easycoder-250105.1}/doc/core/values/float.md +0 -0
  102. {easycoder-250103.2 → easycoder-250105.1}/doc/core/values/from.md +0 -0
  103. {easycoder-250103.2 → easycoder-250105.1}/doc/core/values/hash.md +0 -0
  104. {easycoder-250103.2 → easycoder-250105.1}/doc/core/values/index.md +0 -0
  105. {easycoder-250103.2 → easycoder-250105.1}/doc/core/values/integer.md +0 -0
  106. {easycoder-250103.2 → easycoder-250105.1}/doc/core/values/json.md +0 -0
  107. {easycoder-250103.2 → easycoder-250105.1}/doc/core/values/keys.md +0 -0
  108. {easycoder-250103.2 → easycoder-250105.1}/doc/core/values/left.md +0 -0
  109. {easycoder-250103.2 → easycoder-250105.1}/doc/core/values/length.md +0 -0
  110. {easycoder-250103.2 → easycoder-250105.1}/doc/core/values/lowercase.md +0 -0
  111. {easycoder-250103.2 → easycoder-250105.1}/doc/core/values/memory.md +0 -0
  112. {easycoder-250103.2 → easycoder-250105.1}/doc/core/values/modification.md +0 -0
  113. {easycoder-250103.2 → easycoder-250105.1}/doc/core/values/modulo.md +0 -0
  114. {easycoder-250103.2 → easycoder-250105.1}/doc/core/values/newline.md +0 -0
  115. {easycoder-250103.2 → easycoder-250105.1}/doc/core/values/now.md +0 -0
  116. {easycoder-250103.2 → easycoder-250105.1}/doc/core/values/position.md +0 -0
  117. {easycoder-250103.2 → easycoder-250105.1}/doc/core/values/property.md +0 -0
  118. {easycoder-250103.2 → easycoder-250105.1}/doc/core/values/random.md +0 -0
  119. {easycoder-250103.2 → easycoder-250105.1}/doc/core/values/right.md +0 -0
  120. {easycoder-250103.2 → easycoder-250105.1}/doc/core/values/sin.md +0 -0
  121. {easycoder-250103.2 → easycoder-250105.1}/doc/core/values/stringify.md +0 -0
  122. {easycoder-250103.2 → easycoder-250105.1}/doc/core/values/tab.md +0 -0
  123. {easycoder-250103.2 → easycoder-250105.1}/doc/core/values/tan.md +0 -0
  124. {easycoder-250103.2 → easycoder-250105.1}/doc/core/values/timestamp.md +0 -0
  125. {easycoder-250103.2 → easycoder-250105.1}/doc/core/values/today.md +0 -0
  126. {easycoder-250103.2 → easycoder-250105.1}/doc/core/values/trim.md +0 -0
  127. {easycoder-250103.2 → easycoder-250105.1}/doc/core/values/type.md +0 -0
  128. {easycoder-250103.2 → easycoder-250105.1}/doc/core/values/uppercase.md +0 -0
  129. {easycoder-250103.2 → easycoder-250105.1}/doc/core/values/value.md +0 -0
  130. {easycoder-250103.2 → easycoder-250105.1}/doc/core/values/weekday.md +0 -0
  131. {easycoder-250103.2 → easycoder-250105.1}/doc/graphics/README.md +0 -0
  132. {easycoder-250103.2 → easycoder-250105.1}/easycoder/README.md +0 -0
  133. {easycoder-250103.2 → easycoder-250105.1}/easycoder/ec.py +0 -0
  134. {easycoder-250103.2 → easycoder-250105.1}/easycoder/ec_classes.py +0 -0
  135. {easycoder-250103.2 → easycoder-250105.1}/easycoder/ec_condition.py +0 -0
  136. {easycoder-250103.2 → easycoder-250105.1}/easycoder/ec_handler.py +0 -0
  137. {easycoder-250103.2 → easycoder-250105.1}/easycoder/ec_screenspec.py +0 -0
  138. {easycoder-250103.2 → easycoder-250105.1}/easycoder/ec_timestamp.py +0 -0
  139. {easycoder-250103.2 → easycoder-250105.1}/images/Semoigo Dawn.jpg +0 -0
  140. {easycoder-250103.2 → easycoder-250105.1}/json/graphics-demo.json +0 -0
  141. {easycoder-250103.2 → easycoder-250105.1}/plugins/ec_p100.py +0 -0
  142. {easycoder-250103.2 → easycoder-250105.1}/plugins/example.py +0 -0
  143. {easycoder-250103.2 → easycoder-250105.1}/pyproject.toml +0 -0
  144. {easycoder-250103.2 → easycoder-250105.1}/scripts/README.md +0 -0
  145. {easycoder-250103.2 → easycoder-250105.1}/scripts/graphics-demo.ecg +0 -0
  146. {easycoder-250103.2 → easycoder-250105.1}/scripts/wave.ecg +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.3
2
2
  Name: easycoder
3
- Version: 250103.2
3
+ Version: 250105.1
4
4
  Summary: Rapid scripting in English
5
5
  Keywords: compiler,scripting,prototyping,programming,coding,python,low code,hypertalk,computer language,learn to code
6
6
  Author-email: Graham Trott <gtanyware@gmail.com>
@@ -10,12 +10,13 @@ Requires-Dist: pytz
10
10
  Project-URL: Home, https://github.com/easycoder/easycoder-py
11
11
 
12
12
  # Introduction
13
- **_EasyCoder_** is a high-level English-like scripting language suited for prototyping and rapid testing of ideas. It operates on the command line and a graphics module is under construction. This version of the language is written in Python and its runtime acts as a fairly thin wrapper around Python functions, giving good performance for general applications.
14
-
15
- The JavaScript version of **_EasyCoder_**, which provides a full set of graphical features to run in a browser, is at
13
+ **_EasyCoder_** is a high-level English-like scripting language suited for prototyping and rapid testing of ideas. It operates on the command line and a graphics module is under construction. This version of the language is written in Python and it acts as a fairly thin wrapper around Python functions, giving fast compilation and good runtime performance for general applications.
14
+ <hr>
15
+ For the JavaScript version of **_EasyCoder_**, which provides a full set of graphical features to run in a browser, please visit
16
16
 
17
17
  Repository: [https://github.com/easycoder/easycoder.github.io](https://github.com/easycoder/easycoder.github.io)
18
18
  Website: [https://easycoder.github.io](https://easycoder.github.io)
19
+ <hr>
19
20
 
20
21
  ## Quick Start
21
22
  Install **_EasyCoder_** in your Python environment:
@@ -28,7 +29,7 @@ print `Hello, world!`
28
29
  ```
29
30
  This is traditionally the first program to be written in virtually any language. To run it, use `easycoder hello.ecs`.
30
31
 
31
- The output will look like this:
32
+ The output will look like this (the version number will differ):
32
33
 
33
34
  ```
34
35
  EasyCoder version 250101.1
@@ -72,6 +73,19 @@ A couple of demo graphical scripts are included in the `scripts` directory:
72
73
 
73
74
  **_EasyCoder_** graphics are handled by a library module, `ec_renderer` that can be used outside of the **_EasyCoder_** environment, in other Python programs.
74
75
 
76
+ ## Significant features
77
+
78
+ - English-like syntax based on vocabulary rather than structure. Scripts can be read as English
79
+ - Comprehensive feature set
80
+ - Runs directly from source scripts, using a fast compiler to create efficient intermediate runtime code that is run immediately
81
+ - Low memory requirements
82
+ - Minimim dependency on other 3rd-party packages
83
+ - Built-in co-operative multitasking
84
+ - Dynamic loading of scripts on demand
85
+ - The language can be extended seamlessly using plugin function modules
86
+ - Plays well with any Python code
87
+ - Fully Open Source
88
+
75
89
  ## Programming reference
76
90
 
77
91
  **_EasyCoder_** comprises a set of modules to handle tokenisation, compilation and runtime control. Syntax and grammar are defined by [packages](doc/README.md), of which there are currently two; the [core](doc/core/README.md) package, which implements a comprehensive set of command-line programming features, and and the [graphics](doc/graphics/README.md) package, which adds graphical features in a windowing environment.
@@ -1,10 +1,11 @@
1
1
  # Introduction
2
- **_EasyCoder_** is a high-level English-like scripting language suited for prototyping and rapid testing of ideas. It operates on the command line and a graphics module is under construction. This version of the language is written in Python and its runtime acts as a fairly thin wrapper around Python functions, giving good performance for general applications.
3
-
4
- The JavaScript version of **_EasyCoder_**, which provides a full set of graphical features to run in a browser, is at
2
+ **_EasyCoder_** is a high-level English-like scripting language suited for prototyping and rapid testing of ideas. It operates on the command line and a graphics module is under construction. This version of the language is written in Python and it acts as a fairly thin wrapper around Python functions, giving fast compilation and good runtime performance for general applications.
3
+ <hr>
4
+ For the JavaScript version of **_EasyCoder_**, which provides a full set of graphical features to run in a browser, please visit
5
5
 
6
6
  Repository: [https://github.com/easycoder/easycoder.github.io](https://github.com/easycoder/easycoder.github.io)
7
7
  Website: [https://easycoder.github.io](https://easycoder.github.io)
8
+ <hr>
8
9
 
9
10
  ## Quick Start
10
11
  Install **_EasyCoder_** in your Python environment:
@@ -17,7 +18,7 @@ print `Hello, world!`
17
18
  ```
18
19
  This is traditionally the first program to be written in virtually any language. To run it, use `easycoder hello.ecs`.
19
20
 
20
- The output will look like this:
21
+ The output will look like this (the version number will differ):
21
22
 
22
23
  ```
23
24
  EasyCoder version 250101.1
@@ -61,6 +62,19 @@ A couple of demo graphical scripts are included in the `scripts` directory:
61
62
 
62
63
  **_EasyCoder_** graphics are handled by a library module, `ec_renderer` that can be used outside of the **_EasyCoder_** environment, in other Python programs.
63
64
 
65
+ ## Significant features
66
+
67
+ - English-like syntax based on vocabulary rather than structure. Scripts can be read as English
68
+ - Comprehensive feature set
69
+ - Runs directly from source scripts, using a fast compiler to create efficient intermediate runtime code that is run immediately
70
+ - Low memory requirements
71
+ - Minimim dependency on other 3rd-party packages
72
+ - Built-in co-operative multitasking
73
+ - Dynamic loading of scripts on demand
74
+ - The language can be extended seamlessly using plugin function modules
75
+ - Plays well with any Python code
76
+ - Fully Open Source
77
+
64
78
  ## Programming reference
65
79
 
66
80
  **_EasyCoder_** comprises a set of modules to handle tokenisation, compilation and runtime control. Syntax and grammar are defined by [packages](doc/README.md), of which there are currently two; the [core](doc/core/README.md) package, which implements a comprehensive set of command-line programming features, and and the [graphics](doc/graphics/README.md) package, which adds graphical features in a windowing environment.
@@ -10,7 +10,7 @@ There are three primary components to the language:
10
10
 
11
11
  The core keywords are:
12
12
 
13
- [add](keywords/add.md) [append](keywords/append.md) [assert](keywords/assert.md) [begin](keywords/begin.md) [clear](keywords/clear.md) [close](keywords/close.md) [create](keywords/create.md) [debug](keywords/debug.md) [decrement](keywords/decrement.md) [delete](keywords/delete.md) [divide](keywords/divide.md) [exit](keywords/exit.md) [file](keywords/file.md) [fork](keywords/fork.md) [get](keywords/get.md) [go](keywords/go.md) [gosub](keywords/gosub.md) [if](keywords/if.md) [import](keywords/import.md) [increment](keywords/increment.md) [index](keywords/index.md) [init](keywords/init.md) [input](keywords/input.md) [load](keywords/load.md) [multiply](keywords/multiply.md) [negate](keywords/negate.md) [open](keywords/open.md) [pop](keywords/pop.md) [post](keywords/post.md) [print](keywords/print.md) [push](keywords/push.md) [put](keywords/put.md) [read](keywords/read.md) [replace](keywords/replace.md) [return](keywords/return.md) [save](keywords/save.md) [script](keywords/script.md) [set](keywords/set.md) [split](keywords/split.md) [stack](keywords/stack.md) [stop](keywords/stop.md) [system](keywords/system.md) [take](keywords/take.md) [toggle](keywords/toggle.md) [truncate](keywords/truncate.md) [variable](keywords/variable.md) [wait](keywords/wait.md) [while](keywords/while.md) [write](keywords/write.md)
13
+ [add](keywords/add.md) [append](keywords/append.md) [assert](keywords/assert.md) [begin](keywords/begin.md) [clear](keywords/clear.md) [close](keywords/close.md) [create](keywords/create.md) [debug](keywords/debug.md) [decrement](keywords/decrement.md) [delete](keywords/delete.md) [divide](keywords/divide.md) [exit](keywords/exit.md) [file](keywords/file.md) [fork](keywords/fork.md) [get](keywords/get.md) [go](keywords/go.md) [gosub](keywords/gosub.md) [if](keywords/if.md) [import](keywords/import.md) [increment](keywords/increment.md) [index](keywords/index.md) [init](keywords/init.md) [input](keywords/input.md) [load](keywords/load.md) [lock](keywords/lock.md) [module](keywords/module.md) [multiply](keywords/multiply.md) [negate](keywords/negate.md) [open](keywords/open.md) [pop](keywords/pop.md) [post](keywords/post.md) [print](keywords/print.md) [push](keywords/push.md) [put](keywords/put.md) [read](keywords/read.md) [replace](keywords/replace.md) [return](keywords/return.md) [run](keywords/run.md) [save](keywords/save.md) [script](keywords/script.md) [set](keywords/set.md) [split](keywords/split.md) [stack](keywords/stack.md) [stop](keywords/stop.md) [system](keywords/system.md) [take](keywords/take.md) [toggle](keywords/toggle.md) [truncate](keywords/truncate.md) [unlock](keywords/unlock.md) [variable](keywords/variable.md) [wait](keywords/wait.md) [while](keywords/while.md) [write](keywords/write.md)
14
14
 
15
15
  The core values are:
16
16
 
@@ -1,12 +1,18 @@
1
1
  # import
2
2
 
3
3
  ## Syntax:
4
+ `import {type} {variable} [and {type} {variable} ...]]`
4
5
  `import {classname} from {path}`
5
6
 
6
7
  ## Examples:
8
+ `import variable Name and variable Surname`
7
9
  `import Points from plugins/example.py`
8
10
 
9
11
  ## Description:
12
+ First form:
13
+ This specifies which variable should be provided by a calling script
14
+
15
+ Second form:
10
16
  As with [script](script.md), `import` is a compiler directive that should be placed at the top of the script, under the [script](script.md) directive. It's used to call in a plugin language extension where needed. The example above is provided in the repository, to be used as a starting point for your own extra functionality.
11
17
 
12
18
  Next: [increment](increment.md)
@@ -10,7 +10,7 @@
10
10
  ## Description:
11
11
  Loads the contents of a file into a variable. See also [save](save.md).
12
12
 
13
- Next: [multiply](multiply.md)
13
+ Next: [lock](lock.md)
14
14
  Prev: [init](init.md)
15
15
 
16
16
  [Back](../../README.md)
@@ -0,0 +1,15 @@
1
+ # lock
2
+
3
+ ## Syntax:
4
+ `lock {variable}`
5
+
6
+ ## Examples:
7
+ `lock Status`
8
+
9
+ ## Description:
10
+ Locks a variable to prevent it being modified. See also [unlock](unlock.md).
11
+
12
+ Next: [lock](lock.md)
13
+ Prev: [init](init.md)
14
+
15
+ [Back](../../README.md)
@@ -0,0 +1,17 @@
1
+ # module
2
+
3
+ ## Syntax:
4
+ `module {name}`
5
+
6
+ ## Example:
7
+ `module Loader`
8
+
9
+ ## Description:
10
+ Declare a module variable, which enables you to run another script as a child of the current one. You canarrange for both scripts to run concurrently or for one to wait for the other to complete.
11
+
12
+ Module variables can be assigned any number of elements - see [set the elements](set.md).
13
+
14
+ Next: [multiply](multiply.md)
15
+ Prev: [lock](lock.md)
16
+
17
+ [Back](../../README.md)
@@ -11,6 +11,6 @@
11
11
  Multiplies a numeric variable by a numeric value or multiplies one value by another and puts the result into a variable. See elsewhere in this documentation for an explanation of what is meant by a value. If you multiply a variable it must already hold a numeric value, and if you assign a variable to hold the result of a multiplication it will lose whatever value it previously held.
12
12
 
13
13
  Next: [negate](negate.md)
14
- Prev: [load](load.md)
14
+ Prev: [lock](lock.md)
15
15
 
16
16
  [Back](../../README.md)
@@ -8,7 +8,7 @@
8
8
  ## Description:
9
9
  Read a value from a [file](file.md). See [open](open.md), [write](write.md) and [close](close.md).
10
10
 
11
- Next: [replace](replace.md)
11
+ Next: [release](release.md)
12
12
  Prev: [put](put.md)
13
13
 
14
14
  [Back](../../README.md)
@@ -0,0 +1,15 @@
1
+ # release
2
+
3
+ ## Syntax:
4
+ `release parent`
5
+
6
+ ## Example:
7
+ `release parent`
8
+
9
+ ## Description:
10
+ Release the parent script. When a child module is run it blocks the parent from running until either it exits or it issues the `release parent` command. This allows it to do initialisation that cannot be interrupted but which may involve timed delays.
11
+
12
+ Next: [multiply](multiply.md)
13
+ Prev: [lock](lock.md)
14
+
15
+ [Back](../../README.md)
@@ -10,6 +10,6 @@
10
10
  Replaces all occurrences of one string with another in a string [variable](variable.md).
11
11
 
12
12
  Next: [return](return.md)
13
- Prev: [read](read.md)
13
+ Prev: [release](release.md)
14
14
 
15
15
  [Back](../../README.md)
@@ -8,7 +8,7 @@
8
8
  ## Description:
9
9
  Return from a subroutine. See [gosub](gosub.md).
10
10
 
11
- Next: [save](save.md)
11
+ Next: [run](run.md)
12
12
  Prev: [replace](replace.md)
13
13
 
14
14
  [Back](../../README.md)
@@ -0,0 +1,15 @@
1
+ # run
2
+
3
+ ## Syntax:
4
+ `run {name} {module} as [with {export} [and {export}...]]`
5
+
6
+ ## Example:
7
+ ``run Hello as `hello.ecs` with Name and Surname` ``
8
+
9
+ ## Description:
10
+ Run a second script, optionally passing it variables it can use. Changes to these variables will be seen by the parent script (but see [lock](lock.md)). See also [module](module.md), [release](release.md), [send](send.md)and [on](on.md).
11
+
12
+ Next: [multiply](multiply.md)
13
+ Prev: [lock](lock.md)
14
+
15
+ [Back](../../README.md)
@@ -11,6 +11,6 @@
11
11
  Saves data to a file. See also [load](load.md).
12
12
 
13
13
  Next: [set](set.md)
14
- Prev: [return](return.md)
14
+ Prev: [run](run.md)
15
15
 
16
16
  [Back](../../README.md)
@@ -10,7 +10,7 @@
10
10
  ## Description:
11
11
  Truncate a file
12
12
 
13
- Next: [variable](variable.md)
13
+ Next: [unlock](variable.md)
14
14
  Prev: [toggle](toggle.md)
15
15
 
16
16
  [Back](../../README.md)
@@ -0,0 +1,15 @@
1
+ # ulock
2
+
3
+ ## Syntax:
4
+ `unlock {variable}`
5
+
6
+ ## Examples:
7
+ `lock Status`
8
+
9
+ ## Description:
10
+ Unlocks a locked variable to allow it to be modified. See also [lock](lock.md).
11
+
12
+ Next: [lock](lock.md)
13
+ Prev: [init](init.md)
14
+
15
+ [Back](../../README.md)
@@ -12,6 +12,6 @@ Declare a variable - an arbitrary storage item. Variables may hold string, numer
12
12
  Variables can be assigned any number of elements - see [set the elements](set.md). Each element can hold a data value of any of the 3 types above.
13
13
 
14
14
  Next: [wait](wait.md)
15
- Prev: [toggle](toggle.md)
15
+ Prev: [unlock](toggle.md)
16
16
 
17
17
  [Back](../../README.md)
@@ -10,4 +10,4 @@ from .ec_program import *
10
10
  from .ec_timestamp import *
11
11
  from .ec_value import *
12
12
 
13
- __version__ = "250103.2"
13
+ __version__ = "250105.1"
@@ -128,6 +128,7 @@ class Compiler:
128
128
  FatalError(self, f'Duplicate symbol name "{name}"')
129
129
  return False
130
130
  self.symbols[name] = self.getPC()
131
+ command['program'] = self.program
131
132
  command['type'] = 'symbol'
132
133
  command['valueHolder'] = valueHolder
133
134
  command['name'] = name
@@ -136,6 +137,8 @@ class Compiler:
136
137
  command['value'] = [None]
137
138
  command['used'] = False
138
139
  command['debug'] = False
140
+ command['import'] = None
141
+ command['locked'] = False
139
142
  self.addCommand(command)
140
143
  return True
141
144
 
@@ -367,8 +367,7 @@ class Core(Handler):
367
367
  return True
368
368
 
369
369
  def r_exit(self, command):
370
- sys.exit()
371
- return 0
370
+ return -1
372
371
 
373
372
  # Declare a file variable
374
373
  def k_file(self, command):
@@ -462,7 +461,7 @@ class Core(Handler):
462
461
  else:
463
462
  RuntimeError(self.program, f'Error: {errorReason}')
464
463
  retval['content'] = response.text
465
- self.program.putSymbolValue(target, retval);
464
+ self.program.putSymbolValue(target, retval)
466
465
  return self.nextPC()
467
466
 
468
467
  # Go to a label
@@ -553,15 +552,55 @@ class Core(Handler):
553
552
  self.program.pc += 1
554
553
  return self.program.pc
555
554
 
556
- # Import a plugin. This is done at compile time.
557
- # import {class} from {source}
558
555
  def k_import(self, command):
559
- clazz = self.nextToken()
560
- if self.nextIs('from'):
561
- source = self.nextToken()
562
- self.program.importPlugin(f'{source}:{clazz}')
556
+ if self.peek() == 'plugin':
557
+ # Import a plugin
558
+ self.nextToken()
559
+ clazz = self.nextToken()
560
+ if self.nextIs('from'):
561
+ source = self.nextToken()
562
+ self.program.importPlugin(f'{source}:{clazz}')
563
+ return True
564
+ return False
565
+ else:
566
+ # Import one or more variables
567
+ imports = []
568
+ while True:
569
+ keyword = self.nextToken()
570
+ name = self.nextToken()
571
+ item = [keyword, name]
572
+ imports.append(item)
573
+ self.symbols[name] = self.getPC()
574
+ variable = {}
575
+ variable['domain'] = None
576
+ variable['name'] = name
577
+ variable['keyword'] = keyword
578
+ variable['import'] = None
579
+ self.addCommand(variable)
580
+ if self.peek() != 'and':
581
+ break
582
+ self.nextToken()
583
+ command['imports'] = json.dumps(imports)
584
+ self.add(command)
563
585
  return True
564
- return False
586
+
587
+ def r_import(self, command):
588
+ exports = self.program.exports
589
+ imports = json.loads(command['imports'])
590
+ if len(imports) < len(exports):
591
+ RuntimeError(self.program, 'Too few imports')
592
+ elif len(imports) > len(exports):
593
+ RuntimeError(self.program, 'Too many imports')
594
+ for n in range(0, len(imports)):
595
+ exportRecord = exports[n]
596
+ exportKeyword = exportRecord['keyword']
597
+ name = imports[n][1]
598
+ symbolRecord = self.program.getSymbolRecord(name)
599
+ symbolKeyword = symbolRecord['keyword']
600
+ if symbolKeyword != exportKeyword:
601
+ RuntimeError(self.program, f'Import {n} ({symbolKeyword}) does not match export {n} ({exportKeyword})')
602
+ symbolRecord['import'] = exportRecord
603
+ return self.nextPC()
565
604
 
566
605
  # Increment a variable
567
606
  def k_increment(self, command):
@@ -646,9 +685,17 @@ class Core(Handler):
646
685
  self.putSymbolValue(symbolRecord, value)
647
686
  return self.nextPC()
648
687
 
649
- # Load a variable from a file
688
+ # 1 Load a plugin. This is done at compile time.
689
+ # 2 Load text from a file
650
690
  def k_load(self, command):
651
- if self.nextIsSymbol():
691
+ self.nextToken()
692
+ if self.tokenIs('plugin'):
693
+ clazz = self.nextToken()
694
+ if self.nextIs('from'):
695
+ source = self.nextToken()
696
+ self.program.importPlugin(f'{source}:{clazz}')
697
+ return True
698
+ elif self.isSymbol():
652
699
  command['target'] = self.getToken()
653
700
  if self.nextIs('from'):
654
701
  command['file'] = self.nextValue()
@@ -668,6 +715,27 @@ class Core(Handler):
668
715
  self.putSymbolValue(target, value)
669
716
  return self.nextPC()
670
717
 
718
+ # Lock a variable
719
+ def k_lock(self, command):
720
+ if self.nextIsSymbol():
721
+ symbolRecord = self.getSymbolRecord()
722
+ command['target'] = symbolRecord['name']
723
+ self.add(command)
724
+ return True
725
+ return False
726
+
727
+ def r_lock(self, command):
728
+ target = self.getVariable(command['target'])
729
+ target['locked'] = True
730
+ return self.nextPC()
731
+
732
+ # Declare a module variable
733
+ def k_module(self, command):
734
+ return self.compileVariable(command)
735
+
736
+ def r_module(self, command):
737
+ return self.nextPC()
738
+
671
739
  # Arithmetic multiply
672
740
  # multiply {variable} by {value}[ giving {variable}]}
673
741
  def k_multiply(self, command):
@@ -749,6 +817,36 @@ class Core(Handler):
749
817
  def r_object(self, command):
750
818
  return self.nextPC()
751
819
 
820
+ # on message {action}
821
+ def k_on(self, command):
822
+ if self.nextIs('message'):
823
+ self.nextToken()
824
+ command['goto'] = 0
825
+ self.add(command)
826
+ cmd = {}
827
+ cmd['domain'] = 'core'
828
+ cmd['lino'] = command['lino']
829
+ cmd['keyword'] = 'gotoPC'
830
+ cmd['goto'] = 0
831
+ cmd['debug'] = False
832
+ self.addCommand(cmd)
833
+ # Add the action and a 'stop'
834
+ self.compileOne()
835
+ cmd = {}
836
+ cmd['domain'] = 'core'
837
+ cmd['lino'] = command['lino']
838
+ cmd['keyword'] = 'stop'
839
+ cmd['debug'] = False
840
+ self.addCommand(cmd)
841
+ # Fixup the link
842
+ command['goto'] = self.getPC()
843
+ return True
844
+ return False
845
+
846
+ def r_on(self, command):
847
+ self.program.onMessage(self.nextPC()+1)
848
+ return command['goto']
849
+
752
850
  # Open a file
753
851
  # open {file} for reading/writing/appending
754
852
  def k_open(self, command):
@@ -941,13 +1039,13 @@ class Core(Handler):
941
1039
  if self.nextIsSymbol():
942
1040
  symbolRecord = self.getSymbolRecord()
943
1041
  command['target'] = symbolRecord['name']
944
- if symbolRecord['valueHolder']:
1042
+ if 'valueholder' in symbolRecord and symbolRecord['valueHolder'] == False:
1043
+ FatalError(self.program.compiler, f'Symbol {symbolRecord["name"]} is not a value holder')
1044
+ else:
945
1045
  self.add(command)
946
1046
  return True
947
- else:
948
- FatalError(self.program.compiler, f'Symbol {symbolRecord["name"]} is not a value holder')
949
1047
  else:
950
- FatalError(self.program.compiler, f'No such variable: "{self.getToken()}"')
1048
+ FatalError(self.program.compiler, f'Symbol {self.getToken()} is not a variable')
951
1049
  return False
952
1050
 
953
1051
  def r_put(self, command):
@@ -1030,6 +1128,16 @@ class Core(Handler):
1030
1128
  self.putSymbolValue(templateRecord, value)
1031
1129
  return self.nextPC()
1032
1130
 
1131
+ # Release the parent script
1132
+ def k_release(self, command):
1133
+ if self.nextIs('parent'):
1134
+ self.add(command)
1135
+ return True
1136
+
1137
+ def r_release(self, command):
1138
+ self.program.releaseParent()
1139
+ return self.nextPC()
1140
+
1033
1141
  # Return from subroutine
1034
1142
  def k_return(self, command):
1035
1143
  self.add(command)
@@ -1038,6 +1146,47 @@ class Core(Handler):
1038
1146
  def r_return(self, command):
1039
1147
  return self.stack.pop()
1040
1148
 
1149
+ # Compile and run a script
1150
+ def k_run(self, command):
1151
+ try:
1152
+ command['path'] = self.nextValue()
1153
+ except Exception as e:
1154
+ self.warning(f'Core.run: Path expected')
1155
+ return False
1156
+ if self.nextIs('as'):
1157
+ if self.nextIsSymbol():
1158
+ record = self.getSymbolRecord()
1159
+ if record['keyword'] == 'module':
1160
+ command['module'] = record['name']
1161
+ exports = []
1162
+ if self.nextIs('with'):
1163
+ while True:
1164
+ name = self.nextToken()
1165
+ record = self.getSymbolRecord()
1166
+ exports.append(name)
1167
+ if self.peek() != 'and':
1168
+ break
1169
+ self.nextToken()
1170
+ command['exports'] = json.dumps(exports)
1171
+ self.add(command)
1172
+ return True
1173
+ return False
1174
+
1175
+ def r_run(self, command):
1176
+ module = self.getVariable(command['module'])
1177
+ path = self.getRuntimeValue(command['path'])
1178
+ exports = json.loads(command['exports'])
1179
+ for n in range(0, len(exports)):
1180
+ exports[n] = self.getVariable(exports[n])
1181
+ module['path'] = path
1182
+ parent = Object()
1183
+ parent.program = self.program
1184
+ parent.pc = self.nextPC()
1185
+ parent.waiting = True
1186
+ p = self.program.__class__
1187
+ p(path).start(parent, module, exports)
1188
+ return 0
1189
+
1041
1190
  # Provide a name for the script
1042
1191
  def k_script(self, command):
1043
1192
  self.program.name = self.nextToken()
@@ -1060,6 +1209,24 @@ class Core(Handler):
1060
1209
  f.close()
1061
1210
  return self.nextPC()
1062
1211
 
1212
+ # Send a message to a module
1213
+ def k_send(self, command):
1214
+ command['message'] = self.nextValue()
1215
+ if self.nextIs('to'):
1216
+ if self.nextIsSymbol():
1217
+ record = self.getSymbolRecord()
1218
+ if record['keyword'] == 'module':
1219
+ command['module'] = record['name']
1220
+ self.add(command)
1221
+ return True
1222
+ return False
1223
+
1224
+ def r_send(self, command):
1225
+ message = self.getRuntimeValue(command['message'])
1226
+ module = self.getVariable(command['module'])
1227
+ module['child'].handleMessage(message)
1228
+ return self.nextPC()
1229
+
1063
1230
  # Set a value
1064
1231
  # set {variable}
1065
1232
  # set the elements of {variable} to {value}
@@ -1364,6 +1531,20 @@ class Core(Handler):
1364
1531
  fileRecord['file'].truncate()
1365
1532
  return self.nextPC()
1366
1533
 
1534
+ # Unlock a variable
1535
+ def k_unlock(self, command):
1536
+ if self.nextIsSymbol():
1537
+ symbolRecord = self.getSymbolRecord()
1538
+ command['target'] = symbolRecord['name']
1539
+ self.add(command)
1540
+ return True
1541
+ return False
1542
+
1543
+ def r_unlock(self, command):
1544
+ target = self.getVariable(command['target'])
1545
+ target['locked'] = False
1546
+ return self.nextPC()
1547
+
1367
1548
  # Declare a general-purpose variable
1368
1549
  def k_variable(self, command):
1369
1550
  return self.compileVariable(command, True)
@@ -1669,7 +1850,6 @@ class Core(Handler):
1669
1850
  return value
1670
1851
 
1671
1852
  if token == 'message':
1672
- self.nextToken()
1673
1853
  return value
1674
1854
 
1675
1855
  if token == 'timestamp':
@@ -1975,6 +2155,12 @@ class Core(Handler):
1975
2155
  value['content'] = megabytes
1976
2156
  return value
1977
2157
 
2158
+ def v_message(self, v):
2159
+ value = {}
2160
+ value['type'] = 'text'
2161
+ value['content'] = self.program.message
2162
+ return value
2163
+
1978
2164
  def v_modification(self, v):
1979
2165
  fileName = self.getRuntimeValue(v['fileName'])
1980
2166
  ts = int(os.stat(fileName).st_mtime)