-
Notifications
You must be signed in to change notification settings - Fork 0
/
crab
executable file
·100 lines (83 loc) · 2.96 KB
/
crab
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
#!/usr/bin/env python
import argparse
from subprocess import call, STDOUT
import sys
import os.path
import os
VERSION = "0.1"
main_dir = os.path.dirname(os.path.realpath(__file__)) + "/"
fnull = open(os.devnull, 'w')
parser = argparse.ArgumentParser(
prog = "Crab",
description="Launch tool for Crab, a small functional Programming language")
parser.add_argument('filenames',
metavar='filename',
nargs="+",
help="Run Crab program specified"
)
parser.add_argument('--output', '-o',
action='store',
help="Output executable or object file for Crab"
)
parser.add_argument('--compile', '-c',
action='store_true',
help="Compile file to an object file")
parser.add_argument('--version', action='version', version='%(prog)s {}'.format(VERSION))
args = parser.parse_args()
def call_exit(arr):
ret = call(arr)
if ret == 0:
return
else:
print("Program exited with return value {}".format(ret))
sys.exit(1)
def compile(files, output="a"):
try:
call_exit(["gcc", "-o", output] + files + [main_dir + "prelude.o"])
except OSError as e:
if e.errno == os.errno.ENOENT:
print("""Currently, Crab only supports linking with GCC.
If you want to use a different linker, you will need to pass the -c option to Crab """)
if len(sys.argv) == 1:
parser.print_help()
sys.exit(1)
if len(args.filenames) > 0:
fnames = args.filenames
for filename in fnames:
if os.path.isfile(filename):
# If this doesn't exist, the user hasn't built yet, or it's not in the path
try:
call_exit(["crab_compiler", filename])
except FileNotFoundError:
try:
call_exit(["./crab_compiler", filename])
except FileNotFoundError:
print("Please build before running, or add Crab to your PATH variable.")
sys.exit(0)
else:
print("Argument " + filename + " is not a file.")
sys.exit(1)
# Create an executable
if args.output is not None:
output = args.output
else:
output = "a.out"
filenames = []
for fname in args.filenames:
directory = os.path.dirname(fname)
filename = os.path.basename(fname)
name = filename.split(".")[-2]
name += ".o"
filenames.append(directory + name)
if args.compile:
# We want to compile multiple .o files into one .o file
call_exit(["ld", "-r"] + filenames + [main_dir + 'prelude.o', "-o", output])
# Quietly delete all .o files
for fname in filenames:
call(["rm", fname], stdout=fnull, stderr=STDOUT)
else:
# We want to convert a source file into an executable
compile(filenames, output)
# Same thing as above
for fname in filenames:
call(["rm", fname], stdout=fnull, stderr=STDOUT)