easycoder 251022.1__tar.gz → 251103.2__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 (174) hide show
  1. easycoder-251103.2/.github/copilot-instructions.md +112 -0
  2. {easycoder-251022.1 → easycoder-251103.2}/PKG-INFO +1 -1
  3. {easycoder-251022.1 → easycoder-251103.2}/easycoder/__init__.py +1 -1
  4. {easycoder-251022.1 → easycoder-251103.2}/easycoder/ec_compiler.py +9 -3
  5. {easycoder-251022.1 → easycoder-251103.2}/easycoder/ec_core.py +30 -7
  6. {easycoder-251022.1 → easycoder-251103.2}/easycoder/ec_handler.py +1 -1
  7. {easycoder-251022.1 → easycoder-251103.2}/easycoder/ec_program.py +2 -3
  8. {easycoder-251022.1 → easycoder-251103.2}/easycoder/ec_pyside.py +37 -16
  9. {easycoder-251022.1 → easycoder-251103.2}/.gitignore +0 -0
  10. {easycoder-251022.1 → easycoder-251103.2}/LICENSE +0 -0
  11. {easycoder-251022.1 → easycoder-251103.2}/README.md +0 -0
  12. {easycoder-251022.1 → easycoder-251103.2}/backdrop.jpg +0 -0
  13. {easycoder-251022.1 → easycoder-251103.2}/doc/README.md +0 -0
  14. {easycoder-251022.1 → easycoder-251103.2}/doc/core/README.md +0 -0
  15. {easycoder-251022.1 → easycoder-251103.2}/doc/core/conditions/boolean.md +0 -0
  16. {easycoder-251022.1 → easycoder-251103.2}/doc/core/conditions/empty.md +0 -0
  17. {easycoder-251022.1 → easycoder-251103.2}/doc/core/conditions/ends.md +0 -0
  18. {easycoder-251022.1 → easycoder-251103.2}/doc/core/conditions/even.md +0 -0
  19. {easycoder-251022.1 → easycoder-251103.2}/doc/core/conditions/exists.md +0 -0
  20. {easycoder-251022.1 → easycoder-251103.2}/doc/core/conditions/greater.md +0 -0
  21. {easycoder-251022.1 → easycoder-251103.2}/doc/core/conditions/hasProperty.md +0 -0
  22. {easycoder-251022.1 → easycoder-251103.2}/doc/core/conditions/includes.md +0 -0
  23. {easycoder-251022.1 → easycoder-251103.2}/doc/core/conditions/is.md +0 -0
  24. {easycoder-251022.1 → easycoder-251103.2}/doc/core/conditions/less.md +0 -0
  25. {easycoder-251022.1 → easycoder-251103.2}/doc/core/conditions/list.md +0 -0
  26. {easycoder-251022.1 → easycoder-251103.2}/doc/core/conditions/none.md +0 -0
  27. {easycoder-251022.1 → easycoder-251103.2}/doc/core/conditions/not.md +0 -0
  28. {easycoder-251022.1 → easycoder-251103.2}/doc/core/conditions/numeric.md +0 -0
  29. {easycoder-251022.1 → easycoder-251103.2}/doc/core/conditions/object.md +0 -0
  30. {easycoder-251022.1 → easycoder-251103.2}/doc/core/conditions/odd.md +0 -0
  31. {easycoder-251022.1 → easycoder-251103.2}/doc/core/conditions/starts.md +0 -0
  32. {easycoder-251022.1 → easycoder-251103.2}/doc/core/conditions/string.md +0 -0
  33. {easycoder-251022.1 → easycoder-251103.2}/doc/core/keywords/add.md +0 -0
  34. {easycoder-251022.1 → easycoder-251103.2}/doc/core/keywords/append.md +0 -0
  35. {easycoder-251022.1 → easycoder-251103.2}/doc/core/keywords/assert.md +0 -0
  36. {easycoder-251022.1 → easycoder-251103.2}/doc/core/keywords/begin.md +0 -0
  37. {easycoder-251022.1 → easycoder-251103.2}/doc/core/keywords/clear.md +0 -0
  38. {easycoder-251022.1 → easycoder-251103.2}/doc/core/keywords/close.md +0 -0
  39. {easycoder-251022.1 → easycoder-251103.2}/doc/core/keywords/create.md +0 -0
  40. {easycoder-251022.1 → easycoder-251103.2}/doc/core/keywords/debug.md +0 -0
  41. {easycoder-251022.1 → easycoder-251103.2}/doc/core/keywords/decrement.md +0 -0
  42. {easycoder-251022.1 → easycoder-251103.2}/doc/core/keywords/delete.md +0 -0
  43. {easycoder-251022.1 → easycoder-251103.2}/doc/core/keywords/divide.md +0 -0
  44. {easycoder-251022.1 → easycoder-251103.2}/doc/core/keywords/exit.md +0 -0
  45. {easycoder-251022.1 → easycoder-251103.2}/doc/core/keywords/file.md +0 -0
  46. {easycoder-251022.1 → easycoder-251103.2}/doc/core/keywords/fork.md +0 -0
  47. {easycoder-251022.1 → easycoder-251103.2}/doc/core/keywords/get.md +0 -0
  48. {easycoder-251022.1 → easycoder-251103.2}/doc/core/keywords/go.md +0 -0
  49. {easycoder-251022.1 → easycoder-251103.2}/doc/core/keywords/gosub.md +0 -0
  50. {easycoder-251022.1 → easycoder-251103.2}/doc/core/keywords/if.md +0 -0
  51. {easycoder-251022.1 → easycoder-251103.2}/doc/core/keywords/import.md +0 -0
  52. {easycoder-251022.1 → easycoder-251103.2}/doc/core/keywords/increment.md +0 -0
  53. {easycoder-251022.1 → easycoder-251103.2}/doc/core/keywords/index.md +0 -0
  54. {easycoder-251022.1 → easycoder-251103.2}/doc/core/keywords/init.md +0 -0
  55. {easycoder-251022.1 → easycoder-251103.2}/doc/core/keywords/input.md +0 -0
  56. {easycoder-251022.1 → easycoder-251103.2}/doc/core/keywords/load.md +0 -0
  57. {easycoder-251022.1 → easycoder-251103.2}/doc/core/keywords/lock.md +0 -0
  58. {easycoder-251022.1 → easycoder-251103.2}/doc/core/keywords/log.md +0 -0
  59. {easycoder-251022.1 → easycoder-251103.2}/doc/core/keywords/module.md +0 -0
  60. {easycoder-251022.1 → easycoder-251103.2}/doc/core/keywords/multiply.md +0 -0
  61. {easycoder-251022.1 → easycoder-251103.2}/doc/core/keywords/negate.md +0 -0
  62. {easycoder-251022.1 → easycoder-251103.2}/doc/core/keywords/on.md +0 -0
  63. {easycoder-251022.1 → easycoder-251103.2}/doc/core/keywords/open.md +0 -0
  64. {easycoder-251022.1 → easycoder-251103.2}/doc/core/keywords/pop.md +0 -0
  65. {easycoder-251022.1 → easycoder-251103.2}/doc/core/keywords/post.md +0 -0
  66. {easycoder-251022.1 → easycoder-251103.2}/doc/core/keywords/print.md +0 -0
  67. {easycoder-251022.1 → easycoder-251103.2}/doc/core/keywords/push.md +0 -0
  68. {easycoder-251022.1 → easycoder-251103.2}/doc/core/keywords/put.md +0 -0
  69. {easycoder-251022.1 → easycoder-251103.2}/doc/core/keywords/read.md +0 -0
  70. {easycoder-251022.1 → easycoder-251103.2}/doc/core/keywords/release.md +0 -0
  71. {easycoder-251022.1 → easycoder-251103.2}/doc/core/keywords/replace.md +0 -0
  72. {easycoder-251022.1 → easycoder-251103.2}/doc/core/keywords/return.md +0 -0
  73. {easycoder-251022.1 → easycoder-251103.2}/doc/core/keywords/run.md +0 -0
  74. {easycoder-251022.1 → easycoder-251103.2}/doc/core/keywords/save.md +0 -0
  75. {easycoder-251022.1 → easycoder-251103.2}/doc/core/keywords/script.md +0 -0
  76. {easycoder-251022.1 → easycoder-251103.2}/doc/core/keywords/send.md +0 -0
  77. {easycoder-251022.1 → easycoder-251103.2}/doc/core/keywords/set.md +0 -0
  78. {easycoder-251022.1 → easycoder-251103.2}/doc/core/keywords/shuffle.md +0 -0
  79. {easycoder-251022.1 → easycoder-251103.2}/doc/core/keywords/split.md +0 -0
  80. {easycoder-251022.1 → easycoder-251103.2}/doc/core/keywords/stack.md +0 -0
  81. {easycoder-251022.1 → easycoder-251103.2}/doc/core/keywords/stop.md +0 -0
  82. {easycoder-251022.1 → easycoder-251103.2}/doc/core/keywords/system.md +0 -0
  83. {easycoder-251022.1 → easycoder-251103.2}/doc/core/keywords/take.md +0 -0
  84. {easycoder-251022.1 → easycoder-251103.2}/doc/core/keywords/toggle.md +0 -0
  85. {easycoder-251022.1 → easycoder-251103.2}/doc/core/keywords/truncate.md +0 -0
  86. {easycoder-251022.1 → easycoder-251103.2}/doc/core/keywords/unlock.md +0 -0
  87. {easycoder-251022.1 → easycoder-251103.2}/doc/core/keywords/use.md +0 -0
  88. {easycoder-251022.1 → easycoder-251103.2}/doc/core/keywords/variable.md +0 -0
  89. {easycoder-251022.1 → easycoder-251103.2}/doc/core/keywords/wait.md +0 -0
  90. {easycoder-251022.1 → easycoder-251103.2}/doc/core/keywords/while.md +0 -0
  91. {easycoder-251022.1 → easycoder-251103.2}/doc/core/keywords/write.md +0 -0
  92. {easycoder-251022.1 → easycoder-251103.2}/doc/core/values/arg.md +0 -0
  93. {easycoder-251022.1 → easycoder-251103.2}/doc/core/values/args.md +0 -0
  94. {easycoder-251022.1 → easycoder-251103.2}/doc/core/values/cos.md +0 -0
  95. {easycoder-251022.1 → easycoder-251103.2}/doc/core/values/datime.md +0 -0
  96. {easycoder-251022.1 → easycoder-251103.2}/doc/core/values/decode.md +0 -0
  97. {easycoder-251022.1 → easycoder-251103.2}/doc/core/values/element.md +0 -0
  98. {easycoder-251022.1 → easycoder-251103.2}/doc/core/values/elements.md +0 -0
  99. {easycoder-251022.1 → easycoder-251103.2}/doc/core/values/empty.md +0 -0
  100. {easycoder-251022.1 → easycoder-251103.2}/doc/core/values/encode.md +0 -0
  101. {easycoder-251022.1 → easycoder-251103.2}/doc/core/values/error.md +0 -0
  102. {easycoder-251022.1 → easycoder-251103.2}/doc/core/values/files.md +0 -0
  103. {easycoder-251022.1 → easycoder-251103.2}/doc/core/values/float.md +0 -0
  104. {easycoder-251022.1 → easycoder-251103.2}/doc/core/values/from.md +0 -0
  105. {easycoder-251022.1 → easycoder-251103.2}/doc/core/values/hash.md +0 -0
  106. {easycoder-251022.1 → easycoder-251103.2}/doc/core/values/index.md +0 -0
  107. {easycoder-251022.1 → easycoder-251103.2}/doc/core/values/integer.md +0 -0
  108. {easycoder-251022.1 → easycoder-251103.2}/doc/core/values/json.md +0 -0
  109. {easycoder-251022.1 → easycoder-251103.2}/doc/core/values/keys.md +0 -0
  110. {easycoder-251022.1 → easycoder-251103.2}/doc/core/values/left.md +0 -0
  111. {easycoder-251022.1 → easycoder-251103.2}/doc/core/values/length.md +0 -0
  112. {easycoder-251022.1 → easycoder-251103.2}/doc/core/values/lowercase.md +0 -0
  113. {easycoder-251022.1 → easycoder-251103.2}/doc/core/values/memory.md +0 -0
  114. {easycoder-251022.1 → easycoder-251103.2}/doc/core/values/modification.md +0 -0
  115. {easycoder-251022.1 → easycoder-251103.2}/doc/core/values/modulo.md +0 -0
  116. {easycoder-251022.1 → easycoder-251103.2}/doc/core/values/newline.md +0 -0
  117. {easycoder-251022.1 → easycoder-251103.2}/doc/core/values/now.md +0 -0
  118. {easycoder-251022.1 → easycoder-251103.2}/doc/core/values/position.md +0 -0
  119. {easycoder-251022.1 → easycoder-251103.2}/doc/core/values/property.md +0 -0
  120. {easycoder-251022.1 → easycoder-251103.2}/doc/core/values/random.md +0 -0
  121. {easycoder-251022.1 → easycoder-251103.2}/doc/core/values/right.md +0 -0
  122. {easycoder-251022.1 → easycoder-251103.2}/doc/core/values/sin.md +0 -0
  123. {easycoder-251022.1 → easycoder-251103.2}/doc/core/values/stringify.md +0 -0
  124. {easycoder-251022.1 → easycoder-251103.2}/doc/core/values/tab.md +0 -0
  125. {easycoder-251022.1 → easycoder-251103.2}/doc/core/values/tan.md +0 -0
  126. {easycoder-251022.1 → easycoder-251103.2}/doc/core/values/timestamp.md +0 -0
  127. {easycoder-251022.1 → easycoder-251103.2}/doc/core/values/today.md +0 -0
  128. {easycoder-251022.1 → easycoder-251103.2}/doc/core/values/trim.md +0 -0
  129. {easycoder-251022.1 → easycoder-251103.2}/doc/core/values/type.md +0 -0
  130. {easycoder-251022.1 → easycoder-251103.2}/doc/core/values/uppercase.md +0 -0
  131. {easycoder-251022.1 → easycoder-251103.2}/doc/core/values/value.md +0 -0
  132. {easycoder-251022.1 → easycoder-251103.2}/doc/core/values/weekday.md +0 -0
  133. {easycoder-251022.1 → easycoder-251103.2}/doc/graphics/README.md +0 -0
  134. {easycoder-251022.1 → easycoder-251103.2}/doc/graphics/keywords/attach.md +0 -0
  135. {easycoder-251022.1 → easycoder-251103.2}/doc/graphics/keywords/close.md +0 -0
  136. {easycoder-251022.1 → easycoder-251103.2}/doc/graphics/keywords/create.md +0 -0
  137. {easycoder-251022.1 → easycoder-251103.2}/doc/graphics/keywords/ellipse.md +0 -0
  138. {easycoder-251022.1 → easycoder-251103.2}/doc/graphics/keywords/image.md +0 -0
  139. {easycoder-251022.1 → easycoder-251103.2}/doc/graphics/keywords/move.md +0 -0
  140. {easycoder-251022.1 → easycoder-251103.2}/doc/graphics/keywords/on.md +0 -0
  141. {easycoder-251022.1 → easycoder-251103.2}/doc/graphics/keywords/rectangle.md +0 -0
  142. {easycoder-251022.1 → easycoder-251103.2}/doc/graphics/keywords/render.md +0 -0
  143. {easycoder-251022.1 → easycoder-251103.2}/doc/graphics/keywords/run.md +0 -0
  144. {easycoder-251022.1 → easycoder-251103.2}/doc/graphics/keywords/set.md +0 -0
  145. {easycoder-251022.1 → easycoder-251103.2}/doc/graphics/keywords/text.md +0 -0
  146. {easycoder-251022.1 → easycoder-251103.2}/doc/graphics/values/attribute.md +0 -0
  147. {easycoder-251022.1 → easycoder-251103.2}/doc/graphics/values/window.md +0 -0
  148. {easycoder-251022.1 → easycoder-251103.2}/easycoder/close.png +0 -0
  149. {easycoder-251022.1 → easycoder-251103.2}/easycoder/ec_border.py +0 -0
  150. {easycoder-251022.1 → easycoder-251103.2}/easycoder/ec_classes.py +0 -0
  151. {easycoder-251022.1 → easycoder-251103.2}/easycoder/ec_condition.py +0 -0
  152. {easycoder-251022.1 → easycoder-251103.2}/easycoder/ec_keyboard.py +0 -0
  153. {easycoder-251022.1 → easycoder-251103.2}/easycoder/ec_timestamp.py +0 -0
  154. {easycoder-251022.1 → easycoder-251103.2}/easycoder/ec_value.py +0 -0
  155. {easycoder-251022.1 → easycoder-251103.2}/easycoder/tick.png +0 -0
  156. {easycoder-251022.1 → easycoder-251103.2}/images/Semoigo Dawn.jpg +0 -0
  157. {easycoder-251022.1 → easycoder-251103.2}/json/graphics-demo.json +0 -0
  158. {easycoder-251022.1 → easycoder-251103.2}/plugins/ec_keyboard.py +0 -0
  159. {easycoder-251022.1 → easycoder-251103.2}/plugins/ec_p100.py +0 -0
  160. {easycoder-251022.1 → easycoder-251103.2}/plugins/ec_pyside6.py +0 -0
  161. {easycoder-251022.1 → easycoder-251103.2}/plugins/points.py +0 -0
  162. {easycoder-251022.1 → easycoder-251103.2}/plugins/sql.py +0 -0
  163. {easycoder-251022.1 → easycoder-251103.2}/pyproject.toml +0 -0
  164. {easycoder-251022.1 → easycoder-251103.2}/scripts/benchmark.ecs +0 -0
  165. {easycoder-251022.1 → easycoder-251103.2}/scripts/ec_keyboard.py +0 -0
  166. {easycoder-251022.1 → easycoder-251103.2}/scripts/fizzbuzz.ecs +0 -0
  167. {easycoder-251022.1 → easycoder-251103.2}/scripts/hello.ecs +0 -0
  168. {easycoder-251022.1 → easycoder-251103.2}/scripts/points.ecs +0 -0
  169. {easycoder-251022.1 → easycoder-251103.2}/scripts/test.ecs +0 -0
  170. {easycoder-251022.1 → easycoder-251103.2}/scripts/tests.ecs +0 -0
  171. {easycoder-251022.1 → easycoder-251103.2}/test.py +0 -0
  172. {easycoder-251022.1 → easycoder-251103.2}/testrc.py +0 -0
  173. {easycoder-251022.1 → easycoder-251103.2}/testsql.py +0 -0
  174. {easycoder-251022.1 → easycoder-251103.2}/testui.py +0 -0
@@ -0,0 +1,112 @@
1
+ # EasyCoder-py AI Assistant Instructions
2
+
3
+ This guide helps AI coding assistants understand and work effectively with the EasyCoder-py codebase.
4
+
5
+ ## Project Overview
6
+
7
+ EasyCoder-py is a high-level English-like domain-specific scripting language (DSL) implemented in Python. Key characteristics:
8
+
9
+ - English-like syntax focused on vocabulary rather than structure
10
+ - Command-line based with an emerging graphics module using PySide6
11
+ - Acts as a wrapper around standard Python functions
12
+ - Extensible through plugin modules
13
+ - Suitable for prototyping, rapid testing, and control systems
14
+
15
+ ## Core Architecture
16
+
17
+ ### Main Components:
18
+
19
+ 1. Core Language (`easycoder/`)
20
+ - `ec_compiler.py`: Handles script compilation
21
+ - `ec_program.py`: Manages program execution
22
+ - `ec_core.py`: Core language features
23
+ - `ec_value.py`: Value handling
24
+ - `ec_condition.py`: Condition processing
25
+
26
+ 2. Plugin System (`plugins/`)
27
+ - Seamlessly extends language functionality
28
+ - Example: `points.py` demonstrates coordinate handling
29
+
30
+ 3. Documentation (`doc/`)
31
+ - Core features in `doc/core/`
32
+ - Graphics features in `doc/graphics/`
33
+ - Each keyword/value/condition documented separately
34
+
35
+ ## Development Workflows
36
+
37
+ ### Testing
38
+
39
+ 1. Run the comprehensive test suite:
40
+ ```bash
41
+ easycoder scripts/tests.ecs
42
+ ```
43
+
44
+ 2. Performance benchmarking:
45
+ ```bash
46
+ easycoder scripts/benchmark.ecs
47
+ ```
48
+
49
+ ### Script Development
50
+
51
+ 1. Basic script structure:
52
+ ```
53
+ script ScriptName
54
+ ! Your code here
55
+ exit
56
+ ```
57
+
58
+ 2. Debugging:
59
+ - Use `log` instead of `print` for timestamped debug output
60
+ - Example: `log 'Debug message'` outputs with timestamp and line number
61
+
62
+ ## Project Conventions
63
+
64
+ 1. Script Files
65
+ - Extension: `.ecs`
66
+ - Always include `exit` command to properly terminate
67
+ - Use `script Name` to identify scripts for debugging
68
+
69
+ 2. Plugin Development
70
+ - Place new plugins in `plugins/` directory
71
+ - Must provide both compiler and runtime modules
72
+ - See `plugins/points.py` for reference implementation
73
+
74
+ 3. Documentation
75
+ - Place in `doc/` with appropriate subdirectory
76
+ - One markdown file per language feature
77
+ - Include syntax, parameters, and examples
78
+
79
+ ## Common Patterns
80
+
81
+ 1. Error Handling
82
+ ```
83
+ on error
84
+ log error
85
+ exit
86
+ ```
87
+
88
+ 2. Variable Declaration
89
+ ```
90
+ variable Name
91
+ set Name to Value
92
+ ```
93
+
94
+ 3. Plugin Integration
95
+ ```
96
+ use plugin-name
97
+ ! Plugin-specific commands
98
+ ```
99
+
100
+ ## Key Integration Points
101
+
102
+ 1. Python Integration
103
+ - EasyCoder wraps Python functionality
104
+ - Custom plugins can wrap any Python library with suitable API
105
+ - Direct Python integration via `system` command
106
+
107
+ 2. Graphics (PySide6)
108
+ - Graphics module under active development
109
+ - See `doc/graphics/` for current features
110
+ - Uses plugin system for seamless integration
111
+
112
+ Remember: Focus on English-like syntax and readability when writing or modifying code. Keep scripts as readable as natural language where possible.
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: easycoder
3
- Version: 251022.1
3
+ Version: 251103.2
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>
@@ -12,4 +12,4 @@ from .ec_pyside import *
12
12
  from .ec_timestamp import *
13
13
  from .ec_value import *
14
14
 
15
- __version__ = "251022.1"
15
+ __version__ = "251103.2"
@@ -78,7 +78,10 @@ class Compiler:
78
78
  return self.program.code[pc]
79
79
 
80
80
  # Add a command to the code list
81
- def add(self, command):
81
+ def addCommand(self, command):
82
+ if len(self.code) == 0:
83
+ if self.program.usingGraphics:
84
+ pass
82
85
  self.code.append(command)
83
86
 
84
87
  def isSymbol(self):
@@ -161,7 +164,7 @@ class Compiler:
161
164
  command['locked'] = False
162
165
  command['extra'] = extra
163
166
  if 'keyword' in command: command['hasValue'] = self.hasValue(command['keyword'])
164
- self.add(command)
167
+ self.addCommand(command)
165
168
  return True
166
169
 
167
170
  # Compile the current token
@@ -209,7 +212,7 @@ class Compiler:
209
212
  self.index = index
210
213
  while True:
211
214
  token = self.tokens[self.index]
212
- keyword = token.token
215
+ # keyword = token.token
213
216
  if self.debugCompile: print(self.script.lines[token.lino])
214
217
  # if keyword != 'else':
215
218
  if self.compileOne() == True:
@@ -223,3 +226,6 @@ class Compiler:
223
226
 
224
227
  def compileFromHere(self, stopOn):
225
228
  return self.compileFrom(self.getIndex(), stopOn)
229
+
230
+ def compileFromStart(self):
231
+ return self.compileFrom(0, [])
@@ -1769,12 +1769,17 @@ class Core(Handler):
1769
1769
  self.program.importPlugin(f'{source}:{clazz}')
1770
1770
  return True
1771
1771
  return False
1772
- elif self.nextIs('graphics'):
1773
- print('Loading graphics module')
1774
- from .ec_pyside import Graphics
1775
- self.program.graphics = Graphics
1776
- self.program.useClass(Graphics)
1777
- return True
1772
+ else:
1773
+ token = self.nextToken()
1774
+ if token in ['graphics', 'debugger']:
1775
+ if not hasattr(self.program, 'usingGraphics'):
1776
+ print('Loading graphics module')
1777
+ from .ec_pyside import Graphics
1778
+ self.program.graphics = Graphics
1779
+ self.program.useClass(Graphics)
1780
+ self.program.usingGraphics = True
1781
+ if token == 'debugger': self.program.debugging = True
1782
+ return True
1778
1783
  return False
1779
1784
 
1780
1785
  # Declare a general-purpose variable
@@ -2657,7 +2662,14 @@ class Core(Handler):
2657
2662
  path = self.nextValue()
2658
2663
  condition.path = path
2659
2664
  condition.type = 'exists'
2660
- token = self.nextToken()
2665
+ self.skip('on')
2666
+ if self.nextIsSymbol():
2667
+ record = self.getSymbolRecord()
2668
+ if record['keyword'] == 'ssh':
2669
+ condition.type = 'sshExists'
2670
+ condition.target = record['name']
2671
+ token = self.nextToken()
2672
+ else: token = self.getToken()
2661
2673
  if token == 'exists':
2662
2674
  return condition
2663
2675
  elif token == 'does':
@@ -2841,6 +2853,17 @@ class Core(Handler):
2841
2853
  test = errormsg != None
2842
2854
  return not test if condition.negate else test
2843
2855
 
2856
+ def c_sshExists(self, condition):
2857
+ path = self.getRuntimeValue(condition.path)
2858
+ ssh = self.getVariable(condition.target)
2859
+ sftp = ssh['sftp']
2860
+ try:
2861
+ with sftp.open(path, 'r') as remote_file: remote_file.read().decode()
2862
+ comparison = True
2863
+ except:
2864
+ comparison = False
2865
+ return not comparison if condition.negate else comparison
2866
+
2844
2867
  def c_starts(self, condition):
2845
2868
  value1 = self.getRuntimeValue(condition.value1)
2846
2869
  value2 = self.getRuntimeValue(condition.value2)
@@ -23,7 +23,7 @@ class Handler:
23
23
  self.rewindTo = compiler.rewindTo
24
24
  self.warning = compiler.warning
25
25
  self.getPC = compiler.getPC
26
- self.add = compiler.add
26
+ self.add = compiler.addCommand
27
27
  self.getCommandAt = compiler.getCommandAt
28
28
  self.compileOne = compiler.compileOne
29
29
  self.compileFromHere = compiler.compileFromHere
@@ -34,9 +34,9 @@ class Program:
34
34
  self.domainIndex = {}
35
35
  self.name = '<anon>'
36
36
  self.code = []
37
+ self.pc = 0
37
38
  self.symbols = {}
38
39
  self.onError = 0
39
- self.pc = 0
40
40
  self.debugStep = False
41
41
  self.stack = []
42
42
  self.script = Script(source)
@@ -48,7 +48,6 @@ class Program:
48
48
  self.externalControl = False
49
49
  self.ticker = 0
50
50
  self.running = True
51
- # self.start()
52
51
 
53
52
  # This is called at 10msec intervals by the GUI code
54
53
  def flushCB(self):
@@ -62,7 +61,7 @@ class Program:
62
61
  module['child'] = self
63
62
  startCompile = time.time()
64
63
  self.tokenise(self.script)
65
- if self.compiler.compileFrom(0, []):
64
+ if self.compiler.compileFromStart():
66
65
  finishCompile = time.time()
67
66
  s = len(self.script.lines)
68
67
  t = len(self.script.tokens)
@@ -70,8 +70,12 @@ class Graphics(Handler):
70
70
  ]
71
71
 
72
72
  def setWidget(self, record, widget):
73
+ if record['index'] >= record['elements']:
74
+ RuntimeError(self.program, f'Index out of range for widget {record["name"]}')
73
75
  if not 'widget' in record:
74
76
  record['widget'] = [None] * record['elements']
77
+ while len(record['widget']) < record['elements']:
78
+ record['widget'].append(None)
75
79
  record['widget'][record['index']] = widget
76
80
 
77
81
  def getWidget(self, record):
@@ -832,6 +836,7 @@ class Graphics(Handler):
832
836
 
833
837
  # Initialize the graphics environment
834
838
  def k_init(self, command):
839
+ # return True
835
840
  if self.nextIs('graphics'):
836
841
  self.add(command)
837
842
  return True
@@ -843,7 +848,22 @@ class Graphics(Handler):
843
848
  self.program.screenWidth = screen[0]
844
849
  self.program.screenHeight = screen[1]
845
850
  print(f'Screen: {self.program.screenWidth}x{self.program.screenHeight}')
846
- return self.nextPC()
851
+ # return self.nextPC()
852
+ def on_last_window_closed():
853
+ self.program.kill()
854
+ def init():
855
+ self.program.flush(self.nextPC())
856
+ def flush():
857
+ if not self.blocked:
858
+ if self.runOnTick != 0:
859
+ self.program.run(self.runOnTick)
860
+ self.program.flushCB()
861
+ timer = QTimer()
862
+ timer.timeout.connect(flush)
863
+ timer.start(10)
864
+ QTimer.singleShot(500, init)
865
+ self.app.lastWindowClosed.connect(on_last_window_closed)
866
+ self.app.exec()
847
867
 
848
868
  # Declare a label variable
849
869
  def k_label(self, command):
@@ -1363,21 +1383,22 @@ class Graphics(Handler):
1363
1383
  return False
1364
1384
 
1365
1385
  def r_start(self, command):
1366
- def on_last_window_closed():
1367
- self.program.kill()
1368
- def init():
1369
- self.program.flush(self.nextPC())
1370
- def flush():
1371
- if not self.blocked:
1372
- if self.runOnTick != 0:
1373
- self.program.run(self.runOnTick)
1374
- self.program.flushCB()
1375
- timer = QTimer()
1376
- timer.timeout.connect(flush)
1377
- timer.start(10)
1378
- QTimer.singleShot(500, init)
1379
- self.app.lastWindowClosed.connect(on_last_window_closed)
1380
- self.app.exec()
1386
+ return self.nextPC()
1387
+ # def on_last_window_closed():
1388
+ # self.program.kill()
1389
+ # def init():
1390
+ # self.program.flush(self.nextPC())
1391
+ # def flush():
1392
+ # if not self.blocked:
1393
+ # if self.runOnTick != 0:
1394
+ # self.program.run(self.runOnTick)
1395
+ # self.program.flushCB()
1396
+ # timer = QTimer()
1397
+ # timer.timeout.connect(flush)
1398
+ # timer.start(10)
1399
+ # QTimer.singleShot(500, init)
1400
+ # self.app.lastWindowClosed.connect(on_last_window_closed)
1401
+ # self.app.exec()
1381
1402
 
1382
1403
  # Declare a widget variable
1383
1404
  def k_widget(self, command):
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes