1. Structure

A few definitions used in other places:

letter  ::=  "a"..."z" | "A"..."Z"
digit   ::=  "0"..."9"
integer ::=  digit* | "0x".digit+ | "0b".("0"|"1")+

1.1. Modules

A module is a set of functions and data fields, logically grouped together. Modules have no special meaning to the language, but they allow separating groups of logically distinct code.

A source file represents one module. The file name is the module name followed by .sc.

Modules can contain any number of data fields and any number of functions, in any order.

Modules are automatically compiled when code references that module.

The grammar for a module is:

module ::=  (datafield | function)*

1.2. Comments

Comments start with // and continue until the end of the line. Comments can appear anywhere and are ignored by the grammar.

1.3. Identifiers

unqualifiedidentifier ::=  (letter | "_") (letter | digit | "_")*
qualifiedidentifier   ::=  unqualifiedidentifier "." unqualifiedidentifier
identifier            ::=  unqualifiedidentifier | qualifiedidentifier

Unqualified identifiers are first resolved to local variables and function arguments. If there is no matching variable, the identifier is located within the containing module.

Qualified identifiers are resolved to the data field in the specified module.

1.4. Data fields

The grammar for data fields is:

datafield       ::=  memorydatafield | addrdatafield | constdatafield
memorydatafield ::=  "internal"? datatype unqualifiedidentifier ("=" integer)? ";"
addrdatafield   ::=  "addr" "internal"? datatype unqualifiedidentifier "=" integer ";"
constdatafield  ::=  "const" datatype unqualifiedidentifier "=" integer ";"

Normal data fields are placed in external memory. If the internal modifier is specified, they are placed in internal memory. While internal memory is more efficient than external memory, only 114 bytes of internal memory are available, which must also be shared with the Stack.

If a value is specified, the data field is initialized to this value before the main function is called.

Address data fields specify their own location. This is useful when certain memory has a special meaning.

Constant data fields are not placed in memory. Instead, any usage is replaced by their value.

An example of several data fields:

byte counter;
byte initialized = 47;
internal byte foo;
addr byte fixedAddress = 0xFE00;
const byte theAnswer = 42;

1.5. Functions

The grammar for functions is:

function          ::=  datatype unqualifiedidentifier "(" functionarguments ")" "{" localvariable* statementblock "}"
functionarguments ::=  (functionargument ("," functionargument)*)?
functionargument  ::=  datatype unqualifiedidentifier
localvariable     ::=  datatype unqualifiedidentifier

A function can have at most 6 arguments and local variables.

Functions must return a value if their data type is not void, and cannot return a value if it is void.

An example of a function:

byte doIt(byte argument)
{
    byte localVariable;

    return argument;
}

1.6. Data types

datatype ::=  "void" | "byte"

The void data type indicates ‘nothing’. It is only valid for the return value of functions.

If a function returns void, returining a value is an error.

The byte data type is an unsigned 8-bit integer.

1.7. Statement blocks

statementblock ::=  statement*

A statement block is a sequence of statements which are executed in sequence.

Table Of Contents

Previous topic

SC language reference

Next topic

2. Expressions

This Page