Here we give an example of using the object-oriented features in Camelot. The code below, together with the two standard utility functions rev and len for list reversal and length, defines a program for Sun's MIDP platform (as described in midp), which runs on devices such as PalmOS PDAs. The program displays the list of primes in an interval. Two numbers are entered into the first page of the GUI, and when a button is pressed a second screen appears with the list of primes, calculated using the sieve of Eratosthenes, along with a button leading back to the initial display.
This example has been compiled with our current compiler implementation, and executed on a PalmOS device.
class primes = javax.microedition.midlet.MIDlet with
implement javax.microedition.lcdui.CommandListener
field exitCommand: javax.microedition.lcdui.Command
field goCommand: javax.microedition.lcdui.Command
field doneCommand: javax.microedition.lcdui.Command
field mainForm: javax.microedition.lcdui.Form
(* lower and upper limits: *)
field lltf: javax.microedition.lcdui.TextField
field ultf: javax.microedition.lcdui.TextField
field display: javax.microedition.lcdui.Display
maker () =
let _ = display <-
(javax.microedition.lcdui.Display.getDisplay
(this:> javax.microedition.midlet.MIDlet))
in let _ = goCommand <-
(new javax.microedition.lcdui.Command
"Go" javax.microedition.lcdui.Command.SCREEN 1)
in let _ = exitCommand <-
(new javax.microedition.lcdui.Command
"Exit" javax.microedition.lcdui.Command.SCREEN 2)
in let t = new javax.microedition.lcdui.Form "Primes"
in let ll = new javax.microedition.lcdui.TextField
"Lower limit:" "" 10
javax.microedition.lcdui.TextField.NUMERIC
in let _ = lltf <- ll
in let _ = t#append ll
in let ul = new javax.microedition.lcdui.TextField
"Upper limit:" "" 10
javax.microedition.lcdui.TextField.NUMERIC
in let _ = ultf <- ul
in let _ = t#append ul
in let _ = t#addCommand (this#goCommand)
in let _ = t#addCommand (this#exitCommand)
in let _ = mainForm <- t
in t#setCommandListener this
method startApp (): unit =
this#display#setCurrent (this#mainForm)
method pauseApp (): unit = ()
method destroyApp (b:bool): unit = ()
method commandAction
(cmd: javax.microedition.lcdui.Command)
(s: javax.microedition.lcdui.Displayable)
: unit =
if cmd#equals (this#exitCommand)
then let _ = this#destroyApp false
in this#notifyDestroyed ()
(* create & display list of primes *)
else if cmd#equals (this#goCommand)
then
let lower_limit = int_of_string
(this#lltf#getString())
in let upper_limit = int_of_string
(this#ultf#getString())
in let primes =
new javax.microedition.lcdui.Form "Primes"
in let _ = appendPrimes lower_limit upper_limit primes
in let done = new javax.microedition.lcdui.Command
"Done"
javax.microedition.lcdui.Command.SCREEN 1
in let _ = doneCommand <- done
in let _ = primes#addCommand done
in let _ = primes#setCommandListener this
in let _ =
javax.microedition.lcdui.AlertType.INFO#playSound
(this#display)
in this#display#setCurrent primes
(* back to main form *)
else if cmd#equals (this#doneCommand) then
this#display#setCurrent (this#mainForm)
else ()
end
(* Generate a list of prime numbers in an interval [a..b] *)
(* Integer square roots *)
let increase k n = if (k+1)*(k+1) > n then k else k+1
let rec intsqrt n = if n = 0 then 0
else increase (2*(intsqrt (n/4))) n
(* n is divisible by no member of l which is <= sqrt n *)
let isPrime n l lim =
match l with
[] -> true
| h::t -> h <= lim && n mod h <> 0 && isPrime n t lim
(* generate list of primes between n and top *)
let make1 n top acc =
if n > top then rev acc []
else if isPrime n acc n then make1 (n+2) top (n::acc)
else make1 (n+2) top acc
let makeSmallPrimes top = make1 3 top [2]
let makePrimes n top smallPrimes =
if n > top then []
else if isPrime n smallPrimes n then
n::(makePrimes (n+2) top smallPrimes)
else makePrimes (n+2) top smallPrimes
let appList l (f: javax.microedition.lcdui.Form) =
match l with [] -> ()
| (h::t)@_ -> let _ = f#append ( (string_of_int h)^"\n")
in appList t f
let appendPrimes bot top
(f: javax.microedition.lcdui.Form) =
let smallPrimes = makeSmallPrimes (intsqrt top)
in let primes = makePrimes (bot + 1 - bot mod 2)
top smallPrimes
in let s = (string_of_int (len primes)) ^ " primes\n"
in let _ = f#append s
in appList primes f |