-
Notifications
You must be signed in to change notification settings - Fork 5
/
tampio.py
executable file
·152 lines (135 loc) · 5.22 KB
/
tampio.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
#!/usr/bin/env python3
#
# Tampio Compiler
# Copyright (C) 2018 Iikka Hauhio
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.
import argparse, readline, sys, traceback, os
from fatal_error import TampioSyntaxError
from lex import lexCode
from grammar import initializeParser, parseDeclaration
from highlighter import prettyPrint, HIGHLIGHTERS
from ast import initializeCompiler, compileModule
DEBUG = False
PRINT_INCLUDED = False
included_code = ""
def includeFile(filename):
global included_code
with open(filename) as f:
_, ans, _ = compileCode(f.read())
if PRINT_INCLUDED:
included_code += ans
def compileCode(code):
tokens = lexCode(code)
decls = []
num_errors = 0
def handleError(e):
nonlocal num_errors
if DEBUG:
traceback.print_exc()
else:
e.printMe(sys.stderr)
while not tokens.eof() and tokens.next().token != ".":
pass
num_errors += 1
initializeParser()
while not tokens.eof():
try:
decls += [parseDeclaration(tokens)]
except TampioSyntaxError as e:
handleError(e)
target_code = compileModule(decls, handleError, tokens)
return tokens, target_code, num_errors
def createHTML(code):
tokens, compiled, _ = compileCode(code)
ans = """<!DOCTYPE html><html><head><meta charset="utf-8" /><title>Imperatiivinen Tampio</title>"""
if not PRINT_INCLUDED:
ans += """<script type="text/javascript" src="itp.js" charset="utf-8"></script>"""
ans += """<link rel="stylesheet" type="text/css" href="syntax.css"></head><body>"""
ans += """<div style="max-height:98vh;overflow:auto;float:left;width:50%;">"""
ans += prettyPrint(tokens, "html")
ans += """</div><div style="max-height:98vh;overflow:auto;float:right;width:calc(50% - 5px);padding-left:5px;"><div id="output"><script type="text/javascript">\n"""
ans += included_code + "\n" + compiled
ans += """\ndocument.avautua_A__N();\n</script></div></div></body></html>"""
return ans
def createLatex(code):
tokens, _, _ = compileCode(code)
ans = """\\documentclass{article}\\usepackage[utf8]{inputenc}\\usepackage[T1]{fontenc}\\usepackage[finnish]{babel}"""
ans += """\\title{Tampiokoodi}"""
ans += """\\begin{document}\\setlength\\emergencystretch{\\hsize}"""
ans += prettyPrint(tokens, "latex-lists")
ans += "\\end{document}"
return ans
TAMPIO_VERSION = "1.46"
COMPILER_VERSION = "1.57"
VERSION_STRING = "Tampio " + TAMPIO_VERSION + " Compiler " + COMPILER_VERSION
def main():
global DEBUG, PRINT_INCLUDED
parser = argparse.ArgumentParser(description='Compile Tampio to JavaScript.')
parser.add_argument('-v', '--version', help='show version number and exit', action='store_true')
parser.add_argument('--debug', help='enable debug mode', action='store_true')
compiler_group = parser.add_argument_group('compiler options')
compiler_group.add_argument('filename', type=str, nargs='?', help='source code file')
compiler_group.add_argument('-i', '--print-included', help='print all included files in addition to the given file', action='store_true')
output_mode = compiler_group.add_mutually_exclusive_group()
output_mode.add_argument('-s', '--syntax-markup', type=str, choices=HIGHLIGHTERS.keys(), help='do not compile, instead print the source code with syntax markup')
output_mode.add_argument('-p', '--html-page', help='print a html page containing both compiled code and syntax markup', action='store_true')
output_mode.add_argument('-l', '--latex-document', help='print a latex document containing the code and markup', action='store_true')
output_mode.add_argument('-V', '--validate-syntax', help='parse the code and print syntax errors', action='store_true')
args = parser.parse_args()
if args.version:
print(VERSION_STRING)
return
if args.debug:
DEBUG = True
if args.print_included:
PRINT_INCLUDED = True
initializeCompiler(includeFile)
# ladataan standardikirjasto
includeFile(os.path.join(os.path.dirname(__file__), "std.itp"))
if args.filename:
with open(args.filename) as f:
code = f.read()
if args.html_page:
print(createHTML(code))
elif args.latex_document:
print(createLatex(code))
else:
tokens, compiled, n = compileCode(code)
if args.validate_syntax:
print("OK" if n == 0 else "ERROR")
elif args.syntax_markup:
print(prettyPrint(tokens, args.syntax_markup))
else:
print(included_code+compiled)
if n > 0:
sys.exit(1)
else:
while True:
try:
code = input(">>> ")
tokens, compiled, _ = compileCode(code)
if args.validate_syntax:
print("OK" if n == 0 else "ERROR")
elif args.syntax_markup:
print(prettyPrint(tokens, args.syntax_markup))
else:
print(compiled)
except EOFError:
print("")
break
except Exception:
traceback.print_exc()
if __name__ == "__main__":
main()