Ocean Parse Tree

ocean
ocean::=program | library | module | classes

These are the top level blocks in an ocean file. Note that in sharp contrast to the rest of the language these blocks are implicitely 'the public' as they would otherwise not be visible (and thus usuable) by other parts of the program.

program
program::=program IDENTIFIER ensure? starts : ( statement step )... : contains? else? finally? end ( . program end-name? )?

There is either one program module per program (sic) or one 'library'. The program module declares the contract to the environment.

library
library::=library IDENTIFIER ensure? starts? contains : ( functions step )... : finally? end ( . library end-name? )?

A Library module like a program module declares the contract with the environment, only in the case of a library the environment are other programs which use this as a dynamic loading library A library has an automatic 'switch := 'forbidden''

module
module::=module IDENTIFIER ensure? starts? contains : ( functions step )... : finally? end ( . module end-name? )?

Modules are the generic way to group both data and code. They create their own namespace, but have no further overhead.


classes
classes::=concrete | concept | interface | mixin | delegate | deputy

...

concrete
concrete::=concrete IDENTIFIER ensure?
( starts | is | wraps | extends | delegates | represents | implements | has | finally )...
end ( . concrete end-name? )?

A concrete is a class which can be instantiated, and thus cannot have any defered parts.

concept
concept::=concept IDENTIFIER ensure?
( starts | is | wraps | extends | delegates | represents | implements | defers | has | finally )...
end ( . concept end-name? )?

A concept is a class which will never be instantiated. Concept classes define generic methods working on generic properties.

interface
interface::=interface IDENTIFIER ensure?
( starts | is | defers | has | finally )...
end ( . interface end-name? )?

An interface defines, but usually doesn't implement, a set of calls. Most important is that an interface has no instances as it cannot have any content. It is used to define an API.

mixin
mixin::=mixin IDENTIFIER ensure?
( starts | is | wraps | extends | delegates | implements | defers | has | finally )...
end ( . mixin end-name? )?

A mixin class

delegate
delegate::=delegate IDENTIFIER ensure?
( starts | is | wraps | extends | delegates | represents | implements | defers | has | finally )...
end ( . delegate end-name? )?

A concept delegate

deputy
deputy::=deputy IDENTIFIER ensure?
( starts | is | wraps | extends | delegates | represents | implements | has | finally )...
end ( . deputy end-name? )?

A concrete delegate


contract-paragraphs
contract-paragraphs::=require | ensure | guarantee

...

ensure
ensure::=ensure : ( expression step )... :

The conditions in this paragraph must be true throughout the whole section

require
require::=require : ( expression step )... :

The conditions in this paragraph must be true at the entrance of this section

guarantee
guarantee::=guarantee : ( expression step )... :

The conditions in this paragraph must be true at the exit (end of finally) of this section


class-paragraphs
class-paragraphs::=is | wraps | extends | has | defers | implements | represents | delegates

...

is
is::=is ( ( class-name step )... ) : ( class-name step )... :

True inheritance; in principle all contained classes should be concepts, because is represents a taxonomy. All public and restricted methods/fields are passed on to the world/descendants. Multiple occurences of a ancestor class are folded to a single occurance: this is an is-a relation, not an is-two!

wraps
wraps::=wraps ( ( class-name step )... ) : ( class-name step )... :

Hidden inheritance; In principle all contained classes must be concrete, because wraps represents a shift of metaphore, and none of the defered methods can be implemented. None of the the public and restricted are visible outside this wrapping class. Multiple occurences of an ancestor class are folded to a single occurance, but for any descendents this rule no longer applies.

extends
extends::=extends ( ( class-name step )... ) : ( class-name step )... :

Functional inheritance; All public and restricted methods/fields are passed on to the world/descendants. Multiple occurences of a ancestor class are not folded to a single occurance.

has
has::=has : ( functions step )... :

Defines the properties of this class.

defers
defers::=defers : ( functions step )... :

Defines, but doesn't implement the containing calls. See implements.

implements
implements::=implements : ( functions step )... :

Implementations of the containing calls, some of which may be defer'ed from a parent class.

represents
represents::=represents ( ( class-name step )... ) : ERRANDS :

...

delegates
delegates::=delegates : ( functions step )... :

...


general-paragraphs
general-paragraphs::=starts | contains | does | else | finally

...

starts
starts::=starts : ( statement step )... :

...

does
does::=does : ( statement step )... :

...

else
else::=else : ( statement step )... :

...

finally
finally::=finally : ( statement step )... :

...

contains
contains::=contains : ( functions step )... :

...


ERRANDS
ERRANDS::= TODO

definations of errands


functions
functions::=function | function

...

function
function::=function IDENTIFIER ( ( param , )... ) require? ensure? starts? does? finally? guarantee? end ( . function end-name? )?

...

param
param::= presence? passing param-change param-check param-type IDENTIFIER

...

param-change::= TODO
param-check::= TODO
param-type::= TODO

statement
statement::=( compound-statement | simple-statement ) condition?

...

compound-statement
compound-statement::=with | if | unless | assume | while | until

A statement which can have multiple parts and is used for looping or choices.

with
with::=with : ( statement step )... : ( if | unless | assume | while | until )

With is a break of the part-blocks, as anything declared within it is visible in the following compound statement. The reason for its existence is purely based on readability: to stop unnecessary indenting.

if
if::=if expression require? ensure? does : ( statement step )... : elsif... else? finally? guarantee? end ( . if )?

has no preferences for success or failure

elsif::=elsif expression : ( statement step )... :
unless
unless::=unless expression require? ensure? does : ( statement step )... : elsif... else? finally? guarantee? end ( . unless )?

assumes that the expression will fail, this part of the statement will be placed 'out-of-line'

assume
assume::=assume expression require? ensure? does : ( statement step )... : elsif... else? finally? guarantee? end ( . assume )?

assumes that the expression will succeed, all other parts of this statement, except for the finally part will be placed 'out-of-line'

while
while::=while expression require? ensure? does : ( statement step )... : continue? else? finally? guarantee? end ( . while )?

repeats until the expression fails. While is best suited for loops repeating at least once.

continue::=continue : ( statement step )... :
until
until::=until expression require? ensure? does : ( statement step )... : continue? else? finally? guarantee? end ( . until )?

repeats while the expression fails. Until is best suited for loops that probably won't.

simple-statement
simple-statement::=yield | return | resume | release | next | bounce | leave | redo | expression

A statement which either computes or transfers control.

yield
yield::=yield expression?

returns the (optional) value to the caller, but the generator will continue after this statement when called again

return
return::=return expression?

returns the (optional) value to the caller

resume
resume::=resume LABEL ?

returns the (optional) value to the caller

release
release::=release

switches to next available fibre

next
next::=next LABEL ?

transfers control to the continue clause or the begining of the loop if no continue clause is present

bounce
bounce::=bounce LABEL ?

transfers control to the else clause

leave
leave::=leave LABEL ?

transfers control to the finally clause or the end if no finally clause is present

redo
redo::=redo LABEL ?

transfers control to the begining of the loop

condition
condition::=if expression
 |unless expression
 |assume expression
 |while expression
 |until expression
 |else expression

Please note that the else condition has inversed logic: where all other conditions are called before their dependent statements (which cannot fail), else is called if its dependent statement fails. An else condition leaves any variables defined in the dependent statement undefined, so in that case the else expression must be a 'final' function or statement.

passing
passing::=copy | my | your | use | their | our | give | show

my
by reference and give ownership to callee
your
by reference but ownership stays with caller
our
by reference shared ownership
give
return by reference and ownerships is transfered to the caller
show

presence
presence::=mandatory | automatic | repeated

...


expression
expression::=expr-var | expr-lit | expr-uni-symbol | expr-list

...

expr-var::=IDENT variable-part? expr-dyadic?
variable-part::=. ( IDENTIFIER | expr-list ) variable-part?
 |-> ( IDENTIFIER | expr-list ) variable-part?
 |.*
 |( ( labeled-expr step )... ) variable-part?
 |[ ( expression step )... ] variable-part?
expr-list::=( ( expression step )... )
call-list::=( ( labeled-expr step )... )
labeled-expr::=( LABEL : )? expression
expr-dyadic::=SYMBOL expression
expr-lit::=( LIT_NUM | LIT_TEXT ) LABEL? expr-dyadic?
expr-uni-symbol::=SYMBOL expression

name::=IDENTIFIER
step::=, | ;
end-name::=. IDENTIFIER end-name?
class-name::=IDENTIFIER