User Tools

Site Tools


dynamic_linking

By now you should have a general understanding of Dana's structural paradigm from the introduction section, and an understanding of static linking. This section covers dynamic linking whereby a meta-program is instructed to create, interconnect and launch the collection of components that will form the behaviour of a regular program.

Dana's standard meta-program is called esher (short for “evolution shell runtime”).

The normal way to run a Dana program is to use the command:

dana esher myprogram.txt

Let's break this down. dana is the Dana interpreter which directly executes compiled Dana components. esher is Dana's standard meta-program, found in the components directory. Dana runs this program immediately. myprogram.txt is a text file describing the components that comprise your program. esher examines this text file, loads and interconnects the components listed, and starts up each component.

So why don't we just integrate esher into the Dana interpreter so that you could just type dana myprogram.txt instead? This is because meta-programs are a major research topic and, once you've gotten the hang of the basics of esher, you'll probably want to either customise esher for your needs (its source code is provided) or else write your own meta-program.

Next we'll guide you through converting an example program into a dynamically-linked one and running that program with esher.

esher uses text files to describe the abstract names (called “roles”) of components and the way in which each such role is interconnected with other roles. There are two kinds of text file with different formats. One is the manifest and the other is the configuration fragment.

A manifest file is simply a list of configuration fragment files, one per line:

myprogram.txt
app.txt
timer.txt

A configuration fragment then describes one component and its relationship to other components:

app.txt
App = app.o
Timer -> Timer

The above fragment specifies the creation of a component instance named “App” from the component contained in the file app.o. The Timer required interface of this component should be connected to another component instance named “Timer” if and when such a component exists in the system.

We finish this system off with one more fragment for the timer component as follows:

timer.txt
Timer = time/Timer.o

Now we'll put everything together. Download the above three text files and save them in the components/ directory of Dana's installation folder. Next download the following Dana source file which will represent our application logic. Again, save this file in the components/ directory.

app.dn
component provides App requires io.Output out, data.IntUtil iu, time.Timer it {
   int App:main(AppParam params[])
      {	
      for (int i = 1; i < 5; i++)
         {
         it.sleep(1000);
         out.println("$(iu.intToString(i)) seconds");
         }
      return 0;
      }
   }

Compile the above source file in the usual way to get the file app.o. Make sure your timer component is also compiled with dnc time/Timer.dn. Now, from a command prompt or terminal window in the components/ directory, type the command:

dana esher myprogram.txt

The program should then be launched within the esher environment.

Finally we'll look at incrementally loading the above program using esher's interactive command system. Quit esher by typing “quit” and pressing enter, then run it again with no parameters, so just dana esher. We start by adding the application component to the system:

add app.txt

Now examine the current system state by using the command:

pa

This should result in a report that looks like this:

[0]: App (app.o)
       Timer -> Timer [x]

What we see here is that the application component has been loaded and started but cannot proceed in its logic because it does not have one of its dependencies satisfied (in fact the application component is paused on the line it.sleep(5000)).

So now we add the dependency to the system:

add timer.txt

And program execution will resume as normal. This demonstrates the basis of Dana's ability to control software structure at runtime by connecting the required interfaces of a component to compatible provided interfaces of other components. The runtime evolution tutorial covers swapping dependencies out during execution.

Finally, you may have noticed by now that some required interfaces are automatically linked to implementations. Examples of this are io.Ouput and data.IntUtil. If a component has any required interfaces of these types they are automatically linked directly against implementations in the Dana interpreter. However, you can still override these links if you want by specifying alternative implementations to connect to in the usual way.

dynamic_linking.txt · Last modified: 2014/01/16 08:54 by barryfp

Page Tools