summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorCarlos Maniero <carlosmaniero@gmail.com>2023-04-24 22:33:52 -0300
committerJohnny Richard <johnny@johnnyrichard.com>2023-04-25 09:11:12 +0200
commitcca2c345f9b16b88e1fc4e9ea598cf2f7ed8653a (patch)
treeca827f22e754a38558d57a76fdefca5a2a8f6208
parent6df9e8bf9433cb095090dab0474367b220585a47 (diff)
cli: Create a CLI to generate an executable from pipa code.
This commit introduces a full-featured CLI that allows you to compile a file, set the gas and linker path, and define the executable output. Signed-off-by: Carlos Maniero <carlosmaniero@gmail.com> Reviewed-by: Johnny Richard <johnny@johnnyrichard.com> Link: https://lists.sr.ht/~johnnyrichard/pipalang-devel/patches/40642
-rwxr-xr-xpipa160
-rw-r--r--test/integration_test.c7
2 files changed, 162 insertions, 5 deletions
diff --git a/pipa b/pipa
new file mode 100755
index 0000000..d197ade
--- /dev/null
+++ b/pipa
@@ -0,0 +1,160 @@
+#!/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 <https://www.gnu.org/licenses/>.
+
+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 <as-path>\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 <ld-path>\n"
+ exit 1
+ fi
+}
+
+print_help() {
+ printf "$WELCOME_MESSAGE\n"
+ printf "Usage:\n"
+ printf "$0 [options] <filename.pipa> 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"
diff --git a/test/integration_test.c b/test/integration_test.c
index 0ef3f5d..b6c0f36 100644
--- a/test/integration_test.c
+++ b/test/integration_test.c
@@ -22,15 +22,12 @@
void
assert_exit_status(char* filename, int expected_exit_status)
{
- char command[255] = "../pipac ";
+ char command[255] = "../pipa --silent --out /tmp/pipa_program ";
strcat(command, filename);
- strcat(command, " > /tmp/pipa_example.s");
system(command);
- system("as -o /tmp/pipa_example.o /tmp/pipa_example.s --64");
- system("ld -o /tmp/pipa_example /tmp/pipa_example.o");
- int status = system("/tmp/pipa_example");
+ int status = system("/tmp/pipa_program");
if (WIFEXITED(status)) {
int exit_status = WEXITSTATUS(status);