jtalkc 8.1 KB

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