I've decided to write a very simply output programming language. All the user does is write ASCII values inside ASCII fish, and the interpreter pieces the values together and outputs them.
I'm mainly looking for feedback on the interpreter, as the language itself is very easy to understand.
Here's what a Hello, World!
program looks like in Fishy
:
><72> ><101> ><108> ><108> ><111> ><44> ><32> ><87> ><111> ><114> ><108> ><100> ><33>
All the rules of the language are listed in the module docstring of the program.
"""
Fishy (.fishy extension)
><> Frontfish
Implementation is simple:
You enter ASCII values between the facing signs <>
Commands on separate lines will have output separated by a new line
Example:
><98> ><112> ><113> ><107>
bpqk
><97>
><108>
><101>
a
l
e
NO TRAILING WHITESPACE!
Trailing whitespace after the last fish on the line will result in a syntax error
"""
import argparse
import os
import sys
from typing import List
def run_code(code: List[str]):
"""
Runs the passed Fishy Code
"""
for line in code:
# Clean up code and separate commands#
line = line.strip("\n")
commands = line.split(" ")
# Check if line has multiple statements in it
if len(commands) > 1:
if correct_syntax(commands):
output = "".join(chr(get_number(fish)) for fish in commands)
print(output)
else:
if correct_syntax(commands):
print(chr(get_number(commands[0])))
def correct_syntax(pond: List[str]) -> bool:
"""
Checks the syntax of the passed list of commands on the following criteria:
Is a fish ><..>
Correct Example:
><98> ><108> ><56>
Incorrect Example:
><98> >><<76>> ><[108>
"""
for fish in pond:
if not is_fish(fish):
sys.exit(f"Incorrect Syntax: {fish}")
return True
def is_fish(fish: str) -> bool:
"""
Returns if the passed fish is the fish or not
Fish: Starts with >< ends with >
A fish like so ><98g> will be caught by "get_number()" function
"""
return fish.startswith("><") and fish.endswith(">")
def get_number(fish: str) -> int:
"""
Returns the number in the fish
"""
# Check font fish first #
try:
number = int(fish[2:-1])
except ValueError:
sys.exit(f"Incorrect Syntax: {fish}")
return number
def get_content(file: str) -> List[str]:
"""
Returns all the content in the passed file path
:param file -> str: File to read content
:return List[str]: Content in file
"""
with open(file, "r") as file:
return [line for line in file]
def main() -> None:
"""
Sets up argparser and runs main program
"""
parser = argparse.ArgumentParser(description="Enter path to .fishy program file")
parser.add_argument("Path", metavar="path", type=str, help="path to .fishy program file")
args = parser.parse_args()
file_path = args.Path
if not os.path.isfile(file_path):
sys.exit("The file does not exist")
content = get_content(file_path)
run_code(content)
if __name__ == "__main__":
main()