Browse Source

First Commit.

master
Matthilde 1 year ago
commit
261a03a5ae
  1. 2
      .gitignore
  2. 13
      LICENSE
  3. 9
      parser_test.trt
  4. 130
      programs/README.txt
  5. 2
      programs/error.trt
  6. 56
      programs/hello_world.trt
  7. 6
      programs/recursion.trt
  8. 32
      programs/square.trt
  9. 32
      programs/testing.trt
  10. 25
      programs/turth_machine.trt
  11. 130
      trc.py
  12. 498
      turtlec.py

2
.gitignore vendored

@ -0,0 +1,2 @@ @@ -0,0 +1,2 @@
__pycache__/*
*~

13
LICENSE

@ -0,0 +1,13 @@ @@ -0,0 +1,13 @@
DO WHAT THE FUCK YOU WANT TO PUBLIC LICENSE
Version 2, December 2004
Copyright (C) 2021 Matthilde Autumn Stella
Everyone is permitted to copy and distribute verbatim or modified
copies of this license document, and changing it is allowed as long
as the name is changed.
DO WHAT THE FUCK YOU WANT TO PUBLIC LICENSE
TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
0. You just DO WHAT THE FUCK YOU WANT TO.

9
parser_test.trt

@ -0,0 +1,9 @@ @@ -0,0 +1,9 @@
turtle(turtle(turtle())); # :worry:
mu TuRtlE(ttturtle, tttturtle)
{
Woa( ttturtle, tttturtle); # This is a comment
tttttttUrtle = turtle(turtle(notTurtle())); # This is another comment
turtle(tttttttUrtle);
} # Mu

130
programs/README.txt

@ -0,0 +1,130 @@ @@ -0,0 +1,130 @@
_______ __ __ ______
|_ _.--.--.----| |_| .-----| | by matthilde
| | | | | _| _| | -__| ---|
|___| |_____|__| |____|__|_____|______|
INTRODUCTION
------------
TurtleC is a C-like esoteric programming language that is ran by a
little turtle named... well.... Turtle!
It is quite of a slow programming language because Turtle is not very
fast. It also tends to sleep while running the program. So be patient
when running the program!
NOTE: While pretty much I could test in the interpreter has been tested,
I can't guarantee that the interpreter is 100% stable.
COMPATIBILITY
-------------
The programming language has been entirely developed on a Linux platform
using Python 3.9.5. It does not require any dependencies as it uses the
standard modules included in Python.
NOTE: The programming language has not been tested on Microsoft Windows.
FILES
-----
- turtlec.py - Core TurtleC features, includes a debug interpreter.
- trc.py - TrCI, Turtle C Interpreter. The actual interpreter.
- parser_test.trt - Small script you can't run, designed to test the parser
- programs/*.trt - Example programs
THE INTERPRETER
---------------
Turtle will introduce itself then proceed to run the program, you will
see in the interface the STDERR and STDOUT. This turtle, as I said in
the introduction, is quite slow and can sleep midway in program
execution.
Usage of both the interpreter and the debug interpreter.
./turtlec.py FILENAME
./trc.py FILENAME
HOW TO PROGRAM IN TURTLEC
-------------------------
If you are familiar with any C-like programming langauge such as C,
C++, JavaScript or Rust (there are plenty so i am not going to list
them all), you will get the grip quite easily.
Integers
--------
The integer is the only type bundled in the programming language.
Here are how integers looks like:
noTurtle() = 0
turtle() = 1
turtle(turtle()) = 2
turtle(turtle(turtle(turtle()))) = 4
Arithmetics
-----------
There are builtin functions to do basic arithmetic and logic.
Woa(a, b) = a + b
so Woa(turtle(), turtle(turtle())) == turtle(turtle(turtle()))
WOa(a, b) = a - b
WoA(a, b) = a * b
WOA(a, b) = a / b (since these are integers, it does floor division)
Wow(a, b) = a == b
Returns 1 if true, else it returns 0
WoW(a, b) = a < b
Control Flow
------------
if a>0 then execute the code between brackets
Mu a { ... }
if a==0 then execute the code between brackets
mU a { ... }
while a>0, execute the code between brackets in loop
MU a { ... }
Variable and Function assignement
---------------------------------
Variable assignement goes like this:
varname = expression;
NOTE: variable naming has limitations. For example, if your variable
name does not match this regex: (?i)^t+urtle$
the interpreter will crash.
THIS APPLIES TO BOTH VARIABLE AND FUNCTION NAMES.
Variable names are case sensitive.
ttturtle is a valid variable name
Turtle is a valid variable name
brwhiubhwrui is not valid
TtUrtlE is valid
turtleeeee is not valid
Assigning a function is also as easy as doing it in JavaScript.
mu tTuRtle(tturtle, ttturtle)
{
# ...
}
Comments
--------
Like in Python, type a '#' then write your comment. The text after
# will be ignored.
See examples in the programs
LICENSING
---------
This software is licensed under the WTFPL. see LICENSE for more detail.

2
programs/error.trt

@ -0,0 +1,2 @@ @@ -0,0 +1,2 @@
ghbewuivbhweiubvw
ehuibgewh

56
programs/hello_world.trt

@ -0,0 +1,56 @@ @@ -0,0 +1,56 @@
# Hello World in TurtleC
#
# This is very cursed
# Print out ASCII character
mu tturtle(Tturtle)
{
Turtle = turtle(turtle(turtle(turtle(turtle()))));
Turtle = WoA(Turtle, turtle(turtle()));
Turtle = WoA(Turtle, Turtle);
Turtle = WOa(Turtle, turtle(turtle(turtle())));
wOa(Woa(Turtle, Tturtle));
}
# Space
mu ttturtle()
{
Turtle = turtle(turtle(turtle(turtle())));
Turtle = WoA(Turtle, Turtle);
Turtle = WoA(Turtle, turtle(turtle()));
wOa(Turtle);
}
# Here goes the hello
Turtle = turtle(turtle(turtle(turtle(turtle(turtle(turtle()))))));
tturtle(Turtle); # h
Turtle = WOa(Turtle, turtle(turtle(turtle())));
tturtle(Turtle); # e
Turtle = Woa(Turtle, turtle(turtle(turtle(
turtle(turtle(turtle(turtle())))))));
tturtle(Turtle); # l
tturtle(Turtle); # l
Turtle = Woa(Turtle, turtle(turtle(turtle())));
tturtle(Turtle); # o
ttturtle(); # Space seperating two words.
Turtle = WOa(Turtle, turtle(turtle(turtle())));
Turtle = Woa(Turtle, Turtle);
tturtle(Turtle); # w
Turtle = WOA(Turtle, turtle(turtle()));
Turtle = Woa(Turtle, turtle(turtle(turtle())));
tturtle(Turtle); # o
Turtle = Woa(Turtle, turtle(turtle(turtle())));
tturtle(Turtle); # r
Turtle = WOa(Turtle, turtle(turtle(turtle(
turtle(turtle(turtle()))))));
tturtle(Turtle); # l
tturtle(turtle(turtle(turtle()))); # d
Turtle = WOa(Turtle, turtle());
wOa(Turtle); # \n
# Here goes the world

6
programs/recursion.trt

@ -0,0 +1,6 @@ @@ -0,0 +1,6 @@
mu ttturtle()
{
ttturtle();
}
ttturtle();

32
programs/square.trt

@ -0,0 +1,32 @@ @@ -0,0 +1,32 @@
# Testing control flows
# Prints a square
TURTLE = turtle(turtle(turtle(turtle())));
TURTLE = WoA(TURTLE, WoA(TURTLE, TURTLE));
# Return
mu tturtle()
{
wOa(turtle(turtle(turtle(turtle(turtle(
turtle(turtle(turtle(turtle(turtle()))))))))));
}
# Character
Tturtle = turtle(turtle(turtle(turtle(turtle()))));
TTurtle = Woa(Tturtle, Tturtle);
Turtle = noTurtle(); # x
tUrtle = noTurtle(); # y
MU WoW(tUrtle, Tturtle)
{
MU WoW(Turtle, TTurtle)
{
wOa(TURTLE);
Turtle = Woa(turtle(), Turtle);
}
Turtle = noTurtle();
tUrtle = Woa(turtle(), tUrtle);
tturtle();
}

32
programs/testing.trt

@ -0,0 +1,32 @@ @@ -0,0 +1,32 @@
# Testing control flows
# Prints a square
TURTLE = turtle(turtle(turtle(turtle())));
TURTLE = WoA(TURTLE, WoA(TURTLE, TURTLE));
# Return
mu tturtle()
{
wOa(turtle(turtle(turtle(turtle(turtle(
turtle(turtle(turtle(turtle(turtle()))))))))));
}
# Character
Tturtle = turtle(turtle(turtle(turtle(turtle()))));
TTurtle = Woa(Tturtle, Tturtle);
Turtle = noTurtle(); # x
tUrtle = noTurtle(); # y
MU WoW(tUrtle, Tturtle)
{
MU WoW(Turtle, TTurtle)
{
wOa(TURTLE);
Turtle = Woa(turtle(), Turtle);
}
Turtle = noTurtle();
tUrtle = Woa(turtle(), tUrtle);
tturtle();
}

25
programs/turth_machine.trt

@ -0,0 +1,25 @@ @@ -0,0 +1,25 @@
# TurtleC Truth Machine
mu tturtle()
{
# 3
Turtle = turtle(turtle(turtle()));
# 3 * 4 = 12
Turtle = WoA(Turtle, turtle(turtle(turtle(turtle()))));
# 12 * 4 = 48 = '0'
Turtle = WoA(Turtle, turtle(turtle(turtle(turtle()))));
# 48 + 1 = 49 = '1'
Turtle = Woa(Turtle, turtle());
# Takes input
tUrtle = woA();
wOa(tUrtle);
# If input == '1' then repeat infinitely
MU Wow(tUrtle, Turtle)
{
wOa(tUrtle);
}
}
tturtle();

130
trc.py

@ -0,0 +1,130 @@ @@ -0,0 +1,130 @@
#!/usr/bin/env python3
#
# The TurtleC Interpreter by matthilde
#
import os, sys, time, random, math
from turtlec import *
def _clear():
os.system('cls' if os.name == "nt" else 'clear')
turtle_stderr = ""
turtle_stdout = ""
turtle_pos = 1
file_lines = 0
def turtle_update():
global turtle_stderr
_clear()
n = random.randint(0, 50)
w = 5 if n == 24 else random.randint(5, 40) / 100
if n == 24:
turtle_stderr += "*yawn* this is tiring, imma sleep for a bit...\n"
tp = math.floor((turtle_pos / file_lines) * 20)
print(' '*tp + 'o')
print('-'*20 + '[GOAL!]\n')
print("--- STDERR ---")
stdrr = turtle_stderr.strip()
if stdrr != '':
stdrr = stdrr.split('\n')
print("[Turtle]", "\n[Turtle] ".join(stdrr))
print("--- STDOUT ---")
print(turtle_stdout.strip())
print("--------------")
time.sleep(w)
def turtle_ppre(a, b, linenum):
global turtle_pos, turtle_stderr
if linenum > 0:
turtle_pos = linenum
turtle_update()
def turtle_print(*args, end='\n'):
global turtle_stdout
turtle_stdout += ' '.join([str(x) for x in args])
turtle_stdout += end
turtle_update()
### MODIFIED BUILT-INS
def turtle_wOa(env, *args):
for x in args:
x = x(env).value
turtle_print(chr(x), end='')
def turtle_wOA(env, *args):
for x in args:
x = x(env).value
print(x, end=' ')
print()
def turtle_woA(env):
prompt = "[Turtle] Please type a character on your keyboard,\n" + \
"[Turtle] I need it >.> "
return TurtleInteger(ord(input(prompt)[0]))
######
def turtle_introduction():
print(" o <- the turtle\n---")
quotes = [
"Hewwo!",
"I am Turtle! The small turtle that will run your program!",
"Be patient with me, I am kinda slow >.<",
"Know that a function or a while loop can pull me back " + \
"during my journey >.>"]
for quote in quotes:
print("[Turtle]", quote, end=' ')
input()
def main(fn):
global file_lines, turtle_stderr, turtle_pos
file_lines = len(fn.split('\n'))
_clear()
turtle_introduction()
env = default_env.copy()
env["wOa"] = turtle_wOa
env["wOA"] = turtle_wOA
env["woA"] = turtle_woA
try:
ast = build_ast(tokenize(fn), ppre = turtle_ppre)
for line in ast:
line(env)
except TurtleException as e:
dl = '\n | '.join(lines[max(e.linenum-3, 0):e.linenum+2])
turtle_stderr = f"""
Ouchie!!
I have encountered an error that prevents me from continuing at these
lines:
| {dl}
Error at line {e.linenum}: {e.err}
"""
turtle_update()
sys.exit(1)
except RecursionError:
turtle_stderr = f"Ouchie! Too much recursion >.<"
turtle_update()
sys.exit(1)
turtle_pos = file_lines
turtle_stderr += "I finished!!, that was difficult >.<\n"
turtle_update()
if __name__ == "__main__":
if len(sys.argv) != 2:
print("USAGE: trci FILENAME")
sys.exit(1)
else:
try:
with open(sys.argv[1]) as f:
main(f.read())
except IOError:
print("Could not open the file")

498
turtlec.py

@ -0,0 +1,498 @@ @@ -0,0 +1,498 @@
#!/usr/bin/env python3
# TurtleC - C-like with turtles (i think, not sure)
#
# For the turtle-themed Esojam
#
# Integers
# turtle() = 1
# turtle(turtle()) = 2
# turtle(turtle(turtle(turtle()))) = 4
# noTurtle() = 0
#
# Arith
# Woa(a, b) = a + b
# Woa(turtle(turtle()), turtle(turtle(turtle()))) =
# turtle(turtle(turtle(turtle(turtle())))))
# WOa(a, b) = a - b
# WoA(a, b) = a * b
# WOA(a, b) = a / b
#
# Wow(a, b) = a == b
# WoW(a, b) = a < b
#
# Control Flow
# Mu a { ... } # if (a>0) { ... }
# mU a { ... } # if (a==0) { ... }
# MU a { ... } # while (a) { ... }
#
# Functions and Variables
#
# tUrtle = turtle() # Assigns 1 to tUrtle
# mu Tturtle(tturtle, ttturtle) { ... } # Function named Tturtle
# Function will return the last instruction
#
# I/O
# wOa(a, b, c, ...) # Output a stream of integers as ASCII chars
# wOA(a, b, c, ...) # Output a stream of integers as integers
# woA() # Returns a byte from stdin
#
# Variable notation standards
# Variables are case-sensitive and must be named turtle. You can
# combine uppercase and lowercase to have different variables
# You can also have as much T as you want in the beginning of the name
#
# ttturtle # Valid name
# Turtle # Valid name
# notATurtle # Not a valid name
# TtUrtlE # Valid name
#
import sys, re, time
blocks = ["Mu", "mU", "MU", "mu"]
int_funcs = ["turtle", "noTurtle"]
pchars = "(){},;="
_parser_re = re.compile(r"(#.*(\n|$)|[\(\),{}=;]|[^\(\),{}=;\s]+)")
### BUILT-INS ###
def _builtin_set_value(env, k, v):
k = k.name
assert is_turtle(k), "That variable name is not turtle enough. FIX IT."
env[k] = v(env)
return env[k]
# from pprint import pprint
def _builtin_Woa(env, a, b):
return a(env).__add__(b(env))
def _builtin_WOa(env, a, b):
return a(env).__sub__(b(env))
def _builtin_WoA(env, a, b):
return a(env).__mul__(b(env))
def _builtin_WOA(env, a, b):
return a(env).__floordiv__(b(env))
def _builtin_Wow(env, a, b):
return a(env).__eq__(b(env))
def _builtin_WoW(env, a, b):
return a(env).__lt__(b(env))
def _builtin_wOa(env, *args):
for x in args:
x = x(env).value
print(chr(x), end='')
def _builtin_wOA(env, *args):
for x in args:
x = x(env).value
print(x, end=' ')
print()
def _builtin_woA(env):
return TurtleInteger(ord(input()[0]))
default_env = {
"_set_value": _builtin_set_value,
"Woa": _builtin_Woa,
"WOa": _builtin_WOa,
"WoA": _builtin_WoA,
"WOA": _builtin_WOA,
"Wow": _builtin_Wow,
"WoW": _builtin_WoW,
"wOa": _builtin_wOa,
"wOA": _builtin_wOA,
"woA": _builtin_woA
}
### ERROR ###
class TurtleException(Exception):
def __init__(self, linenum, err):
self.linenum = linenum
self.err = err
def __str__(self):
return self.err
### CLASSES ###
class TurtleInteger:
def __init__(self, value, linenum = 0):
self.value = value
self.linenum = linenum
def __str__(self):
return str(self.value)
def __call__(self, env):
return self
def __add__(self, v):
return TurtleInteger(self.value + v.value)
def __sub__(self, v):
return TurtleInteger(self.value - v.value)
def __mul__(self, v):
return TurtleInteger(self.value * v.value)
def __floordiv__(self, v):
return TurtleInteger(self.value // v.value)
def __eq__(self, v):
return TurtleInteger(int(self.value == v.value))
def __lt__(self, v):
return TurtleInteger(int(self.value < v.value))
class TurtleVariable:
def __init__(self, name, linenum = 0):
self.name = name
self.linenum = linenum
def __str__(self):
return f"[[ variable {self.name} ]]"
def __call__(self, env):
if self.name not in env:
raise TurtleException(self.linenum,
f"{self.name}: Variable does not exist.")
elif type(env[self.name]) != TurtleInteger:
raise TurtleException(self.linenum,
f"{self.name} is not an integer.")
return env[self.name]
class TurtleFunction:
def __init__(self, args, code):
self.args = args
self.code = code
def __call__(self, env, *args):
assert len(args) == len(self.args), "Invalid arguments"
args = [x(env) for x in args]
args = dict(zip(self.args, args))
env = {**env.copy(), **args}
if type(self.code) == list:
for instruction in self.code:
ret = instruction(env)
else:
ret = code(env)
return ret
def __str__(self):
return f"Function {args}"
class TurtleFunctionCall:
def __init__(self, name, args, linenum = 0, pre = None):
self.name = name
self.args = args
self.linenum = linenum
self.pre = pre
def __str__(self):
return f"mu {self.name} {[str(x) for x in self.args]}"
def error(self, msg):
raise TurtleException(self.linenum, f"{self.name}: {msg}")
def _assert(self, cond, msg):
if not cond:
self.error(msg)
def __call__(self, env):
self._assert(self.name in env, "Function does not exist.")
if self.pre:
self.pre(self.name, self.args, self.linenum)
# args = [x(env) for x in self.args]
args = self.args
try:
ret = env[self.name](env, *args)
except AssertionError as e:
self.error(e)
except TypeError as e:
self.error("Invalid Arguments.")
return ret if ret else TurtleInteger(0)
class TurtleBlock:
# name expr
# {
# code
# }
def __init__(self, name, expr, code, linenum = 0):
assert name in blocks, "Unknown Block."
self.name = name
self.expr = expr
self.code = code
self.linenum = linenum
def __str__(self):
return "[[ block ]]"
def __call__(self, env):
name = self.name
if name == "Mu":
if self.expr(env).value > 0:
self.run_block(env)
elif name == "mU":
if self.expr(env).value == 0:
self.run_block(env)
elif name == "MU":
while self.expr(env).value > 0:
self.run_block(env)
elif name == "mu":
if type(self.expr) != TurtleFunctionCall:
raise TurtleException(self.linenum,
"Syntax Error.")
elif not is_turtle(self.expr.name):
raise TurtleException(self.linenum,
"Not a valid turtle name smh")
args = []
for x in self.expr.args:
if type(x) != TurtleVariable:
raise TurtleException(self.linenum,
"Syntax Error.")
elif not is_turtle(x.name):
raise TurtleException(self.linenum,
"Not a valid turtle name smh")
args.append(x.name)
env[self.expr.name] = TurtleFunction(args, self.code)
else:
raise AssertionError("How?????")
def run_block(self, env):
if type(self.code) == list:
for instruction in self.code:
instruction(env)
else:
self.code(env)
class TurtleToken:
def __init__(self, value, linenum = 0, tp = None):
self.value = value
self.linenum = linenum
if tp:
self.type = tp
else:
self.type = find_token_type(self.value)
def __str__(self):
return f"TurtleToken('{self.value}', {self.linenum}, '{self.type}')"
def t(self):
return (self.value, self.type)
### FUNCTIONS ###
def find_token_type(t):
if t in pchars:
return "delim"
elif t in blocks:
return "block"
elif t in int_funcs:
return "integer"
else:
return "symbol"
def is_turtle(s):
return re.match(r"(?i)^t+urtle$", s) != None
def tokenize(s):
output = []
for linenum, line in enumerate(s.split("\n")):
line = line.strip()
if line == '':
continue
matches = [(x[0], linenum+1) for x in _parser_re.findall(line)
if not x[0].startswith("#")]
output += matches
return [TurtleToken(x[0], x[1]) for x in output]
# TODO: AST Builder
def find_parens(oline, tokens, syms = "()"):
b = 1
output = []
sym, isym = syms
while tokens != []:
token = tokens.pop(0)
if token.type == 'delim':
if token.value == sym:
b += 1
elif token.value == isym:
b -= 1
if b == 0:
return output
else:
output.append(token)
raise TurtleException(oline, "Expected parenthese, got EOF.")
def find_until(oline, tokens, sym = '{', parens = '()', fr = False):
expr = []
b = 0
paren, iparen = parens
while tokens != []:
token = tokens.pop(0)
if token.t() == (paren, 'delim'):
b += 1
elif token.t() == (iparen, 'delim'):
b -= 1
if b < 0:
raise TurtleException(token.linenum, "Syntax Error.")
elif token.t() == (sym, 'delim') and b == 0:
return expr
else:
expr.append(token)
if fr:
return expr
else:
raise TurtleException(oline, "Syntax Error.")
def build_ast(tokens, noblock = False, ppre = None):
ast = []
while tokens != []:
token = tokens.pop(0)
if token.type == 'block' and not noblock:
btype = token.value
bline = token.linenum
bexpr = find_until(bline, tokens)
bexpr = build_ast(bexpr, True, ppre = ppre)[0]
bcode = build_ast(find_parens(bline, tokens, "{}"),
ppre = ppre)
ast.append(TurtleBlock(btype, bexpr, bcode, bline))
elif token.type == 'delim':
raise TurtleException(token.linenum, "Syntax Error.")
elif token.type == 'integer':
line = find_until(token.linenum, tokens, ';', fr=True)
if token.value == 'noTurtle':
if line[0].t() == ('(', 'delim') and \
line[1].t() == (')', 'delim'):
ast.append(TurtleInteger(0, token.linenum))
else:
raise TurtleException(token.linenum, "Syntax Error.")
elif token.value == 'turtle':
acc = 1
tline = token.linenum
while line != []:
token = line.pop(0)
if token.t() != ('(', 'delim'):
raise TurtleException(token.linenum,
"Invalid turtle notation.")
else:
token = line.pop(0)
if token.t() == (')', 'delim'):
break
elif token.t() == ('turtle', 'integer'):
acc += 1
else:
raise TurtleException(token.linenum,
"Invalid turtle notation.")
if token.t() != (')', 'delim'):
print(token)
raise TurtleException(token.linenum, "Syntax Error.")
else:
ast.append(TurtleInteger(acc, token.linenum))
else:
# Unlikely to happen so, Imma put a random message.
raise TurtleException(1, ":worry:")
elif token.type == "symbol":
line = find_until(token.linenum, tokens, ';', fr=True)
if line == []:
ast.append(TurtleVariable(token.value, token.linenum))
elif line[0].t() == ('=', 'delim') and len(line) != 1:
vname = token.value
vexpr = build_ast(line[1:], True)[0]
ast.append(TurtleFunctionCall("_set_value",
[TurtleVariable(vname), vexpr],
token.linenum, ppre))
elif line[0].t() == ('(', 'delim') and \
line[-1].t() == (')', 'delim'):
vname = token.value
line = line[1:-1]
mu = []
while line != []:
mu.append(build_ast(find_until(
token.linenum, line, ',', fr=True))[0])
ast.append(TurtleFunctionCall(vname, mu, token.linenum, ppre))
else:
raise TurtleException(token.linenum, "Syntax Error.")
else:
raise TurtleException(1, "???????")
return ast
# TODO: Write tests
# TODO: Add a lil turtle to the interpreter :3
def debug_interpreter(prgm):
lines = prgm.split('\n')
env = default_env.copy()
try:
ast = build_ast(tokenize(prgm))
for line in ast:
line(env)
except TurtleException as e:
print("ERROR!")
print(' |',
'\n | '.join(lines[max(e.linenum-3, 0):e.linenum+2]))
print(f" At line {e.linenum}")
print(f" -> {e.err}")
sys.exit(1)
except RecursionError:
print("Implementing TCO :despair:")
sys.exit(1)
def main(filename):
with open(filename) as f:
debug_interpreter(f.read())
if __name__ == "__main__":
if len(sys.argv) != 2:
print("Usage: mtl FILENAME")
sys.exit(1)
try:
main(sys.argv[1])
except IOError:
print("Couldn't load the file :pensive:")
Loading…
Cancel
Save