beancode 0.3.2__tar.gz → 0.3.4__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.
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.3
2
2
  Name: beancode
3
- Version: 0.3.2
3
+ Version: 0.3.4
4
4
  Summary: A cursed IGCSE pseudocode interpreter/transpiler
5
5
  License: MPL-2.0
6
6
  Author: ezntek
@@ -118,7 +118,7 @@ There are many extra features, which are not standard to IGCSE Pseudocode.
118
118
  * `STRING -> INTEGER` (returns `null` on failure)
119
119
  * `STRING -> REAL` (returns `null` on failure)
120
120
  * `INTEGER -> REAL`
121
- * `REAL -> INTEGER`
121
+ *`REAL -> INTEGER`
122
122
  * `INTEGER -> BOOLEAN` (`0` is false, `1` is true)
123
123
  * `BOOLEAN -> INTEGER`
124
124
  6. Declaration and assignment on the same line is also supported: `DECLARE Num:INTEGER <- 5`
@@ -132,6 +132,15 @@ There are many extra features, which are not standard to IGCSE Pseudocode.
132
132
  OUTPUT X // works
133
133
  ```
134
134
 
135
+ ### REPL features
136
+
137
+ * `.var` gets information regarding an _existing variable_. It prints its name, type, and value.
138
+ * `.vars` prints information regarding _all variables_.
139
+ * `.func` gets information regarding *existing functions* ***or procedures***.
140
+ * `.funcs` prints information regarding _all functions and procedures_.
141
+ * Delete a variable if you need to with `.delete [name]`. (Version `0.3.4` and up)
142
+ * Or, reset the entire interpreter's state with `.reset`.
143
+
135
144
  ## quirks
136
145
 
137
146
  * ***Multiple statements in CASE OFs are not supported! Therefore, the following code is illegal:***
@@ -169,7 +178,7 @@ Python was perfect due to its dynamism, and the fact that I could abuse it to th
169
178
 
170
179
  ### Performance
171
180
 
172
- It's really bad. However, PyPy makes it a lot better. Here's some data for the PrimeTorture benchmark I have, ran on an i7-14700KF with 32GB RAM on Arch Linux:
181
+ It's really bad. However, PyPy makes it a lot better. Here's some data for the PrimeTorture benchmark in the examples, ran on an i7-14700KF with 32GB RAM on Arch Linux:
173
182
 
174
183
  |Language|Time Taken (s)|
175
184
  |--------|----------|
@@ -180,13 +189,6 @@ It's really bad. However, PyPy makes it a lot better. Here's some data for the P
180
189
  |Python (PyPy3)|0.19|
181
190
  |C (gcc 15.2.1)|0.1|
182
191
 
183
- beancode+cpython: 148 seconds
184
- beancode+pypy3: 11 seconds
185
- beancode+nuitka: 185 seconds
186
- cpython: 0.88 seconds
187
- pypy3: 0.19 seconds
188
- C: 0.1 seconds
189
-
190
192
  ## Errata
191
193
 
192
194
  * Some errors will report as `unused expression`, like the following:
@@ -102,7 +102,7 @@ There are many extra features, which are not standard to IGCSE Pseudocode.
102
102
  * `STRING -> INTEGER` (returns `null` on failure)
103
103
  * `STRING -> REAL` (returns `null` on failure)
104
104
  * `INTEGER -> REAL`
105
- * `REAL -> INTEGER`
105
+ *`REAL -> INTEGER`
106
106
  * `INTEGER -> BOOLEAN` (`0` is false, `1` is true)
107
107
  * `BOOLEAN -> INTEGER`
108
108
  6. Declaration and assignment on the same line is also supported: `DECLARE Num:INTEGER <- 5`
@@ -116,6 +116,15 @@ There are many extra features, which are not standard to IGCSE Pseudocode.
116
116
  OUTPUT X // works
117
117
  ```
118
118
 
119
+ ### REPL features
120
+
121
+ * `.var` gets information regarding an _existing variable_. It prints its name, type, and value.
122
+ * `.vars` prints information regarding _all variables_.
123
+ * `.func` gets information regarding *existing functions* ***or procedures***.
124
+ * `.funcs` prints information regarding _all functions and procedures_.
125
+ * Delete a variable if you need to with `.delete [name]`. (Version `0.3.4` and up)
126
+ * Or, reset the entire interpreter's state with `.reset`.
127
+
119
128
  ## quirks
120
129
 
121
130
  * ***Multiple statements in CASE OFs are not supported! Therefore, the following code is illegal:***
@@ -153,7 +162,7 @@ Python was perfect due to its dynamism, and the fact that I could abuse it to th
153
162
 
154
163
  ### Performance
155
164
 
156
- It's really bad. However, PyPy makes it a lot better. Here's some data for the PrimeTorture benchmark I have, ran on an i7-14700KF with 32GB RAM on Arch Linux:
165
+ It's really bad. However, PyPy makes it a lot better. Here's some data for the PrimeTorture benchmark in the examples, ran on an i7-14700KF with 32GB RAM on Arch Linux:
157
166
 
158
167
  |Language|Time Taken (s)|
159
168
  |--------|----------|
@@ -164,13 +173,6 @@ It's really bad. However, PyPy makes it a lot better. Here's some data for the P
164
173
  |Python (PyPy3)|0.19|
165
174
  |C (gcc 15.2.1)|0.1|
166
175
 
167
- beancode+cpython: 148 seconds
168
- beancode+pypy3: 11 seconds
169
- beancode+nuitka: 185 seconds
170
- cpython: 0.88 seconds
171
- pypy3: 0.19 seconds
172
- C: 0.1 seconds
173
-
174
176
  ## Errata
175
177
 
176
178
  * Some errors will report as `unused expression`, like the following:
@@ -1,4 +1,4 @@
1
- __version__ = "0.3.2"
1
+ __version__ = "0.3.4"
2
2
 
3
3
 
4
4
  def error(msg: str):
@@ -1,6 +1,8 @@
1
+ import io
1
2
  import os
2
3
  import sys
3
4
  import argparse
5
+ from typing import NoReturn
4
6
 
5
7
  from .repl import Repl
6
8
 
@@ -10,7 +12,6 @@ from .parser import Parser
10
12
  from .error import *
11
13
  from . import __version__
12
14
 
13
-
14
15
  def _error(s: str) -> NoReturn:
15
16
  error(s)
16
17
  exit(1)
@@ -104,10 +105,11 @@ def real_main():
104
105
 
105
106
 
106
107
  def main():
108
+ sys.stdout = io.TextIOWrapper(sys.stdout.buffer, encoding='utf-8', errors="replace")
109
+ sys.stderr = io.TextIOWrapper(sys.stdout.buffer, encoding='utf-8', errors="replace")
107
110
  try:
108
111
  if len(sys.argv) == 1:
109
112
  sys.exit(Repl().repl())
110
-
111
113
  real_main()
112
114
  except KeyboardInterrupt:
113
115
  warn("caught keyboard interrupt")
@@ -1,5 +1,5 @@
1
1
  import sys
2
- from typing import NoReturn
2
+ import os
3
3
 
4
4
 
5
5
  class BCError(Exception):
@@ -69,7 +69,14 @@ class BCError(Exception):
69
69
 
70
70
  tildes = f"{spaces()}\033[31;1m{'~' * self.len}\033[0m"
71
71
  print(tildes)
72
- indicator = f"{spaces()}\033[31;1m∟ \033[0m\033[1merror at line {line} column {col}\033[0m"
72
+
73
+ indicator = f"{spaces()}\033[31;1m"
74
+ if os.name == "nt":
75
+ indicator += "+-"
76
+ else:
77
+ indicator += "∟"
78
+
79
+ indicator += f" \033[0m\033[1merror at line {line} column {col}\033[0m"
73
80
  print(indicator)
74
81
 
75
82
 
@@ -117,7 +124,12 @@ class BCWarning(Exception):
117
124
 
118
125
  tildes = f"{spaces()}\033[35;1m{'~' * self.len}\033[0m"
119
126
  print(tildes)
120
- indicator = f"{spaces()}\033[35;1m∟ \033[0m\033[1mwarning at line {line} column {col}\033[0m"
127
+ indicator = f"{spaces()}\033[35;1m"
128
+ if os.name == "nt":
129
+ indicator += "+-"
130
+ else:
131
+ indicator += "∟"
132
+ indicator += f" \033[0m\033[1mwarning at line {line} column {col}\033[0m"
121
133
  print(indicator)
122
134
 
123
135
 
@@ -1512,6 +1512,9 @@ class Interpreter:
1512
1512
  self.variables[name] = var
1513
1513
 
1514
1514
  for name, fn in intp.functions.items():
1515
+ if isinstance(fn, BCFunction) or isinstance(fn, BCProcedure):
1516
+ continue
1517
+
1515
1518
  if fn.export: # type: ignore
1516
1519
  self.functions[name] = fn
1517
1520
 
@@ -34,15 +34,16 @@ type ".help" for a list of REPL commands, ".exit" to exit, or start typing some
34
34
  """
35
35
 
36
36
  HELP = """\033[1mAVAILABLE COMMANDS:\033[0m
37
- .var [names] get information regarding a declared variable/constant
38
- .vars get information regarding all declared variables/constants
39
- .func [names] get information regarding a declared procedure/function
40
- .funcs get information regarding all declared procedures/functions
41
- .help show this help message
42
- .clear clear the screen
43
- .reset reset the interpreter
44
- .version print the version
45
- .exit exit the interpreter (.quit also works)
37
+ .var [names] get information regarding a declared variable/constant
38
+ .vars get information regarding all declared variables/constants
39
+ .func [names] get information regarding a declared procedure/function
40
+ .funcs get information regarding all declared procedures/functions
41
+ .delete [names] delete a variable/constant/procedure/function
42
+ .reset reset the interpreter
43
+ .help show this help message
44
+ .clear clear the screen
45
+ .version print the version
46
+ .exit exit the interpreter (.quit also works)
46
47
  """
47
48
 
48
49
 
@@ -227,8 +228,24 @@ class Repl:
227
228
 
228
229
  return DotCommandResult.NO_OP
229
230
 
231
+ def _delete(self, args: list[str]) -> DotCommandResult:
232
+ if len(args) == 1:
233
+ error("not enough args for delete")
234
+ return DotCommandResult.NO_OP
235
+
236
+ for arg in args[1:]:
237
+ if arg in self.i.variables:
238
+ self.i.variables.__delitem__(arg)
239
+ info(f"deleted variable \"{arg}\"")
240
+ elif arg in self.i.functions:
241
+ self.i.functions.__delitem__(arg)
242
+ info(f"deleted function/procedure \"{arg}\"")
243
+ else:
244
+ error(f"no name \"{arg}\" found")
245
+ return DotCommandResult.NO_OP
246
+
230
247
  def handle_dot_command(self, s: str) -> DotCommandResult:
231
- args = s.split(" ")
248
+ args = s.strip().split(" ")
232
249
  base = args[0]
233
250
 
234
251
  match base:
@@ -255,6 +272,8 @@ class Repl:
255
272
  return self._func(args)
256
273
  case "funcs":
257
274
  return self._funcs(args)
275
+ case "delete":
276
+ return self._delete(args)
258
277
 
259
278
  return DotCommandResult.UNKNOWN_COMMAND
260
279
 
@@ -1,6 +1,6 @@
1
1
  [project]
2
2
  name = "beancode"
3
- version = "0.3.2"
3
+ version = "0.3.4"
4
4
  description = "A cursed IGCSE pseudocode interpreter/transpiler"
5
5
  authors = [
6
6
  {name = "ezntek", email = "eason@ezntek.com"}
File without changes
File without changes
File without changes
File without changes
File without changes