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::{
|
||||
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::vm::source_code_location::SourceCodeLocation;
|
||||
@ -15,49 +15,6 @@ fn build_prop(prop_pair: Pair<Rule>) -> Declaration {
|
||||
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 {
|
||||
let fqn_pair = generic_argument_pair.into_inner().next().unwrap();
|
||||
GenericArgument {
|
||||
@ -71,7 +28,7 @@ fn build_generic_arguments_declaration(
|
||||
let mut generic_arguments: Vec<GenericArgument> = vec![];
|
||||
for pair in generic_arguments_declaration_pair.into_inner() {
|
||||
match pair.as_rule() {
|
||||
Rule::generic_argument => {
|
||||
Rule::GenericArguments => {
|
||||
generic_arguments.push(build_generic_argument(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() {
|
||||
match pair.as_rule() {
|
||||
Rule::fqn => {
|
||||
Rule::FullyQualifiedName => {
|
||||
fqn = Some(build_fqn(pair));
|
||||
}
|
||||
Rule::generic_arguments_declaration => {
|
||||
Rule::GenericArguments => {
|
||||
generic_arguments_declaration = Some(build_generic_arguments_declaration(pair));
|
||||
}
|
||||
_ => panic!(
|
||||
@ -119,7 +76,7 @@ fn build_generic_parameters_declaration(
|
||||
let mut parameters: Vec<GenericParameter> = vec![];
|
||||
for pair in generic_parameters_declaration_pair.into_inner() {
|
||||
match pair.as_rule() {
|
||||
Rule::generic_parameter => {
|
||||
Rule::Identifier => {
|
||||
parameters.push(build_generic_parameter(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() {
|
||||
match pair.as_rule() {
|
||||
Rule::type_use => {
|
||||
Rule::TypeUse => {
|
||||
extensions.push(build_type_use(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() {
|
||||
match pair.as_rule() {
|
||||
Rule::identifier => {
|
||||
Rule::Identifier => {
|
||||
identifier = Some(build_identifier(pair));
|
||||
}
|
||||
Rule::generic_parameters_declaration => {
|
||||
Rule::GenericParameters => {
|
||||
generic_parameters = Some(build_generic_parameters_declaration(pair));
|
||||
}
|
||||
Rule::extends_list => {
|
||||
Rule::ExtendsList => {
|
||||
extends = Some(build_extends_list(pair));
|
||||
}
|
||||
Rule::declaration => {
|
||||
declarations.push(build_declaration(pair));
|
||||
Rule::InterfaceLevelDeclaration => {
|
||||
declarations.push(build_module_level_declaration(pair));
|
||||
},
|
||||
_ => panic!(
|
||||
"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(
|
||||
is_extern: bool,
|
||||
is_public: bool,
|
||||
@ -189,26 +150,26 @@ fn build_implementation(
|
||||
) -> Declaration {
|
||||
let mut identifier: Option<Identifier> = 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 declarations: Vec<Declaration> = vec![];
|
||||
|
||||
for pair in implementation_pair.into_inner() {
|
||||
match pair.as_rule() {
|
||||
Rule::identifier => {
|
||||
Rule::Identifier => {
|
||||
identifier = Some(build_identifier(pair));
|
||||
}
|
||||
Rule::generic_parameters_declaration => {
|
||||
Rule::GenericParameters => {
|
||||
generic_parameters = Some(build_generic_parameters_declaration(pair));
|
||||
}
|
||||
Rule::impl_ctor => {
|
||||
impl_ctor = Some(build_impl_ctor(pair));
|
||||
Rule::ClassConstructor => {
|
||||
impl_ctor = Some(build_class_constructor(pair));
|
||||
}
|
||||
Rule::extends_list => {
|
||||
Rule::ExtendsList => {
|
||||
extends = Some(build_extends_list(pair));
|
||||
}
|
||||
Rule::declaration => {
|
||||
declarations.push(build_declaration(pair));
|
||||
Rule::ClassLevelDeclaration => {
|
||||
declarations.push(build_module_level_declaration(pair));
|
||||
}
|
||||
_ => panic!("Unexpected rule: {}", pair),
|
||||
}
|
||||
@ -236,10 +197,10 @@ fn build_parameter(pair: Pair<Rule>) -> Parameter {
|
||||
let mut declared_type: Option<TypeUse> = None;
|
||||
for pair in pair.into_inner() {
|
||||
match pair.as_rule() {
|
||||
Rule::identifier => {
|
||||
Rule::Identifier => {
|
||||
identifier = Some(build_identifier(pair));
|
||||
}
|
||||
Rule::type_use => {
|
||||
Rule::TypeAnnotation => {
|
||||
declared_type = Some(build_type_use(pair));
|
||||
}
|
||||
_ => unreachable!(),
|
||||
@ -255,7 +216,7 @@ fn build_parameters_list(pair: Pair<Rule>) -> Vec<Parameter> {
|
||||
let mut parameters: Vec<Parameter> = vec![];
|
||||
for pair in pair.into_inner() {
|
||||
match pair.as_rule() {
|
||||
Rule::parameter => {
|
||||
Rule::Parameter => {
|
||||
parameters.push(build_parameter(pair));
|
||||
}
|
||||
_ => unreachable!(),
|
||||
@ -264,7 +225,7 @@ fn build_parameters_list(pair: Pair<Rule>) -> Vec<Parameter> {
|
||||
parameters
|
||||
}
|
||||
|
||||
fn build_function_body(pair: Pair<Rule>) -> BlockStatement {
|
||||
fn build_block_statement(pair: Pair<Rule>) -> BlockStatement {
|
||||
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 {
|
||||
let mut is_implementation = false;
|
||||
let mut generic_parameters: Option<Vec<GenericParameter>> = None;
|
||||
let mut identifier: Option<Identifier> = 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() {
|
||||
match pair.as_rule() {
|
||||
Rule::generic_parameters_declaration => {
|
||||
generic_parameters = Some(build_generic_parameters_declaration(pair));
|
||||
Rule::Implementation => {
|
||||
is_implementation = true;
|
||||
}
|
||||
Rule::identifier => {
|
||||
Rule::Identifier => {
|
||||
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));
|
||||
}
|
||||
Rule::type_use => {
|
||||
Rule::TypeUse => {
|
||||
return_type = Some(build_type_use(pair));
|
||||
}
|
||||
Rule::function_body => {
|
||||
statement = Some(build_function_body(pair));
|
||||
Rule::BlockStatement => {
|
||||
statement = Some(build_block_statement(pair));
|
||||
}
|
||||
Rule::function_equals_body => {
|
||||
Rule::FunctionEqualsBody => {
|
||||
statement = Some(build_function_equals_body(pair));
|
||||
}
|
||||
_ => 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_public = false;
|
||||
let mut declaration: Option<Declaration> = None;
|
||||
|
||||
for pair in declaration_pair.into_inner() {
|
||||
match pair.as_rule() {
|
||||
Rule::r#extern => {
|
||||
Rule::Declare => {
|
||||
is_extern = true;
|
||||
}
|
||||
Rule::r#pub => {
|
||||
Rule::Public => {
|
||||
is_public = true;
|
||||
}
|
||||
Rule::interface => {
|
||||
Rule::Interface => {
|
||||
declaration = Some(build_interface(is_extern, is_public, pair));
|
||||
}
|
||||
Rule::implementation => {
|
||||
Rule::Implementation => {
|
||||
declaration = Some(build_implementation(is_extern, is_public, pair));
|
||||
}
|
||||
Rule::module => {
|
||||
Rule::Module => {
|
||||
declaration = Some(build_module(is_extern, is_public, pair));
|
||||
}
|
||||
Rule::function => {
|
||||
Rule::Function => {
|
||||
declaration = Some(build_function(is_extern, is_public, pair));
|
||||
}
|
||||
Rule::prop => {
|
||||
declaration = Some(build_prop(pair));
|
||||
}
|
||||
Rule::field => {
|
||||
declaration = Some(build_field(pair));
|
||||
}
|
||||
_ => panic!(
|
||||
"Expected only interface, implementation, module, or function rules; found {}",
|
||||
pair
|
||||
),
|
||||
_ => unreachable!(),
|
||||
}
|
||||
}
|
||||
declaration.expect("Expected declaration.")
|
||||
@ -362,10 +318,10 @@ fn build_declaration(declaration_pair: Pair<Rule>) -> Declaration {
|
||||
|
||||
fn build_identifier(pair: Pair<Rule>) -> Identifier {
|
||||
match pair.as_rule() {
|
||||
Rule::identifier => Identifier {
|
||||
Rule::Identifier => Identifier {
|
||||
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![];
|
||||
for pair in fqn_pair.into_inner() {
|
||||
match pair.as_rule() {
|
||||
Rule::identifier => {
|
||||
Rule::Identifier => {
|
||||
identifiers.push(build_identifier(pair));
|
||||
}
|
||||
_ => panic!("Expected only identifiers."),
|
||||
_ => unreachable!(),
|
||||
}
|
||||
}
|
||||
Fqn { identifiers }
|
||||
@ -388,18 +344,15 @@ fn build_compilation_unit(pair: Pair<Rule>) -> CompilationUnit {
|
||||
|
||||
for pair in pair.into_inner() {
|
||||
match pair.as_rule() {
|
||||
Rule::namespace => {
|
||||
Rule::Namespace => {
|
||||
let fqn_pair = pair.into_inner().next().unwrap();
|
||||
namespace = Some(build_fqn(fqn_pair));
|
||||
}
|
||||
Rule::declaration => {
|
||||
declarations.push(build_declaration(pair));
|
||||
Rule::ModuleLevelDeclaration => {
|
||||
declarations.push(build_module_level_declaration(pair));
|
||||
}
|
||||
Rule::EOI => {} // ignore
|
||||
_ => panic!(
|
||||
"Expected only namespace, declaration, or EOI rules, found: {}",
|
||||
pair
|
||||
),
|
||||
_ => unreachable!(),
|
||||
}
|
||||
}
|
||||
|
||||
@ -410,12 +363,12 @@ fn build_compilation_unit(pair: Pair<Rule>) -> 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.")
|
||||
.next()
|
||||
.expect("Expcted compilation_unit.");
|
||||
.expect("Expected compilation_unit.");
|
||||
match pair.as_rule() {
|
||||
Rule::compilation_unit => build_compilation_unit(pair),
|
||||
Rule::CompilationUnit => build_compilation_unit(pair),
|
||||
_ => panic!("Expected compilation_unit rule."),
|
||||
}
|
||||
}
|
||||
|
@ -55,7 +55,7 @@ pub enum Declaration {
|
||||
is_extern: bool,
|
||||
is_public: bool,
|
||||
type_declaration: TypeDeclaration,
|
||||
impl_ctor: Option<ImplCtor>,
|
||||
impl_ctor: Option<ClassConstructor>,
|
||||
},
|
||||
Module {
|
||||
identifier: Identifier,
|
||||
@ -149,8 +149,31 @@ pub struct TypeUse {
|
||||
}
|
||||
|
||||
#[derive(Debug)]
|
||||
pub struct ImplCtor {
|
||||
args: Vec<ImplCtorArg>,
|
||||
pub struct ClassConstructor {
|
||||
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)]
|
||||
|
@ -1,68 +1,102 @@
|
||||
compilation_unit = { SOI ~ namespace? ~ declaration* ~ EOI }
|
||||
namespace = { "ns" ~ fqn }
|
||||
// Top-level constructs
|
||||
CompilationUnit = { SOI ~ Namespace? ~ ModuleLevelDeclaration* ~ EOI }
|
||||
Namespace = { "ns" ~ FullyQualifiedName }
|
||||
|
||||
fqn = { identifier ~ ( "::" ~ identifier )* }
|
||||
identifier = @{ identifier_start_char ~ identifier_char* }
|
||||
identifier_start_char = { 'a'..'z' | 'A'..'Z' | "_" }
|
||||
identifier_char = { 'a'..'z' | 'A'..'Z' | '0'..'9' | "_" }
|
||||
CommonDeclaration = { Interface | Class | Module | Function }
|
||||
ModuleLevelDeclaration = { Declare? ~ Public? ~ CommonDeclaration }
|
||||
InterfaceLevelDeclaration = { CommonDeclaration }
|
||||
ClassLevelDeclaration = { Declare? ~ Public? ~ ( CommonDeclaration | ClassMember ) }
|
||||
|
||||
declaration = { extern? ~ pub? ~ ( interface | implementation | module | function | prop | field ) }
|
||||
extern = { "extern" }
|
||||
pub = { "pub" }
|
||||
// Module
|
||||
Module = { "mod" ~ Identifier ~ "{" ~ ModuleLevelDeclaration* ~ "}" }
|
||||
|
||||
interface = { "int" ~ identifier ~ generic_parameters_declaration? ~ extends_list? ~ ( "{" ~ declaration* ~ "}" )? }
|
||||
extends_list = { ":" ~ type_use ~ ( "+" ~ type_use )* }
|
||||
// Interface
|
||||
Interface = { "int" ~ Identifier ~ GenericParameters? ~ ExtendsList? ~ ( "{" ~ InterfaceLevelDeclaration* ~ "}" )? }
|
||||
|
||||
implementation = { "impl" ~ identifier ~ generic_parameters_declaration? ~ impl_ctor? ~ extends_list? ~ ( "{" ~ declaration* ~ "}" )? }
|
||||
impl_ctor = { "(" ~ impl_ctor_args? ~ ")" }
|
||||
impl_ctor_args = { impl_ctor_arg ~ ( "," ~ impl_ctor_arg )* }
|
||||
impl_ctor_arg = { fld? ~ identifier ~ ( ":" ~ type_use )? }
|
||||
fld = { "fld" }
|
||||
// Class
|
||||
Class = { "class" ~ Identifier ~ GenericParameters? ~ ClassConstructor? ~ ExtendsList? ~ ( "{" ~ ClassLevelDeclaration* ~ "}" )? }
|
||||
ClassMember = { Field? ~ Identifier ~ TypeAnnotation? }
|
||||
|
||||
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 ) }
|
||||
function_equals_body = { "=" ~ expression }
|
||||
function_body = { "{" ~ statement* ~ "}" }
|
||||
// Fqn and identifier
|
||||
FullyQualifiedName = { Identifier ~ ( "::" ~ Identifier )* }
|
||||
|
||||
type_use = { fqn ~ generic_arguments_declaration? }
|
||||
generic_parameters_declaration = { "<" ~ generic_parameter ~ ( "," ~ generic_parameter )* ~ ">" }
|
||||
generic_parameter = { identifier }
|
||||
Identifier = @{ IdentifierStartChar ~ IdentifierChar* }
|
||||
IdentifierStartChar = { 'a'..'z' | 'A'..'Z' | "_" }
|
||||
IdentifierChar = { 'a'..'z' | 'A'..'Z' | '0'..'9' | "_" }
|
||||
|
||||
generic_arguments_declaration = { "<" ~ generic_argument ~ ( "," ~ generic_argument )* ~ ">" }
|
||||
generic_argument = { fqn }
|
||||
// Type constructs
|
||||
ExtendsList = { ":" ~ TypeUse ~ ( "+" ~ TypeUse )* }
|
||||
TypeAnnotation = { ":" ~ TypeUse }
|
||||
TypeUse = { FullyQualifiedName ~ GenericArguments? }
|
||||
|
||||
parameters_list = { parameter ~ ( "," ~ parameter )* }
|
||||
parameter = { identifier ~ ( ":" ~ "..."? ~ type_use )? }
|
||||
// Generic arguments given to a TypeUse or function calls
|
||||
GenericArguments = { "<" ~ FullyQualifiedName ~ ( "," ~ FullyQualifiedName )* ~ ">" }
|
||||
|
||||
prop = { identifier ~ ":" ~ type_use }
|
||||
field = { fld ~ identifier ~ ":" ~ type_use }
|
||||
// Generic parameters (for when types are declared)
|
||||
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 }
|
||||
call_expr_with_parens = { fqn ~ "(" ~ call_args? ~ ")" }
|
||||
call_expr_no_parens = { fqn ~ call_args }
|
||||
call_args = { call_arg ~ ( "," ~ call_arg )* }
|
||||
call_arg = { expression }
|
||||
FunctionEqualsBody = { "=" ~ 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 }
|
||||
int_literal = { '0'..'9'+ }
|
||||
// Expressions
|
||||
Expression = { CallExpression | AssignmentExpression | Literal | FullyQualifiedName }
|
||||
ExpressionList = { Expression ~ ( "," ~ Expression )* }
|
||||
|
||||
string_literal = ${ "\"" ~ string_inner ~ "\"" }
|
||||
string_inner = @{ string_char* }
|
||||
string_char = {
|
||||
// Calls
|
||||
CallExpression = { FullyQualifiedName ~ GenericArguments ~ CallArguments }
|
||||
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
|
||||
| "\\" ~ ( "\"" | "\\" | "/" | "b" | "f" | "n" | "r" | "t" )
|
||||
| "\\" ~ ( "u" ~ ASCII_HEX_DIGIT{4} )
|
||||
}
|
||||
|
||||
BooleanLiteral = { "true" | "false" }
|
||||
|
||||
NullLiteral = { "null" }
|
||||
|
||||
WHITESPACE = _{ " " | "\t" | "\n" | "\r" }
|
||||
|
Loading…
Reference in New Issue
Block a user