Module
Syntax
module = { SOI ~ (import)* ~ expr ~ EOI }
Proto
/** A message representing an OpenController module */
message Module {
map<string, Module> imports = 1; // The imports of the module
required Expr body = 2; // The body of the module
}
Static Semantics: ImportEntry
Syntax
import = { "import" ~ string ~ "as" ~ ident }
Static Semantics
- Return a pair of the import name to the module at the import path
Static Semantics: ImportEntries
- Let importEntries be a map of the ImportEntry of imports
- Return importEntries
Static Semantics: imports
- Return the ImportEntries of imports
Runtime Semantics: Evaluation
- Let importResults be the result of evaluating the imports modules.
- Return the result of evaluating body with importResults as the Module Scope.
Expr
Literals
Bool
Syntax
bool = @{ "true" | "false" }
Proto
bool
Runtime Semantics: Evaluation
- Returns ? bool
String
Syntax
// matches anything between 2 double quotes
double_quoted_string = @{ "\"" ~ (!("\"") ~ ANY)* ~ "\""}
// matches anything between 2 single quotes
single_quoted_string = @{ "\'" ~ (!("\'") ~ ANY)* ~ "\'"}
string = @{
double_quoted_string |
single_quoted_string
}
Proto
string
Runtime Semantics: Evaluation
- Returns ? string
Int
Syntax
int = @{ "-" ? ~ ("0" | '1'..'9' ~ '0'..'9' * ) }
Proto
int32
Runtime Semantics: Evaluation
- Returns ? int
Float
Syntax
float = @{
"-" ? ~
(
"0" ~ "." ~ '0'..'9' + |
'1'..'9' ~ '0'..'9' * ~ "." ~ '0'..'9' +
)
}
Proto
float
Runtime Semantics: Evaluation
- Returns ? float
RefExpr
Syntax
ref_expr = @{ ident }
Proto
/** A message representing a reference to the cope */
message RefExpr {
required string ref = 1; // The name of the desired reference in the scope
}
Runtime Semantics: Evaluation
- If key ref in Local Scope
- Returns ? the value of ref in Local Scope
- Else If key ref in Builtins
- Returns ? the value of ref in Builtins
- Else If key ref in Module Scope
- Returns ? the value of ref in Module Scope
- Else
- Type Panic
LambdaExpr
Syntax
lambda = { "(" ~ lambda_args ~ ")" ~ "=>" ~ expr }
Proto
/** A message representing a lambda expression */
message LambdaExpr {
repeated string args = 1; // The args to the lambda
required Expr return = 2; // The return of the lambda
}
Runtime Semantics: Evaluation
- Return Fn that evaluates return with captured Module Scope and an intersection of the captured Local Scope and the Fn arguments, with the arguments taking precedence
CallExpr
Syntax
call = { "(" ~ (expr)+ ~ ")" }
Proto
/** A message representing a function call */
message CallExpr {
required Expr calling = 1; // The expression to call
repeated Expr args = 2; // The arguments to pass
}
Runtime Semantics: Evaluation
- Let argsResult be args evaluated with Local Scope and Module Scope
- Returns ? FnEvaluate with argsResult
IfExpr
Syntax
elif_expr = { "elif" ~ expr ~ "{" ~ expr ~ "}" }
if_expr = { "if" ~ expr ~ "{" ~ expr ~ "}" ~ (elif_expr)* ~ "else" ~ "{" ~ expr ~ "}" }
Proto
/** A message representing an else-if */
message Elif {
required Expr condition = 1; // The condition to call if
required Expr then = 2; // The expression to call
}
/** A message representing an if expression */
message IfExpr {
required Expr condition = 1; // The condition to call if
required Expr then = 2; // The expression to call
repeated Elif elif = 3; // The else-if conditions
required Expr else = 4; // The else condition
}
Runtime Semantics: Evaluation
- Let conditionResult be condition evaluated with Local Scope and Module Scope
- If conditionResult is true
- Return then evaluated with Local Scope and Module Scope
- Else
- For each elif, let conditionResult be condition evaluated with Local Scope and Module Scope
- If conditionResult is true
- Return then evaluated with Local Scope and Module Scope
- If conditionResult is true
- Return else evaluated with Local Scope and Module Scope
- For each elif, let conditionResult be condition evaluated with Local Scope and Module Scope
HouseExpr
Syntax
house = { "house" ~ "{" ~ (struct_param)+ ~ "}" }
Proto
/** The root message representing a house. **/
message HouseExpr {
required Expr display_name = 1; // The name to be displayed by clients
required Expr id = 2; // A unique identifier
map<string, Expr> rooms = 3; // The Rooms inside the House
}
Static Semantic: Early Errors
- Throws Parse Error if there is no displayName field.
- Throws Parse Error if there is no id field.
- Throws Parse Error if there is no rooms field.
Runtime Semantics: Display
RoomExpr
Syntax
room = { "room" ~ "{" ~ (struct_param)+ ~ "}" }
Proto
/** A message representing a room. */
message RoomExpr {
required Expr display_name = 1; // The name to be displayed by clients
map<string, Expr> controllers = 2; // The Controllers inside the Room
optional Expr icon = 3; // The icon of the Room to be displayed by clients
}
Static Semantic: Early Errors
- Throws Parse Error if there is no display_name field.
- Throws Parse Error if there is no controllers field.
Runtime Semantics: Display
ControllerExpr
Syntax
controller = { "controller" ~ "{" ~ (struct_param)+ ~ "}" }
Proto
/** A message representing a controller */
message ControllerExpr {
required Expr display_name = 1; // The name to be displayed by clients
optional Expr brand_color = 2; // A brand color to be displayed by clients
optional Expr display_interface = 3; // The interface for display clients for the Controller
}
Static Semantic: Early Errors
- Throws Parse Error if there is no displayName field.
Runtime Semantics: Display
DeviceExpr
Syntax
device = { "device" ~ "{" ~ (struct_param)+ ~ "}" }
Proto
/** A message representing a controllable device */
message DeviceExpr {
map<string, Expr> lambdas = 1; // The actions the Device is capable of
}
Static Semantic: Early Errors
- Throws Parse Error if there is no lambdas field.
Runtime Semantics: GetDeviceLambda
- Return the lambda in lambdas with the key key
DisplayInterfaceExpr
Syntax
display_interface = { "displayInterface" ~ "{" ~ (struct_param)+ ~ "}" }
Proto
/** A Controller interface for clients with displays */
message DisplayInterfaceExpr {
/**
* The Widgets that make up the controller.
*
* Implementation Notes: The layout of the widgets in the array is flexible for the client.
*/
repeated Expr widgets = 1;
}
Static Semantic: Early Errors
- Throws Parse Error if there is no widgets field.
Runtime Semantics: Display
WidgetExpr
Syntax
xml_param = { ident ~ "=" ~ (("{" ~ expr ~ "}") | string) }
widget = { "<" ~ ident ~ (xml_param)* ~ ">" ~ (widget | "{" ~ expr ~ "}")* ~ "</" ~ ident ~ ">" }
Proto
/** A message representing any controller widget that can be displayed by clients */
message WidgetExpr {
required string widget_type = 2; // The type of widget
map<string, Expr> params = 3; // The parameters to the widget
repeated Expr children = 4; // The children of the widget
}
Runtime Semantics: Display
Syntax Sugar
Get Lambda
Syntax
get_lambda_expr = { ref_expr | device | if_expr | call }
get_lambda = { get_lambda_expr ~ "." ~ ident }
Static Semantics: Conversion
- Return CallExpr calling a RefExpr to "getLambda" with args deviceExpr and lambdaName