#!/bin/sh
# Copyright (C) 2023 Carlos Maniero
#
# 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 .
AS="as"
LD="ld"
SCRIPT_DIR=$(dirname "$0")
PIPAC_PATH="$SCRIPT_DIR/pipac"
SILENT=0
ERROR_PREFIX="[ERROR]"
WELCOME_MESSAGE="Welcome to Pipa Compiler"
PIPA_LOGO=""
COMPILING_MESSAGE="Compiling:"
BUILT_MESSAGE="Built:"
COMPILATION_ERROR_MESSAGE="Compilation error:"
if [ -t 1 ] && [ "$(tput colors)" -ge 8 ]; then
ERROR_PREFIX="\033[31m$ERROR_PREFIX\033[0m"
PIPA_LOGO="🪁"
WELCOME_MESSAGE="\033[1m$PIPA_LOGO $WELCOME_MESSAGE\033[0m"
COMPILING_MESSAGE="\033[1m$PIPA_LOGO $COMPILING_MESSAGE\033[0m"
BUILT_MESSAGE="\033[1m✅ $BUILT_MESSAGE\033[0m"
fi
check_deps() {
if [ ! -e "$PIPAC_PATH" ]; then
printf "$ERROR_PREFIX pipac not found at $PIPAC_PATH. Consider running make command.\n"
exit 1
fi
if [ ! -e "$AS" ] && ! which "$AS" >/dev/null; then
printf "$ERROR_PREFIX $AS not found.\n\n"
printf "Install it or provide the path with --as \n"
exit 1
fi
if [ ! -e "$LD" ] && ! which "$LD" >/dev/null; then
printf "$ERROR_PREFIX $LD not found.\n\n"
printf "Install it or provide the path with --ld \n"
exit 1
fi
}
print_help() {
printf "$WELCOME_MESSAGE\n"
printf "Usage:\n"
printf "$0 [options] Compile filename.pipa\n\n"
printf "Options:\n"
printf -- "--as The path of gas compiler. Default: as\n"
printf -- "--help Prints this prompt.\n"
printf -- "--ld The path of linker compiler. Default: ld\n"
printf -- "--out The executable name. Default: filename without extension.\n"
printf -- "--silent Hide logs. Errors are sill displayed.\n"
exit 0
}
# FIXME: Allow the filename to came before the options
while [ $# -gt 0 ]; do
case "$1" in
--silent)
SILENT=1
shift 1
;;
--as)
if [ ! -n "$2" ]; then
printf "$ERROR_PREFIX no argument passed for --as\n" >&2
exit 1
fi
AS="$2"
shift 2
;;
--ld)
if [ ! -n "$2" ]; then
printf "$ERROR_PREFIX no argument passed for --ld\n" >&2
exit 1
fi
LD="$2"
shift 2
;;
--out)
if [ ! -n "$2" ]; then
printf "$ERROR_PREFIX no argument passed for --out\n" >&2
exit 1
fi
OUT="$2"
shift 2
;;
--help)
print_help
;;
*)
break
;;
esac
done
check_deps
FILE_NAME="$1"
log() {
if [ "$SILENT" -eq 0 ]; then
printf "$1\n"
fi
}
cleanup() {
rm -f "$OUT.s"
rm -f "$OUT.o"
}
if [ ! -n "$FILE_NAME" ]; then
printf "$ERROR_PREFIX no input file.\n" >&2
exit 1
fi
if [ ! -e "$FILE_NAME" ]; then
printf "$ERROR_PREFIX filename not found.\n" >&2
exit 1
fi
log "$COMPILING_MESSAGE $FILE_NAME"
if ! [ -n "${OUT+x}" ]; then
OUT="${FILE_NAME%.*}"
fi
if ! $PIPAC_PATH "$FILE_NAME" > "$OUT.s"; then
printf "$ERROR_PREFIX $COMPILATION_ERROR_MESSAGE unable to generate assembly.\n"
cleanup
exit 1
fi
if ! $AS -o "$OUT.o" "$OUT.s" --64; then
printf "$ERROR_PREFIX $COMPILATION_ERROR_MESSAGE unable to compile gas.\n"
cleanup
exit 1
fi
if ! $LD -o "$OUT" "$OUT.o"; then
printf "$ERROR_PREFIX $COMPILATION_ERROR_MESSAGE unable to link the application.\n"
cleanup
exit 1
fi
cleanup
log "$BUILT_MESSAGE $OUT"