Update grammar.
This commit is contained in:
parent
aa3f4b3a8b
commit
815168603c
163
src/ast/build.rs
163
src/ast/build.rs
@ -1,6 +1,6 @@
|
|||||||
use crate::ast::{
|
use crate::ast::{
|
||||||
BlockStatement, CompilationUnit, Declaration, Fqn, FunctionDeclaration, GenericArgument,
|
BlockStatement, CompilationUnit, Declaration, Fqn, FunctionDeclaration, GenericArgument,
|
||||||
GenericParameter, Identifier, ImplCtor, ImplCtorArg, Parameter, TypeDeclaration, TypeUse,
|
GenericParameter, Identifier, ClassConstructor, Parameter, TypeDeclaration, TypeUse,
|
||||||
};
|
};
|
||||||
use crate::parser::{DeimosParser, Rule};
|
use crate::parser::{DeimosParser, Rule};
|
||||||
use crate::vm::source_code_location::SourceCodeLocation;
|
use crate::vm::source_code_location::SourceCodeLocation;
|
||||||
@ -15,49 +15,6 @@ fn build_prop(prop_pair: Pair<Rule>) -> Declaration {
|
|||||||
todo!()
|
todo!()
|
||||||
}
|
}
|
||||||
|
|
||||||
fn build_impl_ctor_arg(impl_ctor_arg_pair: Pair<Rule>) -> ImplCtorArg {
|
|
||||||
let mut is_field = false;
|
|
||||||
let mut identifier: Option<Identifier> = None;
|
|
||||||
let mut r#type: Option<TypeUse> = None;
|
|
||||||
|
|
||||||
for pair in impl_ctor_arg_pair.into_inner() {
|
|
||||||
match pair.as_rule() {
|
|
||||||
Rule::fld => {
|
|
||||||
is_field = true;
|
|
||||||
}
|
|
||||||
Rule::identifier => {
|
|
||||||
identifier = Some(build_identifier(pair));
|
|
||||||
}
|
|
||||||
Rule::type_use => {
|
|
||||||
r#type = Some(build_type_use(pair));
|
|
||||||
}
|
|
||||||
_ => panic!("Unexpected rule: {}", pair),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
ImplCtorArg {
|
|
||||||
is_field,
|
|
||||||
identifier: identifier.unwrap(),
|
|
||||||
r#type,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
fn build_impl_ctor(impl_ctor_pair: Pair<Rule>) -> ImplCtor {
|
|
||||||
let impl_ctor_args_pair = impl_ctor_pair.into_inner().next().unwrap();
|
|
||||||
let mut args: Vec<ImplCtorArg> = vec![];
|
|
||||||
|
|
||||||
for pair in impl_ctor_args_pair.into_inner() {
|
|
||||||
match pair.as_rule() {
|
|
||||||
Rule::impl_ctor_arg => {
|
|
||||||
args.push(build_impl_ctor_arg(pair));
|
|
||||||
}
|
|
||||||
_ => panic!("Unexpected rule: {}", pair),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
ImplCtor { args }
|
|
||||||
}
|
|
||||||
|
|
||||||
fn build_generic_argument(generic_argument_pair: Pair<Rule>) -> GenericArgument {
|
fn build_generic_argument(generic_argument_pair: Pair<Rule>) -> GenericArgument {
|
||||||
let fqn_pair = generic_argument_pair.into_inner().next().unwrap();
|
let fqn_pair = generic_argument_pair.into_inner().next().unwrap();
|
||||||
GenericArgument {
|
GenericArgument {
|
||||||
@ -71,7 +28,7 @@ fn build_generic_arguments_declaration(
|
|||||||
let mut generic_arguments: Vec<GenericArgument> = vec![];
|
let mut generic_arguments: Vec<GenericArgument> = vec![];
|
||||||
for pair in generic_arguments_declaration_pair.into_inner() {
|
for pair in generic_arguments_declaration_pair.into_inner() {
|
||||||
match pair.as_rule() {
|
match pair.as_rule() {
|
||||||
Rule::generic_argument => {
|
Rule::GenericArguments => {
|
||||||
generic_arguments.push(build_generic_argument(pair));
|
generic_arguments.push(build_generic_argument(pair));
|
||||||
}
|
}
|
||||||
_ => panic!("Expected only generic_argument rules. Found: {}", pair),
|
_ => panic!("Expected only generic_argument rules. Found: {}", pair),
|
||||||
@ -94,10 +51,10 @@ fn build_type_use(type_pair: Pair<Rule>) -> TypeUse {
|
|||||||
|
|
||||||
for pair in type_pair.into_inner() {
|
for pair in type_pair.into_inner() {
|
||||||
match pair.as_rule() {
|
match pair.as_rule() {
|
||||||
Rule::fqn => {
|
Rule::FullyQualifiedName => {
|
||||||
fqn = Some(build_fqn(pair));
|
fqn = Some(build_fqn(pair));
|
||||||
}
|
}
|
||||||
Rule::generic_arguments_declaration => {
|
Rule::GenericArguments => {
|
||||||
generic_arguments_declaration = Some(build_generic_arguments_declaration(pair));
|
generic_arguments_declaration = Some(build_generic_arguments_declaration(pair));
|
||||||
}
|
}
|
||||||
_ => panic!(
|
_ => panic!(
|
||||||
@ -119,7 +76,7 @@ fn build_generic_parameters_declaration(
|
|||||||
let mut parameters: Vec<GenericParameter> = vec![];
|
let mut parameters: Vec<GenericParameter> = vec![];
|
||||||
for pair in generic_parameters_declaration_pair.into_inner() {
|
for pair in generic_parameters_declaration_pair.into_inner() {
|
||||||
match pair.as_rule() {
|
match pair.as_rule() {
|
||||||
Rule::generic_parameter => {
|
Rule::Identifier => {
|
||||||
parameters.push(build_generic_parameter(pair));
|
parameters.push(build_generic_parameter(pair));
|
||||||
}
|
}
|
||||||
_ => panic!("Expected only generic_parameter rule. Found: {}", pair),
|
_ => panic!("Expected only generic_parameter rule. Found: {}", pair),
|
||||||
@ -133,7 +90,7 @@ fn build_extends_list(extends_list_pair: Pair<Rule>) -> Vec<TypeUse> {
|
|||||||
|
|
||||||
for pair in extends_list_pair.into_inner() {
|
for pair in extends_list_pair.into_inner() {
|
||||||
match pair.as_rule() {
|
match pair.as_rule() {
|
||||||
Rule::type_use => {
|
Rule::TypeUse => {
|
||||||
extensions.push(build_type_use(pair));
|
extensions.push(build_type_use(pair));
|
||||||
}
|
}
|
||||||
_ => panic!("Expected only type rule. Found: {}", pair),
|
_ => panic!("Expected only type rule. Found: {}", pair),
|
||||||
@ -151,17 +108,17 @@ fn build_interface(is_extern: bool, is_public: bool, interface_pair: Pair<Rule>)
|
|||||||
|
|
||||||
for pair in interface_pair.into_inner() {
|
for pair in interface_pair.into_inner() {
|
||||||
match pair.as_rule() {
|
match pair.as_rule() {
|
||||||
Rule::identifier => {
|
Rule::Identifier => {
|
||||||
identifier = Some(build_identifier(pair));
|
identifier = Some(build_identifier(pair));
|
||||||
}
|
}
|
||||||
Rule::generic_parameters_declaration => {
|
Rule::GenericParameters => {
|
||||||
generic_parameters = Some(build_generic_parameters_declaration(pair));
|
generic_parameters = Some(build_generic_parameters_declaration(pair));
|
||||||
}
|
}
|
||||||
Rule::extends_list => {
|
Rule::ExtendsList => {
|
||||||
extends = Some(build_extends_list(pair));
|
extends = Some(build_extends_list(pair));
|
||||||
}
|
}
|
||||||
Rule::declaration => {
|
Rule::InterfaceLevelDeclaration => {
|
||||||
declarations.push(build_declaration(pair));
|
declarations.push(build_module_level_declaration(pair));
|
||||||
},
|
},
|
||||||
_ => panic!(
|
_ => panic!(
|
||||||
"Expected only identifier, generics_declaration, extends_list, or declaration rules. Found: {}",
|
"Expected only identifier, generics_declaration, extends_list, or declaration rules. Found: {}",
|
||||||
@ -182,6 +139,10 @@ fn build_interface(is_extern: bool, is_public: bool, interface_pair: Pair<Rule>)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn build_class_constructor(class_constructor_pair: Pair<Rule>) -> ClassConstructor {
|
||||||
|
todo!()
|
||||||
|
}
|
||||||
|
|
||||||
fn build_implementation(
|
fn build_implementation(
|
||||||
is_extern: bool,
|
is_extern: bool,
|
||||||
is_public: bool,
|
is_public: bool,
|
||||||
@ -189,26 +150,26 @@ fn build_implementation(
|
|||||||
) -> Declaration {
|
) -> Declaration {
|
||||||
let mut identifier: Option<Identifier> = None;
|
let mut identifier: Option<Identifier> = None;
|
||||||
let mut generic_parameters: Option<Vec<GenericParameter>> = None;
|
let mut generic_parameters: Option<Vec<GenericParameter>> = None;
|
||||||
let mut impl_ctor: Option<ImplCtor> = None;
|
let mut impl_ctor: Option<ClassConstructor> = None;
|
||||||
let mut extends: Option<Vec<TypeUse>> = None;
|
let mut extends: Option<Vec<TypeUse>> = None;
|
||||||
let mut declarations: Vec<Declaration> = vec![];
|
let mut declarations: Vec<Declaration> = vec![];
|
||||||
|
|
||||||
for pair in implementation_pair.into_inner() {
|
for pair in implementation_pair.into_inner() {
|
||||||
match pair.as_rule() {
|
match pair.as_rule() {
|
||||||
Rule::identifier => {
|
Rule::Identifier => {
|
||||||
identifier = Some(build_identifier(pair));
|
identifier = Some(build_identifier(pair));
|
||||||
}
|
}
|
||||||
Rule::generic_parameters_declaration => {
|
Rule::GenericParameters => {
|
||||||
generic_parameters = Some(build_generic_parameters_declaration(pair));
|
generic_parameters = Some(build_generic_parameters_declaration(pair));
|
||||||
}
|
}
|
||||||
Rule::impl_ctor => {
|
Rule::ClassConstructor => {
|
||||||
impl_ctor = Some(build_impl_ctor(pair));
|
impl_ctor = Some(build_class_constructor(pair));
|
||||||
}
|
}
|
||||||
Rule::extends_list => {
|
Rule::ExtendsList => {
|
||||||
extends = Some(build_extends_list(pair));
|
extends = Some(build_extends_list(pair));
|
||||||
}
|
}
|
||||||
Rule::declaration => {
|
Rule::ClassLevelDeclaration => {
|
||||||
declarations.push(build_declaration(pair));
|
declarations.push(build_module_level_declaration(pair));
|
||||||
}
|
}
|
||||||
_ => panic!("Unexpected rule: {}", pair),
|
_ => panic!("Unexpected rule: {}", pair),
|
||||||
}
|
}
|
||||||
@ -236,10 +197,10 @@ fn build_parameter(pair: Pair<Rule>) -> Parameter {
|
|||||||
let mut declared_type: Option<TypeUse> = None;
|
let mut declared_type: Option<TypeUse> = None;
|
||||||
for pair in pair.into_inner() {
|
for pair in pair.into_inner() {
|
||||||
match pair.as_rule() {
|
match pair.as_rule() {
|
||||||
Rule::identifier => {
|
Rule::Identifier => {
|
||||||
identifier = Some(build_identifier(pair));
|
identifier = Some(build_identifier(pair));
|
||||||
}
|
}
|
||||||
Rule::type_use => {
|
Rule::TypeAnnotation => {
|
||||||
declared_type = Some(build_type_use(pair));
|
declared_type = Some(build_type_use(pair));
|
||||||
}
|
}
|
||||||
_ => unreachable!(),
|
_ => unreachable!(),
|
||||||
@ -255,7 +216,7 @@ fn build_parameters_list(pair: Pair<Rule>) -> Vec<Parameter> {
|
|||||||
let mut parameters: Vec<Parameter> = vec![];
|
let mut parameters: Vec<Parameter> = vec![];
|
||||||
for pair in pair.into_inner() {
|
for pair in pair.into_inner() {
|
||||||
match pair.as_rule() {
|
match pair.as_rule() {
|
||||||
Rule::parameter => {
|
Rule::Parameter => {
|
||||||
parameters.push(build_parameter(pair));
|
parameters.push(build_parameter(pair));
|
||||||
}
|
}
|
||||||
_ => unreachable!(),
|
_ => unreachable!(),
|
||||||
@ -264,7 +225,7 @@ fn build_parameters_list(pair: Pair<Rule>) -> Vec<Parameter> {
|
|||||||
parameters
|
parameters
|
||||||
}
|
}
|
||||||
|
|
||||||
fn build_function_body(pair: Pair<Rule>) -> BlockStatement {
|
fn build_block_statement(pair: Pair<Rule>) -> BlockStatement {
|
||||||
todo!()
|
todo!()
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -273,6 +234,7 @@ fn build_function_equals_body(pair: Pair<Rule>) -> BlockStatement {
|
|||||||
}
|
}
|
||||||
|
|
||||||
fn build_function(is_extern: bool, is_public: bool, pair: Pair<Rule>) -> Declaration {
|
fn build_function(is_extern: bool, is_public: bool, pair: Pair<Rule>) -> Declaration {
|
||||||
|
let mut is_implementation = false;
|
||||||
let mut generic_parameters: Option<Vec<GenericParameter>> = None;
|
let mut generic_parameters: Option<Vec<GenericParameter>> = None;
|
||||||
let mut identifier: Option<Identifier> = None;
|
let mut identifier: Option<Identifier> = None;
|
||||||
let mut parameters: Option<Vec<Parameter>> = None;
|
let mut parameters: Option<Vec<Parameter>> = None;
|
||||||
@ -283,22 +245,25 @@ fn build_function(is_extern: bool, is_public: bool, pair: Pair<Rule>) -> Declara
|
|||||||
|
|
||||||
for pair in pair.into_inner() {
|
for pair in pair.into_inner() {
|
||||||
match pair.as_rule() {
|
match pair.as_rule() {
|
||||||
Rule::generic_parameters_declaration => {
|
Rule::Implementation => {
|
||||||
generic_parameters = Some(build_generic_parameters_declaration(pair));
|
is_implementation = true;
|
||||||
}
|
}
|
||||||
Rule::identifier => {
|
Rule::Identifier => {
|
||||||
identifier = Some(build_identifier(pair));
|
identifier = Some(build_identifier(pair));
|
||||||
}
|
}
|
||||||
Rule::parameters_list => {
|
Rule::GenericParameters => {
|
||||||
|
generic_parameters = Some(build_generic_parameters_declaration(pair));
|
||||||
|
}
|
||||||
|
Rule::Parameters => {
|
||||||
parameters = Some(build_parameters_list(pair));
|
parameters = Some(build_parameters_list(pair));
|
||||||
}
|
}
|
||||||
Rule::type_use => {
|
Rule::TypeUse => {
|
||||||
return_type = Some(build_type_use(pair));
|
return_type = Some(build_type_use(pair));
|
||||||
}
|
}
|
||||||
Rule::function_body => {
|
Rule::BlockStatement => {
|
||||||
statement = Some(build_function_body(pair));
|
statement = Some(build_block_statement(pair));
|
||||||
}
|
}
|
||||||
Rule::function_equals_body => {
|
Rule::FunctionEqualsBody => {
|
||||||
statement = Some(build_function_equals_body(pair));
|
statement = Some(build_function_equals_body(pair));
|
||||||
}
|
}
|
||||||
_ => unreachable!(),
|
_ => unreachable!(),
|
||||||
@ -320,41 +285,32 @@ fn build_function(is_extern: bool, is_public: bool, pair: Pair<Rule>) -> Declara
|
|||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
fn build_declaration(declaration_pair: Pair<Rule>) -> Declaration {
|
fn build_module_level_declaration(declaration_pair: Pair<Rule>) -> Declaration {
|
||||||
let mut is_extern = false;
|
let mut is_extern = false;
|
||||||
let mut is_public = false;
|
let mut is_public = false;
|
||||||
let mut declaration: Option<Declaration> = None;
|
let mut declaration: Option<Declaration> = None;
|
||||||
|
|
||||||
for pair in declaration_pair.into_inner() {
|
for pair in declaration_pair.into_inner() {
|
||||||
match pair.as_rule() {
|
match pair.as_rule() {
|
||||||
Rule::r#extern => {
|
Rule::Declare => {
|
||||||
is_extern = true;
|
is_extern = true;
|
||||||
}
|
}
|
||||||
Rule::r#pub => {
|
Rule::Public => {
|
||||||
is_public = true;
|
is_public = true;
|
||||||
}
|
}
|
||||||
Rule::interface => {
|
Rule::Interface => {
|
||||||
declaration = Some(build_interface(is_extern, is_public, pair));
|
declaration = Some(build_interface(is_extern, is_public, pair));
|
||||||
}
|
}
|
||||||
Rule::implementation => {
|
Rule::Implementation => {
|
||||||
declaration = Some(build_implementation(is_extern, is_public, pair));
|
declaration = Some(build_implementation(is_extern, is_public, pair));
|
||||||
}
|
}
|
||||||
Rule::module => {
|
Rule::Module => {
|
||||||
declaration = Some(build_module(is_extern, is_public, pair));
|
declaration = Some(build_module(is_extern, is_public, pair));
|
||||||
}
|
}
|
||||||
Rule::function => {
|
Rule::Function => {
|
||||||
declaration = Some(build_function(is_extern, is_public, pair));
|
declaration = Some(build_function(is_extern, is_public, pair));
|
||||||
}
|
}
|
||||||
Rule::prop => {
|
_ => unreachable!(),
|
||||||
declaration = Some(build_prop(pair));
|
|
||||||
}
|
|
||||||
Rule::field => {
|
|
||||||
declaration = Some(build_field(pair));
|
|
||||||
}
|
|
||||||
_ => panic!(
|
|
||||||
"Expected only interface, implementation, module, or function rules; found {}",
|
|
||||||
pair
|
|
||||||
),
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
declaration.expect("Expected declaration.")
|
declaration.expect("Expected declaration.")
|
||||||
@ -362,10 +318,10 @@ fn build_declaration(declaration_pair: Pair<Rule>) -> Declaration {
|
|||||||
|
|
||||||
fn build_identifier(pair: Pair<Rule>) -> Identifier {
|
fn build_identifier(pair: Pair<Rule>) -> Identifier {
|
||||||
match pair.as_rule() {
|
match pair.as_rule() {
|
||||||
Rule::identifier => Identifier {
|
Rule::Identifier => Identifier {
|
||||||
name: String::from(pair.as_str()),
|
name: String::from(pair.as_str()),
|
||||||
},
|
},
|
||||||
_ => panic!("Expected an identifier."),
|
_ => unreachable!(),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -373,10 +329,10 @@ fn build_fqn(fqn_pair: Pair<Rule>) -> Fqn {
|
|||||||
let mut identifiers: Vec<Identifier> = vec![];
|
let mut identifiers: Vec<Identifier> = vec![];
|
||||||
for pair in fqn_pair.into_inner() {
|
for pair in fqn_pair.into_inner() {
|
||||||
match pair.as_rule() {
|
match pair.as_rule() {
|
||||||
Rule::identifier => {
|
Rule::Identifier => {
|
||||||
identifiers.push(build_identifier(pair));
|
identifiers.push(build_identifier(pair));
|
||||||
}
|
}
|
||||||
_ => panic!("Expected only identifiers."),
|
_ => unreachable!(),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Fqn { identifiers }
|
Fqn { identifiers }
|
||||||
@ -388,18 +344,15 @@ fn build_compilation_unit(pair: Pair<Rule>) -> CompilationUnit {
|
|||||||
|
|
||||||
for pair in pair.into_inner() {
|
for pair in pair.into_inner() {
|
||||||
match pair.as_rule() {
|
match pair.as_rule() {
|
||||||
Rule::namespace => {
|
Rule::Namespace => {
|
||||||
let fqn_pair = pair.into_inner().next().unwrap();
|
let fqn_pair = pair.into_inner().next().unwrap();
|
||||||
namespace = Some(build_fqn(fqn_pair));
|
namespace = Some(build_fqn(fqn_pair));
|
||||||
}
|
}
|
||||||
Rule::declaration => {
|
Rule::ModuleLevelDeclaration => {
|
||||||
declarations.push(build_declaration(pair));
|
declarations.push(build_module_level_declaration(pair));
|
||||||
}
|
}
|
||||||
Rule::EOI => {} // ignore
|
Rule::EOI => {} // ignore
|
||||||
_ => panic!(
|
_ => unreachable!(),
|
||||||
"Expected only namespace, declaration, or EOI rules, found: {}",
|
|
||||||
pair
|
|
||||||
),
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -410,12 +363,12 @@ fn build_compilation_unit(pair: Pair<Rule>) -> CompilationUnit {
|
|||||||
}
|
}
|
||||||
|
|
||||||
pub fn build_ast(src: &str) -> CompilationUnit {
|
pub fn build_ast(src: &str) -> CompilationUnit {
|
||||||
let pair = DeimosParser::parse(Rule::compilation_unit, src)
|
let pair = DeimosParser::parse(Rule::CompilationUnit, src)
|
||||||
.expect("Unsuccessful parse.")
|
.expect("Unsuccessful parse.")
|
||||||
.next()
|
.next()
|
||||||
.expect("Expcted compilation_unit.");
|
.expect("Expected compilation_unit.");
|
||||||
match pair.as_rule() {
|
match pair.as_rule() {
|
||||||
Rule::compilation_unit => build_compilation_unit(pair),
|
Rule::CompilationUnit => build_compilation_unit(pair),
|
||||||
_ => panic!("Expected compilation_unit rule."),
|
_ => panic!("Expected compilation_unit rule."),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -55,7 +55,7 @@ pub enum Declaration {
|
|||||||
is_extern: bool,
|
is_extern: bool,
|
||||||
is_public: bool,
|
is_public: bool,
|
||||||
type_declaration: TypeDeclaration,
|
type_declaration: TypeDeclaration,
|
||||||
impl_ctor: Option<ImplCtor>,
|
impl_ctor: Option<ClassConstructor>,
|
||||||
},
|
},
|
||||||
Module {
|
Module {
|
||||||
identifier: Identifier,
|
identifier: Identifier,
|
||||||
@ -149,8 +149,31 @@ pub struct TypeUse {
|
|||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
pub struct ImplCtor {
|
pub struct ClassConstructor {
|
||||||
args: Vec<ImplCtorArg>,
|
args: Vec<ClassMember>,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl ClassConstructor {
|
||||||
|
pub fn new(args: Vec<ClassMember>) -> Self {
|
||||||
|
ClassConstructor { args }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Debug)]
|
||||||
|
pub struct ClassMember {
|
||||||
|
is_field: bool,
|
||||||
|
identifier: Identifier,
|
||||||
|
type_use: Option<TypeUse>
|
||||||
|
}
|
||||||
|
|
||||||
|
impl ClassMember {
|
||||||
|
pub fn new(is_field: bool, identifier: Identifier, type_use: Option<TypeUse>) -> Self {
|
||||||
|
ClassMember {
|
||||||
|
is_field,
|
||||||
|
identifier,
|
||||||
|
type_use
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
|
@ -1,68 +1,102 @@
|
|||||||
compilation_unit = { SOI ~ namespace? ~ declaration* ~ EOI }
|
// Top-level constructs
|
||||||
namespace = { "ns" ~ fqn }
|
CompilationUnit = { SOI ~ Namespace? ~ ModuleLevelDeclaration* ~ EOI }
|
||||||
|
Namespace = { "ns" ~ FullyQualifiedName }
|
||||||
|
|
||||||
fqn = { identifier ~ ( "::" ~ identifier )* }
|
CommonDeclaration = { Interface | Class | Module | Function }
|
||||||
identifier = @{ identifier_start_char ~ identifier_char* }
|
ModuleLevelDeclaration = { Declare? ~ Public? ~ CommonDeclaration }
|
||||||
identifier_start_char = { 'a'..'z' | 'A'..'Z' | "_" }
|
InterfaceLevelDeclaration = { CommonDeclaration }
|
||||||
identifier_char = { 'a'..'z' | 'A'..'Z' | '0'..'9' | "_" }
|
ClassLevelDeclaration = { Declare? ~ Public? ~ ( CommonDeclaration | ClassMember ) }
|
||||||
|
|
||||||
declaration = { extern? ~ pub? ~ ( interface | implementation | module | function | prop | field ) }
|
// Module
|
||||||
extern = { "extern" }
|
Module = { "mod" ~ Identifier ~ "{" ~ ModuleLevelDeclaration* ~ "}" }
|
||||||
pub = { "pub" }
|
|
||||||
|
|
||||||
interface = { "int" ~ identifier ~ generic_parameters_declaration? ~ extends_list? ~ ( "{" ~ declaration* ~ "}" )? }
|
// Interface
|
||||||
extends_list = { ":" ~ type_use ~ ( "+" ~ type_use )* }
|
Interface = { "int" ~ Identifier ~ GenericParameters? ~ ExtendsList? ~ ( "{" ~ InterfaceLevelDeclaration* ~ "}" )? }
|
||||||
|
|
||||||
implementation = { "impl" ~ identifier ~ generic_parameters_declaration? ~ impl_ctor? ~ extends_list? ~ ( "{" ~ declaration* ~ "}" )? }
|
// Class
|
||||||
impl_ctor = { "(" ~ impl_ctor_args? ~ ")" }
|
Class = { "class" ~ Identifier ~ GenericParameters? ~ ClassConstructor? ~ ExtendsList? ~ ( "{" ~ ClassLevelDeclaration* ~ "}" )? }
|
||||||
impl_ctor_args = { impl_ctor_arg ~ ( "," ~ impl_ctor_arg )* }
|
ClassMember = { Field? ~ Identifier ~ TypeAnnotation? }
|
||||||
impl_ctor_arg = { fld? ~ identifier ~ ( ":" ~ type_use )? }
|
|
||||||
fld = { "fld" }
|
|
||||||
|
|
||||||
module = { "mod" ~ identifier ~ "{" ~ declaration* ~ "}" }
|
// Class Constructor
|
||||||
|
ClassConstructor = { "(" ~ ClassMemberList? ~ ")" }
|
||||||
|
ClassMemberList = { ClassMember ~ ( "," ~ ClassMember )* }
|
||||||
|
|
||||||
property = { identifier ~ ( ":" ~ type_use )? }
|
// Various Keywords
|
||||||
|
Declare = { "decl" }
|
||||||
|
Public = { "pub" }
|
||||||
|
Field = { "fld" }
|
||||||
|
Implementation = { "impl" }
|
||||||
|
Mutable = { "mut" }
|
||||||
|
|
||||||
function = { "fn" ~ generic_parameters_declaration? ~ identifier ~ "(" ~ parameters_list? ~ ")" ~ ( ":" ~ type_use )? ~ ( function_body | function_equals_body ) }
|
// Fqn and identifier
|
||||||
function_equals_body = { "=" ~ expression }
|
FullyQualifiedName = { Identifier ~ ( "::" ~ Identifier )* }
|
||||||
function_body = { "{" ~ statement* ~ "}" }
|
|
||||||
|
|
||||||
type_use = { fqn ~ generic_arguments_declaration? }
|
Identifier = @{ IdentifierStartChar ~ IdentifierChar* }
|
||||||
generic_parameters_declaration = { "<" ~ generic_parameter ~ ( "," ~ generic_parameter )* ~ ">" }
|
IdentifierStartChar = { 'a'..'z' | 'A'..'Z' | "_" }
|
||||||
generic_parameter = { identifier }
|
IdentifierChar = { 'a'..'z' | 'A'..'Z' | '0'..'9' | "_" }
|
||||||
|
|
||||||
generic_arguments_declaration = { "<" ~ generic_argument ~ ( "," ~ generic_argument )* ~ ">" }
|
// Type constructs
|
||||||
generic_argument = { fqn }
|
ExtendsList = { ":" ~ TypeUse ~ ( "+" ~ TypeUse )* }
|
||||||
|
TypeAnnotation = { ":" ~ TypeUse }
|
||||||
|
TypeUse = { FullyQualifiedName ~ GenericArguments? }
|
||||||
|
|
||||||
parameters_list = { parameter ~ ( "," ~ parameter )* }
|
// Generic arguments given to a TypeUse or function calls
|
||||||
parameter = { identifier ~ ( ":" ~ "..."? ~ type_use )? }
|
GenericArguments = { "<" ~ FullyQualifiedName ~ ( "," ~ FullyQualifiedName )* ~ ">" }
|
||||||
|
|
||||||
prop = { identifier ~ ":" ~ type_use }
|
// Generic parameters (for when types are declared)
|
||||||
field = { fld ~ identifier ~ ":" ~ type_use }
|
GenericParameters = { "<" ~ Identifier ~ ( "," ~ Identifier )* ~ ">" }
|
||||||
|
|
||||||
statement = { call_stmt }
|
// Function
|
||||||
|
Function = { Implementation?
|
||||||
|
~ "fn"
|
||||||
|
~ Identifier
|
||||||
|
~ GenericParameters?
|
||||||
|
~ "(" ~ Parameters? ~ ")"
|
||||||
|
~ TypeAnnotation? ~ ( FunctionEqualsBody | BlockStatement )
|
||||||
|
}
|
||||||
|
|
||||||
call_stmt = { call_expr }
|
Parameters = { Parameter ~ ( "," ~ Parameter )* }
|
||||||
|
Parameter = { Identifier ~ TypeAnnotation? }
|
||||||
|
|
||||||
call_expr = { call_expr_with_parens | call_expr_no_parens }
|
FunctionEqualsBody = { "=" ~ Expression }
|
||||||
call_expr_with_parens = { fqn ~ "(" ~ call_args? ~ ")" }
|
|
||||||
call_expr_no_parens = { fqn ~ call_args }
|
|
||||||
call_args = { call_arg ~ ( "," ~ call_arg )* }
|
|
||||||
call_arg = { expression }
|
|
||||||
|
|
||||||
expression = { literal | identifier }
|
// Statements
|
||||||
|
BlockStatement = { "{" ~ Statement* ~ "}" }
|
||||||
|
Statement = { VariableDeclaration | CallExpression | AssignmentExpression }
|
||||||
|
|
||||||
literal = { number_literal | string_literal }
|
VariableDeclaration = { "let" ~ Mutable? ~ Identifier ~ TypeAnnotation? ~ ( "=" ~ Expression )? }
|
||||||
|
|
||||||
number_literal = { int_literal }
|
// Expressions
|
||||||
int_literal = { '0'..'9'+ }
|
Expression = { CallExpression | AssignmentExpression | Literal | FullyQualifiedName }
|
||||||
|
ExpressionList = { Expression ~ ( "," ~ Expression )* }
|
||||||
|
|
||||||
string_literal = ${ "\"" ~ string_inner ~ "\"" }
|
// Calls
|
||||||
string_inner = @{ string_char* }
|
CallExpression = { FullyQualifiedName ~ GenericArguments ~ CallArguments }
|
||||||
string_char = {
|
CallArguments = {
|
||||||
|
( "(" ~ ExpressionList? ~")")
|
||||||
|
| ExpressionList
|
||||||
|
}
|
||||||
|
|
||||||
|
// Assignment
|
||||||
|
AssignmentExpression = { FullyQualifiedName ~ "=" ~ Expression }
|
||||||
|
|
||||||
|
// Literals
|
||||||
|
Literal = { NumberLiteral | StringLiteral | BooleanLiteral | NullLiteral }
|
||||||
|
|
||||||
|
NumberLiteral = { IntLiteral }
|
||||||
|
IntLiteral = { '0'..'9'+ }
|
||||||
|
LongLiteral = { '0'..'9'+ ~ "L" }
|
||||||
|
|
||||||
|
StringLiteral = ${ "\"" ~ StringInner ~ "\"" }
|
||||||
|
StringInner = @{ StringChar* }
|
||||||
|
StringChar = {
|
||||||
!( "\"" | "\\" ) ~ ANY
|
!( "\"" | "\\" ) ~ ANY
|
||||||
| "\\" ~ ( "\"" | "\\" | "/" | "b" | "f" | "n" | "r" | "t" )
|
| "\\" ~ ( "\"" | "\\" | "/" | "b" | "f" | "n" | "r" | "t" )
|
||||||
| "\\" ~ ( "u" ~ ASCII_HEX_DIGIT{4} )
|
| "\\" ~ ( "u" ~ ASCII_HEX_DIGIT{4} )
|
||||||
}
|
}
|
||||||
|
|
||||||
|
BooleanLiteral = { "true" | "false" }
|
||||||
|
|
||||||
|
NullLiteral = { "null" }
|
||||||
|
|
||||||
WHITESPACE = _{ " " | "\t" | "\n" | "\r" }
|
WHITESPACE = _{ " " | "\t" | "\n" | "\r" }
|
||||||
|
Loading…
Reference in New Issue
Block a user