Backus-Naur form
<program> ::= <comment_block>* <import_block>? <variable_declaration>* <function_block>*
<comment_block> ::= "%%" <comment_content> "%%"
<comment_content> ::= (%any_character% | "\n")*
<import_block> ::= "import" <string_literal>
<function_block> ::= <function_signature> "=" (<identifier> (" " <identifier>)*)? <block>
<function_signature> ::= <identifier> ":" <type>* "->" <type>
<type_definition> ::= <identifier> "::" <type>
<type> ::= "int" | "double" | "float" | "char" | "byte" | "never" | "bool" | "*"<type> | "struct" "{" <struct_field>* "}" | <type>* "->" <type> | <user_defined_type>
<struct_field> ::= <identifier> "->" <type>
<user_defined_type> ::= <identifier>
<statement> ::= <variable_declaration> | <loop> | <for_loop> | <if_statement> | <function_call> | <expression> | <return_statement>
<variable_declaration> ::= <identifier> ":" <type> "=" <expression>
<expression> ::= <literal>
| <binary_expression>
| <unary_expression>
| <function_call>
| <type_conversion>
| <array_access>
| <struct_access>
| <assignment>
<literal> ::= <int_literal> | <float_literal> | <array_literal> | <byte_literal> | <bool_literal> | <struct_literal>
<int_literal> ::= [0-9]+
<float_literal> ::= [0-9]+ "," [0-9]+
<byte_literal> ::= "'%any_printable_character%'"
<bool_literal> ::= "true" | "false"
<array_literal> ::= <string_literal> | <literal_array_literal>
<string_literal> ::= '"' <string_characters> '"'
<struct_literal> :: = <identifier> "{" <field_list> "}"
<field_list> ::= <field> (" " <field>)*
<field> ::= <identifier> "=" <literal>
<string_characters> ::= (%any_printable_character% - '"')*
<literal_array_literal> ::= "[" <expression> (" " <expression>)* "]"
<binary_expression> ::= <expression> <binary_operator> <expression>
<binary_operator> ::= "*" | "/" | "mod"
| "+" | "-"
| "&" | "|" | "^" | "<<" | ">>"
| "==" | "is" | "!=" | "<=" | ">=" | "<" | ">"
| "and" | "or"
<unary_expression> ::= <prefix_operator> <expression> | <expression> <postfix_operator>
<prefix_operator> ::= "!" | "not" | "~" | "++" | "--"
<postfix_operator> ::= "++" | "--" | ".*" | ".&"
<type_conversion> ::= "@<type>" "(" <expression> ")"
<array_access> ::= <identifier> ".#" "(" <expression> ")"
<struct_access> ::= <identifier> "." <identifier>
<assignment> ::= <identifier> "=" <expression>
<loop> ::= "loop" "(" <expression> ")" <block>
<for_loop> ::= "from" <expression> "to" <expression> "by" <expression> "|" <identifier> ":" <type> "|" <block>
<if_statement> ::= "if" <expression> <block> <else_clause>?
<else_clause> ::= "else" <block>
<block> ::= "{" <statement>* "}"
<function_call> ::= <identifier> "(" (<expression> (" " <expression>)*)? ")"
<return_statement> ::= "ret" <expression> | <expression>
<identifier> ::= [a-zA-Z_$][a-zA-Z0-9_$]*
Details on the BNF
Program Structure
A Frost program consists of the following components:
<comment_block>
: Comments enclosed in%%
markers. These are ignored by the parser and provide documentation or notes.<import_block>
: Statements to import external modules or dependencies.<function_block>
: Function definitions that include the function signature, optional arguments, and a block of statements.
Example:
%%
This is a comment block.
It provides information about the code.
%%
import "std/io.ff"
main: never -> int = {
% Main function implementation
}
Include Statements
You can include external modules using import
statements:
<import_block>
: Specifies the inclusion of an external module.<string_literal>
: The name of the module, enclosed in quotes.
Example:
import "std/io.ff"
Functions
Functions in Frost are defined as follows:
<function_block>
: A function definition that includes:<function_signature>
: Declares the function name, parameter types, and return type.Optional arguments: A space-separated list of parameter names.
<block>
: A code block containing the function's statements.
<function_signature>
: Specifies the name, parameter types, and return type of the function.<identifier>
: The name of the function or its parameters.
Example:
sum: int int -> int = a b {
ret a + b
}
Data Types
Frost supports a variety of data types, including primitives, pointers, and composite types:
<type>
:Primitive types:
int
,float
,double
,char
,byte
,bool
,never
.Pointer types: Denoted as
*<type>
.Struct types: Defined using
struct
with fields.User-defined types: Custom types defined by the user.
<struct_field>
: Fields in a struct, defined as<identifier> -> <type>
.
Example:
personType :: struct {
name -> char
age -> int
}
Statements
A Frost program consists of individual statements that define the program's behavior. These include:
<variable_declaration>
: Declares and initializes variables.<loop>
: Iterative constructs.<if_statement>
: Conditional constructs.<function_call>
: Calls to functions.<expression>
: Mathematical, logical, or function-related expressions.<return_statement>
: Specifies the value returned by a function.
Example:
SET_WIDTH: int = 100
if x < 10 {
ret x * 2
} else {
ret x + 2
}
Expressions
Expressions in Frost represent calculations, operations, or data manipulation. They include:
<literal>
: Constants like numbers, strings, booleans, or null.<binary_expression>
: Expressions involving binary operators (e.g.,a + b
).<unary_expression>
: Expressions with prefix or postfix operators.<function_call>
: Invocations of functions.<type_conversion>
: Explicit type conversions.<array_access>
: Accessing elements of arrays.<struct_access>
: Accessing fields of structs.<assignment>
: Assigning values to variables.
Example:
char_index = iter * CHARSET_LENGTH / MAX_ITER
value: int = arr.#(index)
Literals
Literals represent fixed values in Frost, such as numbers, strings, and booleans:
<int_literal>
: Integer values, e.g.,42
.<float_literal>
: Floating-point values, e.g.,3.14
.<byte_literal>
: A single byte enclosed in single quotes, e.g.,'A'
.<bool_literal>
: Boolean values,true
orfalse
.<array_literal>
: Arrays of literals or strings.<string_literal>
: Strings enclosed in double quotes.<literal_array_literal>
: Arrays enclosed in square brackets.
Example:
42 % Integer
3,14 % Float
'A' % Byte
true % Boolean
"hello" % String
[1 2 3] % Array
Control Flow
Control flow constructs allow conditional and iterative execution:
<if_statement>
: Conditional statements with optionalelse
clauses.<loop>
: Repeatedly executes a block of code while a condition holds true.<for_loop>
: Structured iteration over a range with a specific step size. Following the format:from
<start>
to<end>
by<step>
: Specifies the range and step size.|<var>: <type>|
: Declares the loop variable and its type.<block>
: Contains the statements executed in each iteration.
Example:
if x > 0 {
ret x
} else {
ret -x
}
loop (i < 10) {
i = i + 1
}
from 0 to SET_HEIGHT by 1 |y: int| {
from 0 to SET_WIDTH by 1 |x: int| {
sine_value: double = amplitude * sin(frequency * @double(x) / @double(SET_WIDTH) * 2,0 * M_PI + phase)
scaled_y: int = SET_HEIGHT / 2 - @int(sine_value * @double(SET_HEIGHT) / (2,0 * amplitude))
if y is scaled_y {
printf("\x1b[%d;%dH*" y x)
}
}
printf("\n" 0)
}
Comments
Comments in Frost are enclosed in %%
markers. They are ignored by the parser and provide documentation for the code.
Example:
%%
% This function calculates the sum of two numbers.
%%
add: int int -> int = num1 num2 {
ret num1 + num2
}
Last updated