Othello 'O'

Another tragedy in programming language design.

Othello is the result of an independent study I did while I was at USF. I needed an extra course one summer, so I convinced Matt Murrell to join me under Dr Albrecht's supervision for a fun-filled semester of compiler design. We actually got further than I expected us to, and Othello ended up having more features than I could have hoped for. I have tried to include a full description of all those features below.

General Language Specifications

  • Nothing is case sensitive (“if” is the same as “iF” is the same as “IF”)
  • Statements are terminated with a new line
  • Blank Lines are ignored
  • The language is strongly typed

Types

  • boolean
    Can be either true or false. The results of logic operations can also be stored in a boolean variable. For example:
    declare b as boolean
    b := ((x+2) ?= 3)
    
  • integer
    Integers are exactly what you would expect them to be. Othello offers a single integer size of 32 bits.
  • real
    Real numbers in Othello are IEEE Double-precision, 64 bit numbers.
  • string
    Strings hold character data. However, you can assign or append any other type of data to a string and it will be converted to character data.

Operators

:= Assignment ?= Equivlance test
< Less than > Greater than
<= Less than or equal >= Greater than or equal
<> Not equal + Add
- Subtract * Multiply
/ Divide - Unary negate
% Modulus & String concatanation

Order of Operations

The order of operations in Othello should be familiar to anyone who has worked with C or C++. Which is to say that most things are evaluated left to right. The unary negation operator has higher precedence than the other mathematical operators, and assignment has lower precedence than all others, which allows the result of an expression to be assigned to a variable. To alter the order of operations, place the expression you wish to have execute first within ()'s.
a + b / c		/# b is divided by c,and then added to a #/
(a + b) / c		/# b is added to a, and then the result is divided by c. #/

Conditional Statements

In Othello's conditional statements, the braces, '{' and '}', are required and must be on their own lines. The exception to this rule is the else statement, in which the brackets may appear on the same line as the else. Othello supports if statements,
if (expression)
{
	statement-list
}
and if-else statements.
if (expression)
{
	statement-list
} else {
	statement-list
}

Loop Statements

Unfortunately, we only got around to adding a single loop structure into Othello. Like the conditional statements, the opening and closing braces are required, and must be on their own lines.
while (expression)
{
	statement-list
}

Comments

Comments can appear on a line following a statement, or on a line by themselves. However, that doesn't mean you can only have single line comments. A comment in Othello begins with '/#', ends '#/', and can span several lines.
/# A single line comment #/

/#
	Multi-line comment, line 1
	Multi-line comment, line 2
#/

Variables

To use a variable, you must specify what type it will be first. You can declare one or more variables of a specific type as follows
declare test_string as string		
declare i1, i2, i3, i4 as integer;	/# declare 4 integer variables #/ 
Variables must begin with a letter, but can contain letters, numbers, or underscores. If you want a variable of global scope, simply declare that variable outside of any function definition, but before the function or functions that will use it. It is worthwhile to note that you can assign a value to multiple variables at once in the same way that you declare them. Simply specify each variable in a comma separated list.
declare i1, i2, i3, i4 as integer;	
i1, i2, i3, i4 := 1500;				
You can also cast a variable or expression to another type. You do so by enclosing the expression you want to cast in ()'s, and specifying the type you want it cast to.
declare a as integer
declare b as real
a := (b as integer)
The following code segment shows several examples of casting, and is our first complete Othello program listing.
function main() as integer
{
	declare a,b as integer
	declare x,y as real
	declare pi as real

	a:=1
	x:=2.0
	pi:=3.14159

	y:=(2 as real)
	print( y & "\t\t=2.0\n" )

	y:=(a as real)
	print( y & "\t\t=1.0\n" )

	y:=((a+5)/2 as real)
	print( y & "\t\t=3.0\n" )

	y:=((a+5)/2 as real) + 3.14159
	print( y & "\t\t=6.14159\n" )

	y:=((a+5)/2 as real) + x
	print( y & "\t\t=5.0\n" )

	y:=((a+5)/2 as real) + (x*pi)
	print( y & "\t\t=9.28somethingsomething\n" )

	b:=(pi/2.0 as integer) + 1
	print( b & "\n" )

	y:= pi / 2.0	
	print( y & "\n" )
}

Strings

Strings in Othello are what you could call incomplete. There are no string manipulation functions, and the only operator is string concatenation. However, you can concatenate any data type to a string or a string literal to produce a new string. No explicit casting is required. The symbol for string concatenation is &.
declare str3 as string

str3 := "once upon a time, about " & 5 & " years ago. " & 1.5 & " little pigs lived\n"
print( "str3 = '" & str3 & "'")

Functions

prototypes function declaration return types calling a function using the return type entry point, main
function f(a as real, b as real)
{
	return (a+b)
}

IO routines

There are two IO functions provided with Othello, input and print. The print command takes a value or expression and converts it to a string for display. If you need to display more than one value at once, you can simply concatenate them together using string concatenation. You can force a newline by appending "\n" to the end of your value.
print( arg );
The input command reads a single value from the user and stores that value in the provided argument. Othello will automatically make the necessary type conversions needed to convert the user input from a string to whatever the type of the argument is.
input( arg );

Examples

Now that we have covered the essentials of the Othello language, let's look at a couple of full-length examples. This first example provides the user with a menu, from which they can choose to calculate the area of a circle or a factorial.
prototype main(arg as integer) as integer
prototype factorial(x as integer) as integer
prototype area(r as real) as real
prototype usage() as integer

function main(arg as integer) as integer
{
	declare a,b as integer
	declare in as integer
	declare r as real
	a:=usage()
	r:=3.1415+1.0
	while(a<>3)
	{
		if(a?=1)
		{
			print("Enter the number to factorial: ")
			input(in)
			print("\n")
			print("The answer is " & factorial(in))
			print("\n")
		} else {
			print("Enter the radius of the circle: ")
			input(r)
			print("\n")
			print("The answer is " & area(r))
			print("\n")
		}
		a:=usage()
		print("\n")
	}
}

function factorial(x as integer) as integer
{
	if(x>0)
	{
		return (x*factorial(x-1))
	} else {
		return (1)
	}
}

function area(r as real) as real
{
	return (3.1415926535 * r * r)
}

function usage() as integer
{
	declare a as integer

		while((a<>1) and (a<>2) and (a<>3))
		{
			print(" 1) Factorial\n")
			print(" 2) Area of a circle\n")
			print(" 3) Exit\n")
			print(" Selection: ")
			input(a)
			print("\n")
		}
		return(a)
}
This second example is an implementation of the Ackermann's function. It was used to test the recursion capabilities of Othello. To find out what the Akermann function is, visit Wikipedia.
prototype main() as integer
prototype ack(m as integer, n as integer) as integer

function main() as integer
{
	declare tmp2 as integer
	tmp2:=0
	declare m, n as integer
	print("Ackermans function...\n")
	print("Enter m: ")
	input(m)
	print("Enter n: ")
	input(n)
	print("\nThe answer is: " & ack(m, n) & "\n\n")
}

function ack(m as integer, n as integer) as integer
{
	if(m?=0)
	{
		return(n+1)
	} else {
		if(n?=0)
		{
			return( ack(m-1, 1) )
		} else {
			return( ack(m-1, ack(m, n-1) ) )
		}
	}
}

Conclusion

Matt and I had a lot of fun working on Othello. It required an enormous amount of work, but we learned tons and ultimately exceeded our own expectations. All of the functionality mentioned above was implemented over the course of about two months, which should give you an idea of the amount of time we dedicated to it. Of course, all of that time was on top of what was required by our other courses and jobs. That said, there are bound to be some issues with the complier. We just simply didn't have the time to do a through testing job. Thus, I cannot recommend the use of the Othello complier for anything of importance. However, that doesn't mean that you aren't free to play with it if so desire. Enjoy!
Jenny's Website
Jenny's website is much more likely to have current information and pictures than mine, so check it out. Jenny's Site

Home
Games
Projects

Books in my library
What I'm reading