-
Notifications
You must be signed in to change notification settings - Fork 0
/
narratr.py
executable file
·133 lines (112 loc) · 3.84 KB
/
narratr.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
# -----------------------------------------------------------------------------
# narrtr: narratr.py
# This file compiles narratr games.
#
# Copyright (C) 2015 Team narratr
# All Rights Reserved
# Team narratr: Yelin Hong, Shloka Kini, Nivvedan Senthamil Selvan, Jonah
# Smith, Cecilia Watt
#
# File Created: 2 April 2015
# Primary Author: Jonah Smith
#
# Any questions, bug reports and complaints are to be directed at the primary
# author.
#
# -----------------------------------------------------------------------------
import sys
import parser
from codegen import CodeGen
from node import Node
import argparse
def print_tree(node, indent):
prefix = " " * indent
try:
val = ""
if node.value is not None:
val += " (value: " + str(node.value) + ")"
if node.v_type is not None:
val += " (value type: " + str(node.v_type) + ")"
if node.lineno is not None:
val += " (line num: " + str(node.lineno) + ")"
print prefix + node.type + val
if not node.is_leaf():
for n in node.children:
if type(n) is dict:
print " " + prefix + "(dictionary)"
for key, value in n.iteritems():
print_tree(value, indent + 2)
else:
print_tree(n, indent + 1)
except:
print prefix + "[Something bad happened]"
def print_symtab(symtab):
print symtab
def parse(source):
if verbose:
print "parsing...",
p = parser.ParserForNarratr()
ast = p.parse(source)
symtab = p.symtab
if verbose:
print u'\u2713'
return ast, symtab
def generate_code(ast, symtab, outfile):
if verbose:
print "generating code...",
c = CodeGen()
c.process(ast, symtab)
c.construct(outfile)
if verbose:
print u'\u2713'
def read(path):
if verbose:
print "reading file...",
try:
with open(path, 'r') as f:
source = f.read()
except IOError as e:
print "\nERROR: Couldn't read source file " + path
exit(1)
else:
if verbose:
print u'\u2713'
return source
def main():
argparser = argparse.ArgumentParser()
argparser.add_argument('-t', '--tree', action='store_true',
help='print a representation of the abstract' +
' syntax tree from the parser')
argparser.add_argument('-v', '--verbose', action="store_true",
help='print updates on each step of the compile')
argparser.add_argument('source', action="store", help='the source file')
argparser.add_argument('-o', '--output', nargs=1, action="store",
help='specify an output file. defaults to' +
' [input file].py')
argparser.add_argument('-i', '--inert', action="store_true",
help='does not try to use code generator')
argparser.add_argument('-s', '--symtab', action='store_true',
help='print the symbol table')
args = argparser.parse_args(sys.argv[1:])
global verbose
verbose = args.verbose
if args.output is None:
outputfile = args.source + ".py"
else:
outputfile = args.output[0]
source = read(args.source)
ast, symtab = parse(source)
if args.tree:
print "\n------------------- AST ---------------------"
print_tree(ast, 0)
print "------------------- /AST ---------------------\n"
if args.symtab:
print "\n------------------- SymTab ---------------------"
print_symtab(symtab)
print "------------------- /Symtab ---------------------\n"
if not args.inert:
generate_code(ast, symtab, outputfile)
if verbose:
print "Your game is ready. Have fun!"
if __name__ == "__main__":
main()