#!/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=`dirname ${0}`/.. function usage { cat <>main. -K Add libraries to get minimal JTalk Kernel running. -C Add libraries to get minimal JTalk Compiler running. -i Add library standard initializer $JTALK/js/init.js -I file Add library initializer . -m class Add call to #main in class . -M file Add javascript file at the end acting as main. Example invocations: 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 manually 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 Program ENDOFHELP exit 1; } # Check we at least got one argument if [ -z $1 ] ; then usage fi # Define our predefined library combinations BOOT="$JTALK/js/boot.js" KERNEL="$BOOT $JTALK/js/Kernel.js" COMPILER="$KERNEL $JTALK/js/Parser.js $JTALK/js/Compiler.js" # Predefined initializer INITIALIZER="$JTALK/js/init.js" # Default values ENV= INIT= MAIN= MAINFILE= BASE=$KERNEL OURCOMPILER="$COMPILER $JTALK/js/init.js $JTALK/nodejs/nodecompile.js" # Read options and shift them away while getopts "NDKCiI:M:m:h?" o; do case "$o" in N) ENV=NODE BASE=$KERNEL INIT=$INITIALIZER MAIN=Main;; D) ENV=D8 BASE=$KERNEL INIT=$INITIALIZER MAIN=Main;; K) BASE=$KERNEL;; C) BASE=$COMPILER;; I) INIT=$INITIALIZER;; i) INIT=$OPTARG;; M) MAINFILE=$OPTARG;; m) MAIN=$OPTARG;; h) usage;; [?]) usage;; esac done shift $(($OPTIND - 1)) # Combine supplied libraries LIBS="$BASE $ADDONS" # Get a unique tempdir and make it get auto removed on exit TMPDIR=`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) if [ -f "$1" ]; then LIBS="$LIBS $1" else if [ -f $JTALK/js/$1 ]; then LIBS="$LIBS $JTALK/js/$1" else echo "Javascript file not found: $1" exit 1 fi fi ;; *) # Will end up being the last non js/st argument PROGRAM=$1 ;; esac shift done # -------------------------------------------------- # Actual compilation phase of collected .st files # -------------------------------------------------- # Create compiler dynamically cat $OURCOMPILER > $TMPDIR/compiler.js # Compile all collected .st files to .js echo "Compiling ..." node $TMPDIR/compiler.js $COMPILE # Verify all .js files corresponding to .st files were created, otherwise exit IFS=" " for FILE in $COMPILED do if [ ! -f "$FILE" ]; then echo "Failed compilation of $FILE, exiting." exit 1 fi done if [ -z $PROGRAM ]; then echo "Done." exit 0 fi # -------------------------------------------------- # 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.js fi echo "Adding Jtalk code$COMPILED ..." # Check for init file if [ ! -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 main if [ ! -z "$MAIN" ]; then echo "Adding call to $MAIN class >> main ..." echo "smalltalk.$MAIN._main()" > $TMPDIR/main.js MAIN=$TMPDIR/main.js fi # Check for adding main file if [ ! -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=$MAINFILE fi # And finally concatenate Program.js echo "Writing $PROGRAM.js ..." cat $LIBS $COMPILED $INIT $MAIN > $PROGRAM.js echo "Done." # Optionally run Program and give all args left to it if [ -n "$RUN" ]; then echo "Running program" echo "---------------" node $PROGRAM.js $@ fi