% Messages ::= % send( ) % cancel() % status( ) % nextToPrint() \insert 'NewPortObject.oz' declare % representing the state of a print server by records: % states(nextjob: % queue: >> % waiting: >) % ::= # fun {NewPrintServer} {NewPortObject state(nextjob: 0 queue: nil waiting: nil) fun {$ state(nextjob: N queue: Jobs waiting: Vars) Msg} case Msg of send(FileContents ?JN) then JN=N case Vars of nil then state(nextjob: N+1 queue: (JN#FileContents)|Jobs waiting: Vars) [] V|RestVars then V=FileContents state(nextjob: N+1 queue: Jobs waiting: RestVars) end [] cancel(JN) then state(nextjob: N queue: {DeleteJob Jobs JN} waiting: Vars) [] status(JN ?Var) then Var = if {Member JN {Map Jobs fun {$ J#_} J end}} then queued else notFound end state(nextjob: N queue: Jobs waiting: Vars) [] nextToPrint(?FileContentsVar) then local Reversed = {Reverse Jobs} in case Reversed of (_#Contents)|Rest then FileContentsVar=Contents state(nextjob: N queue: {Reverse Rest} waiting: Vars) else local Z in FileContentsVar = Z state(nextjob: N queue: Jobs waiting: Z|Vars) end end end end end} end fun {DeleteJob Jobs JN} {FoldR Jobs fun {$ I#C Res} if I==JN then Res else I#C|Res end end nil} end