jtalkc 8.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344
  1. #!/bin/bash
  2. #
  3. # This is a "compiler" for JTalk code. Run without arguments for help.
  4. # Get JTalk root directory from the location of this script.
  5. JTALK=$(readlink -f `dirname ${0}`/..)
  6. function usage {
  7. cat <<ENDOFHELP
  8. Usage: $0 [-N|D|E] [-K|C] [-o] [-O] [-m class] [-M file]
  9. [-i] [-I file] file1 [file2 ...] [Program]
  10. Will compile Jtalk files - either separately or into a runnable complete
  11. program. Files listed will be handled using these rules:
  12. *.js
  13. Files are concatenated in listed order.
  14. If not found we look in $JTALK/js
  15. *.st
  16. Files are compiled into .js files before concatenated.
  17. If not found we look in $JTALK/st.
  18. NOTE: Each file is currently considered to be a fileout of a single class
  19. category of the same name as the file!
  20. If no Program is specified each given .st file will be compiled into
  21. a .js file. Otherwise a <Program>.js file is linked together based on
  22. the options:
  23. -N or -D or -E
  24. Compilation target. Currently Node.js, D8 (V8 shell) or Enyo (webOS 3.0).
  25. All imply "-K -I" so boot.js and Kernel.js are added first and init.js
  26. is added last.
  27. -K
  28. Add libraries to get minimal JTalk Kernel running.
  29. -C
  30. Add libraries to get minimal JTalk Compiler running.
  31. -o
  32. Optimize each js file using the Google closure compiler.
  33. Using Closure at ~/compiler.jar
  34. -O
  35. Optimize final <Program>.js using the Google closure compiler.
  36. Using Closure at ~/compiler.jar
  37. -A Use --compilation_level ADVANCED_OPTIMIZATIONS for the closure compiler.
  38. -l library1,library2
  39. Load listed libraries (no spaces) into Compiler before compiling.
  40. -L library1,library2
  41. Load listed libraries (no spaces) into Compiler before compiling and also
  42. into Program.js in listed order.
  43. -i
  44. Add library initializer <file>.
  45. -I file
  46. Add library standard initializer $JTALK/js/init.js
  47. -m class
  48. Add call to #main in class <class>.
  49. -M file
  50. Add javascript file <file> at the end acting as main.
  51. Example invocations:
  52. Just compile Kernel.st to Kernel.js:
  53. jtalkc Kernel.st
  54. Compile Hello.st to Hello.js and create complete program called
  55. Program.js for Node.js including boot.js, Kernel.js, init.js and
  56. adding a call to class method #main in class Hello:
  57. jtalkc -N -m Hello Hello.st Program
  58. Compile two .st files into corresponding .js files,
  59. and link with specific myboot.js, myKernel.js, myinit.js
  60. and main.js and create complete program called Program.js:
  61. jtalkc -M main.js -I myinit.js myboot.js myKernel.js Cat1.st Cat2.st Program
  62. ENDOFHELP
  63. exit 1;
  64. }
  65. # Check we at least got one argument
  66. if [ -z $1 ] ; then
  67. usage
  68. fi
  69. # Define our predefined library combinations
  70. BOOT="$JTALK/js/boot.js"
  71. KERNEL="$BOOT $JTALK/js/Kernel.js"
  72. COMPILER="$KERNEL $JTALK/js/Parser.js $JTALK/js/Compiler.js"
  73. KITCHENSINK="$COMPILER $JTALK/js/Canvas.js"
  74. # Predefined initializer
  75. INITIALIZER="$JTALK/js/init.js"
  76. # Default values
  77. ENV=
  78. INIT=
  79. MAIN=
  80. MAINFILE=
  81. BASE=$KERNEL
  82. LOAD=
  83. LOADANDADD=
  84. CLOSUREOPTS=
  85. # Ok, bad coding practice but hey, who would use such a prefix?
  86. PREFIX=no-silly-prefix
  87. PREFIXUSED=
  88. DEBUG=false
  89. NODECOMPILE=nodecompile.js
  90. # Read options and shift them away
  91. while getopts "NDEKCJoOAgp:l:L:i:IM:m:h?" o; do
  92. case "$o" in
  93. N) ENV=NODE
  94. BASE=$KERNEL
  95. INIT=$INITIALIZER;;
  96. D) ENV=D8
  97. BASE=$KERNEL
  98. INIT=$INITIALIZER;;
  99. D) ENV=ENYO
  100. BASE=$KERNEL
  101. INIT=$INITIALIZER;;
  102. K) BASE=$KERNEL;;
  103. C) BASE=$COMPILER;;
  104. o) CLOSURE=true
  105. CLOSUREPARTS=true;;
  106. O) CLOSURE=true
  107. CLOSUREFULL=true;;
  108. A) CLOSURE=true
  109. CLOSUREOPTS="$CLOSUREOPTS --compilation_level ADVANCED_OPTIMIZATIONS"
  110. CLOSUREFULL=true;;
  111. g) DEBUG=true;;
  112. p) PREFIX=$OPTARG
  113. PREFIXUSED=$PREFIX;;
  114. l) LOAD=$OPTARG;;
  115. L) LOADANDADD=$OPTARG;;
  116. I) INIT=$INITIALIZER;;
  117. i) INIT=$OPTARG;;
  118. M) MAINFILE=$OPTARG;;
  119. m) MAIN=$OPTARG;;
  120. h) usage;;
  121. [?]) usage;;
  122. esac
  123. done
  124. shift $(($OPTIND - 1))
  125. # Check for Closure compiler and Java
  126. if [ ! -z $CLOSURE ]; then
  127. java > /dev/null
  128. if [ $? -eq 0 ]; then
  129. if [ ! -f ~/compiler.jar ]; then
  130. echo "Can not find Closure compiler at ~/compiler.jar"
  131. exit 1
  132. fi
  133. else
  134. echo "java is not installed and is needed for -O, -A or -o (Closure compiler)."
  135. exit 1
  136. fi
  137. fi
  138. # Function for looking up listed js files
  139. function resolvejs {
  140. if [ -f "$1" ]; then
  141. RESOLVED="$1"
  142. else
  143. if [ -f $JTALK/js/$1 ]; then
  144. RESOLVED="$JTALK/js/$1"
  145. else
  146. echo "Javascript file not found: $1"
  147. exit 1
  148. fi
  149. fi
  150. }
  151. # Resolve listed libraries in $LOAD separated by spaces
  152. LOAD=${LOAD//,/\ }
  153. for FILE in $LOAD
  154. do
  155. resolvejs $FILE
  156. TOLOAD="$TOLOAD $RESOLVED"
  157. done
  158. # Resolve listed libraries in $LOADANDADD separated by spaces
  159. LOADANDADD=${LOADANDADD//,/\ }
  160. for FILE in $LOADANDADD
  161. do
  162. resolvejs $FILE
  163. TOLOAD="$TOLOAD $RESOLVED"
  164. TOADD="$TOADD $RESOLVED"
  165. done
  166. # Define our Compiler loading supplied libraries
  167. OURCOMPILER="$KITCHENSINK $TOLOAD $JTALK/js/init.js $JTALK/nodejs/nodecompile.js"
  168. # Add supplied libraries
  169. LIBS="$BASE $TOADD"
  170. # Get a unique tempdir and make it get auto removed on exit
  171. TMPDIR=`mktemp -d`
  172. trap "rm -rf $TMPDIR" EXIT
  173. # --------------------------------------------------
  174. # Collect libraries and Smalltalk files looking
  175. # both locally and in $JTALK/js and $JTALK/st
  176. # --------------------------------------------------
  177. PROGRAM=
  178. until [ "$*" = "" ]
  179. do
  180. case $1 in
  181. *.st)
  182. CATEGORY=`basename $1 .st`
  183. if [ -f "$1" ]; then
  184. COMPILE="$COMPILE $1 $CATEGORY"
  185. COMPILED="$COMPILED $CATEGORY.js"
  186. else
  187. if [ -f $JTALK/st/$1 ]; then
  188. COMPILE="$COMPILE $JTALK/st/$1 $CATEGORY"
  189. COMPILED="$COMPILED $CATEGORY.js"
  190. else
  191. echo "JTalk file not found: $1"
  192. exit 1
  193. fi
  194. fi
  195. ;;
  196. *.js)
  197. resolvejs $1
  198. LIBS="$LIBS $RESOLVED"
  199. ;;
  200. *)
  201. # Will end up being the last non js/st argument
  202. PROGRAM=$1
  203. ;;
  204. esac
  205. shift
  206. done
  207. # --------------------------------------------------
  208. # Actual compilation phase of collected .st files
  209. # --------------------------------------------------
  210. # Create compiler dynamically
  211. cat $OURCOMPILER > $TMPDIR/compiler.js
  212. # Compile all collected .st files to .js
  213. echo "Loading libraries $KITCHENSINK $TOLOAD and compiling ..."
  214. node $TMPDIR/compiler.js $COMPILE
  215. # Verify all .js files corresponding to .st files were created, otherwise exit
  216. IFS=" "
  217. for FILE in $COMPILED
  218. do
  219. if [ ! -f "$FILE" ]; then
  220. echo "Failed compilation of $FILE, exiting."
  221. exit 1
  222. fi
  223. done
  224. if [ ! -z $CLOSUREPARTS ]; then
  225. echo "Compiling all js files using Google closure compiler."
  226. ALLJSFILES="$COMPILED $LIBS"
  227. for FILE in $ALLJSFILES
  228. do
  229. mv $FILE $FILE.original
  230. java -jar ~/compiler.jar $CLOSUREOPTS --js $FILE.original --js_output_file $FILE
  231. rm $FILE.original
  232. done
  233. fi
  234. if [ -z $PROGRAM ]; then
  235. echo "Done."
  236. exit 0
  237. fi
  238. # --------------------------------------------------
  239. # Now we start composing resulting javascript file.
  240. # --------------------------------------------------
  241. # Add collected libraries to libs.js file.
  242. if [ ! -z "$LIBS" ]; then
  243. echo "Adding libraries $LIBS ..."
  244. cat $LIBS > $TMPDIR/libs.js
  245. LIBS=$TMPDIR/libs.js
  246. fi
  247. echo "Adding Jtalk code$COMPILED ..."
  248. # Check for init file
  249. if [ ! -z "$INIT" ]; then
  250. if [ -f "$INIT" ]; then
  251. echo "Adding initializer $INIT ..."
  252. else
  253. echo "Can not find init file $INIT, exiting."
  254. exit 1
  255. fi
  256. fi
  257. # Check for adding main
  258. if [ ! -z "$MAIN" ]; then
  259. echo "Adding call to $MAIN class >> main ..."
  260. echo "smalltalk.$MAIN._main()" > $TMPDIR/main.js
  261. MAIN=$TMPDIR/main.js
  262. fi
  263. # Check for adding main file
  264. if [ ! -z "$MAINFILE" ]; then
  265. if [ -f "$MAINFILE" ]; then
  266. echo "Adding main as $MAINFILE ..."
  267. else
  268. echo "Can not find main file $MAINFILE, exiting."
  269. exit 1
  270. fi
  271. MAIN=$MAINFILE
  272. fi
  273. # And finally concatenate Program.js
  274. echo "Writing $PROGRAM.js ..."
  275. cat $LIBS $COMPILED $INIT $MAIN > $PROGRAM.js
  276. echo "Done."
  277. if [ ! -z $CLOSUREFULL ]; then
  278. echo "Compiling $PROGRAM.js file using Google closure compiler."
  279. mv $PROGRAM.js $PROGRAM.js.original
  280. java -jar ~/compiler.jar $CLOSUREOPTS --js $PROGRAM.js.original --js_output_file $PROGRAM.js
  281. rm $PROGRAM.js.original
  282. echo "Done."
  283. fi