dev.ms 16 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497
  1. .TL
  2. Program Development under Inferno
  3. .AU
  4. Roger Peppé
  5. rog@vitanuova.com
  6. .SH
  7. Introduction
  8. .PP
  9. Inferno provides a set of programs that, used in
  10. combination, provide a powerful development environment
  11. in which to write Limbo programs.
  12. .I Limbo (1)
  13. is the compiler for the Limbo language; there
  14. are versions that run inside and outside the Inferno
  15. environment.
  16. .I Acme (1)
  17. is an integrated window system and editor, and the
  18. preferred source-code editing tool within Inferno.
  19. The Limbo debugger,
  20. .I wm-debug (1),
  21. allows interactive inspection of running Limbo programs.
  22. .I Stack (1)
  23. allows a quick inspection of the execution stack of a
  24. currently running process.
  25. .SH
  26. Getting started
  27. .PP
  28. This document assumes that you have already managed
  29. to install Inferno and have managed to obtain an Inferno
  30. window, running the Inferno window manager,
  31. .I wm (1).
  32. The document
  33. \&``Installing Inferno'' in this volume has details on this.
  34. If running within emu, it is worth giving Inferno
  35. as large a window as possible, as it cannot be resized later.
  36. This paper assumes that you are using a three-button mouse, as it is
  37. not feasible to use Acme without a three-button mouse.
  38. (if you have a two button mouse with a ``mouse wheel'',
  39. the wheel can be used as the middle button).
  40. The first thing to do is to get Acme going. By clicking
  41. on the Vita Nuova logo at the bottom left of the window,
  42. you can display a menu naming some preconfigured commands.
  43. If this has an ``Acme'' entry, then just clicking on that entry
  44. will start acme. If not, then click on the ``Shell'' entry,
  45. and type
  46. .P1
  47. acme
  48. .P2
  49. to start it up. The Acme window should then appear,
  50. filling most of the screen (the window manager toolbar
  51. should still be visible).
  52. .SH
  53. Acme basics
  54. .PP
  55. For a general overview and the rationale behind Acme, see ``Acme:
  56. A User Interface for Programmers'', elsewhere in this volume,
  57. and for detailed documentation, see
  58. .I acme (1).
  59. The basics are as follows:
  60. .PP
  61. Acme windows are text-only and organised into columns.
  62. A distinctive feature of Acme is that there are no graphical
  63. title bars to windows; instead, each window (and additionally
  64. each column, and the whole Acme window itself) has
  65. a textual
  66. .I tag ,
  67. which can be edited at will, and is initially primed to contain
  68. a few appropriate commands.
  69. .PP
  70. An Acme command is just represented by text; any textual
  71. command word may be executed simply by clicking with the middle
  72. mouse button on the word. (See ``Acme mouse commands'', below).
  73. If Acme recognizes the word that has been clicked on
  74. as one of its internal commands (e.g. Put, Undo), then it will take the appropriate
  75. action; otherwise it will run the text as a shell command.
  76. (See
  77. .I sh (1)).
  78. .SH
  79. Acme mouse commands
  80. .PP
  81. Mouse usage within Acme is somewhat more versatile
  82. than in most other window systems. Each of the three
  83. mouse buttons has its own action, and there are also
  84. actions bound to
  85. .I chords
  86. of mouse buttons (i.e. mouse buttons depressed simultaneously).
  87. Mouse buttons are numbered from left (1) to right (3).
  88. Button 1 follows similar conventions to other window systems -
  89. it selects text; a double click will select a line if at the beginning or end
  90. of a line, or match brackets if on a bracket character, or select
  91. a word otherwise.
  92. Button 2, as mentioned above, executes an
  93. Acme command; a single click with button 2 will execute
  94. the single word under the click, otherwise the swept text
  95. will be executed.
  96. Button 3 is a general ``look'' operator; if the text under the
  97. click represents a filename, then Acme will open a new
  98. window for the file and read it in, otherwise it will search
  99. within the current window for the next occurrence of the
  100. text.
  101. Clicking button 2 or button 3 on some text already selected
  102. by button 1 causes the click to refer exactly to the text
  103. selected, rather than gathering likely-looking characters
  104. from around the click as is the default.
  105. .PP
  106. There are two mouse chord sequences which are
  107. commonly used in Acme (and you will find that some
  108. other programs in the system also recognise these sequences,
  109. e.g.
  110. .I wm-sh (1)).
  111. They are both available once some text
  112. has been selected by dragging the mouse with button 1,
  113. but before the button has been released. At this point,
  114. touching button 2 will delete the selected text and save
  115. it in Acme's
  116. .I snarf
  117. buffer; clicking button 3 replaces the selected text with the contents
  118. of the snarf buffer. Before button 1 has been released,
  119. these two buttons reverse each other's actions, so, for
  120. example, selecting some text with button 1, keeping button 1
  121. held down, then clicking button 2 and button 3 in succession,
  122. will save the selected text in the snarf buffer while leaving the
  123. original intact.
  124. The following table summarises the mouse commands in
  125. Acme:
  126. .KS
  127. .TS
  128. center box;
  129. l l .
  130. B1 Select text.
  131. B2 Execute text.
  132. B3 Open file or search for text.
  133. B1-B2 Cut text.
  134. B1-B3 Paste text.
  135. B2-B3 Cancel the pending B2 action.
  136. B3-B2 Cancel the pending B3 action.
  137. .TE
  138. .ce
  139. .I "Acme mouse command summary"
  140. .KE
  141. .SH
  142. Scrolling and resizing Acme windows
  143. .PP
  144. The scroll bars in Acme are somewhat different from
  145. conventional scroll bars (including the scroll bars found
  146. in other parts of Inferno). Clicking, or dragging, with
  147. button-2 on the scrollbar acts the most like the conventional
  148. behaviour, namely that the further down the scroll bar
  149. you click, the further down the file you are shown.
  150. .PP
  151. True to form, however, Acme doesn't omit to make
  152. the other buttons useful: button-1 and button-3
  153. move backwards and forwards through the file respectively.
  154. The nearer the top of the scrollbar the mouse, the
  155. slower the movement. Holding one of these buttons
  156. down on the scrollbar will cause the scrolling motion
  157. to auto-repeat, so it is easy to scroll gently through the
  158. entire file, for instance.
  159. .PP
  160. The small square at the top left of each Acme window is
  161. the handle for resizing the window. Dragging this square
  162. from one place to another (within Acme) will move the
  163. window to the new place. A single button click in this square
  164. will grow the window: button 1 grows it a little bit; button 2
  165. grows it as much as possible without obscuring the other
  166. window titles in the column; button 3 grows it so it covers
  167. the whole column (all other windows in the column are
  168. obscured).
  169. .SH
  170. Creating a new file
  171. .PP
  172. All Limbo programs are composed of
  173. .I modules
  174. and each module is stored in its own file. To write a Limbo
  175. program, you need to write at least one module,
  176. the Limbo
  177. .I "source file" ,
  178. which will then be compiled into Dis code which can
  179. then be run by the Inferno Virtual Machine (VM).
  180. The first step is to decide where to store the file.
  181. When Acme starts up, it creates a new window containing
  182. a list of all the files in the directory in which it was started
  183. (usually your home directory). As a consequence of the
  184. mouse rules above, a click of button-3 on any of those
  185. filenames in that window will open a new window
  186. showing that file or, if it is a directory, a list of the
  187. files and directories it contains.
  188. .PP
  189. An important aspect in Acme's mouse commands, is
  190. that the command is interpreted
  191. .I "relative to the window's current directory",
  192. where the current directory is determined from
  193. the filename in the window's tag. For instance,
  194. Acme commands executed in the tag or body of
  195. a window on the file
  196. .CW "/usr/joebloggs/myfile.txt"
  197. would run in the directory
  198. .CW /usr/joebloggs .
  199. .PP
  200. So, to create a new file in Acme, first open the
  201. directory in which to create the file. (If this is
  202. your home directory, then it's probably already on the screen;
  203. otherwise, you can just type (anywhere) the name of
  204. the directory, and button-3 click on it. If the directory
  205. does not exist, then no window will be created.
  206. Then, within the directory's window or its tag,
  207. choose a name,
  208. .I filename ,
  209. for your file (I'll use
  210. .CW myprog
  211. from here on,
  212. for explanatory convenience)
  213. , type the text:
  214. .P1
  215. New \fIfilename\fP.b
  216. .P2
  217. select this text (the Escape key can also be used to highlight
  218. text that you have just typed), and button-2 click on it.
  219. This should create a new empty window in which you
  220. can edit your Limbo source file. It will also create a
  221. window giving a warning that the file does not
  222. currently exist - you can get rid of this by clicking
  223. with button-2 on the text
  224. .CW Del
  225. in the tag of that window.
  226. .SH
  227. Editing the source file
  228. .PP
  229. You can now edit text in the new window.
  230. Type in the following program:
  231. .P1
  232. implement Myprog;
  233. include "sys.m";
  234. sys: Sys;
  235. include "draw.m";
  236. Myprog: module {
  237. init: fn(nil: ref Draw->Context, argv: list of string);
  238. };
  239. init(nil: ref Draw->Context, argv: list of string)
  240. {
  241. sys = load Sys Sys->PATH;
  242. sys->print("Hello, world\en");
  243. }
  244. .P2
  245. When typing it in, note that two new commands have appeared
  246. in the tag of the new window:
  247. .CW Put
  248. and
  249. .CW Undo .
  250. .CW Put
  251. saves the file;
  252. .CW Undo
  253. undoes the last change to the file, and successive
  254. executions of
  255. .CW Undo
  256. will move further back in time. In case you move
  257. too far back accidentally, there is also
  258. .CW Redo ,
  259. which redoes a change that you have just undone.
  260. Changes in the body of any window in Acme can be undone
  261. this way.
  262. .PP
  263. Click with button-2 on the
  264. .CW Put
  265. command, and the file is now saved and ready to be
  266. compiled. If you have problems at this point (say
  267. Acme complains about not being able to write the
  268. file), you have probably chosen an inappropriate
  269. directory, one in which you do not have write permission,
  270. in which to put the file. In this case you can change the
  271. name of the file simply by editing its name in the window's
  272. tag, and clicking on
  273. .CW Put
  274. again.
  275. .SH
  276. Compiling the source file
  277. .PP
  278. Now, you are in a position to compile the Limbo program.
  279. Although you can execute the Limbo compiler directly
  280. from the tag of the new file's window, it is usually more
  281. convenient to do it from a shell window. To start a shell
  282. window, type
  283. .CW win '' ``
  284. at the right of the tag of the new file's window, select
  285. it, and click with button-2 on it.
  286. A new window should appear showing a shell prompt (usually
  287. .CW "; " '' ``
  288. or
  289. .CW "% " ''). ``
  290. At this, you can type any of the commands mentioned
  291. in Section 1 of the Programmer's Manual.
  292. Note that, following Acme's usual rule, the shell has
  293. started up in the same directory as the new file;
  294. typing
  295. .P1
  296. lc
  297. .P2
  298. at the prompt will show all the files in the directory,
  299. including hopefully the newly written Limbo file.
  300. .PP
  301. Type the following command to the shell:
  302. .P1
  303. limbo -g myprog.b
  304. .P2
  305. If you typed in the example program correctly,
  306. then you'll get a short pause, and then another shell
  307. prompt. This indicates a successful compilation (no
  308. news is good news), in which case you will now have
  309. two new files in the current directory,
  310. .CW myprog.sbl
  311. and
  312. .CW myprog.dis .
  313. The
  314. .CW -g
  315. option to the
  316. .CW limbo
  317. command directed it to produce the
  318. .CW myprog.sbl
  319. file, which contains symbolic information
  320. relating the source code to the Dis executable file.
  321. The
  322. .CW myprog.dis
  323. file contains the actual executable file.
  324. At this point, if you type
  325. .CW lc ,
  326. to get a listing of the files in the current directory,
  327. and then click with button-2 on the
  328. .CW myprog.dis
  329. file, and you should see the output ``Hello, world''.
  330. You could also just type
  331. .CW myprog
  332. at the shell prompt.
  333. .PP
  334. If you are normal, however, the above compilation
  335. probably failed because of some mistyped characters
  336. in the source code; and for larger newly created programs,
  337. in my experience, this
  338. is almost invariably the case.
  339. If you got no errors in the above
  340. compilation, try changing
  341. .CW sys->print
  342. to
  343. .CW print ,
  344. saving the file again,
  345. and continue with the next section.
  346. .SH
  347. Finding compilation errors
  348. .PP
  349. When the Limbo compiler finds errors, it prints
  350. the errors, one per line, each one looking something
  351. like the following:
  352. .P1
  353. myprog.b:13: print is not declared
  354. .P2
  355. This shows the filename where the error has occurred,
  356. its line number in the file, and a description of the error.
  357. Acme's button-3 mouse clicking makes it extremely easy
  358. to see where in the source code the error has occurred.
  359. Click with button-3 anywhere in the filename on the
  360. line of the compilation error, and Acme will automatically
  361. take the cursor to the file of that name and highlight
  362. the correct line.
  363. .PP
  364. If there had been no currently appropriate open Acme
  365. window representing the file, then a new one would
  366. be created, and the appropriate line selected.
  367. .PP
  368. Edit
  369. .CW myprog.b
  370. until you have a program that compiles successfully
  371. and produces the ``Hello, world'' output.
  372. For a program as simple as this, that's all there
  373. is to it - you now know the essential stages involved in
  374. writing a Limbo program; there's just the small matter
  375. of absorbing the Limbo language and familiarising
  376. yourself with the libraries (``The Limbo Programming Language''
  377. elsewhere in this volume,
  378. and
  379. .I intro (2)
  380. are the two essential starting points here).
  381. .SH
  382. Finding run-time errors
  383. .PP
  384. For larger programs, there is the problem of programs
  385. that die unexpectedly with a run-time error. This
  386. will happen when, for instance, a Limbo program uses a reference
  387. that has not been initialised, or refers to an out-of-bounds
  388. array element.
  389. .PP
  390. When a Limbo program dies with a run-time exception,
  391. it does not go away completely, but remains hanging
  392. around, dormant, in a
  393. .I broken
  394. state; the state that it was in when it died may
  395. now be examined at leisure. To experiment with this,
  396. edit the Myprog module above to delete the line
  397. that loads the
  398. .CW Sys
  399. module
  400. .CW "sys = load Sys" ...), (
  401. and recompile the program.
  402. .PP
  403. This time when you come to run
  404. .CW myprog ,
  405. it will die, printing a message like:
  406. .P1
  407. sh: 319 "Myprog":module not loaded
  408. .P2
  409. The number
  410. .CW 319
  411. is the
  412. .I "process id"
  413. (or just
  414. .I pid )
  415. of the broken process. The command
  416. .CW ps ,
  417. which shows all currently running processes,
  418. can be used at this point - you will see a line like this:
  419. .P1
  420. 319 245 rog broken 64K Myprog
  421. .P2
  422. The first number is the pid of the process;
  423. the second is the
  424. .I "process group"
  425. id of the process; the third field gives the
  426. owner of the process; the fourth gives its state
  427. (broken, in this case); the fifth shows the current
  428. size of the process, and the last gives the name
  429. of the module that the process is currently running.
  430. .PP
  431. The
  432. .CW stack
  433. command can be used to quickly find the line
  434. at which the process has broken; type:
  435. .P1
  436. stack \fIpid\fP
  437. .P2
  438. where
  439. .I pid
  440. is the number mentioned in the ``module not loaded''
  441. message (319 in this case).
  442. It produces something like the following output:
  443. .P1
  444. init() myprog.b:12.1, 29
  445. unknown fn() Module /dis/sh.dis PC 1706
  446. .P2
  447. As usual, a quick button-3 click on the
  448. .CW myprog.b
  449. part of the first line takes you to the appropriate
  450. part of the source file. The reason that the program
  451. has died here is that, in Limbo, all external modules
  452. must be explicitly loaded before they can be used; to
  453. try to call an uninitialised module is an error
  454. and causes an exception.
  455. .SH
  456. More sophisticated debugging
  457. .PP
  458. .CW Stack
  459. is fine for getting a quick summary of the state
  460. in which a program has died, but there are
  461. times when such a simple post-mortem analysis
  462. is inadequate. The
  463. .CW wm/deb
  464. (see
  465. .I wm-deb\fR(1))\fP
  466. command provides an interactive windowing
  467. debugger for such occasions.
  468. It runs outside Acme,
  469. in the default window system. A convenient way
  470. to start debugging an existing process is
  471. to raise
  472. .CW wm/task
  473. (``Task Manager'' on the
  474. main menu), select with the mouse the process
  475. to debug, and click ``Debug''. This will start
  476. .CW wm/deb
  477. on that process. Before it can start, the debugger will ask
  478. for the names of any source files that it has not been
  479. able to find (usually this includes the source for
  480. the shell, as the module being debugged is often
  481. started by the shell, and so the top-level function will
  482. be in the shell's module).
  483. .PP
  484. .CW Wm/deb
  485. can be used to debug multiple threads, to inspect
  486. the data structures in a thread, and to interactively
  487. step through the running of a thread (single stepping).
  488. See
  489. .I wm-deb (1)
  490. for details.
  491. \" further afield?
  492. \" other development tools?
  493. \" tools to come?