CS 433 - The Omg Report
Omg is a simple procedural programming language used as the input
language for our compiler in CS 433, Spring 2008. Omg stands for "Our
Mix of Grammars" (as well as a few other things.)
Omg supports two basic types: integer (called "num") and boolean
(called "boo", with values "yes" and "no"), as well as arrays of
integers and booleans. The language also supports recursion, nested
scopes, and variable declarations "on the fly". Parameters can be
passed by value and by reference. Input and output of integers and
characters is supported. Not in the language are records, pointers,
floats, and strings. Omg's syntax is based on suggestions of the students in the
class. The language is derived from subsets of C and Pascal, with
some syntactic quirks.
Language details:
- Omg's keywords are:
num boo yes no glob ret if else while mod or and not
- Omg's operators and reserved characters are:
| < <= > >= = <>
| comparison operators
|
| + - * / mod | arithmetic operators
|
| := | assignment operator
|
| @ | indicates pass-by-reference (like "&" in C++)
|
| ( ) { } [ ] | grouping / array subscript (same as in Java)
|
| .. | defines subscript range in array declaration
|
| , | separates parameters and terminates conditions in "if" and "while"
|
| ; | terminates statements
|
- Single-line comments start with "#" and extend to the
end of the line.
Multi-line comments start with "(:" and end with
":)"; they cannot be nested.
- The language is case-sensitive: "boo" is different from "Boo"
(the former is a keyword, the latter is not).
- Variables are declared like in Java / C, e.g.,
"num i, j; boo b;".
- Array declarations include a subscript range after the type name:
"num[0..7] x; boo[-2..2] z;". The range needs to be given
as two integer constants.
- Basic variables can be initialized as they declared ("num x =
2 * y;), but arrays cannot.
- Variable declarations and statements can be
interleaved (like in C++ and Java).
- Functions are declared like in C / Java; procedures are simply
declared without a type. The return statement is "ret".
- Global variables can be declared
before functions and procedures, but they cannot be initialized.
They need to be prefixed with the keyword "glob".
- Integer and boolean parameters can be passed by value (e.g.,
"num a") or by reference (e.g., "num @a"). Array
parameters are automatically passed by reference, without specifying
the bounds (e.g. "num[] a"). Each parameter must be listed
with a type (like in C / Java), e.g., "gcd(num a, num b)".
- "if" and "while" statements are like in C / Java, except the condition
is terminated by a comma, rather than surrounded by parentheses.
- Execution starts with the parameterless procedure "omg()"
(like "main" in C / Java). Command-line arguments are not supported.
- The functions num rdn() and num rdc()
are provided for input; the procedures prn(num n) and
prc(num c) are provided for output. The 'n' versions read/print
integers; the 'c' versions read/print characters.
- Character constants are supported as
'c', where c is any character except
a newline, a backslash, or a single quote. These three special
characters are represented with '\n', '\\', and
'\''. A character constant is simply an integer (the
corresponding ASCII code) - that is, there is no type "char".
Character constants come in handy in conjunction with the
prc procedure.
Here are some sample Omg programs:
# gcd.omg
# asks user for two integers and prints their GCD
num gcd(num a, num b) { # compute the GCD of a, b recursively
if b > a,
ret gcd(b, a);
else if b = 0,
ret a;
else
ret gcd(b, b mod a);
}
omg() { # main program
prc('?');
num x := rdn(); # get first number from user
prc('?');
num y := rdn(); # get second number from user
prc('G'); prc('C'); prc('D'); prc('=');
prn(gcd(x, y));
}
----------------------------------------------------------------------
(: reverse.omg
reverses string entered by the user
:)
glob num newline; # global variable
rev() {
num c := rdc(); # read first character
if c <> newline,
rev(); # reverse rest of string
prc(c); # print first character
}
omg() {
newline := '\n';
prc('?');
rev();
prc(newline);
}
----------------------------------------------------------------------
# bubble.omg
# bubble sort of 5 integers
swap(num @a, num @b) { # swaps a and b, which are passed by reference
num tmp := a;
a := b;
b := tmp;
}
bubble(num[] X, num lo, num hi) { # sorts X[lo..hi] using bubble sort
while hi > lo, {
num j := lo;
boo changed := no;
while j < hi, {
if X[j] > X[j+1], {
swap(X[j], X[j+1]);
changed := yes;
}
j := j + 1;
}
if not changed,
ret;
hi := hi - 1;
}
}
omg() { # main program
num[1..5] A;
A[1] := 6;
A[2] := -2;
A[3] := 44;
A[4] := 3;
A[5] := 5;
bubble(A, 1, 5);
prn(A[1]); prc(' ');
prn(A[2]); prc(' ');
prn(A[3]); prc(' ');
prn(A[4]); prc(' ');
prn(A[5]); prc('\n');
}