jtalkc 8.9 KB

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