| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344 | #!/bin/bash## This is a "compiler" for JTalk code. Run without arguments for help.# Get JTalk root directory from the location of this script.JTALK=$(readlink -f `dirname ${0}`/..)function usage {	cat <<ENDOFHELPUsage: $0 [-N|D|E] [-K|C] [-o] [-O] [-m class] [-M file]          [-i] [-I file] file1 [file2 ...] [Program]   Will compile Jtalk files - either separately or into a runnable complete   program. Files listed will be handled using these rules:   *.js     Files are concatenated in listed order.     If not found we look in $JTALK/js   *.st     Files are compiled into .js files before concatenated.     If not found we look in $JTALK/st.     NOTE: Each file is currently considered to be a fileout of a single class     category of the same name as the file!   If no Program is specified each given .st file will be compiled into   a .js file. Otherwise a <Program>.js file is linked together based on   the options:  -N or -D or -E     Compilation target. Currently Node.js, D8 (V8 shell) or Enyo (webOS 3.0).     All imply "-K -I" so boot.js and Kernel.js are added first and init.js     is added last.  -K     Add libraries to get minimal JTalk Kernel running.  -C     Add libraries to get minimal JTalk Compiler running.  -o     Optimize each js file using the Google closure compiler.     Using Closure at ~/compiler.jar      -O     Optimize final <Program>.js using the Google closure compiler.     Using Closure at ~/compiler.jar  -A Use --compilation_level ADVANCED_OPTIMIZATIONS for the closure compiler.    -l library1,library2     Load listed libraries (no spaces) into Compiler before compiling.  -L library1,library2     Load listed libraries (no spaces) into Compiler before compiling and also     into Program.js in listed order.  -i     Add library initializer <file>.  -I file     Add library standard initializer $JTALK/js/init.js    -m class     Add call to #main in class <class>.   -M file     Add javascript file <file> at the end acting as main.     Example invocations:     Just compile Kernel.st to Kernel.js:        jtalkc Kernel.st     Compile Hello.st to Hello.js and create complete program called     Program.js for Node.js including boot.js, Kernel.js, init.js and     adding a call to class method #main in class Hello:        jtalkc -N -m Hello Hello.st Program     Compile two .st files into corresponding .js files,     and link with specific myboot.js, myKernel.js, myinit.js     and main.js and create complete program called Program.js:        jtalkc -M main.js -I myinit.js myboot.js myKernel.js Cat1.st Cat2.st ProgramENDOFHELP	exit 1;}# Check we at least got one argumentif [ -z $1 ] ; then   usagefi# Define our predefined library combinationsBOOT="$JTALK/js/boot.js"KERNEL="$BOOT $JTALK/js/Kernel.js"COMPILER="$KERNEL $JTALK/js/Parser.js $JTALK/js/Compiler.js"KITCHENSINK="$COMPILER $JTALK/js/Canvas.js"# Predefined initializerINITIALIZER="$JTALK/js/init.js"# Default valuesENV=INIT=MAIN=MAINFILE=BASE=$KERNELLOAD=LOADANDADD=CLOSUREOPTS=# Ok, bad coding practice but hey, who would use such a prefix?PREFIX=no-silly-prefixPREFIXUSED=DEBUG=falseNODECOMPILE=nodecompile.js# Read options and shift them awaywhile getopts "NDEKCJoOAgp:l:L:i:IM:m:h?" o; docase "$o" in   N) ENV=NODE      BASE=$KERNEL      INIT=$INITIALIZER;;   D) ENV=D8      BASE=$KERNEL      INIT=$INITIALIZER;;   D) ENV=ENYO      BASE=$KERNEL      INIT=$INITIALIZER;;   K) BASE=$KERNEL;;   C) BASE=$COMPILER;;   o) CLOSURE=true      CLOSUREPARTS=true;;   O) CLOSURE=true      CLOSUREFULL=true;;   A) CLOSURE=true      CLOSUREOPTS="$CLOSUREOPTS --compilation_level ADVANCED_OPTIMIZATIONS"      CLOSUREFULL=true;;   g) DEBUG=true;;   p) PREFIX=$OPTARG      PREFIXUSED=$PREFIX;;   l) LOAD=$OPTARG;;   L) LOADANDADD=$OPTARG;;   I) INIT=$INITIALIZER;;   i) INIT=$OPTARG;;   M) MAINFILE=$OPTARG;;   m) MAIN=$OPTARG;;   h) usage;;   [?])  usage;;   esacdoneshift $(($OPTIND - 1))# Check for Closure compiler and Javaif [ ! -z $CLOSURE ]; then  java > /dev/null  if [ $? -eq 0 ]; then     if [ ! -f ~/compiler.jar ]; then      echo "Can not find Closure compiler at ~/compiler.jar"      exit 1    fi  else   echo "java is not installed and is needed for -O, -A or -o (Closure compiler)."   exit 1  fifi# Function for looking up listed js filesfunction resolvejs {  if [ -f "$1" ]; then    RESOLVED="$1"   else    if [ -f $JTALK/js/$1 ]; then      RESOLVED="$JTALK/js/$1"    else      echo "Javascript file not found: $1"      exit 1    fi  fi}# Resolve listed libraries in $LOAD separated by spacesLOAD=${LOAD//,/\ }for FILE in $LOADdo   resolvejs $FILE   TOLOAD="$TOLOAD $RESOLVED"done# Resolve listed libraries in $LOADANDADD separated by spacesLOADANDADD=${LOADANDADD//,/\ }for FILE in $LOADANDADDdo   resolvejs $FILE   TOLOAD="$TOLOAD $RESOLVED"   TOADD="$TOADD $RESOLVED"done# Define our Compiler loading supplied librariesOURCOMPILER="$KITCHENSINK $TOLOAD $JTALK/js/init.js $JTALK/nodejs/nodecompile.js"# Add supplied librariesLIBS="$BASE $TOADD"# Get a unique tempdir and make it get auto removed on exitTMPDIR=`mktemp -d`trap "rm -rf $TMPDIR" EXIT# --------------------------------------------------# Collect libraries and Smalltalk files looking# both locally and in $JTALK/js and $JTALK/st # --------------------------------------------------PROGRAM=until [ "$*" = "" ]do  case $1 in     *.st)        CATEGORY=`basename $1 .st`        if [ -f "$1" ]; then           COMPILE="$COMPILE $1 $CATEGORY"           COMPILED="$COMPILED $CATEGORY.js"        else           if [ -f $JTALK/st/$1 ]; then             COMPILE="$COMPILE $JTALK/st/$1 $CATEGORY"             COMPILED="$COMPILED $CATEGORY.js"           else             echo "JTalk file not found: $1"             exit 1           fi        fi        ;;     *.js)        resolvejs $1	LIBS="$LIBS $RESOLVED"         ;;      *)        # Will end up being the last non js/st argument        PROGRAM=$1        ;;  esac  shiftdone# --------------------------------------------------# Actual compilation phase of collected .st files# --------------------------------------------------# Create compiler dynamicallycat $OURCOMPILER > $TMPDIR/compiler.js# Compile all collected .st files to .jsecho "Loading libraries $KITCHENSINK $TOLOAD and compiling ..."node $TMPDIR/compiler.js $COMPILE# Verify all .js files corresponding to .st files were created, otherwise exitIFS=" "for FILE in $COMPILEDdo  if [ ! -f "$FILE" ]; then    echo "Failed compilation of $FILE, exiting."    exit 1  fi doneif [ ! -z $CLOSUREPARTS ]; then  echo "Compiling all js files using Google closure compiler."  ALLJSFILES="$COMPILED $LIBS"  for FILE in $ALLJSFILES  do    mv $FILE $FILE.original    java -jar ~/compiler.jar $CLOSUREOPTS --js $FILE.original --js_output_file $FILE    rm $FILE.original  donefiif [ -z $PROGRAM ]; then  echo "Done."  exit 0fi# --------------------------------------------------# Now we start composing resulting javascript file.# --------------------------------------------------# Add collected libraries to libs.js file.if [ ! -z "$LIBS" ]; then  echo "Adding libraries $LIBS ..."  cat $LIBS > $TMPDIR/libs.js  LIBS=$TMPDIR/libs.jsfiecho "Adding Jtalk code$COMPILED ..."# Check for init fileif [ ! -z "$INIT" ]; then   if [ -f "$INIT" ]; then      echo "Adding initializer $INIT ..."   else      echo "Can not find init file $INIT, exiting."      exit 1   fi fi# Check for adding mainif [ ! -z "$MAIN" ]; then  echo "Adding call to $MAIN class >> main ..."  echo "smalltalk.$MAIN._main()" > $TMPDIR/main.js  MAIN=$TMPDIR/main.jsfi# Check for adding main fileif [ ! -z "$MAINFILE" ]; then   if [ -f "$MAINFILE" ]; then      echo "Adding main as $MAINFILE ..."   else      echo "Can not find main file $MAINFILE, exiting."      exit 1   fi    MAIN=$MAINFILEfi# And finally concatenate Program.jsecho "Writing $PROGRAM.js ..."cat $LIBS $COMPILED $INIT $MAIN > $PROGRAM.jsecho "Done."if [ ! -z $CLOSUREFULL ]; then  echo "Compiling $PROGRAM.js file using Google closure compiler."  mv $PROGRAM.js $PROGRAM.js.original  java -jar ~/compiler.jar $CLOSUREOPTS --js $PROGRAM.js.original --js_output_file $PROGRAM.js  rm $PROGRAM.js.original  echo "Done."fi
 |