easycoder 250103.2__tar.gz → 250104.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-250104.1}/PKG-INFO +19 -5
  2. {easycoder-250103.2 → easycoder-250104.1}/README.md +18 -4
  3. {easycoder-250103.2 → easycoder-250104.1}/doc/core/README.md +1 -1
  4. {easycoder-250103.2 → easycoder-250104.1}/doc/core/keywords/import.md +6 -0
  5. {easycoder-250103.2 → easycoder-250104.1}/doc/core/keywords/load.md +1 -1
  6. easycoder-250104.1/doc/core/keywords/lock.md +15 -0
  7. easycoder-250104.1/doc/core/keywords/module.md +17 -0
  8. {easycoder-250103.2 → easycoder-250104.1}/doc/core/keywords/multiply.md +1 -1
  9. {easycoder-250103.2 → easycoder-250104.1}/doc/core/keywords/read.md +1 -1
  10. easycoder-250104.1/doc/core/keywords/release.md +15 -0
  11. {easycoder-250103.2 → easycoder-250104.1}/doc/core/keywords/replace.md +1 -1
  12. {easycoder-250103.2 → easycoder-250104.1}/doc/core/keywords/return.md +1 -1
  13. easycoder-250104.1/doc/core/keywords/run.md +15 -0
  14. {easycoder-250103.2 → easycoder-250104.1}/doc/core/keywords/save.md +1 -1
  15. {easycoder-250103.2 → easycoder-250104.1}/doc/core/keywords/truncate.md +1 -1
  16. easycoder-250104.1/doc/core/keywords/unlock.md +15 -0
  17. {easycoder-250103.2 → easycoder-250104.1}/doc/core/keywords/variable.md +1 -1
  18. {easycoder-250103.2 → easycoder-250104.1}/easycoder/__init__.py +1 -1
  19. {easycoder-250103.2 → easycoder-250104.1}/easycoder/ec_compiler.py +3 -0
  20. {easycoder-250103.2 → easycoder-250104.1}/easycoder/ec_core.py +135 -13
  21. {easycoder-250103.2 → easycoder-250104.1}/easycoder/ec_graphics.py +39 -11
  22. {easycoder-250103.2 → easycoder-250104.1}/easycoder/ec_program.py +80 -48
  23. {easycoder-250103.2 → easycoder-250104.1}/LICENSE +0 -0
  24. {easycoder-250103.2 → easycoder-250104.1}/doc/README.md +0 -0
  25. {easycoder-250103.2 → easycoder-250104.1}/doc/core/conditions/boolean.md +0 -0
  26. {easycoder-250103.2 → easycoder-250104.1}/doc/core/conditions/empty.md +0 -0
  27. {easycoder-250103.2 → easycoder-250104.1}/doc/core/conditions/ends.md +0 -0
  28. {easycoder-250103.2 → easycoder-250104.1}/doc/core/conditions/even.md +0 -0
  29. {easycoder-250103.2 → easycoder-250104.1}/doc/core/conditions/exists.md +0 -0
  30. {easycoder-250103.2 → easycoder-250104.1}/doc/core/conditions/greater.md +0 -0
  31. {easycoder-250103.2 → easycoder-250104.1}/doc/core/conditions/hasProperty.md +0 -0
  32. {easycoder-250103.2 → easycoder-250104.1}/doc/core/conditions/includes.md +0 -0
  33. {easycoder-250103.2 → easycoder-250104.1}/doc/core/conditions/is.md +0 -0
  34. {easycoder-250103.2 → easycoder-250104.1}/doc/core/conditions/less.md +0 -0
  35. {easycoder-250103.2 → easycoder-250104.1}/doc/core/conditions/list.md +0 -0
  36. {easycoder-250103.2 → easycoder-250104.1}/doc/core/conditions/none.md +0 -0
  37. {easycoder-250103.2 → easycoder-250104.1}/doc/core/conditions/not.md +0 -0
  38. {easycoder-250103.2 → easycoder-250104.1}/doc/core/conditions/numeric.md +0 -0
  39. {easycoder-250103.2 → easycoder-250104.1}/doc/core/conditions/object.md +0 -0
  40. {easycoder-250103.2 → easycoder-250104.1}/doc/core/conditions/odd.md +0 -0
  41. {easycoder-250103.2 → easycoder-250104.1}/doc/core/conditions/starts.md +0 -0
  42. {easycoder-250103.2 → easycoder-250104.1}/doc/core/conditions/string.md +0 -0
  43. {easycoder-250103.2 → easycoder-250104.1}/doc/core/keywords/add.md +0 -0
  44. {easycoder-250103.2 → easycoder-250104.1}/doc/core/keywords/append.md +0 -0
  45. {easycoder-250103.2 → easycoder-250104.1}/doc/core/keywords/assert.md +0 -0
  46. {easycoder-250103.2 → easycoder-250104.1}/doc/core/keywords/begin.md +0 -0
  47. {easycoder-250103.2 → easycoder-250104.1}/doc/core/keywords/clear.md +0 -0
  48. {easycoder-250103.2 → easycoder-250104.1}/doc/core/keywords/close.md +0 -0
  49. {easycoder-250103.2 → easycoder-250104.1}/doc/core/keywords/create.md +0 -0
  50. {easycoder-250103.2 → easycoder-250104.1}/doc/core/keywords/debug.md +0 -0
  51. {easycoder-250103.2 → easycoder-250104.1}/doc/core/keywords/decrement.md +0 -0
  52. {easycoder-250103.2 → easycoder-250104.1}/doc/core/keywords/delete.md +0 -0
  53. {easycoder-250103.2 → easycoder-250104.1}/doc/core/keywords/divide.md +0 -0
  54. {easycoder-250103.2 → easycoder-250104.1}/doc/core/keywords/exit.md +0 -0
  55. {easycoder-250103.2 → easycoder-250104.1}/doc/core/keywords/file.md +0 -0
  56. {easycoder-250103.2 → easycoder-250104.1}/doc/core/keywords/fork.md +0 -0
  57. {easycoder-250103.2 → easycoder-250104.1}/doc/core/keywords/get.md +0 -0
  58. {easycoder-250103.2 → easycoder-250104.1}/doc/core/keywords/go.md +0 -0
  59. {easycoder-250103.2 → easycoder-250104.1}/doc/core/keywords/gosub.md +0 -0
  60. {easycoder-250103.2 → easycoder-250104.1}/doc/core/keywords/if.md +0 -0
  61. {easycoder-250103.2 → easycoder-250104.1}/doc/core/keywords/increment.md +0 -0
  62. {easycoder-250103.2 → easycoder-250104.1}/doc/core/keywords/index.md +0 -0
  63. {easycoder-250103.2 → easycoder-250104.1}/doc/core/keywords/init.md +0 -0
  64. {easycoder-250103.2 → easycoder-250104.1}/doc/core/keywords/input.md +0 -0
  65. {easycoder-250103.2 → easycoder-250104.1}/doc/core/keywords/negate.md +0 -0
  66. {easycoder-250103.2 → easycoder-250104.1}/doc/core/keywords/open.md +0 -0
  67. {easycoder-250103.2 → easycoder-250104.1}/doc/core/keywords/pop.md +0 -0
  68. {easycoder-250103.2 → easycoder-250104.1}/doc/core/keywords/post.md +0 -0
  69. {easycoder-250103.2 → easycoder-250104.1}/doc/core/keywords/print.md +0 -0
  70. {easycoder-250103.2 → easycoder-250104.1}/doc/core/keywords/push.md +0 -0
  71. {easycoder-250103.2 → easycoder-250104.1}/doc/core/keywords/put.md +0 -0
  72. {easycoder-250103.2 → easycoder-250104.1}/doc/core/keywords/script.md +0 -0
  73. {easycoder-250103.2 → easycoder-250104.1}/doc/core/keywords/set.md +0 -0
  74. {easycoder-250103.2 → easycoder-250104.1}/doc/core/keywords/split.md +0 -0
  75. {easycoder-250103.2 → easycoder-250104.1}/doc/core/keywords/stack.md +0 -0
  76. {easycoder-250103.2 → easycoder-250104.1}/doc/core/keywords/stop.md +0 -0
  77. {easycoder-250103.2 → easycoder-250104.1}/doc/core/keywords/system.md +0 -0
  78. {easycoder-250103.2 → easycoder-250104.1}/doc/core/keywords/take.md +0 -0
  79. {easycoder-250103.2 → easycoder-250104.1}/doc/core/keywords/toggle.md +0 -0
  80. {easycoder-250103.2 → easycoder-250104.1}/doc/core/keywords/wait.md +0 -0
  81. {easycoder-250103.2 → easycoder-250104.1}/doc/core/keywords/while.md +0 -0
  82. {easycoder-250103.2 → easycoder-250104.1}/doc/core/keywords/write.md +0 -0
  83. {easycoder-250103.2 → easycoder-250104.1}/doc/core/values/arg.md +0 -0
  84. {easycoder-250103.2 → easycoder-250104.1}/doc/core/values/args.md +0 -0
  85. {easycoder-250103.2 → easycoder-250104.1}/doc/core/values/cos.md +0 -0
  86. {easycoder-250103.2 → easycoder-250104.1}/doc/core/values/datime.md +0 -0
  87. {easycoder-250103.2 → easycoder-250104.1}/doc/core/values/decode.md +0 -0
  88. {easycoder-250103.2 → easycoder-250104.1}/doc/core/values/element.md +0 -0
  89. {easycoder-250103.2 → easycoder-250104.1}/doc/core/values/elements.md +0 -0
  90. {easycoder-250103.2 → easycoder-250104.1}/doc/core/values/empty.md +0 -0
  91. {easycoder-250103.2 → easycoder-250104.1}/doc/core/values/encode.md +0 -0
  92. {easycoder-250103.2 → easycoder-250104.1}/doc/core/values/error.md +0 -0
  93. {easycoder-250103.2 → easycoder-250104.1}/doc/core/values/files.md +0 -0
  94. {easycoder-250103.2 → easycoder-250104.1}/doc/core/values/float.md +0 -0
  95. {easycoder-250103.2 → easycoder-250104.1}/doc/core/values/from.md +0 -0
  96. {easycoder-250103.2 → easycoder-250104.1}/doc/core/values/hash.md +0 -0
  97. {easycoder-250103.2 → easycoder-250104.1}/doc/core/values/index.md +0 -0
  98. {easycoder-250103.2 → easycoder-250104.1}/doc/core/values/integer.md +0 -0
  99. {easycoder-250103.2 → easycoder-250104.1}/doc/core/values/json.md +0 -0
  100. {easycoder-250103.2 → easycoder-250104.1}/doc/core/values/keys.md +0 -0
  101. {easycoder-250103.2 → easycoder-250104.1}/doc/core/values/left.md +0 -0
  102. {easycoder-250103.2 → easycoder-250104.1}/doc/core/values/length.md +0 -0
  103. {easycoder-250103.2 → easycoder-250104.1}/doc/core/values/lowercase.md +0 -0
  104. {easycoder-250103.2 → easycoder-250104.1}/doc/core/values/memory.md +0 -0
  105. {easycoder-250103.2 → easycoder-250104.1}/doc/core/values/modification.md +0 -0
  106. {easycoder-250103.2 → easycoder-250104.1}/doc/core/values/modulo.md +0 -0
  107. {easycoder-250103.2 → easycoder-250104.1}/doc/core/values/newline.md +0 -0
  108. {easycoder-250103.2 → easycoder-250104.1}/doc/core/values/now.md +0 -0
  109. {easycoder-250103.2 → easycoder-250104.1}/doc/core/values/position.md +0 -0
  110. {easycoder-250103.2 → easycoder-250104.1}/doc/core/values/property.md +0 -0
  111. {easycoder-250103.2 → easycoder-250104.1}/doc/core/values/random.md +0 -0
  112. {easycoder-250103.2 → easycoder-250104.1}/doc/core/values/right.md +0 -0
  113. {easycoder-250103.2 → easycoder-250104.1}/doc/core/values/sin.md +0 -0
  114. {easycoder-250103.2 → easycoder-250104.1}/doc/core/values/stringify.md +0 -0
  115. {easycoder-250103.2 → easycoder-250104.1}/doc/core/values/tab.md +0 -0
  116. {easycoder-250103.2 → easycoder-250104.1}/doc/core/values/tan.md +0 -0
  117. {easycoder-250103.2 → easycoder-250104.1}/doc/core/values/timestamp.md +0 -0
  118. {easycoder-250103.2 → easycoder-250104.1}/doc/core/values/today.md +0 -0
  119. {easycoder-250103.2 → easycoder-250104.1}/doc/core/values/trim.md +0 -0
  120. {easycoder-250103.2 → easycoder-250104.1}/doc/core/values/type.md +0 -0
  121. {easycoder-250103.2 → easycoder-250104.1}/doc/core/values/uppercase.md +0 -0
  122. {easycoder-250103.2 → easycoder-250104.1}/doc/core/values/value.md +0 -0
  123. {easycoder-250103.2 → easycoder-250104.1}/doc/core/values/weekday.md +0 -0
  124. {easycoder-250103.2 → easycoder-250104.1}/doc/graphics/README.md +0 -0
  125. {easycoder-250103.2 → easycoder-250104.1}/easycoder/README.md +0 -0
  126. {easycoder-250103.2 → easycoder-250104.1}/easycoder/ec.py +0 -0
  127. {easycoder-250103.2 → easycoder-250104.1}/easycoder/ec_classes.py +0 -0
  128. {easycoder-250103.2 → easycoder-250104.1}/easycoder/ec_condition.py +0 -0
  129. {easycoder-250103.2 → easycoder-250104.1}/easycoder/ec_handler.py +0 -0
  130. {easycoder-250103.2 → easycoder-250104.1}/easycoder/ec_renderer.py +1 -1
  131. {easycoder-250103.2 → easycoder-250104.1}/easycoder/ec_screenspec.py +0 -0
  132. {easycoder-250103.2 → easycoder-250104.1}/easycoder/ec_timestamp.py +0 -0
  133. {easycoder-250103.2 → easycoder-250104.1}/easycoder/ec_value.py +0 -0
  134. {easycoder-250103.2 → easycoder-250104.1}/images/Semoigo Dawn.jpg +0 -0
  135. {easycoder-250103.2 → easycoder-250104.1}/json/graphics-demo.json +0 -0
  136. {easycoder-250103.2 → easycoder-250104.1}/plugins/ec_p100.py +0 -0
  137. {easycoder-250103.2 → easycoder-250104.1}/plugins/example.py +0 -0
  138. {easycoder-250103.2 → easycoder-250104.1}/pyproject.toml +0 -0
  139. {easycoder-250103.2 → easycoder-250104.1}/scripts/README.md +0 -0
  140. {easycoder-250103.2 → easycoder-250104.1}/scripts/benchmark.ecs +0 -0
  141. {easycoder-250103.2 → easycoder-250104.1}/scripts/fizzbuzz.ecs +0 -0
  142. {easycoder-250103.2 → easycoder-250104.1}/scripts/graphics-demo.ecg +0 -0
  143. {easycoder-250103.2 → easycoder-250104.1}/scripts/hello.ecs +0 -0
  144. {easycoder-250103.2 → easycoder-250104.1}/scripts/points.ecs +0 -0
  145. {easycoder-250103.2 → easycoder-250104.1}/scripts/tests.ecs +0 -0
  146. {easycoder-250103.2 → easycoder-250104.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: 250104.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 {module} as {name} [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 [release](release.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__ = "250104.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,45 @@ 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}
555
+ # Import one or more variables
558
556
  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}')
563
- return True
564
- return False
557
+ imports = []
558
+ while True:
559
+ keyword = self.nextToken()
560
+ name = self.nextToken()
561
+ item = [keyword, name]
562
+ imports.append(item)
563
+ self.symbols[name] = self.getPC()
564
+ variable = {}
565
+ variable['domain'] = None
566
+ variable['name'] = name
567
+ variable['keyword'] = keyword
568
+ variable['import'] = None
569
+ self.addCommand(variable)
570
+ if self.peek() != 'and':
571
+ break
572
+ self.nextToken()
573
+ command['imports'] = json.dumps(imports)
574
+ self.add(command)
575
+ return True
576
+
577
+ def r_import(self, command):
578
+ exports = self.program.exports
579
+ imports = json.loads(command['imports'])
580
+ if len(imports) < len(exports):
581
+ RuntimeError(self.program, 'Too few imports')
582
+ elif len(imports) > len(exports):
583
+ RuntimeError(self.program, 'Too many imports')
584
+ for n in range(0, len(imports)):
585
+ exportRecord = exports[n]
586
+ exportKeyword = exportRecord['keyword']
587
+ name = imports[n][1]
588
+ symbolRecord = self.program.getSymbolRecord(name)
589
+ symbolKeyword = symbolRecord['keyword']
590
+ if symbolKeyword != exportKeyword:
591
+ RuntimeError(self.program, f'Import {n} ({symbolKeyword}) does not match export {n} ({exportKeyword})')
592
+ symbolRecord['import'] = exportRecord
593
+ return self.nextPC()
565
594
 
566
595
  # Increment a variable
567
596
  def k_increment(self, command):
@@ -646,9 +675,17 @@ class Core(Handler):
646
675
  self.putSymbolValue(symbolRecord, value)
647
676
  return self.nextPC()
648
677
 
649
- # Load a variable from a file
678
+ # 1 Load a plugin. This is done at compile time.
679
+ # 2 Load text from a file
650
680
  def k_load(self, command):
651
- if self.nextIsSymbol():
681
+ self.nextToken()
682
+ if self.tokenIs('plugin'):
683
+ clazz = self.nextToken()
684
+ if self.nextIs('from'):
685
+ source = self.nextToken()
686
+ self.program.importPlugin(f'{source}:{clazz}')
687
+ return True
688
+ elif self.isSymbol():
652
689
  command['target'] = self.getToken()
653
690
  if self.nextIs('from'):
654
691
  command['file'] = self.nextValue()
@@ -657,8 +694,11 @@ class Core(Handler):
657
694
  return False
658
695
 
659
696
  def r_load(self, command):
697
+ print(command)
660
698
  target = self.getVariable(command['target'])
699
+ print(target)
661
700
  file = self.getRuntimeValue(command['file'])
701
+ print(file)
662
702
  f = open(file, 'r')
663
703
  content = f.read()
664
704
  f.close()
@@ -668,6 +708,27 @@ class Core(Handler):
668
708
  self.putSymbolValue(target, value)
669
709
  return self.nextPC()
670
710
 
711
+ # Lock a variable
712
+ def k_lock(self, command):
713
+ if self.nextIsSymbol():
714
+ symbolRecord = self.getSymbolRecord()
715
+ command['target'] = symbolRecord['name']
716
+ self.add(command)
717
+ return True
718
+ return False
719
+
720
+ def r_lock(self, command):
721
+ target = self.getVariable(command['target'])
722
+ target['locked'] = True
723
+ return self.nextPC()
724
+
725
+ # Declare a module variable
726
+ def k_module(self, command):
727
+ return self.compileVariable(command)
728
+
729
+ def r_module(self, command):
730
+ return self.nextPC()
731
+
671
732
  # Arithmetic multiply
672
733
  # multiply {variable} by {value}[ giving {variable}]}
673
734
  def k_multiply(self, command):
@@ -1030,6 +1091,16 @@ class Core(Handler):
1030
1091
  self.putSymbolValue(templateRecord, value)
1031
1092
  return self.nextPC()
1032
1093
 
1094
+ # Release the parent script
1095
+ def k_release(self, command):
1096
+ if self.nextIs('parent'):
1097
+ self.add(command)
1098
+ return True
1099
+
1100
+ def r_release(self, command):
1101
+ self.program.releaseParent()
1102
+ return self.nextPC()
1103
+
1033
1104
  # Return from subroutine
1034
1105
  def k_return(self, command):
1035
1106
  self.add(command)
@@ -1038,6 +1109,43 @@ class Core(Handler):
1038
1109
  def r_return(self, command):
1039
1110
  return self.stack.pop()
1040
1111
 
1112
+ # Compile and run a script
1113
+ def k_run(self, command):
1114
+ if self.nextIsSymbol():
1115
+ record = self.getSymbolRecord()
1116
+ if record['keyword'] == 'module':
1117
+ command['target'] = record['name']
1118
+ if self.nextIs('as'):
1119
+ command['path'] = self.nextValue()
1120
+ exports = []
1121
+ if self.nextIs('with'):
1122
+ while True:
1123
+ name = self.nextToken()
1124
+ record = self.getSymbolRecord()
1125
+ exports.append(name)
1126
+ if self.peek() != 'and':
1127
+ break
1128
+ self.nextToken()
1129
+ command['exports'] = json.dumps(exports)
1130
+ self.add(command)
1131
+ return True
1132
+ return False
1133
+
1134
+ def r_run(self, command):
1135
+ target = self.getVariable(command['target'])
1136
+ path = self.getRuntimeValue(command['path'])
1137
+ exports = json.loads(command['exports'])
1138
+ for n in range(0, len(exports)):
1139
+ exports[n] = self.getVariable(exports[n])
1140
+ target['path'] = path
1141
+ parent = Object()
1142
+ parent.program = self.program
1143
+ parent.pc = self.nextPC()
1144
+ parent.waiting = True
1145
+ p = self.program.__class__
1146
+ p(path).start(parent, exports)
1147
+ return 0
1148
+
1041
1149
  # Provide a name for the script
1042
1150
  def k_script(self, command):
1043
1151
  self.program.name = self.nextToken()
@@ -1364,6 +1472,20 @@ class Core(Handler):
1364
1472
  fileRecord['file'].truncate()
1365
1473
  return self.nextPC()
1366
1474
 
1475
+ # Unlock a variable
1476
+ def k_unlock(self, command):
1477
+ if self.nextIsSymbol():
1478
+ symbolRecord = self.getSymbolRecord()
1479
+ command['target'] = symbolRecord['name']
1480
+ self.add(command)
1481
+ return True
1482
+ return False
1483
+
1484
+ def r_unlock(self, command):
1485
+ target = self.getVariable(command['target'])
1486
+ target['locked'] = False
1487
+ return self.nextPC()
1488
+
1367
1489
  # Declare a general-purpose variable
1368
1490
  def k_variable(self, command):
1369
1491
  return self.compileVariable(command, True)
@@ -1,7 +1,9 @@
1
+ import sys, threading, json
1
2
  from .ec_classes import FatalError, RuntimeError, Object
2
3
  from .ec_handler import Handler
3
4
  from .ec_screenspec import ScreenSpec
4
5
  from .ec_renderer import Renderer
6
+ from .ec_program import flush
5
7
 
6
8
  class Graphics(Handler):
7
9
 
@@ -173,7 +175,7 @@ class Graphics(Handler):
173
175
  if type == 'window':
174
176
  self.windowSpec = Object()
175
177
  self.windowSpec.title = command['title']['content']
176
- self.windowSpec.flush = self.program.flush
178
+ self.windowSpec.flush = flush
177
179
  self.windowSpec.finish = self.program.finish
178
180
  self.windowSpec.pos = (self.getRuntimeValue(command['pos'][0]), self.getRuntimeValue(command['pos'][1]))
179
181
  self.windowSpec.size = (self.getRuntimeValue(command['size'][0]), self.getRuntimeValue(command['size'][1]))
@@ -219,7 +221,7 @@ class Graphics(Handler):
219
221
  if self.nextIsSymbol():
220
222
  record = self.getSymbolRecord()
221
223
  type = record['keyword']
222
- if type in ['ellipse', 'rectangle']:
224
+ if self.isGraphicType(type):
223
225
  command['target'] = record['id']
224
226
  token = self.nextToken()
225
227
  if token == 'to':
@@ -283,7 +285,7 @@ class Graphics(Handler):
283
285
  if command['type'] == 'tap':
284
286
  record = self.getVariable(command['target'])
285
287
  keyword = record['keyword']
286
- if keyword in ['ellipse', 'rectangle', 'text', 'image']:
288
+ if self.isGraphicType(keyword):
287
289
  id = record['value'][record['index']]['content']
288
290
  self.ui.setOnClick(id, lambda: self.run(pc))
289
291
  else:
@@ -296,12 +298,6 @@ class Graphics(Handler):
296
298
  def r_rectangle(self, command):
297
299
  return self.nextPC()
298
300
 
299
- def k_text(self, command):
300
- return self.compileVariable(command)
301
-
302
- def r_text(self, command):
303
- return self.nextPC()
304
-
305
301
  # render {spec}
306
302
  def k_render(self, command):
307
303
  command['spec'] = self.nextValue()
@@ -332,6 +328,7 @@ class Graphics(Handler):
332
328
  def r_run(self, command):
333
329
  self.renderer = Renderer()
334
330
  self.renderer.init(self.windowSpec)
331
+ self.ui = self.renderer.getUI()
335
332
  self.program.setExternalControl()
336
333
  self.program.run(self.nextPC())
337
334
  self.renderer.run()
@@ -343,7 +340,7 @@ class Graphics(Handler):
343
340
  if self.nextIs('of'):
344
341
  if self.nextIsSymbol():
345
342
  record = self.getSymbolRecord()
346
- if record['keyword'] in ['ellipse', 'rectangle', 'text', 'image']:
343
+ if self.isGraphicType(record['keyword']):
347
344
  command['target'] = record['name']
348
345
  if self.nextIs('to'):
349
346
  command['value'] = self.nextValue()
@@ -363,6 +360,12 @@ class Graphics(Handler):
363
360
  self.ui.setAttribute(id, attribute, value)
364
361
  return self.nextPC()
365
362
 
363
+ def k_text(self, command):
364
+ return self.compileVariable(command)
365
+
366
+ def r_text(self, command):
367
+ return self.nextPC()
368
+
366
369
  #############################################################################
367
370
  # Modify a value or leave it unchanged.
368
371
  def modifyValue(self, value):
@@ -373,6 +376,16 @@ class Graphics(Handler):
373
376
  def compileValue(self):
374
377
  value = {}
375
378
  value['domain'] = self.getName()
379
+ token = self.getToken()
380
+ if self.isSymbol():
381
+ value['name'] = token
382
+ symbolRecord = self.getSymbolRecord()
383
+ keyword = symbolRecord['keyword']
384
+ if keyword == 'graphic':
385
+ value['type'] = 'symbol'
386
+ return value
387
+ return None
388
+
376
389
  if self.tokenIs('the'):
377
390
  self.nextToken()
378
391
  kwd = self.getToken()
@@ -382,7 +395,7 @@ class Graphics(Handler):
382
395
  if self.nextIs('of'):
383
396
  if self.nextIsSymbol():
384
397
  record = self.getSymbolRecord()
385
- if record['keyword'] in ['ellipse', 'rectangle']:
398
+ if self.isGraphicType(record['keyword']):
386
399
  value['attribute'] = attribute
387
400
  value['target'] = record['name']
388
401
  return value
@@ -393,6 +406,12 @@ class Graphics(Handler):
393
406
  return value
394
407
  return None
395
408
 
409
+ #############################################################################
410
+ # Test if a graphic type
411
+
412
+ def isGraphicType(self, type):
413
+ return type in ['ellipse', 'rectangle', 'text', 'image']
414
+
396
415
  #############################################################################
397
416
  # Value handlers
398
417
 
@@ -409,6 +428,15 @@ class Graphics(Handler):
409
428
  except Exception as e:
410
429
  RuntimeError(self.program, e)
411
430
 
431
+ # This is used by the expression evaluator to get the value of a symbol
432
+ def v_symbol(self, symbolRecord):
433
+ result = {}
434
+ if symbolRecord['keyword'] == 'graphic':
435
+ symbolValue = self.getSymbolValue(symbolRecord)
436
+ return symbolValue
437
+ else:
438
+ return None
439
+
412
440
  def v_window(self, v):
413
441
  try:
414
442
  attribute = v['attribute']