-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathdanac.sh
More file actions
executable file
·134 lines (117 loc) · 3.16 KB
/
danac.sh
File metadata and controls
executable file
·134 lines (117 loc) · 3.16 KB
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
#!/bin/bash
set -euo pipefail
IFS=$'\n\t'
# Get the directory where this script resides
SCRIPT_DIR="$(cd "$(dirname "$0")" && pwd)"
# Path to the compiler and the dana binary
DANAC="$SCRIPT_DIR/danac"
DANART="$SCRIPT_DIR/libdanart.a"
# Default compiler options
OUTPUT_FILE="a.out"
OPT_LEVEL=0
MODE=0 # 0=normal compile/link, 1=stdin->imm, 2=stdin->asm
# Function to show usage
usage() {
echo "Usage:"
echo " $0 <input-file.dana> [-o output-file] [-O0|-O1|-O2|-O3]"
echo " $0 -i [-O0|-O1|-O2|-O3] # interactive stdin, print imm to stdout"
echo " $0 -f [-O0|-O1|-O2|-O3] # interactive stdin, print asm to stdout"
echo " $0 -h | --help # show this help message"
exit 1
}
# Parse arguments
if [ "$#" -lt 1 ]; then
usage
fi
INPUT_FILE=""
while [[ $# -gt 0 ]]; do
case "$1" in
-h|--help)
usage
;;
-o)
shift
if [ -z "$1" ]; then
echo "Error: Missing output file name after -o."
usage
fi
OUTPUT_FILE="$1"
shift
;;
-O[0-9]*)
case "$1" in
-O[0-3]) OPT_LEVEL="${1:2}" ;;
*) echo "Error: optimization must be -O0, -O1, -O2, or -O3"; exit 1 ;;
esac
shift
;;
-i)
MODE=1
shift
;;
-f)
MODE=2
shift
;;
*)
if [ -z "$INPUT_FILE" ]; then
INPUT_FILE="$1"
shift
else
echo "Error: Multiple input files provided."
usage
fi
;;
esac
done
# Handle stdin modes (-i and -f)
if [[ $MODE -eq 1 || $MODE -eq 2 ]]; then
if [[ -n "$INPUT_FILE" ]]; then
echo "Error: No input file allowed with -i or -f."
exit 1
fi
TMPFILE=$(mktemp /tmp/dana-stdin-XXXX.dana)
cat > "$TMPFILE"
"$DANAC" "$OPT_LEVEL" "$MODE" < "$TMPFILE"
STATUS=$?
rm -f "$TMPFILE"
exit $STATUS
fi
# Check if input file was provided
if [ -z "$INPUT_FILE" ]; then
usage
fi
# Convert to absolute paths
INPUT_FILE=$(realpath "$INPUT_FILE")
OUTPUT_FILE=$(realpath "$OUTPUT_FILE" 2>/dev/null || echo "$OUTPUT_FILE")
# Check if the file exists
if [ ! -f "$INPUT_FILE" ]; then
echo "Error: File '$INPUT_FILE' does not exist."
exit 1
fi
# Check if the file has a .dana extension
if [[ "$INPUT_FILE" != *.dana ]]; then
echo "Error: File must have a .dana extension."
exit 1
fi
# Extract path and base name
INPUT_DIR=$(dirname "$INPUT_FILE")
INPUT_BASE=$(basename "$INPUT_FILE" .dana)
# Run the compiler
"$DANAC" "$OPT_LEVEL" < "$INPUT_FILE"
# Check if compilation produced output.o
if [ ! -f output.o ]; then
echo "Error: Compilation failed, output.o not found."
exit 1
fi
# Move and rename files to match input file as the assignment says
mv output_opt.asm "$INPUT_DIR/$INPUT_BASE.asm"
mv output_opt.imm "$INPUT_DIR/$INPUT_BASE.imm"
mv output.o "$INPUT_DIR/$INPUT_BASE.o"
# Link with clang++
clang++ "$INPUT_DIR/$INPUT_BASE.o" "$DANART" -o "$OUTPUT_FILE"
# Check if linking failed
if [ $? -ne 0 ]; then
echo "Linking failed."
exit 1
fi