Skip to content

Grammar

Seemann edited this page Nov 22, 2023 · 83 revisions

Whitespaces are optional unless specified otherwise. Rules below are valid for Sanny Builder 3.9+

Docs: https://docs.sannybuilder.com/coding/

notation

  • | - one of
  • ( ) - group
  • ( )* - zero or more
  • ( )+ - one or more
  • "" - terminal
  • .. - range
  • . - any character
  • [ ] - zero or one (optional)
  • A..Z - dynamic values (i.e. read from a config file)
  • # - comments
  • <> - sourced from an external config

Base

digit := "0".."9"
alpha := "a".."z" | "A".."Z" | "_"
digit_hex := ( digit | "A".."F" | "a".."f" )
whitespace := (" ")+
eol := (\n)+
any := (.)+
class_names = <classes.db>
directive_names = <compiler.ini>
model_names = <*.ide>

Elements

Literals

identifier := alpha ( alpha | digit )*
const_name = identifier
literal_int := ( digit )+
literal_int_hex := ( "0x" | "0X" ) ( digit_hex )+
literal_int_bin := ( "0b" | "0B" ) ( '0' | '1' )+
int := [ "+" | "-" ] ( literal_int | literal_int_hex | literal_int_bin )
int_constant := int | const_name
model_name := "#" alpha ( alpha | digit | "@" )* # model_names
label := "@" identifier
string_long := """ any """
string_short := "'" any "'"
e_notation := ( "E | "e" ) [ ( "+" | "-" ) ] literal_int
float := [ "+" | "-" ] ( [ literal_int ] "." literal_int [ e_notation ] | literal_int e_notation )
number := float | int

Variables

var_global := ( "$" ( digit | alpha  )+ |  "&" int # 0..65535 )
var_global_indexed := var_global "[" int_constant "]"
var_global_string = ( "s$" | "v$" ) ( digit | alpha  )+
var_global_string_indexed = var_global_string "[" int_constant "]"
var_local := int "@"
var_local_indexed := var_local "[" int_constant "]"
var_local_string = int ( "@s" | "@v" )
var_local_string_indexed = var_local_string "[" int_constant "]"
var_name := var_global | var_local | const_name
var_type_primitive := "int" | "float" | "string" | "longstring"
var_type := var_type_primitive | identifier # class_names
typed_array_element := var_name "(" ( var_name | var_global_indexed | var_local_indexed ) "," literal_int ( "i" | "f" | "s" | "v" ) ")"
untyped_array_element := var_name "[" ( var_name | var_global_indexed | var_local_indexed ) "]"
variable := var_name | typed_array_element | untyped_array_element | var_global_indexed | var_local_indexed | var_global_string | var_global_string_indexed | var_local_string | var_local_string_indexed

Blocks

Declarations

const_decl := const_name "=" any [ "," const_decl ]
var_decl := var_name ":" ( var_type [ "=" any ] | "array" whitespace int_constant whitespace "of" whitespace var_type ) [ "," var_decl ]
typed_var_decl := var_name [ ( "=" any | "[" int_constant "]" ) ] [ "," typed_var_decl ]
const_decl_line := "const" whitespace const_decl eol
const_decl_block := "const" eol ( const_decl eol )+ "end" eol
var_decl_block := "var" eol ( var_decl eol )+ "end" eol
var_decl_line := "var" whitespace var_decl eol
var_decl_typed_line := var_type_primitive whitespace typed_var_decl eol
hex_number := digit_hex [ digit_hex ] [ "(" int_constant ")" ]
hex_input := (( hex_number | var_global | var_global_indexed | label | string_long | model_name | directive ) whitespace )+
hex_block := "hex" eol ( hex_input eol )+ "end" eol

Conditions

if_head := "if" [ whitespace ( "and" | "or" | statement ) ] eol
then := "then" ( whitespace statement | eol )
else := "else" ( whitespace statement | eol )

if_block := if_head then ( statement )* [ else ( statement )* ] "end" eol
directive_name := ("{$" identifier) # directive_names
directive := directive_name [whitespace any] "}"
directive_line := directive eol

Built-ins

post_increment_line := variable "++" eol
post_decrement_line := variable "--" eol
inc_line := "inc(" variable [ "," ( number | variable ) ] ")" eol
dec_line := "dec(" variable [ "," ( number | variable ) ] ")" eol
mul_line := "mul(" variable [ "," ( number | variable ) ] ")" eol
div_line := "div(" variable [ "," ( number | variable ) ] ")" eol
sqr_line := "sqr(" variable ")" eol
alloc_line := alloc(" ( var_global | var_global_indexed ) "," int ")" eol
random := "random(" ( variable | number ) "," ( variable | number ) ")"

Script

statement := ( 
  directive_line
  | var_decl_line 
  | var_decl_block
  | var_decl_typed_line
  | const_decl_line
  | const_decl_block
  | hex_block
  | post_increment_line
  | post_decrement_line
  | inc_line
  | dec_line
  | mul_line
  | div_line
  | sqr_line
  | alloc_line
  | if_block
)
script := (statement)+