Cooperscript

Cooperscript

 

Cooperscript (implemented in Java) is an open source 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, also statements are separated by semicolons). Cooperscript source files have a .COOP extension. Coopertags files (the sister language of Cooperscript, a text markup language) have a .CPTG extension. COOPERScript, short for Compact Object-Oriented Programming Environment and Runtime System, boasts an ultra-simple Lisp-like syntax unlike all other languages.

Special Characters

  • ()  grouping
  • -  word separator
  • ;  end of stmt.
  • :  dot operator
  • "  string delimiter
  • \  escape char.
  • #  comment
  • _  used in identifiers
  • $  string prefix char.
  • {}  block comment

Op Characters

  • + - * / %
  • = < >
  • & | ^ ~ ! ?

Differences from Python

  • Parentheses, not whitespace
  • Operators come before their operands
  • Integration with Coopertags
  • Information hiding (public/private)
  • Single, not multiple inheritance
  • Adds interfaces ("hedron" defs.)
  • Drops iterators and generators
  • Adds lambdas
  • Adds quote and list-compile functions, treating code as data
  • Adds cons, car and cdr functionality

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

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. Typing space after hyphen at end of identifier converts hyphen to underscore. 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. Mock JSON files using Coopertags syntax have a .CPJS extension, and include no commas. Instead of myid: val, use [myid: val]. Instead of [1, 2, 3], use [arr: [: 1][: 2][: 3]]. Arbitrary Coopertags code can be embedded in the Cooperscript echo statement. Coopertags syntax, where asterisk (*) means occurs zero or more times, is defined as follows:

  • Tags:
    • [tag]
    • [tag (fld val)*: body]
    • [tag (fld val)*| body |tag]
  • Body:
    • text
    • [(fld val)*: text]*
  • Call Cooperscript code:
    • [expr: <expr>]
    • [exec: <stmt>... ]
    • [coop: <path>]

Monetizing Cooperscript

When open source Cooperscript and Coopertags are up and running, the Cooperhub mobile app will be developed. Both of those languages are embedded in the Cooperhub app. A utility converts Coopertags and Cooperscript code to HTML and Javascript, respectively. This utility is used by browser-based versions of multiple Cooperscript apps. Cooperhub executes the multiple Cooperscript apps.

Cooperscript 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>... ) ;
  • <hedron><name> [<does>] [<const list>] do ( [<abdef>]... [<defimp>]... ) ;
  • enum <name><elist> ;
  • ienum <name><elist> ;

<cls typ>:

  • class
  • iclass

<does>:

  • ( does <hedron name>... )

<hedron name>:
<base class>:

  • <name>
  • ( : <name><name>... )

<const list>:

  • ( const <const pair>... )

<const pair>:

  • ( <name><const expr> )

<hedron>:

  • hedron
  • ihedron

<def glb>:

  • gdefun [<vars>] [<ivars>] do <block> ;

<def>:

  • <defun> ( <name> [<parms>] ) [<vars>] [<gvars>] [<dec>] do <block> ;

<defimp>:

  • defimp ( <name> [<parms>] ) [<vars>] [<gvars>] [<dec>] do <block> ;

<abdef>:

  • abdefun ( <name> [<parms>] ) [<dec>] ;

<defun>:

  • defun
  • idefun

<anydef>:

  • <def>
  • <abdef>

<vars>:

  • ( var [<id>]... )

<ivars>:

  • ( ivar [<id>]... )

<gvars>:

  • ( gvar [<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>
  • <switch stmt>
  • <try stmt>
  • <asst stmt>
  • <del stmt>
  • <jump stmt>
  • <call stmt>
  • <print stmt>
  • <bool stmt>

<call expr>:

  • ( <name> [<arg list>] )
  • ( : <colon expr>... <name> )
  • ( : <colon expr>... ( <method name> [<arg list>] ))
  • ( :: <colon expr>... <name> else <expr> )
  • ( :: <colon expr>... ( <method name> [<arg list>] ) else <expr> )
  • ( call <expr> [<arg list>] )

<call stmt>:

  • <name> [<arg list>]
  • : <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 | :

<dotnull op>:

  • dotnull | ::

<asst stmt>:

  • <asst op><target expr><expr>
  • <set op> ( tuple <target expr>... ) <expr>
  • <inc op><name>

<asst op>:

  • set | addset | minusset | mpyset | divset |
  • idivset | modset |
  • shlset | shrset | shruset |
  • andbset | xorbset | orbset
  • andset | xorset | orset
  • = | += | -= | *= | /= |
  • //= | %= |
  • <<= | >>= | >>>= |
  • &= | ^= | '|=' |
  • &&= | ^^= | '||='

<set op>:

  • set | =

<target expr>:

  • <name>
  • ( : <colon expr>... <name> )
  • ( slice <arr><expr> [<expr>] )
  • ( slice <arr><expr> all )
  • ( <crop><cons expr> )

<arr>:   string or array/list

  • <name>
  • <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> [<idx var>] in <expr> do <block>
  • for ( <bool stmt>; <bool stmt>; <bool stmt> ) 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>

<bool stmt>:

  • quest [<expr>]
  • ? [<expr>]
  • <asst stmt>

<switch stmt>:

  • switch <expr><case body> [ else do <block>]

<case body>:

  • [ case <id> do <block>]...
  • [ case <dec int> do <block>]...
  • [ case <str lit> do <block>]...
  • [ case <tuple expr> 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>... )
  • <cons expr>
  • <tuple expr>
  • <list expr>
  • <dict expr>
  • <venum expr>
  • <string expr>
  • <bytes expr>
  • <target expr>
  • <call expr>
  • <cast>

<quest>:

  • quest | ?

<inc op>:

  • incint | decint | ++ | --

<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><expr> )

<tuple expr>:

  • ( tuple [<expr>]... )
  • ( <literal> [<expr>]... )
  • ( )

<list expr>:

  • ( jist [<expr>]... )

<dict expr>:

  • ( dict [ <pair>]... )

<pair>:  // expr1 is a string

  • ( : <expr1><expr2> )
  • ( : <str lit><expr> )

<venum expr>:

  • ( venum <enum name> [<elist>] )
  • ( venum <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> )

<cast>:

  • ( cast <literal><expr> )
  • ( cast <class name><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>:

  • null
  • 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 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>] "

<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

Not implemented: string prefix and bytes data type (rest of grammar)

<str lit>:

  • [ $ <str prefix>] <quoted str>

<str prefix>:

  • r | u | R | U

<quoted str>:

  • " [<str item>]... "

<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
[ Back to Top ]