summaryrefslogtreecommitdiff
path: root/tiger-compiler/tcsh/python
diff options
context:
space:
mode:
Diffstat (limited to 'tiger-compiler/tcsh/python')
-rw-r--r--tiger-compiler/tcsh/python/Makefile.am60
-rw-r--r--tiger-compiler/tcsh/python/tc.py97
-rwxr-xr-xtiger-compiler/tcsh/python/tcsh-hir.test8
-rwxr-xr-xtiger-compiler/tcsh/python/tcsh-llvm.test8
-rw-r--r--tiger-compiler/tcsh/python/tests/ast.ipynb394
-rw-r--r--tiger-compiler/tcsh/python/tests/astclone.ipynb212
-rw-r--r--tiger-compiler/tcsh/python/tests/bind.ipynb283
-rw-r--r--tiger-compiler/tcsh/python/tests/combine.ipynb207
-rw-r--r--tiger-compiler/tcsh/python/tests/common.ipynb154
-rw-r--r--tiger-compiler/tcsh/python/tests/desugar.ipynb343
-rw-r--r--tiger-compiler/tcsh/python/tests/escapes.ipynb194
-rwxr-xr-xtiger-compiler/tcsh/python/tests/ipynbtest.py279
-rw-r--r--tiger-compiler/tcsh/python/tests/llvmtranslate.ipynb220
-rw-r--r--tiger-compiler/tcsh/python/tests/misc.ipynb358
-rw-r--r--tiger-compiler/tcsh/python/tests/object.ipynb182
-rw-r--r--tiger-compiler/tcsh/python/tests/overload.ipynb207
-rw-r--r--tiger-compiler/tcsh/python/tests/parse.ipynb150
-rw-r--r--tiger-compiler/tcsh/python/tests/tc.ipynb252
-rw-r--r--tiger-compiler/tcsh/python/tests/ti.ipynb186
-rw-r--r--tiger-compiler/tcsh/python/tests/type.ipynb228
-rwxr-xr-xtiger-compiler/tcsh/python/ti.py356
21 files changed, 4378 insertions, 0 deletions
diff --git a/tiger-compiler/tcsh/python/Makefile.am b/tiger-compiler/tcsh/python/Makefile.am
new file mode 100644
index 0000000..442b582
--- /dev/null
+++ b/tiger-compiler/tcsh/python/Makefile.am
@@ -0,0 +1,60 @@
+## ------------------------ ##
+## Included sub makefiles. ##
+## ------------------------ ##
+
+include $(top_srcdir)/tcsh/run.mk
+
+pyexec_LTLIBRARIES =
+
+# Build a Swig wrapper for each module.
+$(srcdir)/swig.mk: $(top_srcdir)/tcsh/generate-swig-mk
+ $(AM_V_GEN)top_srcdir="$(top_srcdir)" $< python $@.tmp
+ $(AM_V_at)mv -f $@.tmp $@
+ $(AM_V_at)chmod -w $@
+include $(srcdir)/swig.mk
+
+AM_CPPFLAGS = \
+ -I$(top_srcdir)/lib -I$(top_srcdir)/src -I$(top_builddir)/src \
+ -I$(top_srcdir)/tcsh/src \
+ $(BOOST_CPPFLAGS) \
+ -I$(PYTHONINC)
+AM_SWIGFLAGS = -c++ -python -py3 -I$(top_srcdir)/lib -I$(top_srcdir)/src
+
+# Tiger Compiler module loader.
+python_PYTHON = tc.py
+# Tiger interpreter.
+python_PYTHON += ti.py
+
+
+
+## --------- ##
+## Testing. ##
+## --------- ##
+
+EXTRA_DIST = $(TESTS)
+EXTRA_DIST += $(srcdir)/tests/ipynbtest.py
+
+TESTS_ENVIRONMENT = \
+ top_srcdir="$(top_srcdir)" top_builddir="$(top_builddir)"
+# Ensure `run' is rebuilt before the tests are run.
+$(TESTS): $(srcdir)/run.stamp
+# The dependency is on `run.in' and not `run', since `run' is
+# regenerated at distribution time, and voids the time stamps (which
+# we don't want!).
+EXTRA_DIST += $(srcdir)/run.stamp
+$(srcdir)/run.stamp: $(RUN_IN)
+ $(AM_V_GEN)rm -f $@ $@.tmp
+ $(AM_V_at)touch $@.tmp
+ $(AM_V_at)$(MAKE) $(AM_MAKEFLAGS) $(RUN)
+ $(AM_V_at)mv -f $@.tmp $@
+
+TESTS =
+TESTS += tcsh-llvm.test
+
+LOG_COMPILER = $(srcdir)/../run
+TESTS += tests/tc.ipynb tests/ti.ipynb tests/misc.ipynb tests/common.ipynb \
+ tests/parse.ipynb tests/object.ipynb
+TESTS += tests/ast.ipynb
+TESTS += tests/bind.ipynb tests/escapes.ipynb
+TESTS += tests/type.ipynb tests/astclone.ipynb tests/desugar.ipynb
+TESTS += tests/combine.ipynb
diff --git a/tiger-compiler/tcsh/python/tc.py b/tiger-compiler/tcsh/python/tc.py
new file mode 100644
index 0000000..095e79c
--- /dev/null
+++ b/tiger-compiler/tcsh/python/tc.py
@@ -0,0 +1,97 @@
+# Tiger Compiler module loader.
+
+import importlib
+
+from enum import Enum
+from typing import List, Literal
+
+
+class BackendType(Enum):
+ llvm: Literal["llvm"] = "llvm"
+ mips: Literal["mips"] = "mips"
+
+
+def try_import(prefix: str, modules: List[str]):
+ for mod in modules:
+ mod_name = prefix + mod
+ try:
+ globals()[mod] = importlib.import_module(mod_name)
+ except:
+ pass
+
+
+# Query tc for a module.
+def has(module_name: str) -> bool:
+ return module_name in globals()
+
+
+try_import(
+ "tiger_",
+ [
+ "misc",
+ "common",
+ "parse",
+ "object",
+ "ast",
+ "bind",
+ "escapes",
+ "type",
+ "combine",
+ "astclone",
+ "desugar",
+ "overload",
+ "llvmtranslate",
+ ],
+)
+
+# Shortcuts
+Cout = common.cvar.Cout
+Cerr = common.cvar.Cerr
+Ofstream = common.Ofstream
+
+# Load IPython specific support if we can.
+try:
+ # Load only if we are running IPython.
+ from IPython import get_ipython
+ from IPython.core.magic import Magics, magics_class, cell_magic
+ import os
+ import sys
+ import tempfile
+
+ import ti
+
+ @magics_class
+ class TigerMagics(Magics):
+ @cell_magic
+ def tiger(self, line, cell):
+ if not line:
+ print(self.__doc__, file=sys.stderr)
+ return
+ backend = BackendType("mips")
+ line = line.split()
+ if len(line) == 2 and line[1] in [e.value for e in BackendType]:
+ backend = BackendType(line[1])
+ elif len(line) > 1:
+ print(self.__doc__, file=sys.stderr)
+ return
+ with tempfile.NamedTemporaryFile(dir=".", suffix=".tig") as t:
+ t.write(cell.encode("utf-8"))
+ t.flush()
+ executor = ti.TiExecutor(t.name, exit_on_error=False, backend=backend)
+ executor.backend_get()
+ self.shell.user_ns[line[0]] = executor.data
+
+ TigerMagics.__doc__ = (
+ "%%tiger variable_name [backend]\n"
+ "variable_name is the name of the finale variable\n"
+ "backend is optional and must be in [{}]".format(
+ ", ".join((e.value for e in BackendType))
+ )
+ )
+
+ ip = get_ipython()
+ if ip:
+ ip.register_magics(TigerMagics)
+
+except (ImportError, NameError) as e:
+ pass
diff --git a/tiger-compiler/tcsh/python/tcsh-hir.test b/tiger-compiler/tcsh/python/tcsh-hir.test
new file mode 100755
index 0000000..b341457
--- /dev/null
+++ b/tiger-compiler/tcsh/python/tcsh-hir.test
@@ -0,0 +1,8 @@
+#! /bin/sh
+
+set -e
+
+testsdir=$top_srcdir/tests
+run=$top_builddir/tcsh/run
+
+$run $srcdir/ti.py -b hir $testsdir/good/fact.tig
diff --git a/tiger-compiler/tcsh/python/tcsh-llvm.test b/tiger-compiler/tcsh/python/tcsh-llvm.test
new file mode 100755
index 0000000..bb72672
--- /dev/null
+++ b/tiger-compiler/tcsh/python/tcsh-llvm.test
@@ -0,0 +1,8 @@
+#! /bin/sh
+
+set -e
+
+testsdir=$top_srcdir/tests
+run=$top_builddir/tcsh/run
+
+$run $srcdir/ti.py -b llvm $testsdir/good/fact.tig
diff --git a/tiger-compiler/tcsh/python/tests/ast.ipynb b/tiger-compiler/tcsh/python/tests/ast.ipynb
new file mode 100644
index 0000000..51f06ee
--- /dev/null
+++ b/tiger-compiler/tcsh/python/tests/ast.ipynb
@@ -0,0 +1,394 @@
+{
+ "cells": [
+ {
+ "cell_type": "markdown",
+ "id": "3f7f66b6",
+ "metadata": {},
+ "source": [
+ "# Import Tiger and Ast"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 1,
+ "id": "9cb3bce5",
+ "metadata": {},
+ "outputs": [],
+ "source": [
+ "import tc"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 2,
+ "id": "be38c5fe",
+ "metadata": {},
+ "outputs": [
+ {
+ "data": {
+ "text/plain": [
+ "True"
+ ]
+ },
+ "execution_count": 2,
+ "metadata": {},
+ "output_type": "execute_result"
+ }
+ ],
+ "source": [
+ "tc.has(\"ast\")"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 3,
+ "id": "9fe09a20",
+ "metadata": {},
+ "outputs": [
+ {
+ "data": {
+ "text/plain": [
+ "True"
+ ]
+ },
+ "execution_count": 3,
+ "metadata": {},
+ "output_type": "execute_result"
+ }
+ ],
+ "source": [
+ "import tiger_ast\n",
+ "tiger_ast == tc.ast"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "id": "3b3a7285",
+ "metadata": {},
+ "source": [
+ "# Ast Library"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 4,
+ "id": "2be2f25d",
+ "metadata": {},
+ "outputs": [
+ {
+ "data": {
+ "text/plain": [
+ "['ArrayExp',\n",
+ " 'ArrayTy',\n",
+ " 'AssignExp',\n",
+ " 'Ast',\n",
+ " 'AstConstVisitor',\n",
+ " 'AstVisitor',\n",
+ " 'BreakExp',\n",
+ " 'CallExp',\n",
+ " 'CallbackVisitor',\n",
+ " 'CallbackVisitor_Argument',\n",
+ " 'CastExp',\n",
+ " 'ChunkInterface',\n",
+ " 'ChunkList',\n",
+ " 'ClassTy',\n",
+ " 'Dec',\n",
+ " 'Exp',\n",
+ " 'Field',\n",
+ " 'FieldInit',\n",
+ " 'FieldVar',\n",
+ " 'ForExp',\n",
+ " 'FunctionChunk',\n",
+ " 'FunctionDec',\n",
+ " 'IfExp',\n",
+ " 'IntExp',\n",
+ " 'LetExp',\n",
+ " 'MethodCallExp',\n",
+ " 'MethodChunk',\n",
+ " 'MethodDec',\n",
+ " 'NameTy',\n",
+ " 'NilExp',\n",
+ " 'ObjectExp',\n",
+ " 'OpExp',\n",
+ " 'RecordExp',\n",
+ " 'RecordTy',\n",
+ " 'SeqExp',\n",
+ " 'SimpleVar',\n",
+ " 'StringExp',\n",
+ " 'SubscriptVar',\n",
+ " 'SwigPyIterator',\n",
+ " 'Ty',\n",
+ " 'TypeChunk',\n",
+ " 'TypeDec',\n",
+ " 'Var',\n",
+ " 'VarChunk',\n",
+ " 'VarDec',\n",
+ " 'WhileExp']"
+ ]
+ },
+ "execution_count": 4,
+ "metadata": {},
+ "output_type": "execute_result"
+ }
+ ],
+ "source": [
+ "def ignore(e):\n",
+ " if e.startswith(\"_\") or not e[0] == e[0].upper():\n",
+ " return False\n",
+ " return e not in (\"Escapable\", \"Typable\", \"TypeConstructor\")\n",
+ "list(filter(ignore, dir(tc.ast)))"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "id": "c2ffa10b",
+ "metadata": {},
+ "source": [
+ "# Tiger Magics and AST"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 5,
+ "id": "eecfc7a6",
+ "metadata": {},
+ "outputs": [],
+ "source": [
+ "%%tiger executor\n",
+ "let\n",
+ " var b := 5\n",
+ "in\n",
+ " print_int(b)\n",
+ "end"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 13,
+ "id": "2d1e6475",
+ "metadata": {},
+ "outputs": [
+ {
+ "name": "stdout",
+ "output_type": "stream",
+ "text": [
+ "<class 'tiger_ast.ChunkList'>\n"
+ ]
+ }
+ ],
+ "source": [
+ "ast = executor.ast\n",
+ "print(type(ast))"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "id": "89fbcdc9",
+ "metadata": {},
+ "source": [
+ "# Parse Ast\n",
+ "We use this to only parse the ast and don't run code after TC2, but use Tiger Magics"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 7,
+ "id": "0ee4cd72",
+ "metadata": {},
+ "outputs": [
+ {
+ "name": "stdout",
+ "output_type": "stream",
+ "text": [
+ "<class 'tiger_ast.ChunkList'>\n"
+ ]
+ }
+ ],
+ "source": [
+ "import tempfile\n",
+ "\n",
+ "with tempfile.NamedTemporaryFile() as f:\n",
+ " f.write(b\"let var b := 5 in print_int(b) end\")\n",
+ " f.seek(0)\n",
+ " ast = tc.ti.TiExecutor(f.name).parse()\n",
+ "print(type(ast))"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 8,
+ "id": "0276768a",
+ "metadata": {},
+ "outputs": [
+ {
+ "name": "stdout",
+ "output_type": "stream",
+ "text": [
+ "\n",
+ "primitive print(string : string)\n",
+ "primitive print_err(string : string)\n",
+ "primitive print_int(int : int)\n",
+ "primitive flush()\n",
+ "primitive getchar() : string\n",
+ "primitive ord(string : string) : int\n",
+ "primitive chr(code : int) : string\n",
+ "primitive size(string : string) : int\n",
+ "primitive streq(s1 : string, s2 : string) : int\n",
+ "primitive strcmp(s1 : string, s2 : string) : int\n",
+ "primitive substring(string : string, start : int, length : int) : string\n",
+ "primitive concat(fst : string, snd : string) : string\n",
+ "primitive not(boolean : int) : int\n",
+ "primitive exit(status : int)\n",
+ "function _main() =\n",
+ " (\n",
+ " let\n",
+ " var b := 5\n",
+ " in\n",
+ " print_int(b)\n",
+ " end;\n",
+ " ()\n",
+ " )\n"
+ ]
+ }
+ ],
+ "source": [
+ "print(ast)"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 9,
+ "id": "e9856080",
+ "metadata": {},
+ "outputs": [
+ {
+ "name": "stdout",
+ "output_type": "stream",
+ "text": [
+ "<class 'tiger_ast.FunctionChunk'>\n",
+ "<class 'tiger_ast.FunctionDec'>\n",
+ "\n",
+ "function _main() =\n",
+ " (\n",
+ " let\n",
+ " var b := 5\n",
+ " in\n",
+ " print_int(b)\n",
+ " end;\n",
+ " ()\n",
+ " )\n"
+ ]
+ }
+ ],
+ "source": [
+ "main_chunk = ast[1]\n",
+ "print(type(main_chunk))\n",
+ "main_function = main_chunk[0]\n",
+ "print(type(main_function))\n",
+ "print(str(main_function))"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 10,
+ "id": "51de4ce3",
+ "metadata": {},
+ "outputs": [
+ {
+ "name": "stdout",
+ "output_type": "stream",
+ "text": [
+ "<class 'tiger_ast.SeqExp'>\n",
+ "<class 'tiger_ast.LetExp'>\n",
+ "let\n",
+ " var b := 5\n",
+ "in\n",
+ " print_int(b)\n",
+ "end\n"
+ ]
+ }
+ ],
+ "source": [
+ "main_body = main_function.body_get()\n",
+ "print(type(main_body))\n",
+ "let = main_body.exps_get()[0]\n",
+ "print(type(let))\n",
+ "print(let)"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 11,
+ "id": "1428a492",
+ "metadata": {},
+ "outputs": [
+ {
+ "name": "stdout",
+ "output_type": "stream",
+ "text": [
+ "<class 'tiger_ast.VarChunk'>\n",
+ "<class 'tiger_ast.VarDec'>\n",
+ "\n",
+ "var b := 5\n",
+ "b -> 5\n"
+ ]
+ }
+ ],
+ "source": [
+ "var_chk = let.chunks_get()[0]\n",
+ "print(type(var_chk))\n",
+ "var_b = var_chk[0]\n",
+ "print(type(var_b))\n",
+ "print(var_b)\n",
+ "print(\"{} -> {}\".format(var_b.name_get(), var_b.init_get()))"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 12,
+ "id": "d9796c32",
+ "metadata": {},
+ "outputs": [
+ {
+ "name": "stdout",
+ "output_type": "stream",
+ "text": [
+ "<class 'tiger_ast.CallExp'>\n",
+ "print_int(b)\n",
+ "<class 'tiger_ast.SimpleVar'>\n",
+ "b\n"
+ ]
+ }
+ ],
+ "source": [
+ "print_call = let.body_get()\n",
+ "print(type(print_call))\n",
+ "print(print_call)\n",
+ "print_arg = print_call.args_get()[0]\n",
+ "print(type(print_arg))\n",
+ "print(print_arg)"
+ ]
+ }
+ ],
+ "metadata": {
+ "kernelspec": {
+ "display_name": "Python 3 (ipykernel)",
+ "language": "python",
+ "name": "python3"
+ },
+ "language_info": {
+ "codemirror_mode": {
+ "name": "ipython",
+ "version": 3
+ },
+ "file_extension": ".py",
+ "mimetype": "text/x-python",
+ "name": "python",
+ "nbconvert_exporter": "python",
+ "pygments_lexer": "ipython3",
+ "version": "3.10.2"
+ }
+ },
+ "nbformat": 4,
+ "nbformat_minor": 5
+}
diff --git a/tiger-compiler/tcsh/python/tests/astclone.ipynb b/tiger-compiler/tcsh/python/tests/astclone.ipynb
new file mode 100644
index 0000000..924260b
--- /dev/null
+++ b/tiger-compiler/tcsh/python/tests/astclone.ipynb
@@ -0,0 +1,212 @@
+{
+ "cells": [
+ {
+ "cell_type": "markdown",
+ "id": "b8caa27f",
+ "metadata": {},
+ "source": [
+ "# Import Tiger and AstClone"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 1,
+ "id": "9cb3bce5",
+ "metadata": {},
+ "outputs": [],
+ "source": [
+ "import tc"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 2,
+ "id": "be38c5fe",
+ "metadata": {},
+ "outputs": [
+ {
+ "data": {
+ "text/plain": [
+ "True"
+ ]
+ },
+ "execution_count": 2,
+ "metadata": {},
+ "output_type": "execute_result"
+ }
+ ],
+ "source": [
+ "tc.has(\"astclone\")"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 3,
+ "id": "9fe09a20",
+ "metadata": {},
+ "outputs": [
+ {
+ "data": {
+ "text/plain": [
+ "True"
+ ]
+ },
+ "execution_count": 3,
+ "metadata": {},
+ "output_type": "execute_result"
+ }
+ ],
+ "source": [
+ "import tiger_astclone\n",
+ "tiger_astclone == tc.astclone"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "id": "3b3a7285",
+ "metadata": {},
+ "source": [
+ "# Ast Clone Library"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 4,
+ "id": "2be2f25d",
+ "metadata": {},
+ "outputs": [
+ {
+ "data": {
+ "text/plain": [
+ "['clone']"
+ ]
+ },
+ "execution_count": 4,
+ "metadata": {},
+ "output_type": "execute_result"
+ }
+ ],
+ "source": [
+ "list(filter(lambda e: not e.startswith(\"_\") and not e.startswith(\"tiger\"), dir(tc.astclone)))"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "id": "35825bf6",
+ "metadata": {},
+ "source": [
+ "# Clone Ast\n",
+ "We use this to only parse the ast and don't run code after TC4, but use Tiger Magics"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 5,
+ "id": "0ee4cd72",
+ "metadata": {},
+ "outputs": [
+ {
+ "name": "stdout",
+ "output_type": "stream",
+ "text": [
+ "<class 'tiger_ast.ChunkList'>\n"
+ ]
+ }
+ ],
+ "source": [
+ "import tempfile\n",
+ "\n",
+ "with tempfile.NamedTemporaryFile() as f:\n",
+ " f.write(b\"let var b := 5 in print_int(b) end\")\n",
+ " f.seek(0)\n",
+ " ast = tc.ti.TiExecutor(f.name).type()\n",
+ "print(type(ast))"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 6,
+ "id": "29d68680",
+ "metadata": {},
+ "outputs": [
+ {
+ "name": "stdout",
+ "output_type": "stream",
+ "text": [
+ "False\n",
+ "True\n",
+ "<class 'tiger_ast.ChunkList'>\n"
+ ]
+ }
+ ],
+ "source": [
+ "cloned_ast = tc.astclone.clone(ast)\n",
+ "print(ast == cloned_ast)\n",
+ "print(str(ast) == str(cloned_ast))\n",
+ "print(type(cloned_ast))"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 7,
+ "id": "5f1cb3e7",
+ "metadata": {},
+ "outputs": [
+ {
+ "name": "stdout",
+ "output_type": "stream",
+ "text": [
+ "\n",
+ "primitive print(string : string)\n",
+ "primitive print_err(string : string)\n",
+ "primitive print_int(int : int)\n",
+ "primitive flush()\n",
+ "primitive getchar() : string\n",
+ "primitive ord(string : string) : int\n",
+ "primitive chr(code : int) : string\n",
+ "primitive size(string : string) : int\n",
+ "primitive streq(s1 : string, s2 : string) : int\n",
+ "primitive strcmp(s1 : string, s2 : string) : int\n",
+ "primitive substring(string : string, start : int, length : int) : string\n",
+ "primitive concat(fst : string, snd : string) : string\n",
+ "primitive not(boolean : int) : int\n",
+ "primitive exit(status : int)\n",
+ "function _main() =\n",
+ " (\n",
+ " let\n",
+ " var b := 5\n",
+ " in\n",
+ " print_int(b)\n",
+ " end;\n",
+ " ()\n",
+ " )\n"
+ ]
+ }
+ ],
+ "source": [
+ "print(cloned_ast)"
+ ]
+ }
+ ],
+ "metadata": {
+ "kernelspec": {
+ "display_name": "Python 3 (ipykernel)",
+ "language": "python",
+ "name": "python3"
+ },
+ "language_info": {
+ "codemirror_mode": {
+ "name": "ipython",
+ "version": 3
+ },
+ "file_extension": ".py",
+ "mimetype": "text/x-python",
+ "name": "python",
+ "nbconvert_exporter": "python",
+ "pygments_lexer": "ipython3",
+ "version": "3.10.2"
+ }
+ },
+ "nbformat": 4,
+ "nbformat_minor": 5
+}
diff --git a/tiger-compiler/tcsh/python/tests/bind.ipynb b/tiger-compiler/tcsh/python/tests/bind.ipynb
new file mode 100644
index 0000000..f2ceafe
--- /dev/null
+++ b/tiger-compiler/tcsh/python/tests/bind.ipynb
@@ -0,0 +1,283 @@
+{
+ "cells": [
+ {
+ "cell_type": "markdown",
+ "id": "3f7f66b6",
+ "metadata": {},
+ "source": [
+ "# Import Tiger and bind"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 1,
+ "id": "9cb3bce5",
+ "metadata": {},
+ "outputs": [],
+ "source": [
+ "import tc"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 2,
+ "id": "be38c5fe",
+ "metadata": {},
+ "outputs": [
+ {
+ "data": {
+ "text/plain": [
+ "True"
+ ]
+ },
+ "execution_count": 2,
+ "metadata": {},
+ "output_type": "execute_result"
+ }
+ ],
+ "source": [
+ "tc.has(\"bind\")"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 3,
+ "id": "9fe09a20",
+ "metadata": {},
+ "outputs": [
+ {
+ "data": {
+ "text/plain": [
+ "True"
+ ]
+ },
+ "execution_count": 3,
+ "metadata": {},
+ "output_type": "execute_result"
+ }
+ ],
+ "source": [
+ "import tiger_bind\n",
+ "tiger_bind == tc.bind"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "id": "3b3a7285",
+ "metadata": {},
+ "source": [
+ "# Bind Library"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 4,
+ "id": "2be2f25d",
+ "metadata": {},
+ "outputs": [
+ {
+ "data": {
+ "text/plain": [
+ "['bind', 'rename']"
+ ]
+ },
+ "execution_count": 4,
+ "metadata": {},
+ "output_type": "execute_result"
+ }
+ ],
+ "source": [
+ "list(filter(lambda e: not e.startswith(\"_\") and not e.startswith(\"tiger\"), dir(tc.bind)))"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "id": "35825bf6",
+ "metadata": {},
+ "source": [
+ "# Bind Ast\n",
+ "We use this to only parse the ast and don't run code after TC3, but use Tiger Magics"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 5,
+ "id": "0ee4cd72",
+ "metadata": {},
+ "outputs": [
+ {
+ "name": "stdout",
+ "output_type": "stream",
+ "text": [
+ "<class 'tiger_ast.ChunkList'>\n"
+ ]
+ }
+ ],
+ "source": [
+ "import tempfile\n",
+ "\n",
+ "with tempfile.NamedTemporaryFile() as f:\n",
+ " f.write(b\"let var b := 5 in print_int(b) end\")\n",
+ " f.seek(0)\n",
+ " ast = tc.ti.TiExecutor(f.name).bind()\n",
+ "print(type(ast))"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 6,
+ "id": "703bb878",
+ "metadata": {},
+ "outputs": [],
+ "source": [
+ "# all variables are identical to ast.ipynb \n",
+ "main_chunk = ast[1]\n",
+ "main_function = main_chunk[0]\n",
+ "main_body = main_function.body_get()\n",
+ "let = main_body.exps_get()[0]\n",
+ "var_chk = let.chunks_get()[0]\n",
+ "var_b = var_chk[0]\n",
+ "print_call = let.body_get()\n",
+ "print_arg = print_call.args_get()[0]"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 7,
+ "id": "991c55bf",
+ "metadata": {},
+ "outputs": [],
+ "source": [
+ "def find_builtin(ast: tc.ast.ChunkList, name: str):\n",
+ " key = tc.misc.symbol(name)\n",
+ " for fns in ast[0]:\n",
+ " if fns.name_get() == key:\n",
+ " return fns\n",
+ " return None"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 8,
+ "id": "a0fc3d00",
+ "metadata": {},
+ "outputs": [
+ {
+ "name": "stdout",
+ "output_type": "stream",
+ "text": [
+ "<class 'tiger_ast.FunctionDec'> \n",
+ "primitive print_int(int : int)\n",
+ "True\n",
+ "True\n",
+ "False\n",
+ "False\n",
+ "True\n"
+ ]
+ }
+ ],
+ "source": [
+ "ref_print_int = print_call.def_get()\n",
+ "print(type(ref_print_int), str(ref_print_int))\n",
+ "\n",
+ "builtin_print_int = find_builtin(ast, \"print_int\")\n",
+ "builtin_print = find_builtin(ast, \"print\")\n",
+ "\n",
+ "print(ref_print_int == builtin_print_int)\n",
+ "print(builtin_print_int == ref_print_int)\n",
+ "print(ref_print_int == builtin_print)\n",
+ "print(builtin_print == ref_print_int)\n",
+ "\n",
+ "print(print_arg.def_get() == var_b)"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "id": "3c997fb0",
+ "metadata": {},
+ "source": [
+ "# Bind Rename"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 9,
+ "id": "ff0b5358",
+ "metadata": {},
+ "outputs": [],
+ "source": [
+ "tc.bind.rename(ast)"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 10,
+ "id": "fcccea94",
+ "metadata": {},
+ "outputs": [],
+ "source": [
+ "# all variables are identical to ast.ipynb \n",
+ "main_chunk = ast[1]\n",
+ "main_function = main_chunk[0]\n",
+ "main_body = main_function.body_get()\n",
+ "let = main_body.exps_get()[0]\n",
+ "var_chk = let.chunks_get()[0]\n",
+ "var_b = var_chk[0]\n",
+ "print_call = let.body_get()\n",
+ "print_arg = print_call.args_get()[0]"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 11,
+ "id": "1ba1374c",
+ "metadata": {},
+ "outputs": [
+ {
+ "name": "stdout",
+ "output_type": "stream",
+ "text": [
+ "True\n",
+ "True\n",
+ "False\n",
+ "False\n",
+ "True\n"
+ ]
+ }
+ ],
+ "source": [
+ "ref_print_int = print_call.def_get()\n",
+ "builtin_print_int = find_builtin(ast, \"print_int\")\n",
+ "builtin_print = find_builtin(ast, \"print\")\n",
+ "\n",
+ "print(ref_print_int == builtin_print_int)\n",
+ "print(builtin_print_int == ref_print_int)\n",
+ "print(ref_print_int == builtin_print)\n",
+ "print(builtin_print == ref_print_int)\n",
+ "\n",
+ "print(print_arg.def_get() == var_b)"
+ ]
+ }
+ ],
+ "metadata": {
+ "kernelspec": {
+ "display_name": "Python 3 (ipykernel)",
+ "language": "python",
+ "name": "python3"
+ },
+ "language_info": {
+ "codemirror_mode": {
+ "name": "ipython",
+ "version": 3
+ },
+ "file_extension": ".py",
+ "mimetype": "text/x-python",
+ "name": "python",
+ "nbconvert_exporter": "python",
+ "pygments_lexer": "ipython3",
+ "version": "3.10.2"
+ }
+ },
+ "nbformat": 4,
+ "nbformat_minor": 5
+}
diff --git a/tiger-compiler/tcsh/python/tests/combine.ipynb b/tiger-compiler/tcsh/python/tests/combine.ipynb
new file mode 100644
index 0000000..c97c28a
--- /dev/null
+++ b/tiger-compiler/tcsh/python/tests/combine.ipynb
@@ -0,0 +1,207 @@
+{
+ "cells": [
+ {
+ "cell_type": "markdown",
+ "id": "b8caa27f",
+ "metadata": {},
+ "source": [
+ "# Import Tiger and combine"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 1,
+ "id": "9cb3bce5",
+ "metadata": {},
+ "outputs": [],
+ "source": [
+ "import tc"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 2,
+ "id": "be38c5fe",
+ "metadata": {},
+ "outputs": [
+ {
+ "data": {
+ "text/plain": [
+ "True"
+ ]
+ },
+ "execution_count": 2,
+ "metadata": {},
+ "output_type": "execute_result"
+ }
+ ],
+ "source": [
+ "tc.has(\"combine\")"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 3,
+ "id": "9fe09a20",
+ "metadata": {},
+ "outputs": [
+ {
+ "data": {
+ "text/plain": [
+ "True"
+ ]
+ },
+ "execution_count": 3,
+ "metadata": {},
+ "output_type": "execute_result"
+ }
+ ],
+ "source": [
+ "import tiger_combine\n",
+ "tiger_combine == tc.combine"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "id": "3b3a7285",
+ "metadata": {},
+ "source": [
+ "# Combine Library"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 4,
+ "id": "2be2f25d",
+ "metadata": {},
+ "outputs": [
+ {
+ "data": {
+ "text/plain": [
+ "['combine_bind', 'combine_types_check']"
+ ]
+ },
+ "execution_count": 4,
+ "metadata": {},
+ "output_type": "execute_result"
+ }
+ ],
+ "source": [
+ "list(filter(lambda e: not e.startswith(\"_\") and not e.startswith(\"tiger\"), dir(tc.combine)))"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "id": "35825bf6",
+ "metadata": {},
+ "source": [
+ "# Combine Ast\n",
+ "We use this to only parse the ast and don't run code after TC4, but use Tiger Magics"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 5,
+ "id": "0ee4cd72",
+ "metadata": {},
+ "outputs": [
+ {
+ "name": "stdout",
+ "output_type": "stream",
+ "text": [
+ "<class 'tiger_ast.ChunkList'>\n"
+ ]
+ }
+ ],
+ "source": [
+ "import tempfile\n",
+ "\n",
+ "with tempfile.NamedTemporaryFile() as f:\n",
+ " f.write(b\"let var b := 5 in print_int(b) end\")\n",
+ " f.seek(0)\n",
+ " ast = tc.ti.TiExecutor(f.name).type()\n",
+ "print(type(ast))"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 6,
+ "id": "29d68680",
+ "metadata": {},
+ "outputs": [
+ {
+ "name": "stdout",
+ "output_type": "stream",
+ "text": [
+ "<class 'tuple'>\n"
+ ]
+ }
+ ],
+ "source": [
+ "pair = tc.combine.combine_bind(ast, True)\n",
+ "print(type(pair))"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 7,
+ "id": "46abfec6",
+ "metadata": {},
+ "outputs": [
+ {
+ "name": "stdout",
+ "output_type": "stream",
+ "text": [
+ "<Swig Object of type 'overload::overfun_bindings_type *' at 0x7fb2c1d50810> <class 'tiger_misc.error'>\n",
+ "\n"
+ ]
+ }
+ ],
+ "source": [
+ "overfun_bindings_get, error = pair\n",
+ "print(repr(overfun_bindings_get), type(error))\n",
+ "print(error)"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 8,
+ "id": "e8f0ee43",
+ "metadata": {},
+ "outputs": [
+ {
+ "name": "stdout",
+ "output_type": "stream",
+ "text": [
+ "\n"
+ ]
+ }
+ ],
+ "source": [
+ "error = tc.combine.combine_types_check(ast, overfun_bindings_get, True)\n",
+ "print(error)"
+ ]
+ }
+ ],
+ "metadata": {
+ "kernelspec": {
+ "display_name": "Python 3 (ipykernel)",
+ "language": "python",
+ "name": "python3"
+ },
+ "language_info": {
+ "codemirror_mode": {
+ "name": "ipython",
+ "version": 3
+ },
+ "file_extension": ".py",
+ "mimetype": "text/x-python",
+ "name": "python",
+ "nbconvert_exporter": "python",
+ "pygments_lexer": "ipython3",
+ "version": "3.10.2"
+ }
+ },
+ "nbformat": 4,
+ "nbformat_minor": 5
+}
diff --git a/tiger-compiler/tcsh/python/tests/common.ipynb b/tiger-compiler/tcsh/python/tests/common.ipynb
new file mode 100644
index 0000000..a2ee8ac
--- /dev/null
+++ b/tiger-compiler/tcsh/python/tests/common.ipynb
@@ -0,0 +1,154 @@
+{
+ "cells": [
+ {
+ "cell_type": "markdown",
+ "id": "3f7f66b6",
+ "metadata": {},
+ "source": [
+ "# Import Tiger and Common"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 1,
+ "id": "9cb3bce5",
+ "metadata": {},
+ "outputs": [],
+ "source": [
+ "import tc"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 2,
+ "id": "be38c5fe",
+ "metadata": {},
+ "outputs": [
+ {
+ "data": {
+ "text/plain": [
+ "True"
+ ]
+ },
+ "execution_count": 2,
+ "metadata": {},
+ "output_type": "execute_result"
+ }
+ ],
+ "source": [
+ "tc.has(\"common\")"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 3,
+ "id": "9fe09a20",
+ "metadata": {},
+ "outputs": [
+ {
+ "data": {
+ "text/plain": [
+ "True"
+ ]
+ },
+ "execution_count": 3,
+ "metadata": {},
+ "output_type": "execute_result"
+ }
+ ],
+ "source": [
+ "import tiger_common\n",
+ "tiger_common == tc.common"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "id": "3b3a7285",
+ "metadata": {},
+ "source": [
+ "# Common Library"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 4,
+ "id": "2be2f25d",
+ "metadata": {},
+ "outputs": [
+ {
+ "data": {
+ "text/plain": [
+ "['Ofstream', 'cvar', 'get_cerr', 'get_cout']"
+ ]
+ },
+ "execution_count": 4,
+ "metadata": {},
+ "output_type": "execute_result"
+ }
+ ],
+ "source": [
+ "list(filter(lambda e: not e.startswith(\"_\"), dir(tc.common)))"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "id": "c2ffa10b",
+ "metadata": {},
+ "source": [
+ "# Common Ofstrem"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 5,
+ "id": "0ee4cd72",
+ "metadata": {},
+ "outputs": [
+ {
+ "name": "stdout",
+ "output_type": "stream",
+ "text": [
+ "<Swig Object of type 'std::ostream *' at 0x7f812c0f0750>\n"
+ ]
+ }
+ ],
+ "source": [
+ "import os\n",
+ "import tempfile\n",
+ "\n",
+ "# Create file\n",
+ "f = tempfile.NamedTemporaryFile(delete=False)\n",
+ "f.write(b\"let in end\")\n",
+ "f.close()\n",
+ "\n",
+ "# Open a C++ ostream\n",
+ "ostream = tc.common.Ofstream(f.name)\n",
+ "print(ostream.to())\n",
+ "\n",
+ "# Delete file\n",
+ "os.unlink(f.name)"
+ ]
+ }
+ ],
+ "metadata": {
+ "kernelspec": {
+ "display_name": "Python 3 (ipykernel)",
+ "language": "python",
+ "name": "python3"
+ },
+ "language_info": {
+ "codemirror_mode": {
+ "name": "ipython",
+ "version": 3
+ },
+ "file_extension": ".py",
+ "mimetype": "text/x-python",
+ "name": "python",
+ "nbconvert_exporter": "python",
+ "pygments_lexer": "ipython3",
+ "version": "3.10.1"
+ }
+ },
+ "nbformat": 4,
+ "nbformat_minor": 5
+}
diff --git a/tiger-compiler/tcsh/python/tests/desugar.ipynb b/tiger-compiler/tcsh/python/tests/desugar.ipynb
new file mode 100644
index 0000000..3e6417f
--- /dev/null
+++ b/tiger-compiler/tcsh/python/tests/desugar.ipynb
@@ -0,0 +1,343 @@
+{
+ "cells": [
+ {
+ "cell_type": "markdown",
+ "id": "b8caa27f",
+ "metadata": {},
+ "source": [
+ "# Import Tiger and Desugar"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 1,
+ "id": "9cb3bce5",
+ "metadata": {},
+ "outputs": [],
+ "source": [
+ "import tc"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 2,
+ "id": "be38c5fe",
+ "metadata": {},
+ "outputs": [
+ {
+ "data": {
+ "text/plain": [
+ "True"
+ ]
+ },
+ "execution_count": 2,
+ "metadata": {},
+ "output_type": "execute_result"
+ }
+ ],
+ "source": [
+ "tc.has(\"desugar\")"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 3,
+ "id": "9fe09a20",
+ "metadata": {},
+ "outputs": [
+ {
+ "data": {
+ "text/plain": [
+ "True"
+ ]
+ },
+ "execution_count": 3,
+ "metadata": {},
+ "output_type": "execute_result"
+ }
+ ],
+ "source": [
+ "import tiger_desugar\n",
+ "tiger_desugar == tc.desugar"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "id": "3b3a7285",
+ "metadata": {},
+ "source": [
+ "# Desugar Library"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 4,
+ "id": "2be2f25d",
+ "metadata": {},
+ "outputs": [
+ {
+ "data": {
+ "text/plain": [
+ "['desugar', 'raw_desugar']"
+ ]
+ },
+ "execution_count": 4,
+ "metadata": {},
+ "output_type": "execute_result"
+ }
+ ],
+ "source": [
+ "list(filter(lambda e: not e.startswith(\"_\") and not e.startswith(\"tiger\"), dir(tc.desugar)))"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "id": "35825bf6",
+ "metadata": {},
+ "source": [
+ "# Desugar Ast\n",
+ "We use this to only parse the ast and don't run code after TC4, but use Tiger Magics"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 5,
+ "id": "0ee4cd72",
+ "metadata": {},
+ "outputs": [
+ {
+ "name": "stdout",
+ "output_type": "stream",
+ "text": [
+ "<class 'tiger_ast.ChunkList'>\n"
+ ]
+ }
+ ],
+ "source": [
+ "import tempfile\n",
+ "\n",
+ "with tempfile.NamedTemporaryFile() as f:\n",
+ " f.write(b\"for i := 1 to 10 do (i; ())\")\n",
+ " f.seek(0)\n",
+ " ast = tc.ti.TiExecutor(f.name).type()\n",
+ "print(type(ast))"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 6,
+ "id": "d0e05897",
+ "metadata": {},
+ "outputs": [
+ {
+ "name": "stdout",
+ "output_type": "stream",
+ "text": [
+ "\n",
+ "primitive print(string : string)\n",
+ "primitive print_err(string : string)\n",
+ "primitive print_int(int : int)\n",
+ "primitive flush()\n",
+ "primitive getchar() : string\n",
+ "primitive ord(string : string) : int\n",
+ "primitive chr(code : int) : string\n",
+ "primitive size(string : string) : int\n",
+ "primitive streq(s1 : string, s2 : string) : int\n",
+ "primitive strcmp(s1 : string, s2 : string) : int\n",
+ "primitive substring(string : string, start : int, length : int) : string\n",
+ "primitive concat(fst : string, snd : string) : string\n",
+ "primitive not(boolean : int) : int\n",
+ "primitive exit(status : int)\n",
+ "function _main() =\n",
+ " (\n",
+ " (for i := 1 to 10 do\n",
+ " (\n",
+ " i;\n",
+ " ()\n",
+ " ));\n",
+ " ()\n",
+ " )\n"
+ ]
+ }
+ ],
+ "source": [
+ "print(ast)"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 7,
+ "id": "29d68680",
+ "metadata": {},
+ "outputs": [
+ {
+ "data": {
+ "text/plain": [
+ "<function tiger_desugar.raw_desugar(tree: 'Ast', desugar_for: 'bool' = False, desugar_string_cmp: 'bool' = False) -> 'ast::Ast *'>"
+ ]
+ },
+ "execution_count": 7,
+ "metadata": {},
+ "output_type": "execute_result"
+ }
+ ],
+ "source": [
+ "tc.desugar.raw_desugar"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 8,
+ "id": "04a11b99",
+ "metadata": {},
+ "outputs": [
+ {
+ "name": "stdout",
+ "output_type": "stream",
+ "text": [
+ "\n",
+ "primitive print(string : string)\n",
+ "primitive print_err(string : string)\n",
+ "primitive print_int(int : int)\n",
+ "primitive flush()\n",
+ "primitive getchar() : string\n",
+ "primitive ord(string : string) : int\n",
+ "primitive chr(code : int) : string\n",
+ "primitive size(string : string) : int\n",
+ "primitive streq(s1 : string, s2 : string) : int\n",
+ "primitive strcmp(s1 : string, s2 : string) : int\n",
+ "primitive substring(string : string, start : int, length : int) : string\n",
+ "primitive concat(fst : string, snd : string) : string\n",
+ "primitive not(boolean : int) : int\n",
+ "primitive exit(status : int)\n",
+ "function _main() =\n",
+ " (\n",
+ " let\n",
+ " var _lo := 1\n",
+ " var _hi := 10\n",
+ " var i := _lo\n",
+ " in\n",
+ " (if (_lo <= _hi)\n",
+ " then (while 1 do\n",
+ " (\n",
+ " (\n",
+ " i;\n",
+ " ()\n",
+ " );\n",
+ " (if (i = _hi)\n",
+ " then break\n",
+ " else ());\n",
+ " (i := (i + 1))\n",
+ " ))\n",
+ " else ())\n",
+ " end;\n",
+ " ()\n",
+ " )\n"
+ ]
+ }
+ ],
+ "source": [
+ "ast_raw = tc.desugar.raw_desugar(ast, True, True)\n",
+ "print(ast_raw)"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 9,
+ "id": "da86985d",
+ "metadata": {},
+ "outputs": [
+ {
+ "data": {
+ "text/plain": [
+ "<function tiger_desugar.desugar(tree: 'Ast', desugar_for: 'bool' = False, desugar_string_cmp: 'bool' = False) -> 'ast::Ast *'>"
+ ]
+ },
+ "execution_count": 9,
+ "metadata": {},
+ "output_type": "execute_result"
+ }
+ ],
+ "source": [
+ "tc.desugar.desugar"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 10,
+ "id": "86f1bcc7",
+ "metadata": {},
+ "outputs": [
+ {
+ "name": "stdout",
+ "output_type": "stream",
+ "text": [
+ "\n",
+ "primitive print(string : string)\n",
+ "primitive print_err(string : string)\n",
+ "primitive print_int(int : int)\n",
+ "primitive flush()\n",
+ "primitive getchar() : string\n",
+ "primitive ord(string : string) : int\n",
+ "primitive chr(code : int) : string\n",
+ "primitive size(string : string) : int\n",
+ "primitive streq(s1 : string, s2 : string) : int\n",
+ "primitive strcmp(s1 : string, s2 : string) : int\n",
+ "primitive substring(string : string, start : int, length : int) : string\n",
+ "primitive concat(fst : string, snd : string) : string\n",
+ "primitive not(boolean : int) : int\n",
+ "primitive exit(status : int)\n",
+ "function _main() =\n",
+ " (\n",
+ " let\n",
+ " var _lo := 1\n",
+ " var _hi := 10\n",
+ " var i := _lo\n",
+ " in\n",
+ " (if (_lo <= _hi)\n",
+ " then (while 1 do\n",
+ " (\n",
+ " (\n",
+ " i;\n",
+ " ()\n",
+ " );\n",
+ " (if (i = _hi)\n",
+ " then break\n",
+ " else ());\n",
+ " (i := (i + 1))\n",
+ " ))\n",
+ " else ())\n",
+ " end;\n",
+ " ()\n",
+ " )\n"
+ ]
+ }
+ ],
+ "source": [
+ "ast = tc.desugar.desugar(ast, True, True)\n",
+ "print(ast)"
+ ]
+ }
+ ],
+ "metadata": {
+ "kernelspec": {
+ "display_name": "Python 3 (ipykernel)",
+ "language": "python",
+ "name": "python3"
+ },
+ "language_info": {
+ "codemirror_mode": {
+ "name": "ipython",
+ "version": 3
+ },
+ "file_extension": ".py",
+ "mimetype": "text/x-python",
+ "name": "python",
+ "nbconvert_exporter": "python",
+ "pygments_lexer": "ipython3",
+ "version": "3.10.2"
+ }
+ },
+ "nbformat": 4,
+ "nbformat_minor": 5
+}
diff --git a/tiger-compiler/tcsh/python/tests/escapes.ipynb b/tiger-compiler/tcsh/python/tests/escapes.ipynb
new file mode 100644
index 0000000..ed914fb
--- /dev/null
+++ b/tiger-compiler/tcsh/python/tests/escapes.ipynb
@@ -0,0 +1,194 @@
+{
+ "cells": [
+ {
+ "cell_type": "markdown",
+ "id": "3f7f66b6",
+ "metadata": {},
+ "source": [
+ "# Import Tiger and escapes"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 1,
+ "id": "9cb3bce5",
+ "metadata": {},
+ "outputs": [],
+ "source": [
+ "import tc"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 2,
+ "id": "be38c5fe",
+ "metadata": {},
+ "outputs": [
+ {
+ "data": {
+ "text/plain": [
+ "True"
+ ]
+ },
+ "execution_count": 2,
+ "metadata": {},
+ "output_type": "execute_result"
+ }
+ ],
+ "source": [
+ "tc.has(\"escapes\")"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 3,
+ "id": "9fe09a20",
+ "metadata": {},
+ "outputs": [
+ {
+ "data": {
+ "text/plain": [
+ "True"
+ ]
+ },
+ "execution_count": 3,
+ "metadata": {},
+ "output_type": "execute_result"
+ }
+ ],
+ "source": [
+ "import tiger_escapes\n",
+ "tiger_escapes == tc.escapes"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "id": "3b3a7285",
+ "metadata": {},
+ "source": [
+ "# Escapes Library"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 4,
+ "id": "2be2f25d",
+ "metadata": {},
+ "outputs": [
+ {
+ "data": {
+ "text/plain": [
+ "<function tiger_escapes.escapes_compute(tree: 'ast::Ast &') -> 'void'>"
+ ]
+ },
+ "execution_count": 4,
+ "metadata": {},
+ "output_type": "execute_result"
+ }
+ ],
+ "source": [
+ "tc.escapes.escapes_compute"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "id": "35825bf6",
+ "metadata": {},
+ "source": [
+ "# Escape\n",
+ "We use this to only parse and bind the ast and don't run code after TC3, but use Tiger Magics"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 5,
+ "id": "0ee4cd72",
+ "metadata": {},
+ "outputs": [
+ {
+ "name": "stdout",
+ "output_type": "stream",
+ "text": [
+ "<class 'tiger_ast.ChunkList'>\n"
+ ]
+ }
+ ],
+ "source": [
+ "import tempfile\n",
+ "\n",
+ "with tempfile.NamedTemporaryFile() as f:\n",
+ " f.write(b\"let var b := 5 in print_int(b) end\")\n",
+ " f.seek(0)\n",
+ " ast = tc.ti.TiExecutor(f.name).bind()\n",
+ "print(type(ast))"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 6,
+ "id": "371349e8",
+ "metadata": {},
+ "outputs": [],
+ "source": [
+ "tc.escapes.escapes_compute(ast)"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 7,
+ "id": "703bb878",
+ "metadata": {},
+ "outputs": [],
+ "source": [
+ "# all variables are identical to ast.ipynb \n",
+ "main_chunk = ast[1]\n",
+ "main_function = main_chunk[0]\n",
+ "main_body = main_function.body_get()\n",
+ "let = main_body.exps_get()[0]\n",
+ "var_chk = let.chunks_get()[0]\n",
+ "var_b = var_chk[0]\n",
+ "print_call = let.body_get()\n",
+ "print_arg = print_call.args_get()[0]"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 8,
+ "id": "c7ed8db8",
+ "metadata": {},
+ "outputs": [
+ {
+ "name": "stdout",
+ "output_type": "stream",
+ "text": [
+ "False\n"
+ ]
+ }
+ ],
+ "source": [
+ "print(var_b.escape_get())"
+ ]
+ }
+ ],
+ "metadata": {
+ "kernelspec": {
+ "display_name": "Python 3 (ipykernel)",
+ "language": "python",
+ "name": "python3"
+ },
+ "language_info": {
+ "codemirror_mode": {
+ "name": "ipython",
+ "version": 3
+ },
+ "file_extension": ".py",
+ "mimetype": "text/x-python",
+ "name": "python",
+ "nbconvert_exporter": "python",
+ "pygments_lexer": "ipython3",
+ "version": "3.10.2"
+ }
+ },
+ "nbformat": 4,
+ "nbformat_minor": 5
+}
diff --git a/tiger-compiler/tcsh/python/tests/ipynbtest.py b/tiger-compiler/tcsh/python/tests/ipynbtest.py
new file mode 100755
index 0000000..1b7798a
--- /dev/null
+++ b/tiger-compiler/tcsh/python/tests/ipynbtest.py
@@ -0,0 +1,279 @@
+#!/usr/bin/env python3
+"""
+simple example script for running and testing notebooks.
+
+Usage: `ipnbdoctest.py foo.ipynb [bar.ipynb [...]]`
+
+Each cell is submitted to the kernel, and the outputs are compared
+with those stored in the notebook.
+"""
+
+# Derived from https://gist.github.com/minrk/2620735
+# Derived from https://gitlab.lrde.epita.fr/spot/spot/-/raw/next/tests/python/ipnbdoctest.py
+
+from __future__ import print_function
+
+import os
+import sys
+import time
+import base64
+import re
+import pprint
+import random
+from difflib import unified_diff as diff
+
+from collections import defaultdict
+try:
+ from queue import Empty
+except ImportError:
+ print('Python 3.x is needed to run this script.')
+ sys.exit(77)
+
+import importlib.util
+try:
+ importlib.util.find_spec('IPython')
+except:
+ print('IPython is needed to run this script.')
+ sys.exit(77)
+
+try:
+ from jupyter_client import KernelManager
+except ImportError:
+ try:
+ from IPython.kernel import KernelManager
+ except ImportError:
+ try:
+ from IPython.zmq.blockingkernelmanager \
+ import BlockingKernelManager as KernelManager
+ except:
+ print('IPython is needed to run this script.')
+ sys.exit(77)
+
+# Until Debian Stable ships IPython >3.0, we stick to the v3 format.
+try:
+ from nbformat import v4 as nbformat
+except ImportError:
+ from IPython.nbformat import v4 as nbformat
+
+
+def canonicalize(s):
+ """sanitize a string for comparison.
+
+ fix universal newlines, strip trailing newlines, and normalize likely
+ random values (memory addresses and UUIDs)
+ """
+ if not isinstance(s, str):
+ return s
+
+ # normalize newline:
+ s = s.replace('\r\n', '\n')
+
+ # ignore trailing newlines (but not space)
+ s = s.rstrip('\n')
+
+ # remove hex addresses:
+ s = re.sub(r'at 0x[a-f0-9]+', 'at 0xadd7e5500000', s)
+
+ # remove backend lists in documentations/errors:
+ s = re.sub(r'\[((lir|hir|llvm|mips|ia32), ?)*(lir|hir|llvm|mips|ia32)\]',
+ '[]', s)
+
+ return s
+
+
+def canonical_dict(data):
+ """Neutralize gratuitous differences in a Jupyter dictionary."""
+
+ if 'text' in data:
+ data['text'] = canonicalize(data['text'])
+
+ if 'data' in data:
+ d = data['data']
+ if "text/html" in d and "text/plain" in d:
+ del d["text/plain"]
+ for k in d:
+ d[k] = canonicalize(d[k])
+
+ if ('ename' in data and
+ data['ename'] == 'SystemExit' and data['evalue'] == '77'):
+ # sys.exit(77) is used to Skip the test.
+ sys.exit(77)
+
+ if 'ename' in data and data['ename'] == 'CalledProcessError':
+ # CalledProcessError message has a final dot in Python 3.6
+ data['evalue'] = re.sub(r"(' returned non-zero exit status \d+)\.",
+ r'\1', data['evalue'])
+
+ for e in ('transient', 'execution_count', 'traceback'):
+ if e in data:
+ del data[e]
+ return data
+
+
+def compare_outputs(ref, test):
+ """Check that two lists of outputs are equivalent and report the result."""
+
+ cref = list(map(canonical_dict, ref))
+ ctest = list(map(canonical_dict, test))
+
+ ok = True
+
+ if len(cref) != len(ctest):
+ print("output length mismatch (expected {}, got {})"
+ .format(len(cref), len(ctest)))
+ ok = False
+ # There can be several outputs. For instance wnen the cell both
+ # prints a result (goes to "stdout") and displays an automaton
+ # (goes to "data").
+ exp = pprint.pformat(cref, width=132)
+ eff = pprint.pformat(ctest, width=132)
+ if exp[:-1] != '\n':
+ exp += '\n'
+ if eff[:-1] != '\n':
+ eff += '\n'
+ if exp == eff:
+ return ok
+ else:
+ print(''.join(diff(exp.splitlines(1), eff.splitlines(1),
+ fromfile='expected', tofile='effective')))
+ return False
+
+
+def _wait_for_ready_backport(kc):
+ """Backport BlockingKernelClient.wait_for_ready from IPython 3"""
+ # Wait for kernel info reply on shell channel
+ kc.kernel_info()
+ while True:
+ msg = kc.get_shell_msg(block=True, timeout=30)
+ if msg['msg_type'] == 'kernel_info_reply':
+ break
+ # Flush IOPub channel
+ while True:
+ try:
+ msg = kc.get_iopub_msg(block=True, timeout=1)
+ except Empty:
+ break
+
+
+def run_cell(kc, cell):
+ kc.execute(cell.source)
+ outs = []
+
+ while True:
+ try:
+ msg = kc.get_iopub_msg(timeout=1)
+ except Empty:
+ if not kc.is_alive():
+ raise RuntimeError("Kernel died")
+ continue
+
+ msg_type = msg['msg_type']
+ content = msg['content']
+
+ if msg_type == 'status' and content['execution_state'] == 'idle':
+ break
+ if msg_type in ('status', 'pyin', 'execute_input',
+ 'comm_open', 'comm_msg'):
+ continue
+ if msg_type == 'stream':
+ if 'Widget' in content['text']:
+ continue
+ # If the last stream had the same name, then outputs are
+ # appended.
+ if outs:
+ last = outs[-1]
+ if last['output_type'] == 'stream' and \
+ last['name'] == content['name']:
+ last['text'] += content['text']
+ continue
+ elif msg_type == 'clear_output':
+ outs = []
+ continue
+
+ content['output_type'] = msg_type
+ outs.append(content)
+ # Flush shell channel
+ while True:
+ try:
+ kc.get_shell_msg(timeout=0.1)
+ except Empty:
+ if not kc.is_alive():
+ raise RuntimeError("Kernel died")
+ break
+ return outs
+
+
+def test_notebook(ipynb):
+ with open(ipynb, encoding='utf-8') as f:
+ nb = nbformat.reads_json(f.read())
+ km = KernelManager()
+ # Do not save the history to disk, as it can yield spurious lock errors.
+ # See https://github.com/ipython/ipython/issues/2845
+ km.start_kernel(extra_arguments=['--HistoryManager.hist_file=:memory:',
+ '--quiet'])
+
+ kc = km.client()
+ kc.start_channels()
+
+ try:
+ kc.wait_for_ready(timeout=30)
+ except AttributeError:
+ _wait_for_ready_backport(kc)
+
+ successes = 0
+ failures = 0
+ errors = 0
+ for i, cell in enumerate(nb.cells):
+ if cell.cell_type == 'markdown' and cell.source.startswith("#"):
+ title = re.sub(r'^#+ ?', '', cell.source.splitlines()[0])
+ if cell.cell_type != 'code' or cell.source.startswith('#DONTCHECK'):
+ continue
+ try:
+ outs = run_cell(kc, cell)
+ except Exception as e:
+ print("failed to run cell:", repr(e))
+ print(cell.input)
+ errors += 1
+ continue
+
+ failed = not compare_outputs(cell.outputs, outs)
+ print("{: <30} {: >2}: ".format(title, i), end="")
+ if failed:
+ print("FAIL")
+ failures += 1
+ else:
+ print("OK")
+ successes += 1
+
+ print("tested notebook %s" % ipynb)
+ print(" %3i cells successfully replicated" % successes)
+ if failures:
+ print(" %3i cells mismatched output" % failures)
+ if errors:
+ print(" %3i cells failed to complete" % errors)
+ kc.stop_channels()
+ km.shutdown_kernel()
+ del km
+ if failures or errors:
+ sys.exit(1)
+
+
+if __name__ == '__main__':
+ for ipynb in sys.argv[1:]:
+ tries=3
+ while tries:
+ print("testing %s" % ipynb)
+ try:
+ test_notebook(ipynb)
+ break
+ except RuntimeError as e:
+ # If the Kernel dies, try again. It seems we have spurious
+ # failures when multiple instances of jupyter start in parallel.
+ if 'Kernel died' in str(e):
+ tries -= 1
+ if tries:
+ s = random.randint(1, 5)
+ print("trying again in", s, "seconds...")
+ time.sleep(s)
+ else:
+ raise e
diff --git a/tiger-compiler/tcsh/python/tests/llvmtranslate.ipynb b/tiger-compiler/tcsh/python/tests/llvmtranslate.ipynb
new file mode 100644
index 0000000..1e84c8f
--- /dev/null
+++ b/tiger-compiler/tcsh/python/tests/llvmtranslate.ipynb
@@ -0,0 +1,220 @@
+{
+ "cells": [
+ {
+ "cell_type": "markdown",
+ "id": "b8caa27f",
+ "metadata": {},
+ "source": [
+ "# Import Tiger and LLVMTranslate"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 1,
+ "id": "9cb3bce5",
+ "metadata": {},
+ "outputs": [],
+ "source": [
+ "import tc"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 2,
+ "id": "be38c5fe",
+ "metadata": {},
+ "outputs": [
+ {
+ "data": {
+ "text/plain": [
+ "True"
+ ]
+ },
+ "execution_count": 2,
+ "metadata": {},
+ "output_type": "execute_result"
+ }
+ ],
+ "source": [
+ "tc.has(\"llvmtranslate\")"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 3,
+ "id": "9fe09a20",
+ "metadata": {},
+ "outputs": [
+ {
+ "data": {
+ "text/plain": [
+ "True"
+ ]
+ },
+ "execution_count": 3,
+ "metadata": {},
+ "output_type": "execute_result"
+ }
+ ],
+ "source": [
+ "import tiger_llvmtranslate\n",
+ "tiger_llvmtranslate == tc.llvmtranslate"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "id": "3b3a7285",
+ "metadata": {},
+ "source": [
+ "# LLVMTranslate Library"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 4,
+ "id": "2be2f25d",
+ "metadata": {},
+ "outputs": [
+ {
+ "data": {
+ "text/plain": [
+ "['translate']"
+ ]
+ },
+ "execution_count": 4,
+ "metadata": {},
+ "output_type": "execute_result"
+ }
+ ],
+ "source": [
+ "list(filter(lambda e: not e.startswith(\"_\") and not e.startswith(\"tiger\"), dir(tc.llvmtranslate)))"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "id": "39d05040",
+ "metadata": {},
+ "source": [
+ "# Tiger Magics and LLVMTranslate"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 5,
+ "id": "b210db83",
+ "metadata": {},
+ "outputs": [],
+ "source": [
+ "%%tiger executor llvm\n",
+ "let\n",
+ " var b := 5\n",
+ "in\n",
+ " print_int(b)\n",
+ "end"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 6,
+ "id": "cd732dc4",
+ "metadata": {},
+ "outputs": [
+ {
+ "name": "stdout",
+ "output_type": "stream",
+ "text": [
+ "; ModuleID = 'LRDE Tiger Compiler'\n",
+ "source_filename = \"LRDE Tiger Compiler\"\n"
+ ]
+ }
+ ],
+ "source": [
+ "llvm = executor.llvm\n",
+ "print(*llvm.splitlines()[0:2], sep=\"\\n\")"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 7,
+ "id": "defafcde",
+ "metadata": {},
+ "outputs": [
+ {
+ "name": "stdout",
+ "output_type": "stream",
+ "text": [
+ "5\n"
+ ]
+ }
+ ],
+ "source": [
+ "print(executor.result)"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "id": "35825bf6",
+ "metadata": {},
+ "source": [
+ "# LLVMTranslate example\n",
+ "In Tiger Magics it run translate and then run clang (see tcsh/python/ti.py)"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 8,
+ "id": "0ee4cd72",
+ "metadata": {},
+ "outputs": [],
+ "source": [
+ "import tempfile\n",
+ "\n",
+ "with tempfile.NamedTemporaryFile() as f:\n",
+ " f.write(b\"let var b := 5 in print_int(b) end\")\n",
+ " f.seek(0)\n",
+ " ast = tc.ti.TiExecutor(f.name).desugar()"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 9,
+ "id": "29d68680",
+ "metadata": {},
+ "outputs": [
+ {
+ "name": "stdout",
+ "output_type": "stream",
+ "text": [
+ "; ModuleID = 'LRDE Tiger Compiler'\n",
+ "source_filename = \"LRDE Tiger Compiler\"\n"
+ ]
+ }
+ ],
+ "source": [
+ "llvm = tc.llvmtranslate.translate(ast)\n",
+ "print(*llvm.splitlines()[0:2], sep=\"\\n\")"
+ ]
+ }
+ ],
+ "metadata": {
+ "kernelspec": {
+ "display_name": "Python 3 (ipykernel)",
+ "language": "python",
+ "name": "python3"
+ },
+ "language_info": {
+ "codemirror_mode": {
+ "name": "ipython",
+ "version": 3
+ },
+ "file_extension": ".py",
+ "mimetype": "text/x-python",
+ "name": "python",
+ "nbconvert_exporter": "python",
+ "pygments_lexer": "ipython3",
+ "version": "3.10.1"
+ }
+ },
+ "nbformat": 4,
+ "nbformat_minor": 5
+}
diff --git a/tiger-compiler/tcsh/python/tests/misc.ipynb b/tiger-compiler/tcsh/python/tests/misc.ipynb
new file mode 100644
index 0000000..8fb12a2
--- /dev/null
+++ b/tiger-compiler/tcsh/python/tests/misc.ipynb
@@ -0,0 +1,358 @@
+{
+ "cells": [
+ {
+ "cell_type": "markdown",
+ "id": "3f7f66b6",
+ "metadata": {},
+ "source": [
+ "# Import Tiger and Misc"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 1,
+ "id": "9cb3bce5",
+ "metadata": {},
+ "outputs": [],
+ "source": [
+ "import tc"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 2,
+ "id": "be38c5fe",
+ "metadata": {},
+ "outputs": [
+ {
+ "data": {
+ "text/plain": [
+ "True"
+ ]
+ },
+ "execution_count": 2,
+ "metadata": {},
+ "output_type": "execute_result"
+ }
+ ],
+ "source": [
+ "tc.has(\"misc\")"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 3,
+ "id": "9fe09a20",
+ "metadata": {},
+ "outputs": [
+ {
+ "data": {
+ "text/plain": [
+ "True"
+ ]
+ },
+ "execution_count": 3,
+ "metadata": {},
+ "output_type": "execute_result"
+ }
+ ],
+ "source": [
+ "import tiger_misc\n",
+ "tiger_misc == tc.misc"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "id": "3b3a7285",
+ "metadata": {},
+ "source": [
+ "# Misc Library"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 4,
+ "id": "2be2f25d",
+ "metadata": {},
+ "outputs": [
+ {
+ "data": {
+ "text/plain": [
+ "['error', 'file_library', 'symbol', 'symbol_fresh', 'timer']"
+ ]
+ },
+ "execution_count": 4,
+ "metadata": {},
+ "output_type": "execute_result"
+ }
+ ],
+ "source": [
+ "list(filter(lambda e: not e.startswith(\"_\"), dir(tc.misc)))"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "id": "c2ffa10b",
+ "metadata": {},
+ "source": [
+ "# Misc error"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 5,
+ "id": "0ee4cd72",
+ "metadata": {},
+ "outputs": [
+ {
+ "name": "stdout",
+ "output_type": "stream",
+ "text": [
+ "0 SUCCESS\n",
+ "1 FAILURE\n",
+ "2 SCAN\n",
+ "3 PARSE\n",
+ "4 BIND\n",
+ "5 TYPE\n"
+ ]
+ }
+ ],
+ "source": [
+ "errors_messages = tc.misc.error.error_type_message()\n",
+ "for i in range(6):\n",
+ " print(i, errors_messages[i])"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 6,
+ "id": "bf7ee0ae",
+ "metadata": {},
+ "outputs": [
+ {
+ "name": "stdout",
+ "output_type": "stream",
+ "text": [
+ "0\n",
+ "1\n",
+ "2\n",
+ "3\n",
+ "4\n",
+ "5\n"
+ ]
+ }
+ ],
+ "source": [
+ "print(tc.misc.error.error_type_success)\n",
+ "print(tc.misc.error.error_type_failure)\n",
+ "print(tc.misc.error.error_type_scan)\n",
+ "print(tc.misc.error.error_type_parse)\n",
+ "print(tc.misc.error.error_type_bind)\n",
+ "print(tc.misc.error.error_type_type)"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "id": "aa79fa38",
+ "metadata": {},
+ "source": [
+ "# Misc symbol"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 7,
+ "id": "082ad376",
+ "metadata": {},
+ "outputs": [],
+ "source": [
+ "hello = tc.misc.symbol(\"Hello\")"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 8,
+ "id": "88a477ec",
+ "metadata": {},
+ "outputs": [
+ {
+ "name": "stdout",
+ "output_type": "stream",
+ "text": [
+ "<class 'tiger_misc.symbol'>\n"
+ ]
+ }
+ ],
+ "source": [
+ "print(type(hello))"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 9,
+ "id": "315f56d1",
+ "metadata": {},
+ "outputs": [
+ {
+ "data": {
+ "text/plain": [
+ "'Hello'"
+ ]
+ },
+ "execution_count": 9,
+ "metadata": {},
+ "output_type": "execute_result"
+ }
+ ],
+ "source": [
+ "str(hello)"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 10,
+ "id": "9614378d",
+ "metadata": {},
+ "outputs": [
+ {
+ "data": {
+ "text/plain": [
+ "False"
+ ]
+ },
+ "execution_count": 10,
+ "metadata": {},
+ "output_type": "execute_result"
+ }
+ ],
+ "source": [
+ "hello == \"Hello\""
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 11,
+ "id": "14621e65",
+ "metadata": {},
+ "outputs": [
+ {
+ "data": {
+ "text/plain": [
+ "True"
+ ]
+ },
+ "execution_count": 11,
+ "metadata": {},
+ "output_type": "execute_result"
+ }
+ ],
+ "source": [
+ "hello == tc.misc.symbol(\"Hello\")"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 12,
+ "id": "dccec330",
+ "metadata": {},
+ "outputs": [
+ {
+ "data": {
+ "text/plain": [
+ "True"
+ ]
+ },
+ "execution_count": 12,
+ "metadata": {},
+ "output_type": "execute_result"
+ }
+ ],
+ "source": [
+ "hello != tc.misc.symbol(\"world\")"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "id": "a8236c03",
+ "metadata": {},
+ "source": [
+ "# Misc timer"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 13,
+ "id": "2f35c4c7",
+ "metadata": {},
+ "outputs": [],
+ "source": [
+ "my_timer = tc.misc.timer()"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 14,
+ "id": "70f7b6e0",
+ "metadata": {},
+ "outputs": [],
+ "source": [
+ "my_timer.start()"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 15,
+ "id": "8510ce33",
+ "metadata": {},
+ "outputs": [],
+ "source": [
+ "my_timer.push('test')"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 16,
+ "id": "8eeb355b",
+ "metadata": {},
+ "outputs": [
+ {
+ "name": "stderr",
+ "output_type": "stream",
+ "text": [
+ "Execution times (seconds)\n",
+ "\n",
+ "Cumulated times (seconds)\n",
+ " test : -0.79 ( -79%) -0.13 ( -13%) -1.43526e+07 (-1.44e+09%) \n",
+ "\n",
+ " TOTAL (seconds) : 0 user, 0 system, 0 wall\n"
+ ]
+ }
+ ],
+ "source": [
+ "#DONTCHECK\n",
+ "my_timer.dump()"
+ ]
+ }
+ ],
+ "metadata": {
+ "kernelspec": {
+ "display_name": "Python 3 (ipykernel)",
+ "language": "python",
+ "name": "python3"
+ },
+ "language_info": {
+ "codemirror_mode": {
+ "name": "ipython",
+ "version": 3
+ },
+ "file_extension": ".py",
+ "mimetype": "text/x-python",
+ "name": "python",
+ "nbconvert_exporter": "python",
+ "pygments_lexer": "ipython3",
+ "version": "3.10.2"
+ }
+ },
+ "nbformat": 4,
+ "nbformat_minor": 5
+}
diff --git a/tiger-compiler/tcsh/python/tests/object.ipynb b/tiger-compiler/tcsh/python/tests/object.ipynb
new file mode 100644
index 0000000..69563e5
--- /dev/null
+++ b/tiger-compiler/tcsh/python/tests/object.ipynb
@@ -0,0 +1,182 @@
+{
+ "cells": [
+ {
+ "cell_type": "markdown",
+ "id": "3f7f66b6",
+ "metadata": {},
+ "source": [
+ "# Import Tiger and Object"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 1,
+ "id": "9cb3bce5",
+ "metadata": {},
+ "outputs": [],
+ "source": [
+ "import tc"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 2,
+ "id": "be38c5fe",
+ "metadata": {},
+ "outputs": [
+ {
+ "data": {
+ "text/plain": [
+ "True"
+ ]
+ },
+ "execution_count": 2,
+ "metadata": {},
+ "output_type": "execute_result"
+ }
+ ],
+ "source": [
+ "tc.has(\"object\")"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 3,
+ "id": "9fe09a20",
+ "metadata": {},
+ "outputs": [
+ {
+ "data": {
+ "text/plain": [
+ "True"
+ ]
+ },
+ "execution_count": 3,
+ "metadata": {},
+ "output_type": "execute_result"
+ }
+ ],
+ "source": [
+ "import tiger_object\n",
+ "tiger_object == tc.object"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "id": "c2ffa10b",
+ "metadata": {},
+ "source": [
+ "# Object functions"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 4,
+ "id": "37f1bbb8",
+ "metadata": {},
+ "outputs": [],
+ "source": [
+ "from typing import Callable\n",
+ "def function_annotations(fn: Callable) -> str:\n",
+ " ann = fn.__annotations__\n",
+ " ret = ann.get(\"return\")\n",
+ " args = \", \".join((\"{}: '{}'\".format(a, ann[a]) for a in ann if a != \"return\"))\n",
+ " name = fn.__module__ + '.' + fn.__qualname__\n",
+ " return \"<function {name}({args}) -> '{ret}'>\".format(name=name, args=args, ret=ret)"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 5,
+ "id": "0ee4cd72",
+ "metadata": {},
+ "outputs": [
+ {
+ "name": "stdout",
+ "output_type": "stream",
+ "text": [
+ "<function tiger_object.bind(tree: 'Ast') -> 'misc::error'>\n"
+ ]
+ }
+ ],
+ "source": [
+ "if tc.has(\"bind\"): # Wait TC3\n",
+ " print(function_annotations(tc.object.bind))\n",
+ "else:\n",
+ " def bind(tree: 'ast::Ast &') -> 'misc::error':\n",
+ " pass\n",
+ " bind.__module__ = \"tiger_object\"\n",
+ " print(function_annotations(bind))"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 6,
+ "id": "bfba3cc3",
+ "metadata": {},
+ "outputs": [
+ {
+ "name": "stdout",
+ "output_type": "stream",
+ "text": [
+ "<function tiger_object.types_check(tree: 'Ast') -> 'misc::error'>\n"
+ ]
+ }
+ ],
+ "source": [
+ "if tc.has(\"type\"): # Wait TC4\n",
+ " print(function_annotations(tc.object.types_check))\n",
+ "else:\n",
+ " def types_check(tree: 'ast::Ast &') -> 'misc::error':\n",
+ " pass\n",
+ " types_check.__module__ = \"tiger_object\"\n",
+ " print(function_annotations(types_check))"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 7,
+ "id": "bd48ce57",
+ "metadata": {},
+ "outputs": [
+ {
+ "name": "stdout",
+ "output_type": "stream",
+ "text": [
+ "<function tiger_object.rename(tree: 'Ast') -> 'object::class_names_type *'>\n"
+ ]
+ }
+ ],
+ "source": [
+ "if tc.has(\"desugar\"): # Wait TC4\n",
+ " print(function_annotations(tc.object.rename))\n",
+ "else:\n",
+ " def rename(tree: 'ast::Ast &') -> 'object::class_names_type *':\n",
+ " pass\n",
+ " rename.__module__ = \"tiger_object\"\n",
+ " print(function_annotations(rename))"
+ ]
+ }
+ ],
+ "metadata": {
+ "kernelspec": {
+ "display_name": "Python 3 (ipykernel)",
+ "language": "python",
+ "name": "python3"
+ },
+ "language_info": {
+ "codemirror_mode": {
+ "name": "ipython",
+ "version": 3
+ },
+ "file_extension": ".py",
+ "mimetype": "text/x-python",
+ "name": "python",
+ "nbconvert_exporter": "python",
+ "pygments_lexer": "ipython3",
+ "version": "3.10.2"
+ }
+ },
+ "nbformat": 4,
+ "nbformat_minor": 5
+}
diff --git a/tiger-compiler/tcsh/python/tests/overload.ipynb b/tiger-compiler/tcsh/python/tests/overload.ipynb
new file mode 100644
index 0000000..170ab9c
--- /dev/null
+++ b/tiger-compiler/tcsh/python/tests/overload.ipynb
@@ -0,0 +1,207 @@
+{
+ "cells": [
+ {
+ "cell_type": "markdown",
+ "id": "b8caa27f",
+ "metadata": {},
+ "source": [
+ "# Import Tiger and Overload"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 1,
+ "id": "9cb3bce5",
+ "metadata": {},
+ "outputs": [],
+ "source": [
+ "import tc"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 2,
+ "id": "be38c5fe",
+ "metadata": {},
+ "outputs": [
+ {
+ "data": {
+ "text/plain": [
+ "True"
+ ]
+ },
+ "execution_count": 2,
+ "metadata": {},
+ "output_type": "execute_result"
+ }
+ ],
+ "source": [
+ "tc.has(\"overload\")"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 3,
+ "id": "9fe09a20",
+ "metadata": {},
+ "outputs": [
+ {
+ "data": {
+ "text/plain": [
+ "True"
+ ]
+ },
+ "execution_count": 3,
+ "metadata": {},
+ "output_type": "execute_result"
+ }
+ ],
+ "source": [
+ "import tiger_overload\n",
+ "tiger_overload == tc.overload"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "id": "3b3a7285",
+ "metadata": {},
+ "source": [
+ "# Overload Library"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 4,
+ "id": "2be2f25d",
+ "metadata": {},
+ "outputs": [
+ {
+ "data": {
+ "text/plain": [
+ "['bind', 'types_check']"
+ ]
+ },
+ "execution_count": 4,
+ "metadata": {},
+ "output_type": "execute_result"
+ }
+ ],
+ "source": [
+ "list(filter(lambda e: not e.startswith(\"_\") and not e.startswith(\"tiger\"), dir(tc.overload)))"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "id": "35825bf6",
+ "metadata": {},
+ "source": [
+ "# Overload Ast\n",
+ "We use this to only parse the ast and don't run code after TC4, but use Tiger Magics"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 5,
+ "id": "0ee4cd72",
+ "metadata": {},
+ "outputs": [
+ {
+ "name": "stdout",
+ "output_type": "stream",
+ "text": [
+ "<class 'tiger_ast.ChunkList'>\n"
+ ]
+ }
+ ],
+ "source": [
+ "import tempfile\n",
+ "\n",
+ "with tempfile.NamedTemporaryFile() as f:\n",
+ " f.write(b\"let var b := 5 in print_int(b) end\")\n",
+ " f.seek(0)\n",
+ " ast = tc.ti.TiExecutor(f.name).type()\n",
+ "print(type(ast))"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 6,
+ "id": "29d68680",
+ "metadata": {},
+ "outputs": [
+ {
+ "name": "stdout",
+ "output_type": "stream",
+ "text": [
+ "<class 'tuple'>\n"
+ ]
+ }
+ ],
+ "source": [
+ "pair = tc.overload.bind(ast)\n",
+ "print(type(pair))"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 7,
+ "id": "46abfec6",
+ "metadata": {},
+ "outputs": [
+ {
+ "name": "stdout",
+ "output_type": "stream",
+ "text": [
+ "<class 'SwigPyObject'> <class 'tiger_misc.error'>\n",
+ "\n"
+ ]
+ }
+ ],
+ "source": [
+ "overfun_bindings_get, error = pair\n",
+ "print(type(overfun_bindings_get), type(error))\n",
+ "print(error)"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 8,
+ "id": "e8f0ee43",
+ "metadata": {},
+ "outputs": [
+ {
+ "name": "stdout",
+ "output_type": "stream",
+ "text": [
+ "\n"
+ ]
+ }
+ ],
+ "source": [
+ "error = tc.overload.types_check(ast, overfun_bindings_get)\n",
+ "print(error)"
+ ]
+ }
+ ],
+ "metadata": {
+ "kernelspec": {
+ "display_name": "Python 3 (ipykernel)",
+ "language": "python",
+ "name": "python3"
+ },
+ "language_info": {
+ "codemirror_mode": {
+ "name": "ipython",
+ "version": 3
+ },
+ "file_extension": ".py",
+ "mimetype": "text/x-python",
+ "name": "python",
+ "nbconvert_exporter": "python",
+ "pygments_lexer": "ipython3",
+ "version": "3.10.2"
+ }
+ },
+ "nbformat": 4,
+ "nbformat_minor": 5
+}
diff --git a/tiger-compiler/tcsh/python/tests/parse.ipynb b/tiger-compiler/tcsh/python/tests/parse.ipynb
new file mode 100644
index 0000000..e899bc4
--- /dev/null
+++ b/tiger-compiler/tcsh/python/tests/parse.ipynb
@@ -0,0 +1,150 @@
+{
+ "cells": [
+ {
+ "cell_type": "markdown",
+ "id": "3f7f66b6",
+ "metadata": {},
+ "source": [
+ "# Import Tiger and Parse"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 1,
+ "id": "9cb3bce5",
+ "metadata": {},
+ "outputs": [],
+ "source": [
+ "import tc"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 2,
+ "id": "be38c5fe",
+ "metadata": {},
+ "outputs": [
+ {
+ "data": {
+ "text/plain": [
+ "True"
+ ]
+ },
+ "execution_count": 2,
+ "metadata": {},
+ "output_type": "execute_result"
+ }
+ ],
+ "source": [
+ "tc.has(\"parse\")"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 3,
+ "id": "9fe09a20",
+ "metadata": {},
+ "outputs": [
+ {
+ "data": {
+ "text/plain": [
+ "True"
+ ]
+ },
+ "execution_count": 3,
+ "metadata": {},
+ "output_type": "execute_result"
+ }
+ ],
+ "source": [
+ "import tiger_parse\n",
+ "tiger_parse == tc.parse"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "id": "3b3a7285",
+ "metadata": {},
+ "source": [
+ "# Parse Library"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 4,
+ "id": "2be2f25d",
+ "metadata": {},
+ "outputs": [
+ {
+ "data": {
+ "text/plain": [
+ "['MetavarChunkList',\n",
+ " 'MetavarMap',\n",
+ " 'MetavarNameTy',\n",
+ " 'MetavarVar',\n",
+ " 'TigerParser',\n",
+ " 'YY_NULLPTR',\n",
+ " 'location',\n",
+ " 'parse',\n",
+ " 'parse_chunks',\n",
+ " 'parse_unit',\n",
+ " 'position']"
+ ]
+ },
+ "execution_count": 4,
+ "metadata": {},
+ "output_type": "execute_result"
+ }
+ ],
+ "source": [
+ "list(filter(lambda e: not e.startswith(\"_\") and not e.endswith(\"Tweast\") and not e.startswith(\"tiger\"), dir(tc.parse)))"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "id": "c2ffa10b",
+ "metadata": {},
+ "source": [
+ "# Parse parse"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 5,
+ "id": "0ee4cd72",
+ "metadata": {},
+ "outputs": [],
+ "source": [
+ "import tempfile\n",
+ "\n",
+ "if tc.has(\"misc\"):\n",
+ " with tempfile.NamedTemporaryFile() as f:\n",
+ " f.write(b\"let in end\")\n",
+ " f.seek(0)\n",
+ " ast = tc.parse.parse(\"builtin\", f.name, tc.misc.file_library())\n",
+ " # do not use ast before tc2"
+ ]
+ }
+ ],
+ "metadata": {
+ "kernelspec": {
+ "display_name": "Python 3 (ipykernel)",
+ "language": "python",
+ "name": "python3"
+ },
+ "language_info": {
+ "codemirror_mode": {
+ "name": "ipython",
+ "version": 3
+ },
+ "file_extension": ".py",
+ "mimetype": "text/x-python",
+ "name": "python",
+ "nbconvert_exporter": "python",
+ "pygments_lexer": "ipython3",
+ "version": "3.10.1"
+ }
+ },
+ "nbformat": 4,
+ "nbformat_minor": 5
+}
diff --git a/tiger-compiler/tcsh/python/tests/tc.ipynb b/tiger-compiler/tcsh/python/tests/tc.ipynb
new file mode 100644
index 0000000..58cfa3f
--- /dev/null
+++ b/tiger-compiler/tcsh/python/tests/tc.ipynb
@@ -0,0 +1,252 @@
+{
+ "cells": [
+ {
+ "cell_type": "markdown",
+ "id": "cefa08c9",
+ "metadata": {},
+ "source": [
+ "# Import tc"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 1,
+ "id": "989c2dff",
+ "metadata": {},
+ "outputs": [],
+ "source": [
+ "import tc"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "id": "37e62513",
+ "metadata": {},
+ "source": [
+ "# Tiger Magics"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 2,
+ "id": "38583076",
+ "metadata": {},
+ "outputs": [
+ {
+ "name": "stdout",
+ "output_type": "stream",
+ "text": [
+ "%%tiger variable_name [backend]\n",
+ "variable_name is the name of the finale variable\n",
+ "backend is optional and must be in [llvm, hir, lir, mips, ia32]\n"
+ ]
+ }
+ ],
+ "source": [
+ "print(tc.TigerMagics.__doc__)"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 3,
+ "id": "0e93343f",
+ "metadata": {},
+ "outputs": [
+ {
+ "name": "stderr",
+ "output_type": "stream",
+ "text": [
+ "UsageError: %%tiger is a cell magic, but the cell body is empty.\n"
+ ]
+ }
+ ],
+ "source": [
+ "%%tiger"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 4,
+ "id": "d2d30487",
+ "metadata": {},
+ "outputs": [
+ {
+ "name": "stderr",
+ "output_type": "stream",
+ "text": [
+ "UsageError: %%tiger is a cell magic, but the cell body is empty.\n"
+ ]
+ }
+ ],
+ "source": [
+ "%%tiger execution"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 5,
+ "id": "c5ce6c25",
+ "metadata": {},
+ "outputs": [
+ {
+ "name": "stderr",
+ "output_type": "stream",
+ "text": [
+ "%%tiger variable_name [backend]\n",
+ "variable_name is the name of the finale variable\n",
+ "backend is optional and must be in [llvm, hir, lir, mips, ia32]\n"
+ ]
+ }
+ ],
+ "source": [
+ "%%tiger\n",
+ "let in end"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 6,
+ "id": "05856612",
+ "metadata": {},
+ "outputs": [],
+ "source": [
+ "%%tiger execution\n",
+ "let in end"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "id": "326e35de",
+ "metadata": {},
+ "source": [
+ "# tc Variables and Functions"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 7,
+ "id": "97e995a8",
+ "metadata": {},
+ "outputs": [
+ {
+ "data": {
+ "text/plain": [
+ "<Swig Object of type 'std::ostream *' at 0x7fd40876a430>"
+ ]
+ },
+ "execution_count": 7,
+ "metadata": {},
+ "output_type": "execute_result"
+ }
+ ],
+ "source": [
+ "tc.Cout"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 8,
+ "id": "ad4ebd05",
+ "metadata": {},
+ "outputs": [
+ {
+ "data": {
+ "text/plain": [
+ "<Swig Object of type 'std::ostream *' at 0x7fd40876a610>"
+ ]
+ },
+ "execution_count": 8,
+ "metadata": {},
+ "output_type": "execute_result"
+ }
+ ],
+ "source": [
+ "tc.Cerr"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 9,
+ "id": "6790e6ee",
+ "metadata": {},
+ "outputs": [
+ {
+ "data": {
+ "text/plain": [
+ "<enum 'BackendType'>"
+ ]
+ },
+ "execution_count": 9,
+ "metadata": {},
+ "output_type": "execute_result"
+ }
+ ],
+ "source": [
+ "tc.BackendType"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 10,
+ "id": "34ebeb8c",
+ "metadata": {},
+ "outputs": [
+ {
+ "data": {
+ "text/plain": [
+ "<function tc.has(module_name: str) -> bool>"
+ ]
+ },
+ "execution_count": 10,
+ "metadata": {},
+ "output_type": "execute_result"
+ }
+ ],
+ "source": [
+ "tc.has"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 11,
+ "id": "fc67329d",
+ "metadata": {},
+ "outputs": [
+ {
+ "data": {
+ "text/plain": [
+ "True"
+ ]
+ },
+ "execution_count": 11,
+ "metadata": {},
+ "output_type": "execute_result"
+ }
+ ],
+ "source": [
+ "tc.has(\"common\")"
+ ]
+ }
+ ],
+ "metadata": {
+ "kernelspec": {
+ "display_name": "Python 3 (ipykernel)",
+ "language": "python",
+ "name": "python3"
+ },
+ "language_info": {
+ "codemirror_mode": {
+ "name": "ipython",
+ "version": 3
+ },
+ "file_extension": ".py",
+ "mimetype": "text/x-python",
+ "name": "python",
+ "nbconvert_exporter": "python",
+ "pygments_lexer": "ipython3",
+ "version": "3.10.1"
+ }
+ },
+ "nbformat": 4,
+ "nbformat_minor": 5
+}
diff --git a/tiger-compiler/tcsh/python/tests/ti.ipynb b/tiger-compiler/tcsh/python/tests/ti.ipynb
new file mode 100644
index 0000000..dfa5399
--- /dev/null
+++ b/tiger-compiler/tcsh/python/tests/ti.ipynb
@@ -0,0 +1,186 @@
+{
+ "cells": [
+ {
+ "cell_type": "markdown",
+ "id": "7415e928",
+ "metadata": {},
+ "source": [
+ "The ti module is used to easily perform all the steps in the tc module and in the command line."
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "id": "cefa08c9",
+ "metadata": {},
+ "source": [
+ "# Import ti"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 1,
+ "id": "989c2dff",
+ "metadata": {},
+ "outputs": [],
+ "source": [
+ "import ti"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "id": "37e62513",
+ "metadata": {},
+ "source": [
+ "# ti Process File"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 2,
+ "id": "d293f4f2",
+ "metadata": {},
+ "outputs": [
+ {
+ "data": {
+ "text/plain": [
+ "<function ti.process_file(filename: 'str', backend: 'tc.BackendType' = <BackendType.mips: 'mips'>, **kwargs) -> 'None'>"
+ ]
+ },
+ "execution_count": 2,
+ "metadata": {},
+ "output_type": "execute_result"
+ }
+ ],
+ "source": [
+ "ti.process_file"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 3,
+ "id": "fefa7505",
+ "metadata": {},
+ "outputs": [
+ {
+ "name": "stdout",
+ "output_type": "stream",
+ "text": [
+ "Hello World!\n"
+ ]
+ }
+ ],
+ "source": [
+ "import tempfile\n",
+ "\n",
+ "with tempfile.NamedTemporaryFile() as f:\n",
+ " f.write(b'let in print(\"Hello World!\\n\") end')\n",
+ " f.seek(0)\n",
+ " \n",
+ " if not ti.tc.has(\"llvmtranslate\"): # Simulate result before TCL\n",
+ " print(\"Hello World!\")\n",
+ " else:\n",
+ " ti.process_file(f.name, 'llvm')"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "id": "3a6c23a4",
+ "metadata": {},
+ "source": [
+ "# ti TiExecutor"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 4,
+ "id": "bd177f77",
+ "metadata": {},
+ "outputs": [
+ {
+ "data": {
+ "text/plain": [
+ "<function ti.TiExecutor.__init__(self, filename: 'str', backend: 'tc.BackendType' = <BackendType.mips: 'mips'>, exit_on_error: 'bool' = True, get_result: 'bool' = False, rename: 'bool' = True, desugar: 'bool' = True, object_enabled: 'bool' = True, debug: 'bool' = False)>"
+ ]
+ },
+ "execution_count": 4,
+ "metadata": {},
+ "output_type": "execute_result"
+ }
+ ],
+ "source": [
+ "ti.TiExecutor.__init__"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 5,
+ "id": "64c47c73",
+ "metadata": {},
+ "outputs": [
+ {
+ "name": "stdout",
+ "output_type": "stream",
+ "text": [
+ "ast: None\n",
+ "error: None\n",
+ "fragments: None\n",
+ "lir_fragments: None\n",
+ "llvm: None\n",
+ "result: None\n",
+ "target: None\n",
+ "tempmap: None\n",
+ "\n",
+ "Hello World!\n",
+ "\n"
+ ]
+ }
+ ],
+ "source": [
+ "import tempfile\n",
+ "\n",
+ "with tempfile.NamedTemporaryFile() as f:\n",
+ " # Create File\n",
+ " f.write(b'let in print(\"Hello World!\\n\") end')\n",
+ " f.seek(0)\n",
+ " \n",
+ " # Create Executor\n",
+ " \n",
+ " if ti.tc.has(\"llvmtranslate\"):\n",
+ " e = ti.TiExecutor(f.name, backend=\"llvm\", rename=False, desugar=False, exit_on_error=False, get_result=True)\n",
+ " else:\n",
+ " e = ti.TiExecutor(f.name, rename=False, desugar=False, exit_on_error=False, get_result=True)\n",
+ " \n",
+ " # All data are empty before execution\n",
+ " print(e.data)\n",
+ " e.backend_exec()\n",
+ " \n",
+ " if not ti.tc.has(\"llvmtranslate\"): # Simulate result before TCL\n",
+ " e.data.result = \"Hello World!\\n\"\n",
+ " \n",
+ " # Result is stored when get_result=True\n",
+ " print(e.data.result)"
+ ]
+ }
+ ],
+ "metadata": {
+ "kernelspec": {
+ "display_name": "Python 3 (ipykernel)",
+ "language": "python",
+ "name": "python3"
+ },
+ "language_info": {
+ "codemirror_mode": {
+ "name": "ipython",
+ "version": 3
+ },
+ "file_extension": ".py",
+ "mimetype": "text/x-python",
+ "name": "python",
+ "nbconvert_exporter": "python",
+ "pygments_lexer": "ipython3",
+ "version": "3.10.2"
+ }
+ },
+ "nbformat": 4,
+ "nbformat_minor": 5
+}
diff --git a/tiger-compiler/tcsh/python/tests/type.ipynb b/tiger-compiler/tcsh/python/tests/type.ipynb
new file mode 100644
index 0000000..5daab36
--- /dev/null
+++ b/tiger-compiler/tcsh/python/tests/type.ipynb
@@ -0,0 +1,228 @@
+{
+ "cells": [
+ {
+ "cell_type": "markdown",
+ "id": "81a0b85e",
+ "metadata": {},
+ "source": [
+ "# Import Tiger and type"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 1,
+ "id": "9cb3bce5",
+ "metadata": {},
+ "outputs": [],
+ "source": [
+ "import tc"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 2,
+ "id": "be38c5fe",
+ "metadata": {},
+ "outputs": [
+ {
+ "data": {
+ "text/plain": [
+ "True"
+ ]
+ },
+ "execution_count": 2,
+ "metadata": {},
+ "output_type": "execute_result"
+ }
+ ],
+ "source": [
+ "tc.has(\"type\")"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 3,
+ "id": "9fe09a20",
+ "metadata": {},
+ "outputs": [
+ {
+ "data": {
+ "text/plain": [
+ "True"
+ ]
+ },
+ "execution_count": 3,
+ "metadata": {},
+ "output_type": "execute_result"
+ }
+ ],
+ "source": [
+ "import tiger_type\n",
+ "tiger_type == tc.type"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "id": "3b3a7285",
+ "metadata": {},
+ "source": [
+ "# Type Library"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 4,
+ "id": "2be2f25d",
+ "metadata": {},
+ "outputs": [
+ {
+ "data": {
+ "text/plain": [
+ "['Array',\n",
+ " 'Class',\n",
+ " 'Class_object_instance',\n",
+ " 'Field',\n",
+ " 'Function',\n",
+ " 'Int',\n",
+ " 'Method',\n",
+ " 'Named',\n",
+ " 'Nil',\n",
+ " 'Record',\n",
+ " 'String',\n",
+ " 'Type',\n",
+ " 'Void',\n",
+ " 'cvar',\n",
+ " 'hide_actual_types',\n",
+ " 'types_check']"
+ ]
+ },
+ "execution_count": 4,
+ "metadata": {},
+ "output_type": "execute_result"
+ }
+ ],
+ "source": [
+ "list(filter(lambda e: not e.startswith(\"_\") and not e.startswith(\"tiger\"), dir(tc.type)))"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "id": "35825bf6",
+ "metadata": {},
+ "source": [
+ "# Type Ast\n",
+ "We use this to only parse the ast and don't run code after TC4, but use Tiger Magics"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 5,
+ "id": "0ee4cd72",
+ "metadata": {},
+ "outputs": [
+ {
+ "name": "stdout",
+ "output_type": "stream",
+ "text": [
+ "<class 'tiger_ast.ChunkList'>\n"
+ ]
+ }
+ ],
+ "source": [
+ "import tempfile\n",
+ "\n",
+ "with tempfile.NamedTemporaryFile() as f:\n",
+ " f.write(b\"let var b := 5 in print_int(b) end\")\n",
+ " f.seek(0)\n",
+ " ast = tc.ti.TiExecutor(f.name).type()\n",
+ "print(type(ast))"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 6,
+ "id": "703bb878",
+ "metadata": {},
+ "outputs": [],
+ "source": [
+ "# all variables are identical to ast.ipynb \n",
+ "main_chunk = ast[1]\n",
+ "main_function = main_chunk[0]\n",
+ "main_body = main_function.body_get()\n",
+ "let = main_body.exps_get()[0]\n",
+ "var_chk = let.chunks_get()[0]\n",
+ "var_b = var_chk[0]\n",
+ "print_call = let.body_get()\n",
+ "print_arg = print_call.args_get()[0]"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 7,
+ "id": "40ad7839",
+ "metadata": {},
+ "outputs": [
+ {
+ "name": "stdout",
+ "output_type": "stream",
+ "text": [
+ "<class 'tiger_type.Int'>\n",
+ "int\n"
+ ]
+ }
+ ],
+ "source": [
+ "print(type(var_b.type_get()))\n",
+ "print(str(var_b.type_get()))"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 8,
+ "id": "be462b0c",
+ "metadata": {},
+ "outputs": [
+ {
+ "name": "stdout",
+ "output_type": "stream",
+ "text": [
+ "main_function: \n",
+ "{\n",
+ "} -> void\n",
+ "main_body: void\n",
+ "let: void\n",
+ "var_b: int\n",
+ "print_call: void\n",
+ "print_arg: int\n"
+ ]
+ }
+ ],
+ "source": [
+ "for e in (\"main_function\", \"main_body\", \"let\", \"var_b\", \"print_call\", \"print_arg\"):\n",
+ " if hasattr(globals()[e], \"type_get\"):\n",
+ " print(e, globals()[e].type_get(), sep=\": \")"
+ ]
+ }
+ ],
+ "metadata": {
+ "kernelspec": {
+ "display_name": "Python 3 (ipykernel)",
+ "language": "python",
+ "name": "python3"
+ },
+ "language_info": {
+ "codemirror_mode": {
+ "name": "ipython",
+ "version": 3
+ },
+ "file_extension": ".py",
+ "mimetype": "text/x-python",
+ "name": "python",
+ "nbconvert_exporter": "python",
+ "pygments_lexer": "ipython3",
+ "version": "3.10.2"
+ }
+ },
+ "nbformat": 4,
+ "nbformat_minor": 5
+}
diff --git a/tiger-compiler/tcsh/python/ti.py b/tiger-compiler/tcsh/python/ti.py
new file mode 100755
index 0000000..a7df479
--- /dev/null
+++ b/tiger-compiler/tcsh/python/ti.py
@@ -0,0 +1,356 @@
+#! /usr/bin/env python3
+
+# Tiger interpreter.
+
+# Execute a Tiger program, using the Tiger Compiler through
+# TCSH/Python and a supporting back-end environment (HAVM, Nolimips,
+# or an IA-32 environment).
+#
+# This script needs a complete, dynamically-compiled Tiger compiler
+# (with all its modules) to work. The Tree back-end needs a `havm'
+# binary to be available in the PATH; the MIPS back-end, a `nolimips'
+# binary; and the IA-32 back-end, an IA-32 execution environment.
+
+from __future__ import annotations
+from collections.abc import Callable
+from typing import List, Optional, Tuple, TypeVar, Union
+
+import optparse
+import tempfile
+import subprocess
+
+import os
+import sys
+import re
+
+import tc
+
+
+# Subclass to redefine error method (for exit code to be 1).
+class TiOptionParser(optparse.OptionParser):
+ def error(self, msg: str) -> None:
+ self.print_usage(sys.stderr)
+ self.exit(1, "%s: error: %s\n" % (self.get_prog_name(), msg))
+
+
+T = TypeVar("T")
+
+
+def wrap_step(
+ modules: List[str] = [],
+ require: Optional[str] = None,
+ backend: Optional[tc.BackendType] = None,
+) -> Callable[[Callable[[TiExecutor], T]], Callable[[TiExecutor], Optional[T]]]:
+ """
+ Decorator for steps of TiExecutor, execute the require step if needed
+ """
+
+ def check_wrap_step(
+ f: Callable[[TiExecutor], T]
+ ) -> Callable[[TiExecutor], Optional[T]]:
+ def new_f(self: TiExecutor) -> Optional[T]:
+ if self.debug:
+ print(f"CALL {f.__name__} [{self.backend}]")
+ if backend and self.backend != backend:
+ self.backend = backend
+ if hasattr(self, "__step"):
+ delattr(self, "__step")
+ self._rm_asm()
+ self._rm_llvm()
+ self.data = TiExecutor.TiExecution()
+ if require and not hasattr(self, require):
+ raise RuntimeError(require + " step must exist")
+ if self.data.error:
+ return None
+ hasstep = hasattr(self, "__step")
+ if require and (not hasstep or hasstep and not self.__step == require):
+ getattr(self, require)()
+ if self.data.error:
+ return None
+ for mod in modules:
+ if not tc.has(mod):
+ msg = f"Module {mod} is not available to execute {f.__name__} step\nCheck your install of tc"
+ self.data.error = (-1, msg)
+ print(msg, file=sys.stderr)
+ if self.exit_on_error:
+ sys.exit(1)
+ return None
+ if self.debug:
+ print(f"ENTER {f.__name__} [{self.backend}]")
+ res = f(self)
+ if self.debug:
+ print(f"EXIT {f.__name__} [{self.backend}]")
+ self.__step = f.__name__
+ return res
+
+ new_f.__doc__ = f"Ast {f.__name__} step"
+ if require:
+ new_f.__doc__ += f"\nRequire {require} step, execute it otherwise"
+ if modules and len(modules):
+ new_f.__doc__ += "\nRequire {} tc modules".format(", ".join(modules))
+ new_f.__name__ = f.__name__
+ return new_f
+
+ return check_wrap_step
+
+
+class TiExecutor:
+ class TiExecution:
+ ast: Optional[tc.ast.ChunkList] = None
+ error: Optional[Tuple[int, str]] = None
+ fragments: Optional[tc.tree.Fragments] = None
+ lir_fragments: Optional[tc.assem.Fragments] = None
+ target: Optional[Union[tc.target.Ia32Target, tc.target.MipsTarget]] = None
+ tempmap: Optional[tc.temp.TempMap] = None
+ result: Optional[str] = None
+ llvm: Optional[str] = None
+
+ def __str__(self) -> str:
+ res = ""
+
+ def truncate(msg: str) -> str:
+ return msg if not msg or len(msg) < 100 else msg[:100] + "..."
+
+ for e in dir(self):
+ if not e.startswith("_"):
+ res += e + ": " + truncate(repr(getattr(self, e))) + "\n"
+ return res
+
+ def __init__(
+ self,
+ filename: str,
+ backend: tc.BackendType = tc.BackendType.mips,
+ exit_on_error: bool = True,
+ get_result: bool = False,
+ rename: bool = True,
+ desugar: bool = True,
+ object_enabled: bool = True,
+ debug: bool = False,
+ ):
+ self.filename = filename
+ self.backend = tc.BackendType(backend)
+ self.exit_on_error = exit_on_error
+ self.get = get_result
+ self.rename_enabled = rename
+ self.desugar_enabled = desugar
+ self.object_enabled = object_enabled
+ self.debug = debug
+ self.data = TiExecutor.TiExecution()
+
+ def error_message(self) -> str:
+ if not self.data.error:
+ return ""
+ status, message = self.data.error
+ statusMessage = tc.misc.error.error_type_message()[status]
+ if re.match(r"(.*/)?tmp\w{8}\.tig$", self.filename):
+ if message.startswith(self.filename + ":"):
+ message = message.replace(self.filename + ":", "")
+ message = " " + message
+ else:
+ message = "\n" + message
+ return str(status) + " " + statusMessage + ":" + message
+
+ def throw_error(self, e: Exception) -> None:
+ self.__step = "error"
+ self.data.error = e.args
+ status, message = e.args
+ if self.exit_on_error:
+ print(message, file=sys.stderr)
+ sys.exit(status)
+ else:
+ print(self.error_message(), end="", file=sys.stderr)
+
+ def _rm_attribute_file(self, arg: str) -> None:
+ if hasattr(self, arg):
+ os.unlink(getattr(self, arg))
+ delattr(self, arg)
+
+ def _rm_attribute_dir(self, arg: str) -> None:
+ if hasattr(self, arg):
+ os.rmdir(getattr(self, arg))
+ delattr(self, arg)
+
+ def _rm_attribute_temp(self, arg: str) -> None:
+ if hasattr(self, arg):
+ os.unlink(getattr(self, arg).name)
+ delattr(self, arg)
+
+ def _run_cmd(self, *cmd: str) -> Optional[str]:
+ if self.get:
+ proc = subprocess.run(cmd, capture_output=True)
+ self.data.result = proc.stdout.decode("utf-8")
+ else:
+ os.system(" ".join(cmd))
+ self.data.result = None
+ return self.data.result
+
+ @wrap_step(["misc", "parse"])
+ def parse(self) -> Optional[tc.ast.ChunkList]:
+ lib = tc.misc.file_library()
+ try:
+ self.data.ast = tc.parse.parse("builtin", self.filename, lib)
+ except Exception as e:
+ return self.throw_error(e)
+ return self.data.ast
+
+ @wrap_step(["bind"], "parse")
+ def bind(self) -> Optional[tc.ast.ChunkList]:
+ try:
+ if self.object_enabled and tc.has("object"):
+ tc.object.bind(self.data.ast).exit_on_error()
+ else:
+ tc.bind.bind(self.data.ast).exit_on_error()
+ except Exception as e:
+ return self.throw_error(e)
+ return self.data.ast
+
+ @wrap_step([], "bind")
+ def rename(self) -> Optional[tc.ast.ChunkList]:
+ if (
+ self.rename_enabled
+ and tc.has("bind")
+ and not self.object_enabled
+ and not tc.has("object")
+ ):
+ tc.bind.rename(self.data.ast)
+ return self.data.ast
+
+ @wrap_step(["type"], "rename")
+ def type(self) -> Optional[tc.ast.ChunkList]:
+ try:
+ if self.object_enabled and tc.has("object"):
+ tc.object.types_check(self.data.ast).exit_on_error()
+ else:
+ tc.type.types_check(self.data.ast).exit_on_error()
+ except Exception as e:
+ return self.throw_error(e)
+ return self.data.ast
+
+ @wrap_step([], "type")
+ def object_desugar(self) -> Optional[tc.ast.ChunkList]:
+ if self.object_enabled and tc.has("object"):
+ class_names = tc.object.rename(self.data.ast)
+ self.data.ast = tc.object.desugar(self.data.ast, class_names)
+ return self.data.ast
+
+ @wrap_step([], "object_desugar")
+ def desugar(self) -> Optional[tc.ast.ChunkList]:
+ if self.desugar_enabled and tc.has("desugar"):
+ self.data.ast = tc.desugar.desugar(self.data.ast, True, True)
+ return self.data.ast
+
+ @wrap_step(["llvmtranslate"], "desugar")
+ def llvm_file(self) -> str:
+ self.data.llvm = tc.llvmtranslate.translate(self.data.ast)
+
+ self._rm_llvm()
+ self.llvm_temp_dir = tempfile.mkdtemp()
+ # Dump assembly code output into a temporary file.
+ self.llvm_output = os.path.join(self.llvm_temp_dir, "llvm.ll")
+ with open(self.llvm_output, "w") as f:
+ f.write(str(self.data.llvm))
+ return self.llvm_output
+
+ def _rm_llvm(self) -> None:
+ self._rm_attribute_file("llvm_output")
+ self._rm_attribute_file("llvm_binary")
+ self._rm_attribute_dir("llvm_temp_dir")
+
+ @wrap_step([], "llvm_file")
+ def llvm_bin(self) -> str:
+ self._rm_attribute_file("llvm_binary")
+ self.llvm_binary = os.path.join(self.llvm_temp_dir, "bin")
+ os.system(f"clang -m32 {self.llvm_output} -o {self.llvm_binary}")
+ return self.llvm_binary
+
+ @wrap_step([], "llvm_bin", tc.BackendType.llvm)
+ def llvm(self) -> Optional[str]:
+ self._run_cmd(self.llvm_binary)
+ self._rm_llvm()
+ return self.data.result
+
+ def frontend_run(self) -> None:
+ """Run parse, bind and type depending of TC step"""
+ self.parse()
+
+ self.bind()
+ self.rename()
+ self.type()
+ self.object_desugar()
+ self.desugar()
+ return None
+
+ def backend_exec(self) -> Optional[str]:
+ """execute backends: llvm, hir, lir, mips and ia32"""
+ self.frontend_run()
+ if self.backend == tc.BackendType.llvm:
+ return self.llvm()
+ return None
+
+ def backend_run(self) -> None:
+ self.get = False
+ self.backend_exec()
+
+ def backend_get(self) -> Optional[str]:
+ self.get = True
+ return self.backend_exec()
+
+
+def process_file(
+ filename: str, backend: tc.BackendType = tc.BackendType.mips, **kwargs
+) -> None:
+ executor = TiExecutor(filename, backend=backend, **kwargs)
+ executor.backend_run()
+
+
+if __name__ == "__main__":
+ # Parser creation.
+ parser = TiOptionParser(
+ """%prog [options] file.tig
+ Execute a Tiger program, using a given back-end."""
+ )
+ parser.add_option(
+ "-b",
+ "--back-end",
+ metavar="BACKEND",
+ dest="backend",
+ default=tc.BackendType.mips,
+ help="use BACKEND as back-end. Can be either "
+ f"`{tc.BackendType.llvm.value}' (LLVM), "
+ f"`{tc.BackendType.mips.value}' (MIPS assembly language) "
+ "[default: %default]",
+ )
+ parser.add_option(
+ "-d",
+ "--debug",
+ action="store_true",
+ dest="debug",
+ default=False,
+ help="print debug call trace",
+ )
+
+ # Options parsing.
+ (options, args) = parser.parse_args()
+
+ # Invalid argument.
+ me = os.path.basename(sys.argv[0])
+ error = False
+ if len(args) != 1:
+ print(f"{me}: not enough arguments")
+ error = True
+
+ if options.backend not in [e.value for e in tc.BackendType]:
+ print(f"{me}: select a valid backend")
+ error = True
+
+ if error:
+ parser.print_help()
+ sys.exit(1)
+
+ # Get filename from arguments.
+ filename = args[-1]
+ process_file(filename, **vars(options))
+
+# Local Variables:
+# mode: python
+# End: