easycoder 251103.4__tar.gz → 251104.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.
- easycoder-251104.1/.github/copilot-instructions.md +552 -0
- {easycoder-251103.4 → easycoder-251104.1}/PKG-INFO +1 -1
- {easycoder-251103.4 → easycoder-251104.1}/easycoder/__init__.py +1 -1
- {easycoder-251103.4 → easycoder-251104.1}/easycoder/ec_compiler.py +24 -3
- {easycoder-251103.4 → easycoder-251104.1}/easycoder/ec_core.py +18 -18
- {easycoder-251103.4 → easycoder-251104.1}/easycoder/ec_handler.py +1 -1
- {easycoder-251103.4 → easycoder-251104.1}/easycoder/ec_pyside.py +6 -6
- easycoder-251103.4/.github/copilot-instructions.md +0 -112
- {easycoder-251103.4 → easycoder-251104.1}/.gitignore +0 -0
- {easycoder-251103.4 → easycoder-251104.1}/LICENSE +0 -0
- {easycoder-251103.4 → easycoder-251104.1}/README.md +0 -0
- {easycoder-251103.4 → easycoder-251104.1}/backdrop.jpg +0 -0
- {easycoder-251103.4 → easycoder-251104.1}/doc/README.md +0 -0
- {easycoder-251103.4 → easycoder-251104.1}/doc/core/README.md +0 -0
- {easycoder-251103.4 → easycoder-251104.1}/doc/core/conditions/boolean.md +0 -0
- {easycoder-251103.4 → easycoder-251104.1}/doc/core/conditions/empty.md +0 -0
- {easycoder-251103.4 → easycoder-251104.1}/doc/core/conditions/ends.md +0 -0
- {easycoder-251103.4 → easycoder-251104.1}/doc/core/conditions/even.md +0 -0
- {easycoder-251103.4 → easycoder-251104.1}/doc/core/conditions/exists.md +0 -0
- {easycoder-251103.4 → easycoder-251104.1}/doc/core/conditions/greater.md +0 -0
- {easycoder-251103.4 → easycoder-251104.1}/doc/core/conditions/hasProperty.md +0 -0
- {easycoder-251103.4 → easycoder-251104.1}/doc/core/conditions/includes.md +0 -0
- {easycoder-251103.4 → easycoder-251104.1}/doc/core/conditions/is.md +0 -0
- {easycoder-251103.4 → easycoder-251104.1}/doc/core/conditions/less.md +0 -0
- {easycoder-251103.4 → easycoder-251104.1}/doc/core/conditions/list.md +0 -0
- {easycoder-251103.4 → easycoder-251104.1}/doc/core/conditions/none.md +0 -0
- {easycoder-251103.4 → easycoder-251104.1}/doc/core/conditions/not.md +0 -0
- {easycoder-251103.4 → easycoder-251104.1}/doc/core/conditions/numeric.md +0 -0
- {easycoder-251103.4 → easycoder-251104.1}/doc/core/conditions/object.md +0 -0
- {easycoder-251103.4 → easycoder-251104.1}/doc/core/conditions/odd.md +0 -0
- {easycoder-251103.4 → easycoder-251104.1}/doc/core/conditions/starts.md +0 -0
- {easycoder-251103.4 → easycoder-251104.1}/doc/core/conditions/string.md +0 -0
- {easycoder-251103.4 → easycoder-251104.1}/doc/core/keywords/add.md +0 -0
- {easycoder-251103.4 → easycoder-251104.1}/doc/core/keywords/append.md +0 -0
- {easycoder-251103.4 → easycoder-251104.1}/doc/core/keywords/assert.md +0 -0
- {easycoder-251103.4 → easycoder-251104.1}/doc/core/keywords/begin.md +0 -0
- {easycoder-251103.4 → easycoder-251104.1}/doc/core/keywords/clear.md +0 -0
- {easycoder-251103.4 → easycoder-251104.1}/doc/core/keywords/close.md +0 -0
- {easycoder-251103.4 → easycoder-251104.1}/doc/core/keywords/create.md +0 -0
- {easycoder-251103.4 → easycoder-251104.1}/doc/core/keywords/debug.md +0 -0
- {easycoder-251103.4 → easycoder-251104.1}/doc/core/keywords/decrement.md +0 -0
- {easycoder-251103.4 → easycoder-251104.1}/doc/core/keywords/delete.md +0 -0
- {easycoder-251103.4 → easycoder-251104.1}/doc/core/keywords/divide.md +0 -0
- {easycoder-251103.4 → easycoder-251104.1}/doc/core/keywords/exit.md +0 -0
- {easycoder-251103.4 → easycoder-251104.1}/doc/core/keywords/file.md +0 -0
- {easycoder-251103.4 → easycoder-251104.1}/doc/core/keywords/fork.md +0 -0
- {easycoder-251103.4 → easycoder-251104.1}/doc/core/keywords/get.md +0 -0
- {easycoder-251103.4 → easycoder-251104.1}/doc/core/keywords/go.md +0 -0
- {easycoder-251103.4 → easycoder-251104.1}/doc/core/keywords/gosub.md +0 -0
- {easycoder-251103.4 → easycoder-251104.1}/doc/core/keywords/if.md +0 -0
- {easycoder-251103.4 → easycoder-251104.1}/doc/core/keywords/import.md +0 -0
- {easycoder-251103.4 → easycoder-251104.1}/doc/core/keywords/increment.md +0 -0
- {easycoder-251103.4 → easycoder-251104.1}/doc/core/keywords/index.md +0 -0
- {easycoder-251103.4 → easycoder-251104.1}/doc/core/keywords/init.md +0 -0
- {easycoder-251103.4 → easycoder-251104.1}/doc/core/keywords/input.md +0 -0
- {easycoder-251103.4 → easycoder-251104.1}/doc/core/keywords/load.md +0 -0
- {easycoder-251103.4 → easycoder-251104.1}/doc/core/keywords/lock.md +0 -0
- {easycoder-251103.4 → easycoder-251104.1}/doc/core/keywords/log.md +0 -0
- {easycoder-251103.4 → easycoder-251104.1}/doc/core/keywords/module.md +0 -0
- {easycoder-251103.4 → easycoder-251104.1}/doc/core/keywords/multiply.md +0 -0
- {easycoder-251103.4 → easycoder-251104.1}/doc/core/keywords/negate.md +0 -0
- {easycoder-251103.4 → easycoder-251104.1}/doc/core/keywords/on.md +0 -0
- {easycoder-251103.4 → easycoder-251104.1}/doc/core/keywords/open.md +0 -0
- {easycoder-251103.4 → easycoder-251104.1}/doc/core/keywords/pop.md +0 -0
- {easycoder-251103.4 → easycoder-251104.1}/doc/core/keywords/post.md +0 -0
- {easycoder-251103.4 → easycoder-251104.1}/doc/core/keywords/print.md +0 -0
- {easycoder-251103.4 → easycoder-251104.1}/doc/core/keywords/push.md +0 -0
- {easycoder-251103.4 → easycoder-251104.1}/doc/core/keywords/put.md +0 -0
- {easycoder-251103.4 → easycoder-251104.1}/doc/core/keywords/read.md +0 -0
- {easycoder-251103.4 → easycoder-251104.1}/doc/core/keywords/release.md +0 -0
- {easycoder-251103.4 → easycoder-251104.1}/doc/core/keywords/replace.md +0 -0
- {easycoder-251103.4 → easycoder-251104.1}/doc/core/keywords/return.md +0 -0
- {easycoder-251103.4 → easycoder-251104.1}/doc/core/keywords/run.md +0 -0
- {easycoder-251103.4 → easycoder-251104.1}/doc/core/keywords/save.md +0 -0
- {easycoder-251103.4 → easycoder-251104.1}/doc/core/keywords/script.md +0 -0
- {easycoder-251103.4 → easycoder-251104.1}/doc/core/keywords/send.md +0 -0
- {easycoder-251103.4 → easycoder-251104.1}/doc/core/keywords/set.md +0 -0
- {easycoder-251103.4 → easycoder-251104.1}/doc/core/keywords/shuffle.md +0 -0
- {easycoder-251103.4 → easycoder-251104.1}/doc/core/keywords/split.md +0 -0
- {easycoder-251103.4 → easycoder-251104.1}/doc/core/keywords/stack.md +0 -0
- {easycoder-251103.4 → easycoder-251104.1}/doc/core/keywords/stop.md +0 -0
- {easycoder-251103.4 → easycoder-251104.1}/doc/core/keywords/system.md +0 -0
- {easycoder-251103.4 → easycoder-251104.1}/doc/core/keywords/take.md +0 -0
- {easycoder-251103.4 → easycoder-251104.1}/doc/core/keywords/toggle.md +0 -0
- {easycoder-251103.4 → easycoder-251104.1}/doc/core/keywords/truncate.md +0 -0
- {easycoder-251103.4 → easycoder-251104.1}/doc/core/keywords/unlock.md +0 -0
- {easycoder-251103.4 → easycoder-251104.1}/doc/core/keywords/use.md +0 -0
- {easycoder-251103.4 → easycoder-251104.1}/doc/core/keywords/variable.md +0 -0
- {easycoder-251103.4 → easycoder-251104.1}/doc/core/keywords/wait.md +0 -0
- {easycoder-251103.4 → easycoder-251104.1}/doc/core/keywords/while.md +0 -0
- {easycoder-251103.4 → easycoder-251104.1}/doc/core/keywords/write.md +0 -0
- {easycoder-251103.4 → easycoder-251104.1}/doc/core/values/arg.md +0 -0
- {easycoder-251103.4 → easycoder-251104.1}/doc/core/values/args.md +0 -0
- {easycoder-251103.4 → easycoder-251104.1}/doc/core/values/cos.md +0 -0
- {easycoder-251103.4 → easycoder-251104.1}/doc/core/values/datime.md +0 -0
- {easycoder-251103.4 → easycoder-251104.1}/doc/core/values/decode.md +0 -0
- {easycoder-251103.4 → easycoder-251104.1}/doc/core/values/element.md +0 -0
- {easycoder-251103.4 → easycoder-251104.1}/doc/core/values/elements.md +0 -0
- {easycoder-251103.4 → easycoder-251104.1}/doc/core/values/empty.md +0 -0
- {easycoder-251103.4 → easycoder-251104.1}/doc/core/values/encode.md +0 -0
- {easycoder-251103.4 → easycoder-251104.1}/doc/core/values/error.md +0 -0
- {easycoder-251103.4 → easycoder-251104.1}/doc/core/values/files.md +0 -0
- {easycoder-251103.4 → easycoder-251104.1}/doc/core/values/float.md +0 -0
- {easycoder-251103.4 → easycoder-251104.1}/doc/core/values/from.md +0 -0
- {easycoder-251103.4 → easycoder-251104.1}/doc/core/values/hash.md +0 -0
- {easycoder-251103.4 → easycoder-251104.1}/doc/core/values/index.md +0 -0
- {easycoder-251103.4 → easycoder-251104.1}/doc/core/values/integer.md +0 -0
- {easycoder-251103.4 → easycoder-251104.1}/doc/core/values/json.md +0 -0
- {easycoder-251103.4 → easycoder-251104.1}/doc/core/values/keys.md +0 -0
- {easycoder-251103.4 → easycoder-251104.1}/doc/core/values/left.md +0 -0
- {easycoder-251103.4 → easycoder-251104.1}/doc/core/values/length.md +0 -0
- {easycoder-251103.4 → easycoder-251104.1}/doc/core/values/lowercase.md +0 -0
- {easycoder-251103.4 → easycoder-251104.1}/doc/core/values/memory.md +0 -0
- {easycoder-251103.4 → easycoder-251104.1}/doc/core/values/modification.md +0 -0
- {easycoder-251103.4 → easycoder-251104.1}/doc/core/values/modulo.md +0 -0
- {easycoder-251103.4 → easycoder-251104.1}/doc/core/values/newline.md +0 -0
- {easycoder-251103.4 → easycoder-251104.1}/doc/core/values/now.md +0 -0
- {easycoder-251103.4 → easycoder-251104.1}/doc/core/values/position.md +0 -0
- {easycoder-251103.4 → easycoder-251104.1}/doc/core/values/property.md +0 -0
- {easycoder-251103.4 → easycoder-251104.1}/doc/core/values/random.md +0 -0
- {easycoder-251103.4 → easycoder-251104.1}/doc/core/values/right.md +0 -0
- {easycoder-251103.4 → easycoder-251104.1}/doc/core/values/sin.md +0 -0
- {easycoder-251103.4 → easycoder-251104.1}/doc/core/values/stringify.md +0 -0
- {easycoder-251103.4 → easycoder-251104.1}/doc/core/values/tab.md +0 -0
- {easycoder-251103.4 → easycoder-251104.1}/doc/core/values/tan.md +0 -0
- {easycoder-251103.4 → easycoder-251104.1}/doc/core/values/timestamp.md +0 -0
- {easycoder-251103.4 → easycoder-251104.1}/doc/core/values/today.md +0 -0
- {easycoder-251103.4 → easycoder-251104.1}/doc/core/values/trim.md +0 -0
- {easycoder-251103.4 → easycoder-251104.1}/doc/core/values/type.md +0 -0
- {easycoder-251103.4 → easycoder-251104.1}/doc/core/values/uppercase.md +0 -0
- {easycoder-251103.4 → easycoder-251104.1}/doc/core/values/value.md +0 -0
- {easycoder-251103.4 → easycoder-251104.1}/doc/core/values/weekday.md +0 -0
- {easycoder-251103.4 → easycoder-251104.1}/doc/graphics/README.md +0 -0
- {easycoder-251103.4 → easycoder-251104.1}/doc/graphics/keywords/attach.md +0 -0
- {easycoder-251103.4 → easycoder-251104.1}/doc/graphics/keywords/close.md +0 -0
- {easycoder-251103.4 → easycoder-251104.1}/doc/graphics/keywords/create.md +0 -0
- {easycoder-251103.4 → easycoder-251104.1}/doc/graphics/keywords/ellipse.md +0 -0
- {easycoder-251103.4 → easycoder-251104.1}/doc/graphics/keywords/image.md +0 -0
- {easycoder-251103.4 → easycoder-251104.1}/doc/graphics/keywords/move.md +0 -0
- {easycoder-251103.4 → easycoder-251104.1}/doc/graphics/keywords/on.md +0 -0
- {easycoder-251103.4 → easycoder-251104.1}/doc/graphics/keywords/rectangle.md +0 -0
- {easycoder-251103.4 → easycoder-251104.1}/doc/graphics/keywords/render.md +0 -0
- {easycoder-251103.4 → easycoder-251104.1}/doc/graphics/keywords/run.md +0 -0
- {easycoder-251103.4 → easycoder-251104.1}/doc/graphics/keywords/set.md +0 -0
- {easycoder-251103.4 → easycoder-251104.1}/doc/graphics/keywords/text.md +0 -0
- {easycoder-251103.4 → easycoder-251104.1}/doc/graphics/values/attribute.md +0 -0
- {easycoder-251103.4 → easycoder-251104.1}/doc/graphics/values/window.md +0 -0
- {easycoder-251103.4 → easycoder-251104.1}/easycoder/close.png +0 -0
- {easycoder-251103.4 → easycoder-251104.1}/easycoder/ec_border.py +0 -0
- {easycoder-251103.4 → easycoder-251104.1}/easycoder/ec_classes.py +0 -0
- {easycoder-251103.4 → easycoder-251104.1}/easycoder/ec_condition.py +0 -0
- {easycoder-251103.4 → easycoder-251104.1}/easycoder/ec_keyboard.py +0 -0
- {easycoder-251103.4 → easycoder-251104.1}/easycoder/ec_program.py +0 -0
- {easycoder-251103.4 → easycoder-251104.1}/easycoder/ec_timestamp.py +0 -0
- {easycoder-251103.4 → easycoder-251104.1}/easycoder/ec_value.py +0 -0
- {easycoder-251103.4 → easycoder-251104.1}/easycoder/tick.png +0 -0
- {easycoder-251103.4 → easycoder-251104.1}/images/Semoigo Dawn.jpg +0 -0
- {easycoder-251103.4 → easycoder-251104.1}/json/graphics-demo.json +0 -0
- {easycoder-251103.4 → easycoder-251104.1}/plugins/ec_keyboard.py +0 -0
- {easycoder-251103.4 → easycoder-251104.1}/plugins/ec_p100.py +0 -0
- {easycoder-251103.4 → easycoder-251104.1}/plugins/ec_pyside6.py +0 -0
- {easycoder-251103.4 → easycoder-251104.1}/plugins/points.py +0 -0
- {easycoder-251103.4 → easycoder-251104.1}/plugins/sql.py +0 -0
- {easycoder-251103.4 → easycoder-251104.1}/pyproject.toml +0 -0
- {easycoder-251103.4 → easycoder-251104.1}/scripts/benchmark.ecs +0 -0
- {easycoder-251103.4 → easycoder-251104.1}/scripts/ec_keyboard.py +0 -0
- {easycoder-251103.4 → easycoder-251104.1}/scripts/fizzbuzz.ecs +0 -0
- {easycoder-251103.4 → easycoder-251104.1}/scripts/hello.ecs +0 -0
- {easycoder-251103.4 → easycoder-251104.1}/scripts/points.ecs +0 -0
- {easycoder-251103.4 → easycoder-251104.1}/scripts/test.ecs +0 -0
- {easycoder-251103.4 → easycoder-251104.1}/scripts/tests.ecs +0 -0
- {easycoder-251103.4 → easycoder-251104.1}/test.py +0 -0
- {easycoder-251103.4 → easycoder-251104.1}/testrc.py +0 -0
- {easycoder-251103.4 → easycoder-251104.1}/testsql.py +0 -0
- {easycoder-251103.4 → easycoder-251104.1}/testui.py +0 -0
|
@@ -0,0 +1,552 @@
|
|
|
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
|
+
- Direct integration with Python libraries possible through plugins
|
|
30
|
+
- Plugin must provide both compiler and runtime components
|
|
31
|
+
|
|
32
|
+
3. Documentation (`doc/`)
|
|
33
|
+
- Core features in `doc/core/`
|
|
34
|
+
- Graphics features in `doc/graphics/`
|
|
35
|
+
- Each keyword/value/condition documented separately
|
|
36
|
+
|
|
37
|
+
## Development Workflows
|
|
38
|
+
|
|
39
|
+
### Setup and Installation
|
|
40
|
+
|
|
41
|
+
1. Basic installation:
|
|
42
|
+
```bash
|
|
43
|
+
pip install requests easycoder
|
|
44
|
+
```
|
|
45
|
+
|
|
46
|
+
2. Environment setup (Linux):
|
|
47
|
+
```bash
|
|
48
|
+
export PATH=$HOME/.local/bin:$PATH
|
|
49
|
+
```
|
|
50
|
+
|
|
51
|
+
### Testing
|
|
52
|
+
|
|
53
|
+
1. Run the comprehensive test suite:
|
|
54
|
+
```bash
|
|
55
|
+
easycoder scripts/tests.ecs
|
|
56
|
+
```
|
|
57
|
+
|
|
58
|
+
2. Performance benchmarking:
|
|
59
|
+
```bash
|
|
60
|
+
easycoder scripts/benchmark.ecs
|
|
61
|
+
```
|
|
62
|
+
|
|
63
|
+
3. Individual component testing:
|
|
64
|
+
- `test.py`: Core functionality tests
|
|
65
|
+
- `testrc.py`: Resource tests
|
|
66
|
+
- `testsql.py`: SQL plugin tests
|
|
67
|
+
- `testui.py`: UI/Graphics tests
|
|
68
|
+
|
|
69
|
+
### Script Development
|
|
70
|
+
|
|
71
|
+
1. Basic script structure:
|
|
72
|
+
```
|
|
73
|
+
script ScriptName
|
|
74
|
+
! Your code here
|
|
75
|
+
exit
|
|
76
|
+
```
|
|
77
|
+
|
|
78
|
+
2. Debugging:
|
|
79
|
+
- Use `log` instead of `print` for timestamped debug output
|
|
80
|
+
- Example: `log 'Debug message'` outputs with timestamp and line number
|
|
81
|
+
- Include `debug` command to enter debug mode when needed
|
|
82
|
+
|
|
83
|
+
## Project Conventions
|
|
84
|
+
|
|
85
|
+
1. Script Files
|
|
86
|
+
- Extension: `.ecs`
|
|
87
|
+
- Always include `exit` command to properly terminate
|
|
88
|
+
- Use `script Name` to identify scripts for debugging
|
|
89
|
+
- Place scripts in `scripts/` directory
|
|
90
|
+
|
|
91
|
+
2. Plugin Development
|
|
92
|
+
- Place new plugins in `plugins/` directory
|
|
93
|
+
- Must provide both compiler and runtime modules
|
|
94
|
+
- See `plugins/points.py` for reference implementation
|
|
95
|
+
- Use `use plugin-name` to import plugins in scripts
|
|
96
|
+
|
|
97
|
+
3. Documentation
|
|
98
|
+
- Place in `doc/` with appropriate subdirectory
|
|
99
|
+
- One markdown file per language feature
|
|
100
|
+
- Include syntax, parameters, and examples
|
|
101
|
+
- Follow existing documentation patterns in `doc/core/`
|
|
102
|
+
|
|
103
|
+
## Common Patterns
|
|
104
|
+
|
|
105
|
+
1. Error Handling
|
|
106
|
+
```
|
|
107
|
+
on error
|
|
108
|
+
log error
|
|
109
|
+
exit
|
|
110
|
+
```
|
|
111
|
+
|
|
112
|
+
2. Variable Declaration and Management
|
|
113
|
+
```
|
|
114
|
+
variable Name
|
|
115
|
+
set Name to Value
|
|
116
|
+
```
|
|
117
|
+
|
|
118
|
+
3. Plugin Integration
|
|
119
|
+
```
|
|
120
|
+
use plugin-name
|
|
121
|
+
! Plugin-specific commands
|
|
122
|
+
```
|
|
123
|
+
|
|
124
|
+
## Key Integration Points
|
|
125
|
+
|
|
126
|
+
1. Python Integration
|
|
127
|
+
- EasyCoder wraps Python functionality
|
|
128
|
+
- Custom plugins can wrap any Python library with suitable API
|
|
129
|
+
- Direct Python integration via `system` command
|
|
130
|
+
|
|
131
|
+
2. Graphics (PySide6)
|
|
132
|
+
- Graphics module under active development
|
|
133
|
+
- See `doc/graphics/` for current features
|
|
134
|
+
- Uses plugin system for seamless integration
|
|
135
|
+
|
|
136
|
+
## Extending the Language
|
|
137
|
+
|
|
138
|
+
### Handler Structure
|
|
139
|
+
|
|
140
|
+
1. Basic Setup
|
|
141
|
+
```python
|
|
142
|
+
class MyHandler(Handler):
|
|
143
|
+
def __init__(self, compiler):
|
|
144
|
+
Handler.__init__(self, compiler)
|
|
145
|
+
|
|
146
|
+
def getName(self):
|
|
147
|
+
return 'my_handler'
|
|
148
|
+
```
|
|
149
|
+
|
|
150
|
+
2. Command Implementation Pattern
|
|
151
|
+
- Each command needs two methods:
|
|
152
|
+
- `k_commandname`: Compile-time handler (parsing)
|
|
153
|
+
- `r_commandname`: Runtime handler (execution)
|
|
154
|
+
|
|
155
|
+
Example:
|
|
156
|
+
```python
|
|
157
|
+
def k_mycommand(self, command):
|
|
158
|
+
# Parse the command
|
|
159
|
+
command['value'] = self.nextValue()
|
|
160
|
+
if self.nextIs('to'):
|
|
161
|
+
command['target'] = self.nextToken()
|
|
162
|
+
self.add(command)
|
|
163
|
+
return True
|
|
164
|
+
return False
|
|
165
|
+
|
|
166
|
+
def r_mycommand(self, command):
|
|
167
|
+
# Execute the command
|
|
168
|
+
value = self.getRuntimeValue(command['value'])
|
|
169
|
+
target = self.getVariable(command['target'])
|
|
170
|
+
# Implement command logic
|
|
171
|
+
return self.nextPC()
|
|
172
|
+
```
|
|
173
|
+
|
|
174
|
+
### Key Components
|
|
175
|
+
|
|
176
|
+
1. Value Handling
|
|
177
|
+
- Use `self.nextValue()` to get the next value token
|
|
178
|
+
- Use `self.getRuntimeValue()` to get actual value during runtime
|
|
179
|
+
- Values can be:
|
|
180
|
+
- Variables: Check with `self.nextIsSymbol()`
|
|
181
|
+
- Literals: Strings, numbers
|
|
182
|
+
- Computed values: From expressions
|
|
183
|
+
|
|
184
|
+
2. Symbol Management
|
|
185
|
+
- Use `self.getSymbolRecord()` for compile-time symbol info
|
|
186
|
+
- Use `self.getVariable()` for runtime variable access
|
|
187
|
+
- Check `hasValue` property for value-holding variables
|
|
188
|
+
|
|
189
|
+
3. Error Handling
|
|
190
|
+
- Compile time: Use `self.warning()` for non-fatal errors
|
|
191
|
+
- Runtime: Raise appropriate exceptions:
|
|
192
|
+
- `RuntimeError` for general errors
|
|
193
|
+
- `NoValueError` for missing values
|
|
194
|
+
- `AssertionError` for failed assertions
|
|
195
|
+
|
|
196
|
+
### Plugin Development Best Practices
|
|
197
|
+
|
|
198
|
+
1. Structure
|
|
199
|
+
- Place plugin file in `plugins/` directory
|
|
200
|
+
- Implement both compiler and runtime components
|
|
201
|
+
- Follow naming convention: `ec_pluginname.py`
|
|
202
|
+
|
|
203
|
+
2. Integration
|
|
204
|
+
- Register commands in `__init__`
|
|
205
|
+
- Handle both compilation and runtime phases
|
|
206
|
+
- Provide clear error messages
|
|
207
|
+
- Document syntax and usage
|
|
208
|
+
|
|
209
|
+
3. Testing
|
|
210
|
+
- Create test scripts in `scripts/` directory
|
|
211
|
+
- Test both success and error cases
|
|
212
|
+
- Validate variable state changes
|
|
213
|
+
- Check error handling
|
|
214
|
+
|
|
215
|
+
### Graphics Extension (PySide6)
|
|
216
|
+
|
|
217
|
+
1. Widget Handling
|
|
218
|
+
- Extend `Graphics` class for new widgets
|
|
219
|
+
- Implement widget-specific commands
|
|
220
|
+
- Use `isWidget()` for type checking
|
|
221
|
+
- Handle widget lifecycle
|
|
222
|
+
|
|
223
|
+
2. Layout Management
|
|
224
|
+
- Support different layout types
|
|
225
|
+
- Handle parent-child relationships
|
|
226
|
+
- Manage widget positioning
|
|
227
|
+
- Support dynamic updates
|
|
228
|
+
|
|
229
|
+
Example widget command:
|
|
230
|
+
```python
|
|
231
|
+
def k_mywidget(self, command):
|
|
232
|
+
if self.nextIsSymbol():
|
|
233
|
+
record = self.getSymbolRecord()
|
|
234
|
+
command['widget'] = record['name']
|
|
235
|
+
self.add(command)
|
|
236
|
+
return True
|
|
237
|
+
return False
|
|
238
|
+
```
|
|
239
|
+
|
|
240
|
+
## Compiler Reference
|
|
241
|
+
|
|
242
|
+
### Token Management
|
|
243
|
+
|
|
244
|
+
1. Position Control
|
|
245
|
+
- `getIndex()`: Get current token position
|
|
246
|
+
- `next()`: Move to next token
|
|
247
|
+
- `rewindTo(index)`: Return to a previous position
|
|
248
|
+
- `peek()`: Look at next token without advancing
|
|
249
|
+
|
|
250
|
+
2. Token Access
|
|
251
|
+
- `getToken()`: Get current token
|
|
252
|
+
- `nextToken()`: Get next token and advance
|
|
253
|
+
- `tokenIs(value)`: Check current token value
|
|
254
|
+
- `nextIs(value)`: Check next token value
|
|
255
|
+
- `skip(token)`: Skip specified token if next
|
|
256
|
+
|
|
257
|
+
### Value and Condition Handling
|
|
258
|
+
|
|
259
|
+
1. Value Processing
|
|
260
|
+
- `getValue()`: Compile current value
|
|
261
|
+
- `nextValue()`: Compile next value
|
|
262
|
+
- `getConstant(token)`: Process constant value
|
|
263
|
+
- `addValueType()`: Register a new value type
|
|
264
|
+
- `hasValue(type)`: Check if type exists
|
|
265
|
+
|
|
266
|
+
2. Condition Processing
|
|
267
|
+
- `getCondition()`: Compile current condition
|
|
268
|
+
- `nextCondition()`: Compile next condition
|
|
269
|
+
- `compileCondition()`: Process condition syntax
|
|
270
|
+
|
|
271
|
+
### Symbol Management
|
|
272
|
+
|
|
273
|
+
1. Symbol Operations
|
|
274
|
+
- `isSymbol()`: Check if current token is a symbol
|
|
275
|
+
- `nextIsSymbol()`: Check if next token is a symbol
|
|
276
|
+
- `getSymbolRecord()`: Get current symbol's data
|
|
277
|
+
- `compileSymbol(command, name, extra)`: Create new symbol
|
|
278
|
+
- `compileVariable(command, extra)`: Create variable symbol
|
|
279
|
+
|
|
280
|
+
2. Command Compilation
|
|
281
|
+
- `compileToken()`: Compile single token
|
|
282
|
+
- `compileOne()`: Compile one command
|
|
283
|
+
- `compileLabel(command)`: Handle label definitions
|
|
284
|
+
- `compileFromStart()`: Begin compilation
|
|
285
|
+
- `compileFromHere(stopOn)`: Continue from current point
|
|
286
|
+
|
|
287
|
+
### Error Handling
|
|
288
|
+
|
|
289
|
+
1. Diagnostic Tools
|
|
290
|
+
- `getLino()`: Get current line number
|
|
291
|
+
- `warning(message)`: Record compilation warning
|
|
292
|
+
- `showWarnings()`: Display all warnings
|
|
293
|
+
- `debugCompile`: Toggle debug output
|
|
294
|
+
|
|
295
|
+
### Common Usage Patterns
|
|
296
|
+
|
|
297
|
+
1. Basic Command Parsing
|
|
298
|
+
```python
|
|
299
|
+
def k_mycommand(self, command):
|
|
300
|
+
# Parse: mycommand {value} to {variable}
|
|
301
|
+
command['value'] = self.nextValue() # Get first parameter
|
|
302
|
+
if self.nextIs('to'): # Check syntax
|
|
303
|
+
if self.nextIsSymbol(): # Verify target is a symbol
|
|
304
|
+
record = self.getSymbolRecord() # Get symbol info
|
|
305
|
+
command['target'] = record['name'] # Store target name
|
|
306
|
+
self.add(command) # Add to compiled code
|
|
307
|
+
return True
|
|
308
|
+
return False
|
|
309
|
+
```
|
|
310
|
+
|
|
311
|
+
2. Complex Syntax With Options
|
|
312
|
+
```python
|
|
313
|
+
def k_create(self, command):
|
|
314
|
+
# Parse: create (file|directory) {name} [with {options}]
|
|
315
|
+
token = self.nextToken()
|
|
316
|
+
if token in ['file', 'directory']:
|
|
317
|
+
command['type'] = token
|
|
318
|
+
command['name'] = self.nextValue()
|
|
319
|
+
if self.peek() == 'with':
|
|
320
|
+
self.nextToken()
|
|
321
|
+
command['options'] = self.nextValue()
|
|
322
|
+
self.add(command)
|
|
323
|
+
return True
|
|
324
|
+
return False
|
|
325
|
+
```
|
|
326
|
+
|
|
327
|
+
3. Working with Symbols and Values
|
|
328
|
+
```python
|
|
329
|
+
def k_set(self, command):
|
|
330
|
+
# Parse: set {variable} to {value}
|
|
331
|
+
if self.nextIsSymbol():
|
|
332
|
+
record = self.getSymbolRecord()
|
|
333
|
+
if record['hasValue']: # Check if can hold value
|
|
334
|
+
command['target'] = record['name']
|
|
335
|
+
self.skip('to') # Skip optional keyword
|
|
336
|
+
command['value'] = self.nextValue()
|
|
337
|
+
self.add(command)
|
|
338
|
+
return True
|
|
339
|
+
self.warning('Variable cannot hold a value')
|
|
340
|
+
return False
|
|
341
|
+
```
|
|
342
|
+
|
|
343
|
+
4. Handling Multiple Parameters
|
|
344
|
+
```python
|
|
345
|
+
def k_add(self, command):
|
|
346
|
+
# Parse: add {value} to {variable} [giving {variable}]
|
|
347
|
+
command['value1'] = self.nextValue()
|
|
348
|
+
if self.nextIs('to'):
|
|
349
|
+
if self.nextIsSymbol():
|
|
350
|
+
record = self.getSymbolRecord()
|
|
351
|
+
if self.peek() == 'giving':
|
|
352
|
+
# Format: add val1 to val2 giving target
|
|
353
|
+
command['value2'] = self.getValue()
|
|
354
|
+
self.nextToken()
|
|
355
|
+
command['target'] = self.nextToken()
|
|
356
|
+
else:
|
|
357
|
+
# Format: add val1 to target
|
|
358
|
+
command['target'] = record['name']
|
|
359
|
+
self.add(command)
|
|
360
|
+
return True
|
|
361
|
+
return False
|
|
362
|
+
```
|
|
363
|
+
|
|
364
|
+
5. Position Control and Recovery
|
|
365
|
+
```python
|
|
366
|
+
def k_complex(self, command):
|
|
367
|
+
# Save position in case we need to rewind
|
|
368
|
+
mark = self.getIndex()
|
|
369
|
+
|
|
370
|
+
# Try to parse one format
|
|
371
|
+
command['value'] = self.nextValue()
|
|
372
|
+
if self.nextIs('to'):
|
|
373
|
+
# First format succeeded
|
|
374
|
+
self.add(command)
|
|
375
|
+
return True
|
|
376
|
+
|
|
377
|
+
# Rewind and try alternate format
|
|
378
|
+
self.rewindTo(mark)
|
|
379
|
+
if self.nextIs('alternative'):
|
|
380
|
+
# Handle alternative syntax
|
|
381
|
+
return True
|
|
382
|
+
|
|
383
|
+
return False
|
|
384
|
+
|
|
385
|
+
```
|
|
386
|
+
|
|
387
|
+
## Runtime Handler Reference
|
|
388
|
+
|
|
389
|
+
### Purpose and Structure
|
|
390
|
+
|
|
391
|
+
Each command's `r_xxx` function implements runtime behavior after compilation. Runtime handlers:
|
|
392
|
+
- Retrieve and evaluate parameters from the compiled command dictionary
|
|
393
|
+
- Perform the command's core logic (variable operations, I/O, control flow)
|
|
394
|
+
- Manage program state and side effects
|
|
395
|
+
- Return the next program counter (PC) to continue execution
|
|
396
|
+
|
|
397
|
+
Basic runtime handler structure:
|
|
398
|
+
```python
|
|
399
|
+
def r_commandname(self, command):
|
|
400
|
+
# 1. Retrieve parameters from command dict
|
|
401
|
+
value = self.getRuntimeValue(command['value'])
|
|
402
|
+
target = self.getVariable(command['target'])
|
|
403
|
+
|
|
404
|
+
# 2. Perform the command's action
|
|
405
|
+
result = perform_operation(value)
|
|
406
|
+
|
|
407
|
+
# 3. Update state if needed
|
|
408
|
+
val = self.getSymbolValue(target)
|
|
409
|
+
val['content'] = result
|
|
410
|
+
self.putSymbolValue(target, val)
|
|
411
|
+
|
|
412
|
+
# 4. Return next PC
|
|
413
|
+
return self.nextPC()
|
|
414
|
+
```
|
|
415
|
+
|
|
416
|
+
### Core Runtime Functions
|
|
417
|
+
|
|
418
|
+
1. Value and Variable Access
|
|
419
|
+
- `self.getRuntimeValue(param)`: Evaluate values, variables, expressions at runtime
|
|
420
|
+
- `self.getVariable(name)`: Fetch variable symbol record
|
|
421
|
+
- `self.getSymbolValue(record)`: Get variable's value dict
|
|
422
|
+
- `self.putSymbolValue(record, value)`: Set variable's value dict
|
|
423
|
+
|
|
424
|
+
2. Control Flow
|
|
425
|
+
- `self.nextPC()`: Return next program counter (normal flow)
|
|
426
|
+
- `self.getPC()`: Get current program counter
|
|
427
|
+
- Return specific PC value for jumps/gotos
|
|
428
|
+
|
|
429
|
+
3. Condition Evaluation
|
|
430
|
+
- `self.program.condition.testCondition(cond)`: Evaluate condition
|
|
431
|
+
|
|
432
|
+
4. Error Handling
|
|
433
|
+
- `RuntimeError(self.program, message)`: Runtime error
|
|
434
|
+
- `NoValueRuntimeError(self.program, name)`: Variable has no value
|
|
435
|
+
- `AssertionError(self.program, message)`: Assertion failed
|
|
436
|
+
|
|
437
|
+
### Runtime Patterns
|
|
438
|
+
|
|
439
|
+
1. Simple Value Assignment
|
|
440
|
+
```python
|
|
441
|
+
def r_set(self, command):
|
|
442
|
+
# set {variable} to {value}
|
|
443
|
+
value = self.getRuntimeValue(command['value'])
|
|
444
|
+
target = self.getVariable(command['target'])
|
|
445
|
+
val = {}
|
|
446
|
+
val['type'] = 'string'
|
|
447
|
+
val['content'] = value
|
|
448
|
+
self.putSymbolValue(target, val)
|
|
449
|
+
return self.nextPC()
|
|
450
|
+
```
|
|
451
|
+
|
|
452
|
+
2. Arithmetic Operation
|
|
453
|
+
```python
|
|
454
|
+
def r_add(self, command):
|
|
455
|
+
# add {value} to {variable}
|
|
456
|
+
value1 = self.getRuntimeValue(command['value1'])
|
|
457
|
+
target = self.getVariable(command['target'])
|
|
458
|
+
targetValue = self.getSymbolValue(target)
|
|
459
|
+
|
|
460
|
+
if targetValue == None:
|
|
461
|
+
targetValue = {'type': 'int', 'content': 0}
|
|
462
|
+
|
|
463
|
+
targetValue['content'] = int(targetValue['content']) + int(value1)
|
|
464
|
+
self.putSymbolValue(target, targetValue)
|
|
465
|
+
return self.nextPC()
|
|
466
|
+
```
|
|
467
|
+
|
|
468
|
+
3. Conditional Execution
|
|
469
|
+
```python
|
|
470
|
+
def r_if(self, command):
|
|
471
|
+
# if {condition} ...
|
|
472
|
+
test = self.program.condition.testCondition(command['condition'])
|
|
473
|
+
if test:
|
|
474
|
+
# Continue to next command
|
|
475
|
+
return self.nextPC()
|
|
476
|
+
else:
|
|
477
|
+
# Jump to 'else' or end
|
|
478
|
+
if 'else' in command:
|
|
479
|
+
return command['else']
|
|
480
|
+
return command['goto']
|
|
481
|
+
```
|
|
482
|
+
|
|
483
|
+
4. Array/List Operations
|
|
484
|
+
```python
|
|
485
|
+
def r_append(self, command):
|
|
486
|
+
# append {value} to {array}
|
|
487
|
+
value = self.getRuntimeValue(command['value'])
|
|
488
|
+
target = self.getVariable(command['target'])
|
|
489
|
+
val = self.getSymbolValue(target)
|
|
490
|
+
content = val['content']
|
|
491
|
+
|
|
492
|
+
if content == '':
|
|
493
|
+
content = []
|
|
494
|
+
content.append(value)
|
|
495
|
+
val['content'] = content
|
|
496
|
+
self.putSymbolValue(target, val)
|
|
497
|
+
return self.nextPC()
|
|
498
|
+
```
|
|
499
|
+
|
|
500
|
+
5. File/IO Operations
|
|
501
|
+
```python
|
|
502
|
+
def r_read(self, command):
|
|
503
|
+
# read {file} to {variable}
|
|
504
|
+
fileRecord = self.getVariable(command['file'])
|
|
505
|
+
target = self.getVariable(command['target'])
|
|
506
|
+
|
|
507
|
+
content = fileRecord['file'].read()
|
|
508
|
+
val = {}
|
|
509
|
+
val['type'] = 'string'
|
|
510
|
+
val['content'] = content
|
|
511
|
+
self.putSymbolValue(target, val)
|
|
512
|
+
return self.nextPC()
|
|
513
|
+
```
|
|
514
|
+
|
|
515
|
+
6. Error Handling Pattern
|
|
516
|
+
```python
|
|
517
|
+
def r_assert(self, command):
|
|
518
|
+
# assert {condition} [with {message}]
|
|
519
|
+
test = self.program.condition.testCondition(command['test'])
|
|
520
|
+
if test:
|
|
521
|
+
return self.nextPC()
|
|
522
|
+
# Raise assertion error
|
|
523
|
+
AssertionError(self.program, self.getRuntimeValue(command['with']))
|
|
524
|
+
```
|
|
525
|
+
|
|
526
|
+
### Best Practices
|
|
527
|
+
|
|
528
|
+
1. Value Types
|
|
529
|
+
- Always set `val['type']` when creating value dicts ('int', 'string', 'boolean', 'object')
|
|
530
|
+
- Use `val['content']` to store the actual value
|
|
531
|
+
|
|
532
|
+
2. Variable Validation
|
|
533
|
+
- Check `record['hasValue']` during compilation
|
|
534
|
+
- Handle None values gracefully at runtime
|
|
535
|
+
- Validate array indices and object keys
|
|
536
|
+
|
|
537
|
+
3. Error Messages
|
|
538
|
+
- Provide clear, actionable error messages
|
|
539
|
+
- Include variable names and values when helpful
|
|
540
|
+
- Use appropriate error types for different failure modes
|
|
541
|
+
|
|
542
|
+
4. Performance
|
|
543
|
+
- Cache frequently accessed values
|
|
544
|
+
- Avoid redundant symbol lookups
|
|
545
|
+
- Consider lazy evaluation where appropriate
|
|
546
|
+
|
|
547
|
+
5. Side Effects
|
|
548
|
+
- Document any state changes or I/O operations
|
|
549
|
+
- Ensure proper cleanup (close files, release locks)
|
|
550
|
+
- Handle exceptions from external libraries
|
|
551
|
+
|
|
552
|
+
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:
|
|
3
|
+
Version: 251104.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>
|
|
@@ -18,9 +18,11 @@ class Compiler:
|
|
|
18
18
|
self.debugCompile = False
|
|
19
19
|
self.valueTypes = {}
|
|
20
20
|
|
|
21
|
-
|
|
21
|
+
# Get the current code size. Used during compilation
|
|
22
|
+
def getCodeSize(self):
|
|
22
23
|
return len(self.program.code)
|
|
23
24
|
|
|
25
|
+
# Get the current index (the program counter)
|
|
24
26
|
def getIndex(self):
|
|
25
27
|
return self.index
|
|
26
28
|
|
|
@@ -39,6 +41,7 @@ class Compiler:
|
|
|
39
41
|
self.index += 1
|
|
40
42
|
return self.getToken()
|
|
41
43
|
|
|
44
|
+
# Peek ahead to see the next token without advancing the index
|
|
42
45
|
def peek(self):
|
|
43
46
|
try:
|
|
44
47
|
return self.tokens[self.index + 1].token
|
|
@@ -68,12 +71,15 @@ class Compiler:
|
|
|
68
71
|
self.index += 1
|
|
69
72
|
return self.condition.compileCondition()
|
|
70
73
|
|
|
74
|
+
# Test if the current token has a specified value
|
|
71
75
|
def tokenIs(self, value):
|
|
72
76
|
return self.getToken() == value
|
|
73
77
|
|
|
78
|
+
# Test if the next token has the specified value
|
|
74
79
|
def nextIs(self, value):
|
|
75
80
|
return self.nextToken() == value
|
|
76
81
|
|
|
82
|
+
# Get the command at a given pc in the code list
|
|
77
83
|
def getCommandAt(self, pc):
|
|
78
84
|
return self.program.code[pc]
|
|
79
85
|
|
|
@@ -81,6 +87,7 @@ class Compiler:
|
|
|
81
87
|
def addCommand(self, command):
|
|
82
88
|
self.code.append(command)
|
|
83
89
|
|
|
90
|
+
# Test if the current token is a symbol
|
|
84
91
|
def isSymbol(self):
|
|
85
92
|
token = self.getToken()
|
|
86
93
|
try:
|
|
@@ -89,10 +96,12 @@ class Compiler:
|
|
|
89
96
|
return False
|
|
90
97
|
return True
|
|
91
98
|
|
|
99
|
+
# Test if the next token is a symbol
|
|
92
100
|
def nextIsSymbol(self):
|
|
93
101
|
self.next()
|
|
94
102
|
return self.isSymbol()
|
|
95
103
|
|
|
104
|
+
# Skip the next token if it matches the value given
|
|
96
105
|
def skip(self, token):
|
|
97
106
|
next = self.peek()
|
|
98
107
|
if type(token) == list:
|
|
@@ -102,21 +111,26 @@ class Compiler:
|
|
|
102
111
|
return
|
|
103
112
|
elif next == token: self.nextToken()
|
|
104
113
|
|
|
114
|
+
# Rewind to a given position in the code list
|
|
105
115
|
def rewindTo(self, index):
|
|
106
116
|
self.index = index
|
|
107
117
|
|
|
118
|
+
# Get source line number containing the current token
|
|
108
119
|
def getLino(self):
|
|
109
120
|
if self.index >= len(self.tokens):
|
|
110
121
|
return 0
|
|
111
122
|
return self.tokens[self.index].lino
|
|
112
123
|
|
|
124
|
+
# Issue a warning
|
|
113
125
|
def warning(self, message):
|
|
114
126
|
self.warnings.append(f'Warning at line {self.getLino() + 1} of {self.program.name}: {message}')
|
|
115
127
|
|
|
128
|
+
# Print all warnings
|
|
116
129
|
def showWarnings(self):
|
|
117
130
|
for warning in self.warnings:
|
|
118
131
|
print(warning)
|
|
119
132
|
|
|
133
|
+
# Get the symbol record for the current token (assumes it is a symbol name)
|
|
120
134
|
def getSymbolRecord(self):
|
|
121
135
|
token = self.getToken()
|
|
122
136
|
if not token in self.symbols:
|
|
@@ -128,18 +142,23 @@ class Compiler:
|
|
|
128
142
|
symbolRecord['used'] = True
|
|
129
143
|
return symbolRecord
|
|
130
144
|
|
|
145
|
+
# Add a value type
|
|
131
146
|
def addValueType(self):
|
|
132
147
|
self.valueTypes[self.getToken()] = True
|
|
133
148
|
|
|
149
|
+
# Test if a given value is in the value types list
|
|
134
150
|
def hasValue(self, type):
|
|
135
151
|
return type in self.valueTypes
|
|
136
152
|
|
|
153
|
+
# Compile a program label (a symbol ending with ':')
|
|
137
154
|
def compileLabel(self, command):
|
|
138
155
|
return self.compileSymbol(command, self.getToken())
|
|
139
156
|
|
|
157
|
+
# Compile a variable
|
|
140
158
|
def compileVariable(self, command, extra=None):
|
|
141
159
|
return self.compileSymbol(command, self.nextToken(), extra)
|
|
142
160
|
|
|
161
|
+
# Compile a symbol
|
|
143
162
|
def compileSymbol(self, command, name, extra=None):
|
|
144
163
|
try:
|
|
145
164
|
v = self.symbols[name]
|
|
@@ -148,7 +167,7 @@ class Compiler:
|
|
|
148
167
|
if v:
|
|
149
168
|
FatalError(self, f'Duplicate symbol name "{name}"')
|
|
150
169
|
return False
|
|
151
|
-
self.symbols[name] = self.
|
|
170
|
+
self.symbols[name] = self.getCodeSize()
|
|
152
171
|
command['program'] = self.program
|
|
153
172
|
command['type'] = 'symbol'
|
|
154
173
|
command['name'] = name
|
|
@@ -199,7 +218,7 @@ class Compiler:
|
|
|
199
218
|
keyword = self.getToken()
|
|
200
219
|
if not keyword:
|
|
201
220
|
return False
|
|
202
|
-
print(f'Compile keyword "{keyword}"')
|
|
221
|
+
# print(f'Compile keyword "{keyword}"')
|
|
203
222
|
if keyword.endswith(':'):
|
|
204
223
|
command = {}
|
|
205
224
|
command['domain'] = None
|
|
@@ -225,8 +244,10 @@ class Compiler:
|
|
|
225
244
|
else:
|
|
226
245
|
return False
|
|
227
246
|
|
|
247
|
+
# Compile fom the current location, stopping on any of a list of tokens
|
|
228
248
|
def compileFromHere(self, stopOn):
|
|
229
249
|
return self.compileFrom(self.getIndex(), stopOn)
|
|
230
250
|
|
|
251
|
+
# Compile from the start of the script
|
|
231
252
|
def compileFromStart(self):
|
|
232
253
|
return self.compileFrom(0, [])
|