Skip to content

Commit 2c8ebec

Browse files
Merge pull request #11 from RetiredWizard/1.2-Beta
Version 1.2
2 parents a251f30 + 028e628 commit 2c8ebec

File tree

134 files changed

+3721
-4346
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

134 files changed

+3721
-4346
lines changed

3.aut

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
11
@echo off
22
del autoexec.bat
3-
if exist autoexec.sav rename autoexec.sav autoexec.bat
3+
if exist _autoexec._PyD rename _autoexec._PyD autoexec.bat
44
type menu.txt

3.bat

Lines changed: 4 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,7 @@
11
@echo off
2-
pexec from sys import implementation
3-
pexec envVars["_implementation"] = implementation.name.upper()
4-
if %_implementation% == MICROPYTHON goto micropython
5-
if exist autoexec.bat copy/y autoexec.bat autoexec.sav
2+
if exist _autoexec._PyD goto skip
3+
if exist autoexec.bat rename autoexec.bat _autoexec._PyD
4+
:skip
65
copy/y 3.aut autoexec.bat
7-
runvm "PyBasic/PyBasic adventure-fast.pgm"
8-
:micropython
9-
cd /PyBasic
10-
pexec import PyBasic
11-
pexec PyBasic.main("adventure-fast.pgm")
12-
cd /
6+
runvm /PyBasic/PyBasic adventure-fast.pgm
137
menu.bat

PyBasic/PyBasic.py

Lines changed: 4 additions & 264 deletions
Original file line numberDiff line numberDiff line change
@@ -1,264 +1,4 @@
1-
#! /usr/bin/python
2-
3-
# SPDX-License-Identifier: GPL-3.0-or-later
4-
#
5-
# This program is free software: you can redistribute it and/or modify
6-
# it under the terms of the GNU General Public License as published by
7-
# the Free Software Foundation, either version 3 of the License, or
8-
# (at your option) any later version.
9-
#
10-
# This program is distributed in the hope that it will be useful,
11-
# but WITHOUT ANY WARRANTY; without even the implied warranty of
12-
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13-
# GNU General Public License for more details.
14-
#
15-
# You should have received a copy of the GNU General Public License
16-
# along with this program. If not, see <https://www.gnu.org/licenses/>.
17-
18-
"""This class implements a BASIC interpreter that
19-
presents a prompt to the user. The user may input
20-
program statements, list them and run the program.
21-
The program may also be saved to disk and loaded
22-
again.
23-
24-
"""
25-
26-
from basictoken import BASICToken as Token
27-
from lexer import Lexer
28-
from program import Program
29-
from sys import stderr,implementation
30-
from os import listdir,rename,remove
31-
import gc
32-
try:
33-
from pydos_ui import input
34-
except:
35-
pass
36-
37-
if implementation.name.upper() == 'MICROPYTHON':
38-
from sys import print_exception
39-
40-
gc.collect()
41-
if 'threshold' in dir(gc):
42-
gc.threshold(gc.mem_free() // 4 + gc.mem_alloc())
43-
44-
def main(passedIn=""):
45-
46-
banner = (
47-
"""
48-
PPPP Y Y BBBB AAA SSSS I CCC
49-
P P Y Y B B A A S I C
50-
P P Y Y B B A A S I C
51-
PPPP Y BBBB AAAAA SSSS I C
52-
u u P Y B B A A S I C
53-
u u P Y B B A A S I C
54-
uuuu P Y BBBB A A SSSS I CCC
55-
microPyBasic
56-
""")
57-
58-
print(banner)
59-
60-
lexer = Lexer()
61-
program = Program()
62-
63-
fOpened = False
64-
#initialize and open temporary file
65-
tmpfile = open('_pybTmp.tmp','w+')
66-
infile = tmpfile
67-
68-
#Attempting memory pre-allocation to prepare for large Basic programs
69-
if implementation.name.upper() in ['MICROPYTHON','CIRCUITPYTHON']:
70-
gc.collect()
71-
for i in range(1600):
72-
if i % 100 == 0:
73-
print(".",end="")
74-
try:
75-
program.__program[i] = i
76-
except:
77-
print("\nMemory pre-allocation limit reached at ",i)
78-
break
79-
print()
80-
program.__program.clear()
81-
82-
if passedIn != "":
83-
infile = program.load(passedIn,tmpfile)
84-
program.execute(infile,tmpfile)
85-
86-
# Continuously accept user input and act on it until
87-
# the user enters 'EXIT'
88-
while True:
89-
90-
# kfw stmt = input_keyboard(': ')
91-
stmt = input(': ')
92-
93-
try:
94-
#if True:
95-
tokenlist = lexer.tokenize(stmt)
96-
97-
# Execute commands directly, otherwise
98-
# add program statements to the stored
99-
# BASIC program
100-
101-
if len(tokenlist) > 0:
102-
103-
# remove blank tokens
104-
i = 0
105-
iend = len(tokenlist)
106-
for _ in range(iend):
107-
if i>0 and tokenlist[i].lexeme.strip() == "" and tokenlist[i].category != Token.STRING:
108-
tokenlist.pop(i)
109-
else:
110-
i+=1
111-
112-
# Exit the interpreter
113-
if tokenlist[0].category == Token.EXIT:
114-
if fOpened:
115-
infile.close()
116-
tmpfile.close()
117-
remove('_pybTmp.tmp')
118-
break
119-
120-
# Add a new program statement
121-
elif tokenlist[0].category == Token.UNSIGNEDINT\
122-
and len(tokenlist) > 1:
123-
program.add_stmt(tokenlist,-1,tmpfile)
124-
125-
# Delete a statement from the program
126-
elif tokenlist[0].category == Token.UNSIGNEDINT \
127-
and len(tokenlist) == 1:
128-
program.delete_statement(int(tokenlist[0].lexeme))
129-
130-
# Execute the program
131-
elif tokenlist[0].category == Token.RUN:
132-
try:
133-
program.execute(infile,tmpfile)
134-
135-
except KeyboardInterrupt:
136-
print("Program terminated")
137-
138-
# List the program
139-
elif tokenlist[0].category == Token.LIST:
140-
if len(tokenlist) == 2:
141-
program.list(int(tokenlist[1].lexeme),int(tokenlist[1].lexeme),infile,tmpfile)
142-
elif len(tokenlist) == 3:
143-
program.list(int(tokenlist[1].lexeme),int(tokenlist[2].lexeme),infile,tmpfile)
144-
elif len(tokenlist) == 4:
145-
program.list(int(tokenlist[1].lexeme),int(tokenlist[3].lexeme),infile,tmpfile)
146-
else:
147-
program.list(-1,-1,infile,tmpfile)
148-
149-
# Save the program to disk
150-
elif tokenlist[0].category == Token.SAVE:
151-
if len(tokenlist) <= 1:
152-
print("No filename specified")
153-
elif "/" in tokenlist[1].lexeme or "\\" in tokenlist[1].lexeme or ":" in tokenlist[1].lexeme:
154-
print("Can only save to current directory")
155-
else:
156-
if tokenlist[1].lexeme.split(".")[-1].upper() == "PGM":
157-
filename = tokenlist[1].lexeme+".BAS"
158-
if filename in listdir():
159-
remove(filename)
160-
else:
161-
filename = tokenlist[1].lexeme
162-
163-
if program.save(filename,infile,tmpfile):
164-
# Since we are running the program from the disk file "in place"
165-
# the current program listing is contained only on disk in the
166-
# loaded file (if one has been loaded) and the _pYbTmp.tmp working file
167-
# the program.save function has to save the file to a temporary filename
168-
# and we now have to replace the specified output filename with that
169-
# temporary file. Finally we need to reload the saved file to initialize
170-
# the in place files and index
171-
#
172-
# PGM files are worse since we use the internal file index keys we have to
173-
# first save as a normal BAS file and reaload to eliminate all code from
174-
# the temporary file
175-
program.delete()
176-
if fOpened:
177-
infile.close()
178-
179-
if filename in listdir():
180-
remove(filename)
181-
182-
rename(filename+".pYb",filename)
183-
184-
tmpfile.close()
185-
tmpfile = open('_pybTmp.tmp','w+')
186-
infile = program.load(filename,tmpfile)
187-
if infile != None:
188-
189-
if tokenlist[1].lexeme.split(".")[-1].upper() == "PGM":
190-
191-
filename = tokenlist[1].lexeme
192-
if program.save(filename,infile,tmpfile):
193-
194-
if filename in listdir():
195-
remove(filename)
196-
197-
rename(filename+".pYb",filename)
198-
199-
#.PGM.BAS file now being used, need to close .PGM.BAS and reload .pgm file
200-
program.delete()
201-
infile.close()
202-
infile = program.load(filename,tmpfile)
203-
if infile != None:
204-
remove(filename+".BAS")
205-
fOpened = True
206-
print("Program written to file")
207-
else:
208-
# This should never happen, but just in case...
209-
fOpened = False
210-
print("Program saved but lost from active memory, ",end="")
211-
print("enter load command to re-load saved work")
212-
else:
213-
fOpened = True
214-
print("Program written to file")
215-
else:
216-
# This should never happen, but just in case...
217-
fOpened = False
218-
if tokenlist[1].lexeme.split(".")[-1].upper() == "PGM":
219-
rename(filename,tokenlist[1].lexeme+".BAS")
220-
print("Texed program saved as "+tokenlist[1].lexeme+".BAS but lost from active memory, ",end="")
221-
else:
222-
print("Program saved but lost from active memory, ",end="")
223-
print("enter load command to re-load saved work")
224-
225-
226-
# Load the program from disk and/or delete the program from memory
227-
elif tokenlist[0].category == Token.LOAD or tokenlist[0].category == Token.NEW:
228-
program.delete()
229-
if fOpened:
230-
infile.close()
231-
fOpened = False
232-
233-
tmpfile.close()
234-
tmpfile = open('_pybTmp.tmp','w+')
235-
236-
if tokenlist[0].category == Token.LOAD:
237-
238-
if len(tokenlist) > 1:
239-
infile = program.load(tokenlist[1].lexeme,tmpfile)
240-
if infile != None:
241-
fOpened = True
242-
print("Program read from file")
243-
else:
244-
fOpened = False
245-
else:
246-
print("Program file not found")
247-
248-
else:
249-
print("Unrecognized input")
250-
for token in tokenlist:
251-
token.print_lexeme()
252-
print("")
253-
254-
# Trap all exceptions so that interpreter keeps running
255-
except Exception as e:
256-
if implementation.name.upper() == 'MICROPYTHON':
257-
print_exception(e)
258-
else:
259-
print(e)
260-
261-
if __name__ == "PyDOS":
262-
main(passedIn)
263-
else:
264-
print("Enter 'PyBasic.main()' in the REPL to run.")
1+
import interpreter
2+
if __name__ != "PyDOS":
3+
passedIn = ""
4+
interpreter.main(passedIn)

PyBasic/basicparser.py

Lines changed: 20 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -26,8 +26,9 @@
2626
except:
2727
pass
2828
try:
29-
from pydos_hw import Pydos_hw
30-
sndPin = Pydos_hw.sndPin
29+
from pydos_hw import sndPin as hwsndPin
30+
from pydos_hw import Pydos_hw, quietSnd
31+
sndPin = hwsndPin
3132
except:
3233
sndPin = None
3334

@@ -42,7 +43,7 @@
4243
try: # temporary? until broadcom port supports pwmio
4344
from pwmio import PWMOut
4445
except:
45-
pass
46+
sndPin = None
4647
else:
4748
import winsound
4849
from time import monotonic
@@ -123,15 +124,19 @@ def __init__(self):
123124
#file handle list
124125
self.__file_handles = {}
125126

127+
self.__pwm = None
126128
if implementation.name.upper() == 'MICROPYTHON':
127129
if sndPin:
128130
try:
129131
self.__pwm = PWM(sndPin,freq=0)
130132
except:
131-
self.__pwm = PWM(sndPin)
133+
try:
134+
self.__pwm = PWM(sndPin)
135+
except:
136+
pass
132137
if 'duty_u16' in dir(self.__pwm):
133138
self.__pwm.duty_u16(0)
134-
else:
139+
elif 'duty' in dir(self.__pwm):
135140
self.__pwm.duty(0)
136141

137142

@@ -892,7 +897,7 @@ def __soundstmt(self):
892897
volume = 800
893898

894899
if implementation.name.upper() == 'MICROPYTHON':
895-
if sndPin:
900+
if sndPin and self.__pwm:
896901
self.__pwm.freq(freq)
897902
if "duty_u16" in dir(self.__pwm):
898903
self.__pwm.duty_u16(volume)
@@ -903,14 +908,15 @@ def __soundstmt(self):
903908
sleep(duration/18.2)
904909
self.__pwm.duty(0)
905910
elif implementation.name.upper() == 'CIRCUITPYTHON':
906-
try:
907-
Pydos_hw.sndGPIO.deinit() # Workaround for ESP32-S2 GPIO issue
908-
audioPin = PWMOut(sndPin, duty_cycle=volume, frequency=freq, variable_frequency=True)
909-
sleep(duration/18.2)
910-
audioPin.deinit()
911-
Pydos_hw.quietSnd() # Workaround for ESP32-S2 GPIO issue
912-
except:
913-
pass
911+
if sndPin:
912+
try:
913+
Pydos_hw.sndGPIO.deinit() # Workaround for ESP32-S2 GPIO issue
914+
audioPin = PWMOut(sndPin, duty_cycle=volume, frequency=freq)
915+
sleep(duration/18.2)
916+
audioPin.deinit()
917+
quietSnd() # Workaround for ESP32-S2 GPIO issue
918+
except:
919+
pass
914920
else:
915921
winsound.Beep(freq,int(self.__operand_stack.pop()*1000/18.2))
916922

PyBasic/fractal.bas

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
10 FOR Y = - 12 TO 12
2+
20 FOR X = - 39 TO 30
3+
30 CA = X * 0.0458
4+
40 CB = Y * 0.08333
5+
50 A = CA
6+
60 B = CB
7+
70 FOR I = 0 TO 15
8+
80 T = A * A - B * B + CA
9+
90 B = 2 * A * B + CB
10+
100 A = T
11+
110 IF ( A * A + B * B ) > 5 THEN GOTO 200
12+
120 NEXT I
13+
130 PRINT " " ;
14+
140 GOTO 210
15+
200 IF I > 9 THEN I = I + 7
16+
205 PRINT CHR$ ( 48 + I ) ;
17+
210 NEXT X
18+
220 PRINT
19+
230 NEXT Y

0 commit comments

Comments
 (0)