Skip to content

Instantly share code, notes, and snippets.

@seebs
Created May 30, 2019 16:59
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save seebs/855290333f0506296056165e7b8f83af to your computer and use it in GitHub Desktop.
Save seebs/855290333f0506296056165e7b8f83af to your computer and use it in GitHub Desktop.
A C interpreter as a shell script. Note, this is every bit as stupid as it sounds. The summer of 1995 was not a great time for good engineering decisions for me.
#!/bin/sh
# C interpreter in sh. Wow.
# Logic: we parse files, or arguments, or stdin.
# We see if we have exactly one argument that looks like a file. If so,
# we parse it. Otherwise, we look for arguments. Otherwise, we work on
# stdin.
ANSI="Y"
VERBOSE="N"
INCLUDES="stdio.h stdlib.h ctype.h"
tmp=/tmp/.$$.c
>$tmp
trap 'rm -f $tmp ${tmp}2 ${tmp}3 /tmp/.$$.out' 2 3
eat() {
echo $* >> $tmp
}
while getopts ai:v i
do
case $i in
a) ANSI="N";;
i) INCLUDES="$INCLUDES $OPTARG";;
v) VERBOSE="Y";;
\?) echo >&2 "usage: c2 [-i header] [file] | [lines]"
break;;
esac
done
shift `expr $OPTIND - 1`
case $# in
0) grep -v '^#!' > $tmp
;;
1) if [ -r "$1" ]
then grep -v '^#!' $1 > $tmp
else eat "$1"
fi
;;
*) for i
do eat "$i"
done
;;
esac
for i in $INCLUDES
do
echo "#include <$i>" >> ${tmp}2
done
if grep "main[ ]*(" $tmp >/dev/null 2>&1
then cat ${tmp}2 $tmp > ${tmp}3
mv ${tmp}3 $tmp
else case "$ANSI" in
"Y") echo "int main(int argc, char *argv[]) {" >> ${tmp}2;;
"N") echo "int main(argc, argv) char *argv[]; {" >> ${tmp}2;;
esac
cat ${tmp}2 $tmp > ${tmp}3
mv ${tmp}3 $tmp
echo "; return 0;}" >> $tmp
fi
rm -f ${tmp}2
[ -z "$CC" ] && case "$ANSI" in "Y") CC=lcc;; "N") CC=cc;; esac
[ "$VERBOSE" = "Y" ] && echo "Source:" && cat $tmp
if ${CC:-cc} $tmp -o /tmp/.$$.out
then /tmp/.$$.out
save="$?"
else save=1
fi
rm -f $tmp /tmp/.$$.out
exit $save
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment