Tuesday, November 2, 2010

M Language Tutorial - Getting started

I am learning MUMPS/M language to understand one of our systems, that has been implemented using M. I feel, there is a lack of a documentation in form of quick start and tutorial, so I put some notes here hoping that it will be useful for someone.
For a thorough listing of the M language commands, operators, functions and special variables, see MUMPS by Example
One of M implementations available as open source is GTM from FIS, we can download it from http://sourceforge.net/projects/fis-gtm/. The documentation is available from here
Setup a environment to start some test is fairly simple, just unzip the downloaded file, run configure and answer few questions, then we can start
setting env. for running GTM
$source ./gtmprofile
This shell will set various env, variables required by GTM also create a global directory and a default datafile, that is actually M database. M is a language with built in persistence. The global directory is kind of control file in Oracle.
start gtm - the interpreter
GTM>write "hello world"
hello world
M use write command to output some thing to a console, in Ruby we would use puts in Python, this is print. The command halt is used to quit the gtm.
For a beginner of any language, the ability to write something out to see and to exit are the two most important commands.
string and numbers
String is enclosed by " as in C, Java, Python, Ruby, to concatenate two or more string we use operator _, not that common any more.
GTM>set x="hello"
GTM>set y="world"
GTM>set z=x_" "_y
GTM>write z
hello world
The command set set these local variables, these variables are created automatically if not exist.
GTM>set a=10
GTM>set b=20
GTM>set c=(a+b)*5/10
GTM>write c
For number, this is quite straightforward, no surprise.

create and run the first program
$export gtmroutines=/home/gtm/samples
$source ./gtmprofile
GTM>write $ZROutines
this gtmroutines env. variable specifies where GTM is going to store and search for its routines, inside GTM however it is kept in variable $ZROutines. The concept routine in GTM is synonym for a single file containing M code.
GTM>zedit "hello"
This will popup a vi editor with opened file /home/gtm/samples/hello.m. Create the following content, save and quit vi editor.
  write "Hello ",who,!
In the routine hello.m we see a label hello(who), which is calling entry point. GTM's routine can have many labels and the general syntax of calling a section of code in the routine is label^routine. The label hello will take one parameters. The write above command takes 3 parameters separated by comma where ! means new line. It is possible to write the above code in a single line
hello(who) write "Hello ",who,! quit
The quit at the end is important in case other labels are added below if we want a label to behave as a function, which mean that the execution flow in the routine terminates at quit command .
GTM> zlink "hello"
The zlink compiles and link hello.m to GTM image so we can call this routine in GTM environment
GTM>do hello^hello("Moon")
Hello Moon
If we do not specify a label then the code will be executed from the first line.
GTM>do ^hello("World")
Hello World
If we look closely to gtm, we will see that gtm is shell script that call the binary mumps in direct mode (with parameter -direct).
We can run the routine hello.m from command line as follow
$export gtmroutines="/home/gtm/samples/ ."
$mumps -run %XCMD 'do ^hello("World")'
The %XCMD is in fact a routine _XCMD.m located in distribution directory of GTM, that is why we need add "." into gtmroutines env. variables, so mumps knows where to find the files being executed.
language syntax
M syntax is very strict, SPACE characters between M statements are significant. A single space separates a command from its argument, COMMA "," is used to separate one argument from other of these commands taking more than one arguments.
A SPACE, or newline, separates the command's arguments from others. Commands which take no arguments (e.g., ELSE) require two following spaces.
Character ; is used to indicate start of a comment, that runs until end of line.
GTM>write  "hello"; two SPACES after write
%GTM-E-EXPR, Expression expected but not found
 write  "hello"
GTM>write "hello"; single SPACE after write
GTM>set x=1,y=2 write "x=",x,",y=",y !set and write commands are on the same line separated by SPACE
GTM>set x=1 + 2; SPACE surrounding + 
%GTM-E-CMD, Command expected but not found
 set x=1 + 2
GTM>set x=1+2; no SPACE in expression
GTM>write x
GTM>set x= 9 ; SPACE after =  
%GTM-E-EXPR, Expression expected but not found
 set x= 9
GTM>set x=9; no SPACE after=
GTM>write x
Math expression
Comparing to other language, math operator has no order precedences, a expression is evaluated from left to right
GTM>write 1+2*3
GTM>write (1+2)*3
Parentheses has to be used to make thing work as expecting.
GTM>write 1+(2*3)

No comments: