Go to the first, previous, next, last section, table of contents.


Projects

All the examples so far have presumed you are executing code interactively.

This is great for learning and experimentation, but for serious coding you need to be able to edit up archival code in a text editor, save it in a host file, and compile it into the db.

The purpose of this section is to take you quickly through the detailed mechanics of one way of establishing a serious Muq MUF project of your own: Where to put the source files, how to compile them and so forth. It presumes you are running your own Muq developmental server, with full Unix level access to the development account.

The purpose of this section is not to cover all the possibilities, just to present one simple, workable approach.

We will do the development using a development version of the Muq executable in `muq/c/muq', and a test version of the database, in `muq/c/muq-*'. This frees us up to do whatever debugging hacks we want on either, since the production server normally uses the executable `muq/bin/muq' and keeps the database in `muq/db/*'.

Start by installing the full source distribution, if you have not already, and doing

cynbe@chee muq/c> make
cynbe@chee muq/c> make check

to verify that you can compile the server from scratch. I usually do

cynbe@chee muq/c> rm -rf muq-*
cynbe@chee muq/c> rm -rf #check.tmp#

next to clean out the debris from make check.

Now do

% muq-db-c
[...]

to create a test db in `muq/c/muq-*'. Test that it works as expected interactively:

cynbe@chee muq/c> ./muq
[...]
Hints from me$s.loginHints$h[1,2...]:
  For configuration menu do:       config
  To exit server from console do:  <CTRL>-C or rootShutdown
root: 
2 2 +
root: 4
rootShutdown
[...]
cynbe@chee muq/c>

(For what it is worth, I usually do all this sort of stuff from inside an emacs shell buffer: M-x shell in emacs. This makes editing and re-trying expressions trivial, and also allows pasting in full function definitions direct from files in other emacs buffers.)

Now, let's create our own MUF source file establishing our own package, and compile it into the db.

MUF source code lives in MUQ/PKG/. When MUQ/BIN/MUQ-DB-C builds a database from scratch, it compiles the files in ascending order of numerical prefix, which ensures that critical system files are loaded before other files that depend on them.

Prefix numbers 000-499 are reserved for the standard Muq libraries, while prefix numbers 500-999 are reserved for local source libraries. By obeying this convention, you ensure that your files won't be clobbered by files in future source distributions, and that your files will be loaded after the standard Muq facilities they depend on are in place.

Use your favorite text editor to create a file muq/pkg/500-mystuff.t containing

@example  @c
"mystuff" inPackage
2001 -->constant myconst
2002 --> _myvar
: myfn "Hello, world!\n" , ;
myfn
@end example

Explanation:

(I usually test code like this interactively before saving it in a file, but we'll skip that step here for brevity. One reason I do this is because the interactive error diagnostics are not as bad as the batchmode compile diagnostics, which currently often consist of the server hanging...)

Now load that file into the db:

cynbe@chee muq/c> muq-c-lib 500-mystuff
[...]
cynbe@chee muq/c> 

For a simple example like this, of course, it would be easier -- and equivalent -- to simply skip the source file editing and enter the code interactively, but for a realistic project consisting of a dozen or two source files each containing hundreds or thousands of lines of MUF source, batchmode compilation is a virtual necessity.

Now we check that the db has been updated as we expect:

cynbe@chee muq/c> ./muq
[...]
Hints from me$s.loginHints$h[1,2...]:
  For configuration menu do:       config
  To exit server from console do:  <CTRL>-C or rootShutdown
root: 
"mystuff" inPackage
mystuff:
myconst
mystuff: 2001
pop
mystuff: 
_myvar
mystuff: 2002
pop
mystuff: 
myfn
Hello, world!
mystuff: 
rootShutdown
[...]
cynbe@chee muq/c>

Now let's create the world's simplest shell. Edit muq/pkg/500-mystuff.t to contain

@example  @c
"mystuff" inPackage
: ]shell { [] -> @ }
    do{
        t @.standardInput readStreamPacket[ ]pop
        "Huh?\n" ,
    }
;
@end example

Explanation: This declares ]shell to be a function accepting one stackblock and never returning. The do{...} construct is an infinite loop, and inside it we eternally read one line from standard input, ignore the result, and print "Huh?" to standard output.

Again, this example is so simple that we could as easily have defined the function interactively, but we're warming up for cases where the shell might have hundreds or thousands of lines of code.

We could load the file in just as before, using muq-c-lib, but let us suppose instead that we've spent a few days thrashing around and prefer now to build a pristine new database from scratch:

cynbe@chee muq/c> rm -rf muq-*
cynbe@chee muq/c> muq-db-c
[...]
cynbe@chee muq/c>

As you do this, you'll notice that your muq/pkg/500-mystuff.t file now gets loaded in last automatically.


Go to the first, previous, next, last section, table of contents.