-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathf4main.py
99 lines (93 loc) · 3.7 KB
/
f4main.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
import os
import sys
import pickle
import subprocess
from termcolor import cprint
from f4codegen import generate_c
from f4error import error
from f4interp import interpret
import f4parser
from f4ppc import preprocess, to_string
import f4ppc
from f4ver import verstr, vername
__author__ = 'hyst329'
def main():
if len(sys.argv) == 1:
print("PyF4 --- F4PL implementation in Python\n")
print("Version %s '%s'" % (verstr, vername))
print("Usage: f4main infile.f4 [options]\n")
return 0
try:
if len(sys.argv) == 2 or sys.argv[2] == '-i':
mode = 'int'
elif sys.argv[2] == '-c':
mode = 'ast'
elif sys.argv[2] == '-b':
mode = 'from_ast'
elif sys.argv[2] == '-g':
mode = 'gen_c'
elif sys.argv[2] == '-gc':
mode = 'gen_c_gcc'
else:
print("Unknown format specified: '%s'" % sys.argv[2])
return
f4ppc.ppc_path[0:0] = [os.path.dirname(os.path.abspath(os.path.normpath(sys.argv[1])))]
if mode in ('int', 'ast', 'gen_c', 'gen_c_gcc'):
cont = open(sys.argv[1], 'r').read()
if cont[-1] != '\n':
cont += '\n'
cont = to_string(preprocess(cont))
parser = f4parser.parser
res = parser.parse(cont)
# if parser.error:
# print "Error"
if mode == 'int':
print('Interpreting...')
interpret(res)
elif mode == 'ast':
print("AST:\n", res)
pickle.dump(res, open(sys.argv[1] + ".ast", 'wb'), 2)
elif mode == 'from_ast':
print("Experimental AST interpreting mode. May be unsafe")
res = pickle.load(open(sys.argv[1], 'rb'))
print(res)
interpret(res)
elif mode in ('gen_c', 'gen_c_gcc'):
if mode == 'gen_c_gcc':
p = subprocess.Popen("gcc --version", stdout=open(os.devnull, "w"))
p.communicate()
if p.returncode:
print("GCC not found or works incorrectly,"
" but required to compile generated C code... Sorry :(")
return
generate_c(res, open(sys.argv[1] + ".c", 'w'))
fsize = os.stat(sys.argv[1] + ".c").st_size
print("%s bytes of C code generated" % fsize)
if mode == 'gen_c_gcc':
print("Compiling with GCC...")
if getattr(sys, 'frozen', False):
rundir = os.path.dirname(sys.executable)
else:
rundir = os.path.dirname(os.path.realpath(__file__))
cmd = 'gcc ' + sys.argv[1] + ".c" + " -o " + sys.argv[1] + \
'.exe --std=c99 -I"' + rundir + '/library"'
print("Calling %s" % cmd)
p = subprocess.Popen(cmd,
stdout=open(os.devnull, "w"))
p.communicate()
if p.returncode:
print("GCC cannot compile the generated code..."
" This maybe was an error, either in your Helen code or"
" in the codegen... Sorry :(")
return
print("Executable written to %s with size of %s bytes,"
" you can run it and test!" % (sys.argv[1] + ".exe",
os.stat(sys.argv[1] + ".exe").st_size))
return 0
except IOError as e:
error('NOFILE', e.filename, e.strerror, e.errno, exc=0)
except RuntimeError:
cprint('Fatal errors, translation terminated', 'grey', 'on_red')
return 1
if __name__ == "__main__":
main()