Cooperscript is a Python dialect in which all operators precede their operands, and parentheses are used for all grouping (except string literals, which are delimited with double quotes). Cooperscript source files have a .COOP extension. Coopertags files have a .CPTG extension. COOPERScript stands for Compact Object-Oriented Program Editor and Runtime System. Cooperscript is open source and implemented using Java.
Special Characters
- () grouping
- - used in identifiers
- ; end of stmt.
- : dot operator
- " string delimiter
- \ escape char.
- # comment
- Extra:
- _ used in identifiers
- $ string prefix char.
- {} block comment
- {{ }} Coopertags comment
Differences from Python
- Parentheses, not whitespace
- Integration with Coopertags
- Operators come before their operands
- Information hiding (public/private)
- Single, not multiple inheritance
- Adds interfaces ("scool" defs.)
- Drops iterators and generators
- Adds lambdas
- Adds quote and list-compile functions, treating code as data
- Adds cons, car and cdr functionality
Version 0.1
- No inheritance
- No interfaces
- No IDE
Keyboard Aid
This optional feature enables hyphens, open parentheses, and close parentheses to be entered by typing semicolons, commas, and periods, respectively. When enabled, keyboard aid can be temporarily suppressed by using the Ctrl key in conjunction with typing semicolons, commas, and periods (no character substitution takes place). By convention, hyphens are used to separate words in multi-word identifiers, but semicolons are easier to type than hyphens. Similarly, commas and periods are easier to type than parentheses. Typing semicolon converts previous hyphen to a semicolon, and previous semicolon to a hyphen (use the Ctrl key to override this behaviour). Typing semicolon after close parenthesis simply inserts semicolon. The close delim switch automatically inserts a closing parenthesis/double quote when the open delimiter is inserted.
Coopertags
Coopertags is a simplified markup language used to replace HTML (also used to define screen layouts). Arbitrary Coopertags code can be embedded in the Cooperscript echo statement. Coopertags syntax, where asterisk (*) means repetition, is defined as follows:
- Tags:
- [tag]
- [tag: body]
- [tag (fld val)*: body]
- Body:
- text
- [: text]*
- [(fld val)*: text]*
- Call Cooperscript code:
- [expr: <expr>]
- [exec: <stmt>... ]
- [coop: <path>]
Grammar Notation
- Non-terminal symbol: <symbol>
- Optional text in brackets: [ text ]
- Repeats zero or more times: [ text ]...
- Repeats one or more times: <symbol>...
- Pipe separates alternatives: opt1 | opt2
- Comments in italics
Language Grammar
White space occurs between tokens (parentheses and semicolons need no adjacent white space):
<source file>:
- do ( [<imp>]... [<def glb>] [<def>]... [<class>]... )
<imp>:
- <import stmt> ;
<import stmt>:
- import <module>...
- from <rel module> import <mod list>
- from <rel module> import all
<module>:
- <name>
- ( : <name><name>... )
- ( as <name><name> )
- ( as ( : <name><name>... ) <name> )
<mod list>:
- <id as>...
<id as>:
- <mod id>
- ( as <mod id><name> )
<mod id>:
- <mod name>
- <class name>
- <func name>
- <var name>
<rel module>:
- ( : [<num>][<name>]... )
- <name> // ?
<class>:
- <cls typ><name> [<base class>] [<does>] [<vars>] [<ivars>] do ( <def>... ) ;
- abclass <name> [<base class>] [<does>] [<vars>] [<ivars>] do ( <anydef>... ) ;
- <scool><name> [<does>] [<const list>] do ( [<abdef>]... [<defimp>]... ) ;
- enum <name><elist> ;
- ienum <name><elist> ;
<cls typ>:
- class
- iclass
<does>:
- ( does <scool name>... )
<scool name>:
<base class>:
- <name>
- ( : <name><name>... )
<const list>:
- ( const <const pair>... )
<const pair>:
- ( <name><const expr> )
<scool>:
- scool
- iscool
<def glb>:
- gdefun [<vars>] [<ivars>] do <block> ;
<def>:
- <defun> ( <name> [<parms>] ) [<vars>] [<dec>] do <block> ;
<defimp>:
- defimp ( <name> [<parms>] ) [<vars>] [<dec>] do <block> ;
<abdef>:
- abdefun ( <name> [<parms>] ) [<dec>] ;
<defun>:
- defun
- idefun
<anydef>:
- <def>
- <abdef>
<vars>:
- ( var [<id>]... )
<ivars>:
- ( ivar [<id>]... )
<parms>:
- [<id>]... [<parm>]... [ ( * <id> ) ] [ ( ** <id> ) ]
<parm>:
- ( <set op><id><const expr> )
<dec>:
- ( decor <dec expr>... )
<block>:
- ( [<stmt-semi>]... )
<stmt-semi>:
- <stmt> ;
<jump stmt>:
- <continue stmt>
- <break stmt>
- <return stmt>
- return <expr>
- <raise stmt>
<raise stmt>:
- raise [<expr> [ from <expr>]]
<stmt>:
- <if stmt>
- <while stmt>
- <for stmt>
- <try stmt>
- <asst stmt>
- <del stmt>
- <jump stmt>
- <call stmt>
- <print stmt>
<call expr>:
- ( <name> [<arg list>] )
- ( : <obj expr> [<colon expr>]... ( <method name> [<arg list>] ))
- ( call <expr> [<arg list>] )
<call stmt>:
- <name> [<arg list>]
- : <obj expr> [<colon expr>]... ( <method name> [<arg list>] )
- call <expr> [<arg list>]
<colon expr>:
- <name>
- ( <name> [<arg list>] )
<arg list>:
- [<expr>]... [ ( <set op><id><expr> ) ]...
<dec expr>:
- <name>
- ( <name><id>... )
- ( : <name><id>... )
- ( : <name>... (<id>... ))
<dot op>: // 'dot', ':', both OK
- dot | :
<asst stmt>:
- <asst op><target expr><expr>
- <set op> ( tuple <target expr>... ) <expr>
<asst op>:
- set | addset | minusset | mpyset | divset |
- idivset | modset |
- shlset | shrset | shruset |
- andbset | xorbset | orbset
- andset | xorset | orset
- = | += | -= | *= | /= |
- //= | %= |
- <<= | >>= | >>>= |
- &= | ^= | '|=' |
- &&= | ^^= | '||='
<set op>:
- set | =
<target expr>:
- <name>
- ( : <name> [<colon expr>]... <name> )
- ( slice <arr><expr> [<expr>] )
- ( slice <arr><expr> all )
- ( <crop><cons expr> )
<arr>: string or array/lyst
- <name>
- <expr>
<obj expr>:
- <name>
- <call expr>
<if stmt>:
- if <expr> do <block> [ elif <expr> do <block>]... [ else do <block>]
<while stmt>:
- while <expr> do <block>
- while do <block> until <expr>
<for stmt>:
- for <name> in <expr> do <block>
<try stmt>:
- try do <block> <except clause>... [ else do <block>] [ eotry do <block>]
- try do <block> eotry do <block>
<except clause>:
- except <name> [ as <name>] do <block>
<return stmt>:
- return
<break stmt>:
- break
<continue stmt>:
- continue
<del stmt>:
- del <expr>
<paren stmt>:
- ( <stmt> )
<qblock>:
- ( quote [<paren stmt>]... )
<expr>:
- <keyword const>
- <literal>
- <name>
- ( <unary op><expr> )
- ( <bin op><expr><expr> )
- ( <multi op><expr><expr>... )
- ( <quest><expr><expr><expr> )
- <lambda>
- ( quote <expr>... )
- <renum expr>
- <cons expr>
- <tuple expr>
- <lyst expr>
- <dict expr>
- <bitarray expr>
- <string expr>
- <bytezero expr>
- <bytes expr>
- <target expr>
- <obj expr>
- <cast>
<quest>:
- quest | ?
<unary op>:
- minus | notbitz | not |
- - | ~ | !
<bin op>:
- <arith op>
- <comparison op>
- <shift op>
- <bitwise op>
- <boolean op>
<arith op>:
- div | idiv | mod | mpy | add | minus |
- / | // | % | * | + | -
<comparison op>:
- ge | le | gt | lt | eq | ne | is | in |
- >= | <= | > | < | == | !=
<shift op>:
- shl | shr | shru |
- << | >> | >>>
Note: some operators delimited with single quotes for clarity (quotes omitted in source code)
<bitwise op>:
- andbitz | xorbitz | orbitz |
- & | ^ | '|'
<boolean op>:
- and | xor | or |
- && | ^^ | '||'
<multi op>:
- mpy | add | strdo | strcat |
- and | xor | andbitz | xorbitz |
- or | orbitz |
- * | + | % | + |
- && | ^^ | & | ^ |
- '||' | '|'
<const expr>:
- <literal>
- <keyword const>
<literal>:
- <num lit>
- <str lit>
- <bytes lit>
<cons expr>:
- ( cons <expr> [<expr>] )
- ( <crop><cons expr> )
<tuple expr>:
- ( tuple <expr>... )
<lyst expr>:
- ( lyst [<expr>]... )
<dict expr>:
- ( dict [ <pair>]... )
<bitarray expr>:
- ( bitarray <enum name> [<elist>] )
- ( bitarray <enum name><idpair>... )
<elist>:
- <id>...
- <intpair>...
- <chpair>...
<intpair>: // integer constant
- <int const>
- ( <int const><int const> )
<chpair>: // one-char. string
- <char lit>
- ( <char lit><char lit> )
<idpair>:
- <id>
- ( <id><id> )
<pair>: // expr1 is a string
- ( <expr1><expr2> )
- ( <str lit><expr> )
<renum expr>:
- ( renumize <expr><ren id>... )
- ( renumize <expr><ren int>... )
- ( renumize <expr><ren ch>... )
<ren id>:
- ( 0 <id> )
- ( 1 <id> )
- ( 1 <id><id> )
<ren int>: // expr is <dec int>
<ren ch>: // expr is <char lit>
- ( 0 <expr> )
- ( 0 <expr><expr> )
- ( 1 <expr> )
- ( 1 <expr><expr> )
<cast>:
- ( cast <type><expr> )
<print stmt>: // built-in function
- print <expr>...
- println [<expr>]...
- echo <expr>...
<lambda>: // must pass qblock thru compile func
- ( lambda ( [<id>]... ) <expr> )
- ( lambda ( [<id>]... ) do <block> )
- ( lambdaq ( [<id>]... ) do <qblock> )
No white space allowed between tokens, for rest of Cooperscript Grammar:
<white space>:
- <white token>...
<white token>:
- <white char>
- <line-comment>
- <blk-comment>
<line-comment>:
- # [<char>]... <new-line>
<blk-comment>:
- { [<char>]... }
<white char>:
- <space> | <tab> | <new-line>
<name>:
- [<underscore>]... <letter> [<alnum>]... [<hyphen-alnum>]... [<underscore>]...
<hyphen-alnum>:
- <hyphen><alnum>...
<alnum>:
- <letter>
- <digit>
In plain English, names begin and end with zero or more underscores. In between is a letter followed by zero or more alphanumeric characters. Names may also contain hyphens, where each hyphen is preceded and succeeded by an alphanumeric character.
<num lit>:
- <dec int>
- <long int>
- <oct int>
- <hex int>
- <bin int>
- <float>
<dec int>:
- [<hyphen>] 0
- [<hyphen>] <any digit except 0> [<digit>]...
<long int>:
- <dec int> L
<float>:
- <dec int> <fraction> [<exponent>]
- <dec int> <exponent>
<fraction>:
- <dot> [<digit>]...
<exponent>:
- <e> [<sign>] <digit>...
<e>:
- e | E
<sign>:
- + | -
<keyword const>:
- none
- true
- false
<oct int>:
- 0o <octal digit>...
<hex int>:
- 0x <hex digit>...
- 0X <hex digit>...
<bin int>:
- 0b <zero or one>...
- 0B <zero or one>...
<octal digit>:
- 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7
<hex digit>:
- <digit>
- A | B | C | D | E | F
- a | b | c | d | e | f
<str lit>:
- [ $ <str prefix>] <quoted str>
<str prefix>:
- r | u | R | U
<quoted str>:
- " [<str item>]... "
<str item>:
- <str char>
- <escaped str char>
- <str newline>
<str char>:
- any source char. except "\", newline, or end quote
<str newline>:
- \ <newline> [<white space>] "
<bytes lit>:
- $ <byte prefix><quoted bytes>
<byte prefix>: any case/order
- b | br
<quoted bytes>:
- " [<bytes item>]... "
<bytes item>:
- <bytes char>
- <escaped char>
- <str newline>
<bytes char>:
- any ASCII char. except "\", newline, or end quote
<escaped char>:
- \\ backslash
- \" double quote
- \} close brace
- \a bell
- \b backspace
- \f formfeed
- \n new line
- \r carriage return
- \t tab
- \v vertical tab
- \ooo octal value = ooo
- \xhh hex value = hh
<escaped str char>:
- <escaped char>
- \N{name} Unicode char. = name
- \uxxxx hex value (16-bit) = xxxx
<crop>:
- c <crmid>... r
<crmid>:
- a | d