Skip to content

Instantly share code, notes, and snippets.

@Jeff-Russ
Created June 20, 2016 05:26
Show Gist options
  • Select an option

  • Save Jeff-Russ/fd8d3365396d333509e5b904a8a76f75 to your computer and use it in GitHub Desktop.

Select an option

Save Jeff-Russ/fd8d3365396d333509e5b904a8a76f75 to your computer and use it in GitHub Desktop.
#!/usr/bin/env bash
# BAShIC - BASIC interpreter written in Bash
# Based on bournebasic by Brandon S. Allbery 1987
#
# 10 print "Enter any number and I will double it for you ";
# 20 input x
# 30 y = 2*x
# 40 print "The answer is ";
# 50 print y
# 60 print "Enter -1 if you want to continue."
# 70 input c
# 80 if c = -1 then 10
# 90 print "Bye"
#
# Also, the commands 'load', 'save', 'list', 'run', and 'new'
print() {
expr=`echo $line | sed 's/print\ *//'`
case $expr in
\"*)
printf `echo "$expr" | sed 's/^\"//
s/\".*$//'`
case $line in
*\;) ;;
*) echo ;;
esac
;;
*) > ${tfiles}.ex
files=`echo ${tfiles}.?`
case $files in
${tfiles}.\?)
;;
*)
for i in $files; do
cat $i >> ${tfiles}.ex;
done
;;
esac
echo $expr >> ${tfiles}.ex
c < ${tfiles}.ex > ${tfiles}.res
cat ${tfiles}.res
;;
esac
}
goto() {
expr=`echo $line | sed 's/goto\ *//'`
echo $expr > ${tfiles}.ln
exit
}
input() {
var=`echo $line | sed 's/input\ *//'`
printf "?"
printf "$var=" > ${tfiles}.$var
while true; do
read val
echo $val
break
done < /dev/tty >> ${tfiles}.$var
}
if_cmd() {
expr=`echo $line | sed '{
s/if\ */\(/
s/[#=]/\)-\(/
s/\ *then.*/\)/
}'`
target=`echo $line | sed 's/.*then\ *//'`
> ${tfiles}.ex
files=`echo ${tfiles}.?`
case $files in
${tfiles}.\?) ;;
*)
for i in $files; do
cat $i >> ${tfiles}.ex
done
;;
esac
echo $expr >>${tfiles}.ex
res=`bc < ${tfiles}.ex`
case $res in
0*)
case $line in
*=*) echo $target > ${tfiles}.ln; exit ;;
*) ;;
esac
;;
*)
case $line in
*#*)
echo $target > ${tfiles}.ln
exit ;;
*) ;;
esac
;;
esac
}
star() {
> ${tfiles}.ex
files=`echo ${tfiles}.?`
case $files in
${tfiles}.\?) ;;
*)
for i in $files; do
cat $i >> ${tfiles}.ex
done
;;
esac
echo $line >>${tfiles}.ex
var=`echo $line | sed 's/\ *=.*//'`
echo $var >> ${tfiles}.ex
bc < ${tfiles}.ex > ${tfiles}.res
printf $var= > ${tfiles}.$var
cat ${tfiles}.res >> ${tfiles}.$var
}
run() {
echo 0 > ${tfiles}.ln
while true; do
while true; do
case `cat ${tfiles}.ln` in
0) read lineno line || exit ;;
*) while true; do
read lineno line || exit
match=`cat ${tfiles}.ln`
case $lineno in
$match)
break ;;
*)
;;
esac
done
esac
while true; do
case $line in
print*) print ;;
if*) ;;
end*) echo 0 > ${tfiles}.ln; exit ;;
goto*) goto ;;
input*) input ;;
*) star ;;
esac
read lineno line || exit
done
done < ${tfiles}
case `cat ${tfiles}.ln` in
0*) break ;;
*) ;;
esac
done
}
quit() {
echo 'Goodbye'
rm ${tfiles?Bug}*
exit
}
lnumb() {
echo $com $com2 > ${tfiles}.nl
grep -v "^$com" ${tfiles} >> ${tfiles}.nl
sort -n ${tfiles}.nl > ${tfiles}
}
tfiles=/tmp/bas$$
export tfiles
trap "rm ${tfiles?Bug}*; exit" 2
> ${tfiles}
echo 'BASIC'
while true; do
printf '>'
read com com2 || exit
case $com in
list) cat ${tfiles} ;;
run) run ;;
new) >${tfiles} ;;
quit) quit ;;
load) cp $com2 ${tfiles} ;;
save) cp ${tfiles} $com2 ;;
[0-9]*) lnumb ;;
"") ;;
*) echo 'Illegal command'
esac
done
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment