moon_script 0.8.2

Fast and simple scripting language based on Rust.
Documentation
null = { "null"|"empty" }
boolean = { "true"|"yes"|"false"|"no" }
decimal = { ASCII_DIGIT*~"."~ASCII_DIGIT+ } //0.1 .1
integer = { ASCII_DIGIT+ } //1
string = {"\"" ~ (!"\"" ~ ANY)* ~ "\""}

ARRAY = { "[" ~ (WHITE_SPACE* ~ VALUE ~ (WHITE_SPACE* ~ ",")? )* ~ WHITE_SPACE* ~ "]" }

ident = { ASCII_ALPHA ~ (ASCII_ALPHANUMERIC|":"|"_")* }

fncall_object = { ident }
fncall_module_name = { ident }
fncall_function_name = { ident }
fncall = { (fncall_object ~ ".")? ~ (fncall_module_name ~ "/")? ~ fncall_function_name ~ WHITE_SPACE* ~ "(" ~ WHITE_SPACE* ~ ( VALUE ~ WHITE_SPACE* ~ ("," ~ WHITE_SPACE*)? )* ~ VALUE? ~ WHITE_SPACE* ~ ")" ~ WHITE_SPACE* }

property_params = {
    "("~
    (WHITE_SPACE* ~ VALUE ~ WHITE_SPACE* ~("," ~ WHITE_SPACE*)?)*
    ~ ")"
}
property = { ident ~ (WHITE_SPACE* ~ "." ~ WHITE_SPACE* ~ ident ~ WHITE_SPACE* ~ property_params? )+ }

unary_operator = { ("!"|"-") }

UNARY_OPERATION= { unary_operator ~ WHITE_SPACE* ~ ("("~VALUE~")"|UNARY_OPERATION|ARRAY_ACCESS|ARRAY|string|decimal|integer|null|boolean|property|fncall|ident) }

//binary operator cannot self-chain
BINARY_OPERATION = {
    (
        ("("~VALUE~")"|UNARY_OPERATION|ARRAY_ACCESS|ARRAY|string|decimal|integer|null|boolean|property|fncall|ident)
        ~ WHITE_SPACE* ~
        (
            WHITE_SPACE* ~
            (sum|sub|mul|div|rem|and|or|xor|slf|srg|eq|neq|gte|lte|gt|lt)
            ~ WHITE_SPACE* ~
            (
                "("~(UNARY_OPERATION|ARRAY_ACCESS|ARRAY|string|decimal|integer|null|boolean|property|fncall|ident)~")"
                |
                (UNARY_OPERATION|ARRAY_ACCESS|ARRAY|string|decimal|integer|null|boolean|property|fncall|ident)
                |
                "("~(BINARY_OPERATION)~")"
            )
        )+
    )
}

ARRAY_INDEX = { ASCII_DIGIT+ }
ARRAY_ACCESS = { ( ARRAY | ident | property|fncall ) ~ ("[" ~ ARRAY_INDEX ~ "]")+ }

VALUE = { "("~VALUE~")"|BINARY_OPERATION|UNARY_OPERATION|ARRAY_ACCESS|ARRAY|string|decimal|integer|null|boolean|property|fncall|ident }

PREDICATE = { VALUE }

ASSIGNMENT = { ("let" ~ WHITE_SPACE+)? ~ (property|ident) ~ WHITE_SPACE* ~ "=" ~ WHITE_SPACE* ~ VALUE }
IF_BLOCK = {
    "if" ~ WHITE_SPACE+ ~ PREDICATE ~ WHITE_SPACE* ~ "{" ~ STATEMENTS ~ "}"
    ~ ( WHITE_SPACE* ~ "else" ~ WHITE_SPACE* ~ "if" ~ WHITE_SPACE+ ~ PREDICATE ~ WHITE_SPACE* ~ "{" ~ STATEMENTS ~ "}")*
    ~ ( WHITE_SPACE* ~ "else" ~ WHITE_SPACE* ~ "{" ~ STATEMENTS ~ "}")?
    }
WHILE_BLOCK = { "while" ~ WHITE_SPACE+ ~ PREDICATE ~ WHITE_SPACE* ~ "{" ~ STATEMENTS ~ "}"}
RETURN_CALL = { "return" ~ WHITE_SPACE+ ~ VALUE  }

STATEMENTS = { (WHITE_SPACE* ~ (WHILE_BLOCK|IF_BLOCK|((ASSIGNMENT|RETURN_CALL|VALUE) ~ WHITE_SPACE* ~ ";"? )))* ~ WHITE_SPACE* }
BASE_STATEMENTS = { SOI ~ WHITE_SPACE* ~ STATEMENTS ~ WHITE_SPACE* ~ EOI  }


and = {"&&"}
or = {"||"}
xor = {"^"}
slf = {"<<"}
srg = {">>"}

sum = {"+"}
sub = {"-"}
mul = {"*"}
div = {"/"}
rem = {"%"}

eq = {"=="}
neq = {"!="}
gte = {">="}
lte = {"<="}
gt = {">"}
lt = {"<"}