Skip to content

Commit

Permalink
Merge pull request #60 from Rudxain/patch-1
Browse files Browse the repository at this point in the history
Refactor and bug fix
  • Loading branch information
SatinWukerORIG authored Nov 30, 2022
2 parents 351fdb2 + 753f1f7 commit cfce12c
Show file tree
Hide file tree
Showing 9 changed files with 457 additions and 412 deletions.
34 changes: 18 additions & 16 deletions src-py/AudioGenerator.py
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
from typing import Final

pyttsxMissingBool = False
playsoundMissingBool = False
dependancyMissingBool = False
Expand All @@ -19,16 +21,16 @@

if dependancyMissingBool:
print(dependancyMissingCounter, " packages are missing. Would you like to install them or stop the script?(Y/N)")
installChoice=input().upper()
installChoice: Final = input().upper()
if installChoice=="Y":
print("pip needed for this to work.")
import os
from os import system
if pyttsxMissingBool:
print("Installing the pip package pyttsx3...")
os.system("pip install pyttsx3")
system("pip install pyttsx3")
if playsoundMissingBool:
print("Installing the pip package playsound...")
os.system("pip install playsound")
system("pip install playsound")
try:
from pyttsx3 import init
except:
Expand All @@ -45,21 +47,21 @@

from Keywords import *

engine = init()
engine: Final = init()

audio = {
KW_print: 'audios/print.wav',
KW_let: 'audios/let.wav',
KW_main: 'audios/main.wav',
KW_if: 'audios/if.wav',
KW_end: 'audios/end.wav',
KW_break: 'audios/break.wav',
KW_while_loop: 'audios/whileloop.wav',
KW_endless_loop: 'audios/loop.wav',
audio: Final = {
KW.PRINT.value: 'audios/print.wav',
KW.LET.value: 'audios/let.wav',
KW.MAIN.value: 'audios/main.wav',
KW.IF.value: 'audios/if.wav',
KW.END.value: 'audios/end.wav',
KW.BREAK.value: 'audios/break.wav',
KW.WHILE_LOOP.value: 'audios/whileloop.wav',
KW.ENDLESS_LOOP.value: 'audios/loop.wav',
}

def play(token):
au = audio.get(token)
def play(token: str):
au: Final = audio.get(token)

if au:
play_wav(au)
Expand Down
108 changes: 41 additions & 67 deletions src-py/Keywords.py
Original file line number Diff line number Diff line change
@@ -1,86 +1,60 @@
from sys import stdout
from typing import Final
from enum import Enum

# Keywords
KW_print = 'ijustwannatelluhowimfeeling'
KW_if = 'andifuaskmehowimfeeling'

KW_let = 'give'
KW_assign = 'up'
KW_import1 = 'weknowthe'
KW_import2 = "andwe'regonnaplayit"
KW_def = 'gonna'
KW_return1 = 'whenigivemy'
KW_return2 = 'itwillbecompletely'
KW_try = 'thereaintnomistaking'
KW_except = 'iftheyevergetudown'
KW_main = 'takemetourheart'
KW_end = 'saygoodbye'
class KW(Enum):
"""Keywords"""
PRINT = 'ijustwannatelluhowimfeeling'
IF = 'andifuaskmehowimfeeling'

KW_break = 'desertu'
KW_continue = 'runaround'
KW_endless_loop = 'togetherforeverandnevertopart'
KW_while_loop = 'togetherforeverwith'
LET = 'give'
ASSIGN = 'up'
IMPORT1 = 'weknowthe'
IMPORT2 = "andwe'regonnaplayit"
DEF = 'gonna'
RETURN1 = 'whenigivemy'
RETURN2 = 'itwillbecompletely'
TRY = 'thereaintnomistaking'
EXCEPT = 'iftheyevergetudown'
MAIN = 'takemetourheart'
END = 'saygoodbye'

KW_L_OP = 'islessthan'
KW_G_OP = 'isgreaterthan'
KW_GOE_OP = 'isgreaterthanorequalto'
KW_LOE_OP = 'islessthanorequalto'
KW_is_not_OP = 'aint'
KW_E_OP = 'is'
BREAK = 'desertu'
CONTINUE = 'runaround'
ENDLESS_LOOP = 'togetherforeverandnevertopart'
WHILE_LOOP = 'togetherforeverwith'

KW_PY = "py:"
G_OP = 'isgreaterthan'
L_OP = 'islessthan'
GOE_OP = 'isgreaterthanorequalto'
LOE_OP = 'islessthanorequalto'
IS_NOT_OP = 'aint'
E_OP = 'is'

keywords = [
KW_print,
KW_if,
KW_let,
KW_assign,
KW_import1,
KW_import2,
KW_def,
KW_return1,
KW_return2,
KW_try,
KW_except,
KW_main,
KW_end,
KW_break,
KW_continue,
KW_endless_loop,
KW_while_loop,
KW_L_OP,
KW_G_OP,
KW_GOE_OP,
KW_LOE_OP,
KW_is_not_OP,
KW_E_OP,
PY = 'py:'

KW_PY
]

INDENT_KW = [
KW_if, KW_def, KW_try, KW_except, KW_while_loop, KW_endless_loop
]
KEYWORDS: Final[list[str]] = [e.value for e in KW]
"""values in `KW`"""

INDENT_KW: Final = [KW[k].value for k in ['IF', 'DEF', 'TRY', 'EXCEPT', 'WHILE_LOOP', 'ENDLESS_LOOP']]
"""keywords that require indentation in their body (when transpiled to py)"""

# Tokens that the interpreter will totally ignore
ignore_tokens = {'~', "'"}
IGNORE_TOKENS: Final = set("~'")
"""Tokens that the interpreter will totally ignore"""

# Characters in numbers
digits = {'0', '1', '2', '3', '4', '5', '6', '7', '8', '9', '.'}
DIGITS: Final = set('0123456789.')
"""Characters in numerals"""

# Separators are used in tokenization
separators = {
SEPARATORS: Final = {
# not using `set`, because readability, and multi-char `str`s may be added in the future
'(', ')', '[', ']', '{', '}', ',', '\n', ' ', '+', '-', '*', '/', '%', '^', '='
}
"""Separators are used in tokenization"""

# Operators
operators = {
OPERATORS: Final = {
'+', '-', '*', '/', '%', '^', '=',
'[', ']', '(', ')', '{', '}', ',',
'>', '<', '<=', '>=', '!=', 'is', 'aint'
}
OP_build_in_functions = {'to_string', 'to_int', 'to_float', 'length'}

def join_list(l):
return ''.join(map(str, l))
OP_BUILT_IN_FUNCTIONS: Final = {'to_string', 'to_int', 'to_float', 'length'}
38 changes: 21 additions & 17 deletions src-py/Lexer.py
Original file line number Diff line number Diff line change
@@ -1,39 +1,46 @@
# the type-checker complains about the re-export, for some reason,
# so we must explicitly import it here.
from typing import Final

from Keywords import *
from helpers import remove_all

ALL_KW_STR: Final = ','.join(KEYWORDS)

all_keyword_string = ','.join(keywords)
def lexicalize(stmt: str):
SP_LN: Final = {' ', '\n'}

def lexicalize(stmt):
current_token = ''
quote_count = 0
tokens = []
tokens: list[str] = []
for char in stmt:
if char == '"': quote_count += 1
if char == '#': break
if char in ignore_tokens and quote_count % 2 == 0:
if char in IGNORE_TOKENS and quote_count % 2 == 0:
continue

if char in separators and quote_count % 2 == 0:
if current_token not in {' ', '\n'}:
if char in SEPARATORS and quote_count % 2 == 0:
if current_token not in SP_LN:
tokens.append(current_token)
if char not in {' ', '\n'}:
if char not in SP_LN:
tokens.append(char)

current_token = ''
else: current_token += char

return order_words(tokens)

def order_words(tokens):
def order_words(tokens: list[str]):
"""
if current token+kw_in_statement is in all keyword string, kw_in_statement += token
if current token+kw_in_statement not in all keyword string, add kw_in_statement to final_token
if statement is ended, add kw_in_statement to final_token
if current `token+kw_in_statement` is in all keyword string, `kw_in_statement += token`
if current `token+kw_in_statement` not in all keyword string, add `kw_in_statement` to `final_token`
if statement is ended, add `kw_in_statement` to `final_token`
"""
final_token = []
final_token: Final[list[str]] = []
kw_in_statement = ''
temp = False
for tok in tokens:
if tok in all_keyword_string and kw_in_statement + tok in all_keyword_string:
if tok in ALL_KW_STR and kw_in_statement + tok in ALL_KW_STR:
kw_in_statement += tok

else:
Expand All @@ -45,7 +52,4 @@ def order_words(tokens):
if not temp:
final_token.append(kw_in_statement)

while '' in final_token:
final_token.remove('')

return final_token
return remove_all(final_token, '')
136 changes: 69 additions & 67 deletions src-py/RickRoll.py
100644 → 100755
Original file line number Diff line number Diff line change
@@ -1,67 +1,69 @@
from time import time
start = time() # Set and start a timer

from sys import stdout
from traceback import format_exc
from argparse import ArgumentParser


def play_audio(src_file_name):
import AudioGenerator
from pyrickroll import Token
from Lexer import lexicalize

with open(src_file_name, mode='r', encoding='utf-8') as src:
content = src.readlines()
content[-1] += '\n'
for statement in content:
tokens = lexicalize(statement)
tok = Token(tokens)

for i in range(len(tok.t_values)):
AudioGenerator.play(tok.t_values[i])

def main():

arg_parser = ArgumentParser()
arg_parser.add_argument("file", nargs='?', default="")
arg_parser.add_argument("-cpp", action = "store_true")
arg_parser.add_argument("-intpr", action = "store_true")
arg_parser.add_argument("--time", action = "store_true")
arg_parser.add_argument("--audio", action = "store_true")
args = arg_parser.parse_args()

# Run the RickRoll program
if args.file:
from os.path import exists
# Convert .rickroll to C++
if args.cpp:
from crickroll import run_in_cpp
run_in_cpp(args.file)

# Execute .rickroll using the interpreter
elif args.intpr:
from interpreter import run_in_interpreter
run_in_interpreter(args.file)

else:
try:
from pyrickroll import run_in_py
exec(run_in_py(args.file), globals(), globals())
except Exception:
error_msg = format_exc().split('File "<string>",')[-1]
stdout.write(f'Exception in{error_msg}')

else:
stdout.write('Warning: [Not executing any script...]')


if args.audio:
play_audio(args.file)

if args.time:
stdout.write(f'\nExecution Time: [{time() - start}] sec.\n')


if __name__ == "__main__":
main()
#!/usr/bin/env python3
from typing import Final
from traceback import format_exc


def play_audio(src_file_name: str):
import AudioGenerator
from pyrickroll import Token
from Lexer import lexicalize

with open(src_file_name, mode='r', encoding='utf-8') as src:
content = src.readlines()
if len(content) > 0:
content[-1] += '\n'
for statement in content:
tokens = lexicalize(statement)
tok = Token(tokens)

for v in tok.t_values:
AudioGenerator.play(v)


def main():
from argparse import ArgumentParser
from sys import stdout
from time import time

arg_parser = ArgumentParser()
arg_parser.add_argument("file", nargs='?', default="")
arg_parser.add_argument("-cpp", action="store_true")
arg_parser.add_argument("-intpr", action="store_true")
arg_parser.add_argument("--time", action="store_true")
arg_parser.add_argument("--audio", action="store_true")
args = arg_parser.parse_args()

# excludes `def`s, `import`s and `argparse` times
start: Final = time()
# Run the RickRoll program
if args.file:
# Convert .rickroll to C++
if args.cpp:
from crickroll import run_in_cpp
run_in_cpp(args.file)

# Execute .rickroll using the interpreter
elif args.intpr:
from interpreter import run_in_interpreter
run_in_interpreter(args.file)

else:
try:
from pyrickroll import run_in_py
exec(run_in_py(args.file), globals(), globals())
except Exception:
error_msg = format_exc().split('File "<string>",')[-1]
stdout.write(f'Exception in{error_msg}')

else:
stdout.write('Warning: [Not executing any script...]')

if args.audio:
play_audio(args.file)

if args.time:
stdout.write(f'\nExecution Time: [{time() - start}] sec.\n')


if __name__ == "__main__":
main()
Loading

0 comments on commit cfce12c

Please sign in to comment.