Compare commits
No commits in common. "82af6b4dfbdccbbf647e82cf6a0725ea05421fae" and "68de104595a0d3560388b2d3549a6faec05ee984" have entirely different histories.
82af6b4dfb
...
68de104595
@ -1,16 +0,0 @@
|
|||||||
class Counter {
|
|
||||||
fld count: Int
|
|
||||||
|
|
||||||
mut getAndIncrement() -> Int {
|
|
||||||
let result = count
|
|
||||||
count++
|
|
||||||
result
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Synthetic
|
|
||||||
class MyClosure(delegate: Counter) : MutClosure(Int, Int) -> Int |delegate| {
|
|
||||||
mut fn call(x: Int, y: Int) -> Int {
|
|
||||||
x + y + delegate.getAndIncrement()
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,14 +0,0 @@
|
|||||||
pub type Iterator<T> |backing: &Any| = mut fn () -> Option<&T ref backing>
|
|
||||||
|
|
||||||
pub int Iterable<T> {
|
|
||||||
ref fn iterator() -> Iterator<T>(&self)
|
|
||||||
}
|
|
||||||
|
|
||||||
fn main() {
|
|
||||||
let nums: List<Int> = [1, 2, 3]
|
|
||||||
let iterator: Iterator<Int> |backing = nums| = nums.iterator()
|
|
||||||
let first: &Int ref nums = iterator().unwrap()
|
|
||||||
let second: &Int ref nums = iterator().unwrap()
|
|
||||||
let third: &Int ref nums = iterator().unwrap()
|
|
||||||
println "${*first}, ${*second}, ${*third}"
|
|
||||||
}
|
|
530
src/ast/build.rs
530
src/ast/build.rs
@ -1,208 +1,374 @@
|
|||||||
use crate::ast::{CompilationUnit, DelegateOrIdentifier, Fqn, FunctionModifier, FunctionTypeUse, GenericArgument, GenericArguments, GenericParameter, GenericParameters, Identifier, InputArgument, InputArguments, InterfaceOrClassTypeUse, Reference, References, ReturnType, TupleTypeUse, TypeUse, VoidOrTypeUse};
|
use crate::ast::{
|
||||||
use crate::parser::Rule;
|
BlockStatement, CompilationUnit, Declaration, Fqn, FunctionDeclaration, GenericArgument,
|
||||||
|
GenericParameter, Identifier, ClassConstructor, Parameter, TypeDeclaration, TypeUse,
|
||||||
|
};
|
||||||
|
use crate::parser::{DeimosParser, Rule};
|
||||||
|
use crate::vm::source_code_location::SourceCodeLocation;
|
||||||
use pest::iterators::Pair;
|
use pest::iterators::Pair;
|
||||||
|
use pest::Parser;
|
||||||
|
|
||||||
fn expect_and_use<T>(pair: Pair<Rule>, rule: Rule, f: fn(Pair<Rule>) -> T) -> T {
|
fn build_field(field_pair: Pair<Rule>) -> Declaration {
|
||||||
if pair.as_rule() != rule {
|
|
||||||
panic!("Expected rule {:?} but found {:?}", rule, pair.as_rule())
|
|
||||||
}
|
|
||||||
f(pair)
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn build_ast(compilation_unit_pair: Pair<Rule>) -> CompilationUnit {
|
|
||||||
todo!()
|
todo!()
|
||||||
}
|
}
|
||||||
|
|
||||||
fn build_identifier(identifier_pair: Pair<Rule>) -> Identifier {
|
fn build_prop(prop_pair: Pair<Rule>) -> Declaration {
|
||||||
Identifier {
|
todo!()
|
||||||
name: identifier_pair.as_str().to_string(),
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fn build_fqn(fqn_pair: Pair<Rule>) -> Fqn {
|
fn build_generic_argument(generic_argument_pair: Pair<Rule>) -> GenericArgument {
|
||||||
let mut identifiers: Vec<Identifier> = vec![];
|
let fqn_pair = generic_argument_pair.into_inner().next().unwrap();
|
||||||
for identifier_pair in fqn_pair.into_inner() {
|
|
||||||
identifiers.push(expect_and_use(
|
|
||||||
identifier_pair,
|
|
||||||
Rule::Identifier,
|
|
||||||
build_identifier,
|
|
||||||
));
|
|
||||||
}
|
|
||||||
Fqn { identifiers }
|
|
||||||
}
|
|
||||||
|
|
||||||
fn build_type_use(type_use_pair: Pair<Rule>) -> TypeUse {
|
|
||||||
let inner_pair = type_use_pair.into_inner().next().unwrap();
|
|
||||||
match inner_pair.as_rule() {
|
|
||||||
Rule::InterfaceOrClassTypeUse => {
|
|
||||||
TypeUse::InterfaceOrClass(build_interface_or_class_type_use(inner_pair))
|
|
||||||
}
|
|
||||||
Rule::TupleTypeUse => TypeUse::Tuple(build_tuple_type_use(inner_pair)),
|
|
||||||
Rule::FunctionTypeUse => TypeUse::Function(build_function_type_use(inner_pair)),
|
|
||||||
_ => unreachable!(),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
fn build_interface_or_class_type_use(pair: Pair<Rule>) -> InterfaceOrClassTypeUse {
|
|
||||||
let mut inner = pair.into_inner();
|
|
||||||
let fqn = expect_and_use(inner.next().unwrap(), Rule::FullyQualifiedName, build_fqn);
|
|
||||||
|
|
||||||
let generics = inner
|
|
||||||
.next()
|
|
||||||
.map(|inner_pair| {
|
|
||||||
expect_and_use(inner_pair, Rule::GenericArguments, build_generic_arguments)
|
|
||||||
})
|
|
||||||
.unwrap_or(GenericArguments(vec![]));
|
|
||||||
|
|
||||||
InterfaceOrClassTypeUse { fqn, generics }
|
|
||||||
}
|
|
||||||
|
|
||||||
fn build_tuple_type_use(tuple_type_use_pair: Pair<Rule>) -> TupleTypeUse {
|
|
||||||
TupleTypeUse(
|
|
||||||
tuple_type_use_pair
|
|
||||||
.into_inner()
|
|
||||||
.map(|type_use_pair| expect_and_use(type_use_pair, Rule::TypeUse, build_type_use))
|
|
||||||
.collect(),
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
fn build_function_type_use(function_pair: Pair<Rule>) -> FunctionTypeUse {
|
|
||||||
let mut function_modifier: Option<FunctionModifier> = None;
|
|
||||||
let mut generics: Option<GenericParameters> = None;
|
|
||||||
let mut parameters: Option<TupleTypeUse> = None;
|
|
||||||
let mut inputs: Option<InputArguments> = None;
|
|
||||||
let mut return_type: Option<ReturnType> = None;
|
|
||||||
|
|
||||||
for inner_pair in function_pair.into_inner() {
|
|
||||||
match inner_pair.as_rule() {
|
|
||||||
Rule::FunctionTypeModifier => {
|
|
||||||
function_modifier = Some(build_function_modifier(inner_pair));
|
|
||||||
}
|
|
||||||
Rule::Fn => {}
|
|
||||||
Rule::GenericParameters => {
|
|
||||||
generics = Some(build_generic_parameters(inner_pair));
|
|
||||||
}
|
|
||||||
Rule::TupleTypeUse => {
|
|
||||||
parameters = Some(build_tuple_type_use(inner_pair));
|
|
||||||
}
|
|
||||||
Rule::FunctionInputArguments => {
|
|
||||||
inputs = Some(build_function_input_arguments(inner_pair));
|
|
||||||
}
|
|
||||||
Rule::ReturnType => {
|
|
||||||
return_type = Some(build_return_type(inner_pair));
|
|
||||||
},
|
|
||||||
_ => unreachable!(),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
FunctionTypeUse {
|
|
||||||
function_modifier,
|
|
||||||
generics: generics.unwrap_or(GenericParameters(vec![])),
|
|
||||||
parameters: parameters.unwrap(),
|
|
||||||
inputs: inputs.unwrap_or(InputArguments(vec![])),
|
|
||||||
return_type: return_type.unwrap(),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
fn build_generic_arguments(generic_arguments_pair: Pair<Rule>) -> GenericArguments {
|
|
||||||
let mut generic_arguments: Vec<GenericArgument> = vec![];
|
|
||||||
for generic_argument_pair in generic_arguments_pair.into_inner() {
|
|
||||||
generic_arguments.push(expect_and_use(
|
|
||||||
generic_argument_pair,
|
|
||||||
Rule::FullyQualifiedName,
|
|
||||||
build_generic_argument,
|
|
||||||
));
|
|
||||||
}
|
|
||||||
GenericArguments(generic_arguments)
|
|
||||||
}
|
|
||||||
|
|
||||||
fn build_generic_argument(fqn_pair: Pair<Rule>) -> GenericArgument {
|
|
||||||
GenericArgument {
|
GenericArgument {
|
||||||
fqn: build_fqn(fqn_pair),
|
fqn: build_fqn(fqn_pair),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn build_function_modifier(function_modifier_pair: Pair<Rule>) -> FunctionModifier {
|
fn build_generic_arguments_declaration(
|
||||||
let mut inner = function_modifier_pair.into_inner();
|
generic_arguments_declaration_pair: Pair<Rule>,
|
||||||
if inner.len() == 2 {
|
) -> Vec<GenericArgument> {
|
||||||
FunctionModifier::MutRef
|
let mut generic_arguments: Vec<GenericArgument> = vec![];
|
||||||
} else {
|
for pair in generic_arguments_declaration_pair.into_inner() {
|
||||||
match inner.next().unwrap().as_rule() {
|
match pair.as_rule() {
|
||||||
Rule::Cons => FunctionModifier::Cons,
|
Rule::GenericArguments => {
|
||||||
Rule::Mut => FunctionModifier::Mut,
|
generic_arguments.push(build_generic_argument(pair));
|
||||||
Rule::Ref => FunctionModifier::Ref,
|
}
|
||||||
|
_ => panic!("Expected only generic_argument rules. Found: {}", pair),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
generic_arguments
|
||||||
|
}
|
||||||
|
|
||||||
|
fn build_generic_parameter(generic_parameter_pair: Pair<Rule>) -> GenericParameter {
|
||||||
|
let identifier_pair = generic_parameter_pair.into_inner().next().unwrap();
|
||||||
|
GenericParameter {
|
||||||
|
identifier: build_identifier(identifier_pair),
|
||||||
|
bound: None,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn build_type_use(type_pair: Pair<Rule>) -> TypeUse {
|
||||||
|
let mut fqn: Option<Fqn> = None;
|
||||||
|
let mut generic_arguments_declaration: Option<Vec<GenericArgument>> = None;
|
||||||
|
|
||||||
|
for pair in type_pair.into_inner() {
|
||||||
|
match pair.as_rule() {
|
||||||
|
Rule::FullyQualifiedName => {
|
||||||
|
fqn = Some(build_fqn(pair));
|
||||||
|
}
|
||||||
|
Rule::GenericArguments => {
|
||||||
|
generic_arguments_declaration = Some(build_generic_arguments_declaration(pair));
|
||||||
|
}
|
||||||
|
_ => panic!(
|
||||||
|
"Expected only fqn or generic_arguments_declaration rules. Found: {}",
|
||||||
|
pair
|
||||||
|
),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
TypeUse {
|
||||||
|
fqn: fqn.unwrap(),
|
||||||
|
generics: generic_arguments_declaration.unwrap_or(vec![]),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn build_generic_parameters_declaration(
|
||||||
|
generic_parameters_declaration_pair: Pair<Rule>,
|
||||||
|
) -> Vec<GenericParameter> {
|
||||||
|
let mut parameters: Vec<GenericParameter> = vec![];
|
||||||
|
for pair in generic_parameters_declaration_pair.into_inner() {
|
||||||
|
match pair.as_rule() {
|
||||||
|
Rule::Identifier => {
|
||||||
|
parameters.push(build_generic_parameter(pair));
|
||||||
|
}
|
||||||
|
_ => panic!("Expected only generic_parameter rule. Found: {}", pair),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
parameters
|
||||||
|
}
|
||||||
|
|
||||||
|
fn build_extends_list(extends_list_pair: Pair<Rule>) -> Vec<TypeUse> {
|
||||||
|
let mut extensions: Vec<TypeUse> = vec![];
|
||||||
|
|
||||||
|
for pair in extends_list_pair.into_inner() {
|
||||||
|
match pair.as_rule() {
|
||||||
|
Rule::TypeUse => {
|
||||||
|
extensions.push(build_type_use(pair));
|
||||||
|
}
|
||||||
|
_ => panic!("Expected only type rule. Found: {}", pair),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
extensions
|
||||||
|
}
|
||||||
|
|
||||||
|
fn build_interface(is_extern: bool, is_public: bool, interface_pair: Pair<Rule>) -> Declaration {
|
||||||
|
let mut identifier: Option<Identifier> = None;
|
||||||
|
let mut generic_parameters: Option<Vec<GenericParameter>> = None;
|
||||||
|
let mut extends: Option<Vec<TypeUse>> = None;
|
||||||
|
let mut declarations: Vec<Declaration> = vec![];
|
||||||
|
|
||||||
|
for pair in interface_pair.into_inner() {
|
||||||
|
match pair.as_rule() {
|
||||||
|
Rule::Identifier => {
|
||||||
|
identifier = Some(build_identifier(pair));
|
||||||
|
}
|
||||||
|
Rule::GenericParameters => {
|
||||||
|
generic_parameters = Some(build_generic_parameters_declaration(pair));
|
||||||
|
}
|
||||||
|
Rule::ExtendsList => {
|
||||||
|
extends = Some(build_extends_list(pair));
|
||||||
|
}
|
||||||
|
Rule::InterfaceLevelDeclaration => {
|
||||||
|
declarations.push(build_module_level_declaration(pair));
|
||||||
|
},
|
||||||
|
_ => panic!(
|
||||||
|
"Expected only identifier, generics_declaration, extends_list, or declaration rules. Found: {}",
|
||||||
|
pair
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Declaration::Interface {
|
||||||
|
identifier: identifier.unwrap(),
|
||||||
|
is_extern,
|
||||||
|
is_public,
|
||||||
|
type_declaration: TypeDeclaration::new(
|
||||||
|
generic_parameters.unwrap_or(vec![]),
|
||||||
|
extends.unwrap_or(vec![]),
|
||||||
|
declarations,
|
||||||
|
),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn build_class_constructor(class_constructor_pair: Pair<Rule>) -> ClassConstructor {
|
||||||
|
todo!()
|
||||||
|
}
|
||||||
|
|
||||||
|
fn build_implementation(
|
||||||
|
is_extern: bool,
|
||||||
|
is_public: bool,
|
||||||
|
implementation_pair: Pair<Rule>,
|
||||||
|
) -> Declaration {
|
||||||
|
let mut identifier: Option<Identifier> = None;
|
||||||
|
let mut generic_parameters: Option<Vec<GenericParameter>> = 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 => {
|
||||||
|
identifier = Some(build_identifier(pair));
|
||||||
|
}
|
||||||
|
Rule::GenericParameters => {
|
||||||
|
generic_parameters = Some(build_generic_parameters_declaration(pair));
|
||||||
|
}
|
||||||
|
Rule::ClassConstructor => {
|
||||||
|
impl_ctor = Some(build_class_constructor(pair));
|
||||||
|
}
|
||||||
|
Rule::ExtendsList => {
|
||||||
|
extends = Some(build_extends_list(pair));
|
||||||
|
}
|
||||||
|
Rule::ClassLevelDeclaration => {
|
||||||
|
declarations.push(build_module_level_declaration(pair));
|
||||||
|
}
|
||||||
|
_ => panic!("Unexpected rule: {}", pair),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Declaration::Implementation {
|
||||||
|
identifier: identifier.unwrap(),
|
||||||
|
is_extern,
|
||||||
|
is_public,
|
||||||
|
type_declaration: TypeDeclaration::new(
|
||||||
|
generic_parameters.unwrap_or(vec![]),
|
||||||
|
extends.unwrap_or(vec![]),
|
||||||
|
declarations,
|
||||||
|
),
|
||||||
|
impl_ctor,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn build_module(is_extern: bool, is_public: bool, pair: Pair<Rule>) -> Declaration {
|
||||||
|
todo!()
|
||||||
|
}
|
||||||
|
|
||||||
|
fn build_parameter(pair: Pair<Rule>) -> Parameter {
|
||||||
|
let mut identifier: Option<Identifier> = None;
|
||||||
|
let mut declared_type: Option<TypeUse> = None;
|
||||||
|
for pair in pair.into_inner() {
|
||||||
|
match pair.as_rule() {
|
||||||
|
Rule::Identifier => {
|
||||||
|
identifier = Some(build_identifier(pair));
|
||||||
|
}
|
||||||
|
Rule::TypeAnnotation => {
|
||||||
|
declared_type = Some(build_type_use(pair));
|
||||||
|
}
|
||||||
_ => unreachable!(),
|
_ => unreachable!(),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
Parameter {
|
||||||
|
identifier: identifier.unwrap(),
|
||||||
fn build_generic_parameters(generic_parameters_pair: Pair<Rule>) -> GenericParameters {
|
|
||||||
GenericParameters(
|
|
||||||
generic_parameters_pair
|
|
||||||
.into_inner()
|
|
||||||
.map(|identifier_pair| {
|
|
||||||
GenericParameter(expect_and_use(
|
|
||||||
identifier_pair,
|
|
||||||
Rule::Identifier,
|
|
||||||
build_identifier,
|
|
||||||
))
|
|
||||||
})
|
|
||||||
.collect(),
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
fn build_function_input_arguments(pair: Pair<Rule>) -> InputArguments {
|
|
||||||
InputArguments(
|
|
||||||
pair.into_inner()
|
|
||||||
.map(|function_input_argument_pair| {
|
|
||||||
let mut inner = function_input_argument_pair.into_inner();
|
|
||||||
let lhs_pair = inner.next().unwrap();
|
|
||||||
let lhs = match lhs_pair.as_rule() {
|
|
||||||
Rule::Delegate => DelegateOrIdentifier::Delegate,
|
|
||||||
Rule::Identifier => {
|
|
||||||
DelegateOrIdentifier::Identifier(build_identifier(lhs_pair))
|
|
||||||
}
|
|
||||||
_ => unreachable!(),
|
|
||||||
};
|
|
||||||
let rhs = build_identifier(inner.next().unwrap());
|
|
||||||
InputArgument { lhs, rhs }
|
|
||||||
})
|
|
||||||
.collect(),
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
fn build_return_type(return_type_pair: Pair<Rule>) -> ReturnType {
|
|
||||||
let mut inner = return_type_pair.into_inner();
|
|
||||||
|
|
||||||
let declared_type_pair = inner.next().unwrap();
|
|
||||||
let declared_type = match declared_type_pair.as_rule() {
|
|
||||||
Rule::Void => VoidOrTypeUse::Void,
|
|
||||||
Rule::TypeUse => VoidOrTypeUse::TypeUse(Box::new(
|
|
||||||
build_type_use(declared_type_pair)
|
|
||||||
)),
|
|
||||||
_ => unreachable!(),
|
|
||||||
};
|
|
||||||
|
|
||||||
let references = inner.next().map(|ref_list_pair| {
|
|
||||||
expect_and_use(ref_list_pair, Rule::RefList, build_references)
|
|
||||||
}).unwrap_or(References(vec![]));
|
|
||||||
|
|
||||||
ReturnType {
|
|
||||||
declared_type,
|
declared_type,
|
||||||
references,
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn build_references(ref_list_pair: Pair<Rule>) -> References {
|
fn build_parameters_list(pair: Pair<Rule>) -> Vec<Parameter> {
|
||||||
let mut identifiers: Vec<Identifier> = vec![];
|
let mut parameters: Vec<Parameter> = vec![];
|
||||||
for pair in ref_list_pair.into_inner() {
|
for pair in pair.into_inner() {
|
||||||
|
match pair.as_rule() {
|
||||||
|
Rule::Parameter => {
|
||||||
|
parameters.push(build_parameter(pair));
|
||||||
|
}
|
||||||
|
_ => unreachable!(),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
parameters
|
||||||
|
}
|
||||||
|
|
||||||
|
fn build_block_statement(pair: Pair<Rule>) -> BlockStatement {
|
||||||
|
todo!()
|
||||||
|
}
|
||||||
|
|
||||||
|
fn build_function_equals_body(pair: Pair<Rule>) -> BlockStatement {
|
||||||
|
todo!()
|
||||||
|
}
|
||||||
|
|
||||||
|
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;
|
||||||
|
let mut return_type: Option<TypeUse> = None;
|
||||||
|
let mut statement: Option<BlockStatement> = None;
|
||||||
|
|
||||||
|
let (line, col) = pair.line_col();
|
||||||
|
|
||||||
|
for pair in pair.into_inner() {
|
||||||
|
match pair.as_rule() {
|
||||||
|
Rule::Implementation => {
|
||||||
|
is_implementation = true;
|
||||||
|
}
|
||||||
|
Rule::Identifier => {
|
||||||
|
identifier = Some(build_identifier(pair));
|
||||||
|
}
|
||||||
|
Rule::GenericParameters => {
|
||||||
|
generic_parameters = Some(build_generic_parameters_declaration(pair));
|
||||||
|
}
|
||||||
|
Rule::Parameters => {
|
||||||
|
parameters = Some(build_parameters_list(pair));
|
||||||
|
}
|
||||||
|
Rule::TypeUse => {
|
||||||
|
return_type = Some(build_type_use(pair));
|
||||||
|
}
|
||||||
|
Rule::BlockStatement => {
|
||||||
|
statement = Some(build_block_statement(pair));
|
||||||
|
}
|
||||||
|
Rule::FunctionEqualsBody => {
|
||||||
|
statement = Some(build_function_equals_body(pair));
|
||||||
|
}
|
||||||
|
_ => unreachable!(),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Declaration::Function(FunctionDeclaration {
|
||||||
|
is_extern,
|
||||||
|
is_public,
|
||||||
|
identifier: identifier.unwrap(),
|
||||||
|
parameters: parameters.unwrap(),
|
||||||
|
declared_type: return_type,
|
||||||
|
block_statement: statement.unwrap(),
|
||||||
|
source_code_location: SourceCodeLocation {
|
||||||
|
source_file_name: "TODO".to_string(),
|
||||||
|
line,
|
||||||
|
col,
|
||||||
|
},
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
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::Declare => {
|
||||||
|
is_extern = true;
|
||||||
|
}
|
||||||
|
Rule::Public => {
|
||||||
|
is_public = true;
|
||||||
|
}
|
||||||
|
Rule::Interface => {
|
||||||
|
declaration = Some(build_interface(is_extern, is_public, pair));
|
||||||
|
}
|
||||||
|
Rule::Implementation => {
|
||||||
|
declaration = Some(build_implementation(is_extern, is_public, pair));
|
||||||
|
}
|
||||||
|
Rule::Module => {
|
||||||
|
declaration = Some(build_module(is_extern, is_public, pair));
|
||||||
|
}
|
||||||
|
Rule::Function => {
|
||||||
|
declaration = Some(build_function(is_extern, is_public, pair));
|
||||||
|
}
|
||||||
|
_ => unreachable!(),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
declaration.expect("Expected declaration.")
|
||||||
|
}
|
||||||
|
|
||||||
|
fn build_identifier(pair: Pair<Rule>) -> Identifier {
|
||||||
|
match pair.as_rule() {
|
||||||
|
Rule::Identifier => Identifier {
|
||||||
|
name: String::from(pair.as_str()),
|
||||||
|
},
|
||||||
|
_ => unreachable!(),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
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() {
|
match pair.as_rule() {
|
||||||
Rule::Ref => {},
|
|
||||||
Rule::Identifier => {
|
Rule::Identifier => {
|
||||||
identifiers.push(build_identifier(pair));
|
identifiers.push(build_identifier(pair));
|
||||||
},
|
}
|
||||||
_ => unreachable!(),
|
_ => unreachable!(),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
References(identifiers.into_iter().map(|identifier| Reference(identifier)).collect())
|
Fqn { identifiers }
|
||||||
|
}
|
||||||
|
|
||||||
|
fn build_compilation_unit(pair: Pair<Rule>) -> CompilationUnit {
|
||||||
|
let mut namespace: Option<Fqn> = None;
|
||||||
|
let mut declarations: Vec<Declaration> = vec![];
|
||||||
|
|
||||||
|
for pair in pair.into_inner() {
|
||||||
|
match pair.as_rule() {
|
||||||
|
Rule::Namespace => {
|
||||||
|
let fqn_pair = pair.into_inner().next().unwrap();
|
||||||
|
namespace = Some(build_fqn(fqn_pair));
|
||||||
|
}
|
||||||
|
Rule::ModuleLevelDeclaration => {
|
||||||
|
declarations.push(build_module_level_declaration(pair));
|
||||||
|
}
|
||||||
|
Rule::EOI => {} // ignore
|
||||||
|
_ => unreachable!(),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
CompilationUnit {
|
||||||
|
namespace,
|
||||||
|
declarations,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn build_ast(src: &str) -> CompilationUnit {
|
||||||
|
let pair = DeimosParser::parse(Rule::CompilationUnit, src)
|
||||||
|
.expect("Unsuccessful parse.")
|
||||||
|
.next()
|
||||||
|
.expect("Expected compilation_unit.");
|
||||||
|
match pair.as_rule() {
|
||||||
|
Rule::CompilationUnit => build_compilation_unit(pair),
|
||||||
|
_ => panic!("Expected compilation_unit rule."),
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
671
src/ast/mod.rs
671
src/ast/mod.rs
@ -1,535 +1,256 @@
|
|||||||
|
use crate::vm::source_code_location::SourceCodeLocation;
|
||||||
use pest::Parser;
|
use pest::Parser;
|
||||||
|
|
||||||
pub mod build;
|
pub mod build;
|
||||||
pub mod unparse;
|
|
||||||
|
|
||||||
// Operators
|
|
||||||
|
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
pub enum Operator {
|
pub struct CompilationUnit {
|
||||||
Binary(BinaryOperator),
|
namespace: Option<Fqn>,
|
||||||
Unary(UnaryOperator),
|
declarations: Vec<Declaration>,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug)]
|
impl CompilationUnit {
|
||||||
pub enum BinaryOperator {
|
pub fn namespace(&self) -> &Option<Fqn> {
|
||||||
Or,
|
&self.namespace
|
||||||
And,
|
}
|
||||||
EqualTo,
|
|
||||||
NotEqualTo,
|
|
||||||
Greater,
|
|
||||||
Less,
|
|
||||||
GreaterEqual,
|
|
||||||
LessEqual,
|
|
||||||
Add,
|
|
||||||
Subtract,
|
|
||||||
Multiply,
|
|
||||||
Divide,
|
|
||||||
Modulo,
|
|
||||||
LeftShift,
|
|
||||||
RightShift,
|
|
||||||
}
|
|
||||||
|
|
||||||
#[derive(Debug)]
|
pub fn declarations(&self) -> &Vec<Declaration> {
|
||||||
pub enum UnaryOperator {
|
&self.declarations
|
||||||
Not,
|
}
|
||||||
Negative,
|
|
||||||
PlusPlus,
|
|
||||||
MinusMinus,
|
|
||||||
CallOp,
|
|
||||||
Spread,
|
|
||||||
}
|
|
||||||
|
|
||||||
// Names
|
|
||||||
|
|
||||||
#[derive(Debug, Clone)]
|
|
||||||
pub struct Identifier {
|
|
||||||
pub name: String,
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
pub struct Fqn {
|
pub struct Fqn {
|
||||||
pub identifiers: Vec<Identifier>,
|
identifiers: Vec<Identifier>,
|
||||||
}
|
}
|
||||||
|
|
||||||
// Generic parameters
|
impl Fqn {
|
||||||
|
pub fn new(identifiers: Vec<Identifier>) -> Self {
|
||||||
|
Fqn { identifiers }
|
||||||
|
}
|
||||||
|
|
||||||
#[derive(Debug)]
|
pub fn identifiers(&self) -> &Vec<Identifier> {
|
||||||
pub struct GenericParameters(pub Vec<GenericParameter>);
|
&self.identifiers
|
||||||
|
}
|
||||||
|
|
||||||
impl GenericParameters {
|
pub fn push_identifier(&mut self, identifier: Identifier) {
|
||||||
pub fn is_empty(&self) -> bool {
|
self.identifiers.push(identifier);
|
||||||
self.0.is_empty()
|
}
|
||||||
|
|
||||||
|
pub fn pop_identifier(&mut self) {
|
||||||
|
self.identifiers.pop();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
pub struct GenericParameter(Identifier);
|
pub enum Declaration {
|
||||||
|
Interface {
|
||||||
// Generic arguments
|
identifier: Identifier,
|
||||||
|
is_extern: bool,
|
||||||
#[derive(Debug)]
|
is_public: bool,
|
||||||
pub struct GenericArguments(pub Vec<GenericArgument>);
|
type_declaration: TypeDeclaration,
|
||||||
|
},
|
||||||
impl GenericArguments {
|
Implementation {
|
||||||
pub fn is_empty(&self) -> bool {
|
identifier: Identifier,
|
||||||
self.0.is_empty()
|
is_extern: bool,
|
||||||
}
|
is_public: bool,
|
||||||
}
|
type_declaration: TypeDeclaration,
|
||||||
|
impl_ctor: Option<ClassConstructor>,
|
||||||
#[derive(Debug)]
|
},
|
||||||
pub struct GenericArgument {
|
Module {
|
||||||
pub fqn: Fqn,
|
identifier: Identifier,
|
||||||
}
|
is_extern: bool,
|
||||||
|
is_public: bool,
|
||||||
// Type-use and components
|
declarations: Vec<Declaration>,
|
||||||
|
},
|
||||||
// #[derive(Debug)]
|
|
||||||
// pub struct TypeUse {
|
|
||||||
// pub fqn: Fqn,
|
|
||||||
// pub arguments: Option<TypeArguments>,
|
|
||||||
// pub inputs: Option<InputArguments>,
|
|
||||||
// }
|
|
||||||
|
|
||||||
#[derive(Debug)]
|
|
||||||
pub enum TypeUse {
|
|
||||||
InterfaceOrClass(InterfaceOrClassTypeUse),
|
|
||||||
Tuple(TupleTypeUse),
|
|
||||||
Function(FunctionTypeUse),
|
|
||||||
}
|
|
||||||
|
|
||||||
#[derive(Debug)]
|
|
||||||
pub struct InterfaceOrClassTypeUse {
|
|
||||||
pub fqn: Fqn,
|
|
||||||
pub generics: GenericArguments,
|
|
||||||
}
|
|
||||||
|
|
||||||
#[derive(Debug)]
|
|
||||||
pub struct TupleTypeUse(pub Vec<TypeUse>);
|
|
||||||
|
|
||||||
#[derive(Debug)]
|
|
||||||
pub struct FunctionTypeUse {
|
|
||||||
pub function_modifier: Option<FunctionModifier>,
|
|
||||||
pub generics: GenericParameters,
|
|
||||||
pub parameters: TupleTypeUse,
|
|
||||||
pub inputs: InputArguments,
|
|
||||||
pub return_type: ReturnType,
|
|
||||||
}
|
|
||||||
|
|
||||||
#[derive(Debug)]
|
|
||||||
pub enum TypeArguments {
|
|
||||||
Generics(GenericArguments),
|
|
||||||
Tuple(TupleArguments),
|
|
||||||
Function(FunctionTypeArguments),
|
|
||||||
}
|
|
||||||
|
|
||||||
#[derive(Debug)]
|
|
||||||
pub struct TupleArguments(pub Vec<Fqn>);
|
|
||||||
|
|
||||||
impl TupleArguments {
|
|
||||||
pub fn is_empty(&self) -> bool {
|
|
||||||
self.0.is_empty()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#[derive(Debug)]
|
|
||||||
pub struct FunctionTypeArguments {
|
|
||||||
pub parameters: TupleParameters,
|
|
||||||
pub return_type: Box<TypeUse>,
|
|
||||||
}
|
|
||||||
|
|
||||||
// Function components
|
|
||||||
|
|
||||||
#[derive(Debug)]
|
|
||||||
pub struct Parameters(pub Vec<Parameter>);
|
|
||||||
|
|
||||||
impl Parameters {
|
|
||||||
pub fn is_empty(&self) -> bool {
|
|
||||||
self.0.is_empty()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#[derive(Debug)]
|
|
||||||
pub struct Parameter {
|
|
||||||
identifier: Identifier,
|
|
||||||
type_use: TypeUse,
|
|
||||||
}
|
|
||||||
|
|
||||||
#[derive(Debug)]
|
|
||||||
pub struct ReturnType {
|
|
||||||
pub declared_type: VoidOrTypeUse,
|
|
||||||
pub references: References,
|
|
||||||
}
|
|
||||||
|
|
||||||
#[derive(Debug)]
|
|
||||||
pub enum VoidOrTypeUse {
|
|
||||||
Void,
|
|
||||||
TypeUse(Box<TypeUse>),
|
|
||||||
}
|
|
||||||
|
|
||||||
#[derive(Debug)]
|
|
||||||
pub struct References(pub Vec<Reference>);
|
|
||||||
|
|
||||||
impl References {
|
|
||||||
pub fn is_empty(&self) -> bool {
|
|
||||||
self.0.is_empty()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#[derive(Debug)]
|
|
||||||
pub struct Reference(pub Identifier);
|
|
||||||
|
|
||||||
// Inputs
|
|
||||||
|
|
||||||
#[derive(Debug)]
|
|
||||||
pub enum DelegateOrIdentifier {
|
|
||||||
Delegate,
|
|
||||||
Identifier(Identifier),
|
|
||||||
}
|
|
||||||
|
|
||||||
#[derive(Debug)]
|
|
||||||
pub struct InputParameters(pub Vec<DelegateOrIdentifier>);
|
|
||||||
|
|
||||||
impl InputParameters {
|
|
||||||
pub fn is_empty(&self) -> bool {
|
|
||||||
self.0.is_empty()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#[derive(Debug)]
|
|
||||||
pub struct InputArguments(pub Vec<InputArgument>);
|
|
||||||
|
|
||||||
impl InputArguments {
|
|
||||||
pub fn is_empty(&self) -> bool {
|
|
||||||
self.0.is_empty()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#[derive(Debug)]
|
|
||||||
pub struct InputArgument {
|
|
||||||
pub lhs: DelegateOrIdentifier,
|
|
||||||
pub rhs: Identifier,
|
|
||||||
}
|
|
||||||
|
|
||||||
// Where guards
|
|
||||||
|
|
||||||
#[derive(Debug)]
|
|
||||||
pub struct WhereGuards(pub Vec<WhereGuard>);
|
|
||||||
|
|
||||||
impl WhereGuards {
|
|
||||||
pub fn is_empty(&self) -> bool {
|
|
||||||
self.0.is_empty()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#[derive(Debug)]
|
|
||||||
pub struct WhereGuard {
|
|
||||||
pub identifier: Identifier,
|
|
||||||
pub implements: ImplementsList,
|
|
||||||
}
|
|
||||||
|
|
||||||
// Implements
|
|
||||||
|
|
||||||
#[derive(Debug)]
|
|
||||||
pub struct ImplementsList(pub Vec<TypeUse>);
|
|
||||||
|
|
||||||
impl ImplementsList {
|
|
||||||
pub fn is_empty(&self) -> bool {
|
|
||||||
self.0.is_empty()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Top-level construct
|
|
||||||
|
|
||||||
#[derive(Debug)]
|
|
||||||
pub struct CompilationUnit {
|
|
||||||
pub namespace: Option<Fqn>,
|
|
||||||
pub declarations: Vec<ModuleLevelDeclaration>,
|
|
||||||
}
|
|
||||||
|
|
||||||
// Declarations allowed in each level
|
|
||||||
|
|
||||||
#[derive(Debug)]
|
|
||||||
pub enum ModuleLevelDeclaration {
|
|
||||||
Type(TypeDeclaration),
|
|
||||||
Module(ModuleDeclaration),
|
|
||||||
Interface(InterfaceDeclaration),
|
|
||||||
Class(ClassDeclaration),
|
|
||||||
Function(FunctionDeclaration),
|
Function(FunctionDeclaration),
|
||||||
PlatformFunction(PlatformFunctionDeclaration),
|
Prop(Prop),
|
||||||
}
|
Field(Field),
|
||||||
|
|
||||||
#[derive(Debug)]
|
|
||||||
pub enum InterfaceLevelDeclaration {
|
|
||||||
Type(TypeDeclaration),
|
|
||||||
Module(ModuleDeclaration),
|
|
||||||
Interface(InterfaceDeclaration),
|
|
||||||
Class(ClassDeclaration),
|
|
||||||
Function(InterfaceFunctionDeclaration),
|
|
||||||
OperatorFunction(InterfaceOperatorFunctionDeclaration),
|
|
||||||
}
|
|
||||||
|
|
||||||
#[derive(Debug)]
|
|
||||||
pub enum ClassLevelDeclaration {
|
|
||||||
Type(TypeDeclaration),
|
|
||||||
Module(ModuleDeclaration),
|
|
||||||
Interface(InterfaceDeclaration),
|
|
||||||
Class(ClassDeclaration),
|
|
||||||
Function(FunctionDeclaration),
|
|
||||||
OperatorFunction(OperatorFunctionDeclaration),
|
|
||||||
PlatformFunction(PlatformFunctionDeclaration),
|
|
||||||
Field(FieldDeclaration),
|
|
||||||
}
|
|
||||||
|
|
||||||
// Declarations
|
|
||||||
|
|
||||||
#[derive(Debug)]
|
|
||||||
pub struct TypeDeclaration {
|
|
||||||
pub is_public: bool,
|
|
||||||
pub identifier: Identifier,
|
|
||||||
pub parameters: Option<TypeParameters>,
|
|
||||||
pub where_guards: WhereGuards,
|
|
||||||
pub rhs: TypeUse,
|
|
||||||
}
|
|
||||||
|
|
||||||
#[derive(Debug)]
|
|
||||||
pub struct ModuleDeclaration {
|
|
||||||
pub is_public: bool,
|
|
||||||
pub identifier: Identifier,
|
|
||||||
pub declarations: Vec<ModuleLevelDeclaration>,
|
|
||||||
}
|
|
||||||
|
|
||||||
#[derive(Debug)]
|
|
||||||
pub struct InterfaceDeclaration {
|
|
||||||
pub is_public: bool,
|
|
||||||
pub identifier: Identifier,
|
|
||||||
pub generics: GenericParameters,
|
|
||||||
pub inputs: InputParameters,
|
|
||||||
pub implements: ImplementsList,
|
|
||||||
pub where_guards: WhereGuards,
|
|
||||||
pub declarations: Vec<InterfaceLevelDeclaration>,
|
|
||||||
}
|
|
||||||
|
|
||||||
#[derive(Debug)]
|
|
||||||
pub struct ClassDeclaration {
|
|
||||||
pub is_public: bool,
|
|
||||||
pub identifier: Identifier,
|
|
||||||
pub generics: GenericParameters,
|
|
||||||
pub class_constructor: Option<ClassConstructor>,
|
|
||||||
pub inputs: InputArguments,
|
|
||||||
pub implements: ImplementsList,
|
|
||||||
pub where_guards: WhereGuards,
|
|
||||||
pub declarations: Vec<ClassLevelDeclaration>,
|
|
||||||
}
|
|
||||||
|
|
||||||
// Function declarations and components
|
|
||||||
|
|
||||||
#[derive(Debug)]
|
|
||||||
pub enum FunctionModifier {
|
|
||||||
Static,
|
|
||||||
Cons,
|
|
||||||
Mut,
|
|
||||||
Ref,
|
|
||||||
MutRef,
|
|
||||||
}
|
|
||||||
|
|
||||||
#[derive(Debug)]
|
|
||||||
pub enum FunctionBody {
|
|
||||||
EqualsBody(Expression),
|
|
||||||
BlockBody(BlockStatement),
|
|
||||||
AliasBody(Identifier),
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
pub struct FunctionDeclaration {
|
pub struct FunctionDeclaration {
|
||||||
pub is_public: bool,
|
source_code_location: SourceCodeLocation,
|
||||||
pub modifier: Option<FunctionModifier>,
|
identifier: Identifier,
|
||||||
pub generics: GenericParameters,
|
is_extern: bool,
|
||||||
pub identifier: Identifier,
|
is_public: bool,
|
||||||
pub parameters: Parameters,
|
parameters: Vec<Parameter>,
|
||||||
pub return_type: Option<ReturnType>,
|
declared_type: Option<TypeUse>,
|
||||||
pub body: FunctionBody,
|
block_statement: BlockStatement,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl FunctionDeclaration {
|
||||||
|
pub fn source_code_location(&self) -> &SourceCodeLocation {
|
||||||
|
&self.source_code_location
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn identifier(&self) -> &Identifier {
|
||||||
|
&self.identifier
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn block_statement(&self) -> &BlockStatement {
|
||||||
|
&self.block_statement
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
pub struct OperatorFunctionDeclaration {
|
pub struct TypeDeclaration {
|
||||||
pub is_public: bool,
|
generics: Vec<GenericParameter>,
|
||||||
pub modifier: Option<FunctionModifier>,
|
extends: Vec<TypeUse>,
|
||||||
pub generics: GenericParameters,
|
declarations: Vec<Declaration>,
|
||||||
pub operator: Operator,
|
}
|
||||||
pub parameters: Parameters,
|
|
||||||
pub return_type: Option<ReturnType>,
|
impl TypeDeclaration {
|
||||||
pub body: FunctionBody,
|
pub fn new(
|
||||||
|
generics: Vec<GenericParameter>,
|
||||||
|
extends: Vec<TypeUse>,
|
||||||
|
declarations: Vec<Declaration>,
|
||||||
|
) -> TypeDeclaration {
|
||||||
|
TypeDeclaration {
|
||||||
|
generics,
|
||||||
|
extends,
|
||||||
|
declarations,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Debug, Clone)]
|
||||||
|
pub struct Identifier {
|
||||||
|
name: String,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Identifier {
|
||||||
|
pub fn name(&self) -> &str {
|
||||||
|
&self.name
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
pub struct PlatformFunctionDeclaration {
|
pub struct GenericParameter {
|
||||||
pub is_public: bool,
|
identifier: Identifier,
|
||||||
pub modifier: Option<FunctionModifier>,
|
bound: Option<GenericBound>,
|
||||||
pub generics: GenericParameters,
|
|
||||||
pub identifier: Identifier,
|
|
||||||
pub parameters: Parameters,
|
|
||||||
pub return_type: TypeUse,
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
pub struct InterfaceFunctionDeclaration {
|
pub enum GenericBound {
|
||||||
pub modifier: Option<FunctionModifier>,
|
Extends { fqn: Fqn },
|
||||||
pub generics: GenericParameters,
|
Super { fqn: Fqn },
|
||||||
pub identifier: Identifier,
|
|
||||||
pub parameters: Parameters,
|
|
||||||
pub return_type: ReturnType,
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
pub struct InterfaceOperatorFunctionDeclaration {
|
pub struct GenericArgument {
|
||||||
pub modifier: Option<FunctionModifier>,
|
fqn: Fqn,
|
||||||
pub generics: GenericParameters,
|
|
||||||
pub operator: Operator,
|
|
||||||
pub parameters: Parameters,
|
|
||||||
pub return_type: ReturnType,
|
|
||||||
}
|
|
||||||
|
|
||||||
// Type components
|
|
||||||
|
|
||||||
#[derive(Debug)]
|
|
||||||
pub enum TypeParameters {
|
|
||||||
Generic(GenericParameters),
|
|
||||||
Tuple(TupleParameters),
|
|
||||||
Function(FunctionTypeParameters),
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
pub struct TupleParameters(pub Vec<Identifier>);
|
pub struct TypeUse {
|
||||||
|
fqn: Fqn,
|
||||||
#[derive(Debug)]
|
generics: Vec<GenericArgument>,
|
||||||
pub struct FunctionTypeParameters {
|
|
||||||
pub parameters: Parameters,
|
|
||||||
pub return_type: TypeUse,
|
|
||||||
}
|
|
||||||
|
|
||||||
// Class components
|
|
||||||
|
|
||||||
#[derive(Debug)]
|
|
||||||
pub struct ClassConstructor(pub Vec<ClassConstructorParameter>);
|
|
||||||
|
|
||||||
#[derive(Debug)]
|
|
||||||
pub struct ClassConstructorParameter {
|
|
||||||
pub is_field: bool,
|
|
||||||
pub identifier: Identifier,
|
|
||||||
pub declared_type: TypeUse,
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
pub struct FieldDeclaration {
|
pub struct ClassConstructor {
|
||||||
pub is_mutable: bool,
|
args: Vec<ClassMember>,
|
||||||
pub identifier: Identifier,
|
|
||||||
pub declared_type: TypeUse,
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Statements
|
impl ClassConstructor {
|
||||||
|
pub fn new(args: Vec<ClassMember>) -> Self {
|
||||||
|
ClassConstructor { args }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
pub struct BlockStatement(pub Vec<Statement>);
|
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)]
|
||||||
|
pub struct ImplCtorArg {
|
||||||
|
is_field: bool,
|
||||||
|
identifier: Identifier,
|
||||||
|
r#type: Option<TypeUse>,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Debug)]
|
||||||
|
pub struct Prop {
|
||||||
|
identifier: Identifier,
|
||||||
|
r#type: TypeUse,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Debug)]
|
||||||
|
pub struct Field {
|
||||||
|
identifier: Identifier,
|
||||||
|
r#type: TypeUse,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Debug)]
|
||||||
|
pub struct BlockStatement {
|
||||||
|
statements: Vec<Statement>,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl BlockStatement {
|
||||||
|
pub fn statements(&self) -> &Vec<Statement> {
|
||||||
|
&self.statements
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
pub enum Statement {
|
pub enum Statement {
|
||||||
BlockStatement(BlockStatement),
|
|
||||||
CallStatement(CallExpression),
|
CallStatement(CallExpression),
|
||||||
VariableDeclarationStatement(VariableDeclarationStatement),
|
AssignStatement(AssignExpression),
|
||||||
AssignStatement(AssignStatement),
|
|
||||||
ReturnStatement(ReturnStatement),
|
|
||||||
IfStatement(IfStatement),
|
|
||||||
IfElseStatement(IfElseStatement),
|
|
||||||
WhileStatement(WhileStatement),
|
|
||||||
ForStatement(ForStatement),
|
|
||||||
}
|
|
||||||
|
|
||||||
#[derive(Debug)]
|
|
||||||
pub struct VariableDeclarationStatement {
|
|
||||||
is_mutable: bool,
|
|
||||||
identifier: Identifier,
|
|
||||||
declared_type: Option<TypeUse>,
|
|
||||||
initializer: Option<Expression>,
|
|
||||||
}
|
|
||||||
|
|
||||||
#[derive(Debug)]
|
|
||||||
pub struct AssignStatement(pub AssignmentExpression);
|
|
||||||
|
|
||||||
#[derive(Debug)]
|
|
||||||
pub struct ReturnStatement(pub Option<Expression>);
|
|
||||||
|
|
||||||
#[derive(Debug)]
|
|
||||||
pub struct IfStatement {
|
|
||||||
pub condition: Expression,
|
|
||||||
pub then_branch: BlockStatement,
|
|
||||||
}
|
|
||||||
|
|
||||||
#[derive(Debug)]
|
|
||||||
pub struct IfElseStatement {
|
|
||||||
pub condition: Expression,
|
|
||||||
pub then_branch: BlockStatement,
|
|
||||||
pub else_ifs: ElseIfs,
|
|
||||||
pub else_branch: BlockStatement,
|
|
||||||
}
|
|
||||||
|
|
||||||
#[derive(Debug)]
|
|
||||||
pub struct ElseIfs(pub Vec<IfStatement>);
|
|
||||||
|
|
||||||
#[derive(Debug)]
|
|
||||||
pub struct WhileStatement {
|
|
||||||
pub condition: Expression,
|
|
||||||
pub body: BlockStatement,
|
|
||||||
}
|
|
||||||
|
|
||||||
#[derive(Debug)]
|
|
||||||
pub struct ForStatement {
|
|
||||||
pub variable: Identifier,
|
|
||||||
pub iterator: Expression,
|
|
||||||
pub body: BlockStatement,
|
|
||||||
}
|
|
||||||
|
|
||||||
// Expressions
|
|
||||||
|
|
||||||
#[derive(Debug)]
|
|
||||||
pub enum Expression {
|
|
||||||
Binary(BinaryExpression),
|
|
||||||
Unary(UnaryExpression),
|
|
||||||
Assignment(Box<AssignmentExpression>),
|
|
||||||
Call(CallExpression),
|
|
||||||
Literal(Literal),
|
|
||||||
}
|
|
||||||
|
|
||||||
#[derive(Debug)]
|
|
||||||
pub struct BinaryExpression {
|
|
||||||
pub left: Box<Expression>,
|
|
||||||
pub operator: BinaryOperator,
|
|
||||||
pub right: Box<Expression>,
|
|
||||||
}
|
|
||||||
|
|
||||||
#[derive(Debug)]
|
|
||||||
pub struct UnaryExpression {
|
|
||||||
pub operator: UnaryOperator,
|
|
||||||
pub expression: Box<Expression>,
|
|
||||||
}
|
|
||||||
|
|
||||||
#[derive(Debug)]
|
|
||||||
pub struct AssignmentExpression {
|
|
||||||
identifier: Identifier,
|
|
||||||
expression: Expression,
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
pub struct CallExpression {
|
pub struct CallExpression {
|
||||||
pub callee: Box<Expression>,
|
receiver: Expression,
|
||||||
pub arguments: CallArguments,
|
actuals_list: Vec<Expression>,
|
||||||
|
source_code_location: SourceCodeLocation,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl CallExpression {
|
||||||
|
pub fn receiver(&self) -> &Expression {
|
||||||
|
&self.receiver
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn actuals_list(&self) -> &Vec<Expression> {
|
||||||
|
&self.actuals_list
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn source_code_location(&self) -> &SourceCodeLocation {
|
||||||
|
&self.source_code_location
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
pub struct CallArguments(pub Vec<CallArgument>);
|
pub struct AssignExpression {
|
||||||
|
left: LValue,
|
||||||
|
right: Expression,
|
||||||
|
}
|
||||||
|
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
pub struct CallArgument(pub Box<Expression>);
|
pub enum Expression {
|
||||||
|
CallExpression(Box<CallExpression>),
|
||||||
|
AssignExpression(Box<AssignExpression>),
|
||||||
|
LValue(Box<LValue>),
|
||||||
|
Literal(Box<Literal>),
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Debug)]
|
||||||
|
pub enum LValue {
|
||||||
|
Fqn(Fqn),
|
||||||
|
}
|
||||||
|
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
pub enum Literal {
|
pub enum Literal {
|
||||||
@ -540,3 +261,9 @@ pub enum Literal {
|
|||||||
StringLiteral(String),
|
StringLiteral(String),
|
||||||
BooleanLiteral(bool),
|
BooleanLiteral(bool),
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[derive(Debug)]
|
||||||
|
pub struct Parameter {
|
||||||
|
identifier: Identifier,
|
||||||
|
declared_type: Option<TypeUse>,
|
||||||
|
}
|
||||||
|
1018
src/ast/unparse.rs
1018
src/ast/unparse.rs
File diff suppressed because it is too large
Load Diff
@ -1,6 +1,6 @@
|
|||||||
use crate::ast::{
|
use crate::ast::{
|
||||||
AssignExpression, BlockStatement, CallExpression, CompilationUnit, Expression, Fqn,
|
AssignExpression, BlockStatement, CallExpression, CompilationUnit, Declaration, Expression,
|
||||||
FunctionDeclaration, Identifier, LValue, ModuleLevelDeclaration, Statement,
|
Fqn, FunctionDeclaration, Identifier, LValue, Statement,
|
||||||
};
|
};
|
||||||
use crate::object_file::{DvmObjectFile, DvmPath};
|
use crate::object_file::{DvmObjectFile, DvmPath};
|
||||||
use crate::vm::function::DvmFunction;
|
use crate::vm::function::DvmFunction;
|
||||||
@ -153,7 +153,7 @@ pub fn convert(file_name: &str, ast: CompilationUnit) -> DvmObjectFile {
|
|||||||
|
|
||||||
for declaration in ast.declarations() {
|
for declaration in ast.declarations() {
|
||||||
match declaration {
|
match declaration {
|
||||||
ModuleLevelDeclaration::Function(function_declaration) => {
|
Declaration::Function(function_declaration) => {
|
||||||
let function = convert_static_function(&state, &context, function_declaration);
|
let function = convert_static_function(&state, &context, function_declaration);
|
||||||
object_file.add_function(function);
|
object_file.add_function(function);
|
||||||
}
|
}
|
||||||
|
@ -1,780 +1,140 @@
|
|||||||
// Keywords
|
// Top-level constructs
|
||||||
Ns = { "ns" }
|
CompilationUnit = { SOI ~ Namespace? ~ ModuleLevelDeclaration* ~ EOI }
|
||||||
TypeKw = { "type" }
|
Namespace = { "ns" ~ FullyQualifiedName }
|
||||||
Mod = { "mod" }
|
|
||||||
Int = { "int" }
|
|
||||||
ClassKw = { "class" }
|
|
||||||
Platform = { "platform" }
|
|
||||||
Pub = { "pub" }
|
|
||||||
Fld = { "fld" }
|
|
||||||
Impl = { "impl" }
|
|
||||||
Mut = { "mut" }
|
|
||||||
Cons = { "cons" }
|
|
||||||
Static = { "static" }
|
|
||||||
Ref = { "ref" }
|
|
||||||
Def = { "def" }
|
|
||||||
Where = { "where" }
|
|
||||||
Infer = { "infer" }
|
|
||||||
Void = { "Void" }
|
|
||||||
Delegate = { "delegate" }
|
|
||||||
Let = { "let" }
|
|
||||||
Fn = { "fn" }
|
|
||||||
Op = { "op" }
|
|
||||||
|
|
||||||
// Keywords as a rule (for preventing identifiers with keywords, etc.)
|
CommonDeclaration = { Interface | Class | Module | Function }
|
||||||
Keyword = {
|
ModuleLevelDeclaration = { Declare? ~ Public? ~ CommonDeclaration }
|
||||||
Ns
|
InterfaceLevelDeclaration = { CommonDeclaration }
|
||||||
| TypeKw
|
ClassLevelDeclaration = { Declare? ~ Public? ~ ( CommonDeclaration | ClassMember ) }
|
||||||
| Mod
|
|
||||||
| Int
|
// Module
|
||||||
| ClassKw
|
Module = { "mod" ~ Identifier ~ "{" ~ ModuleLevelDeclaration* ~ "}" }
|
||||||
| Platform
|
|
||||||
| Pub
|
// Interface
|
||||||
| Fld
|
Interface = { "int" ~ Identifier ~ GenericParameters? ~ ExtendsList? ~ ( "{" ~ InterfaceLevelDeclaration* ~ "}" )? }
|
||||||
| Impl
|
|
||||||
| Mut
|
// Class
|
||||||
| Cons
|
Class = { "class" ~ Identifier ~ GenericParameters? ~ ClassConstructor? ~ ExtendsList? ~ ( "{" ~ ClassLevelDeclaration* ~ "}" )? }
|
||||||
| Static
|
ClassMember = { Field? ~ Identifier ~ TypeAnnotation? }
|
||||||
| Ref
|
|
||||||
| Def
|
// Class Constructor
|
||||||
| Where
|
ClassConstructor = { "(" ~ ClassMemberList? ~ ")" }
|
||||||
| Infer
|
ClassMemberList = { ClassMember ~ ( "," ~ ClassMember )* }
|
||||||
| Void
|
|
||||||
| Delegate
|
// Various Keywords
|
||||||
| Let
|
Declare = { "decl" }
|
||||||
| Fn
|
Public = { "pub" }
|
||||||
| Op
|
Field = { "fld" }
|
||||||
|
Implementation = { "impl" }
|
||||||
|
Mutable = { "mut" }
|
||||||
|
|
||||||
|
// Fqn and identifier
|
||||||
|
FullyQualifiedName = { Identifier ~ ( "::" ~ Identifier )* }
|
||||||
|
|
||||||
|
Identifier = @{ IdentifierStartChar ~ IdentifierChar* }
|
||||||
|
IdentifierStartChar = { 'a'..'z' | 'A'..'Z' | "_" }
|
||||||
|
IdentifierChar = { 'a'..'z' | 'A'..'Z' | '0'..'9' | "_" }
|
||||||
|
|
||||||
|
// Type constructs
|
||||||
|
ExtendsList = { ":" ~ TypeUse ~ ( "+" ~ TypeUse )* }
|
||||||
|
TypeAnnotation = { ":" ~ TypeUse }
|
||||||
|
TypeUse = { FullyQualifiedName ~ GenericArguments? }
|
||||||
|
|
||||||
|
// Generic arguments given to a TypeUse or function calls
|
||||||
|
GenericArguments = { "<" ~ FullyQualifiedName ~ ( "," ~ FullyQualifiedName )* ~ ">" }
|
||||||
|
|
||||||
|
// Generic parameters (for when types are declared)
|
||||||
|
GenericParameters = { "<" ~ Identifier ~ ( "," ~ Identifier )* ~ ">" }
|
||||||
|
|
||||||
|
// Function
|
||||||
|
Function = { Implementation?
|
||||||
|
~ "fn"
|
||||||
|
~ Identifier
|
||||||
|
~ GenericParameters?
|
||||||
|
~ "(" ~ Parameters? ~ ")"
|
||||||
|
~ TypeAnnotation? ~ ( FunctionEqualsBody | BlockStatement )
|
||||||
}
|
}
|
||||||
|
|
||||||
// Symbols
|
Parameters = { Parameter ~ ( "," ~ Parameter )* }
|
||||||
Ellipsis = { "..." }
|
Parameter = { Identifier ~ TypeAnnotation? }
|
||||||
Underscore = { "_" }
|
|
||||||
|
|
||||||
// Operators
|
FunctionEqualsBody = { "=" ~ Expression }
|
||||||
Or = { "||" }
|
|
||||||
And = { "&&" }
|
// Statements
|
||||||
|
BlockStatement = { "{" ~ Statement* ~ "}" }
|
||||||
|
Statement = { VariableDeclaration | CallExpression | AssignmentExpression }
|
||||||
|
|
||||||
|
VariableDeclaration = { "let" ~ Mutable? ~ Identifier ~ TypeAnnotation? ~ ( "=" ~ Expression )? }
|
||||||
|
|
||||||
|
// Expressions
|
||||||
|
Expression = { OrExpression }
|
||||||
|
|
||||||
|
OrExpression = { AndExpression ~ ( "||" ~ AndExpression )* }
|
||||||
|
AndExpression = { EqualityExpression ~ ( "&&" ~ EqualityExpression )* }
|
||||||
|
|
||||||
|
EqualityExpression = { ComparisonExpression ~ ( ( EqualTo | NotEqualTo ) ~ ComparisonExpression )* }
|
||||||
EqualTo = { "==" }
|
EqualTo = { "==" }
|
||||||
NotEqualTo = { "!=" }
|
NotEqualTo = { "!=" }
|
||||||
|
|
||||||
|
ComparisonExpression = { AdditiveExpression ~ ( ( Greater | Less | GreaterEqual | LessEqual ) ~ AdditiveExpression )* }
|
||||||
Greater = { ">" }
|
Greater = { ">" }
|
||||||
Less = { "<" }
|
Less = { "<" }
|
||||||
GreaterEqual = { ">=" }
|
GreaterEqual = { ">=" }
|
||||||
LessEqual = { "<=" }
|
LessEqual = { "<=" }
|
||||||
|
|
||||||
|
AdditiveExpression = { MultiplicativeExpression ~ ( ( Add | Subtract ) ~ MultiplicativeExpression )* }
|
||||||
Add = { "+" }
|
Add = { "+" }
|
||||||
Subtract = { "-" }
|
Subtract = { "-" }
|
||||||
|
|
||||||
|
MultiplicativeExpression = { UnaryExpression ~ ( ( Multiply | Divide | Modulo ) ~ UnaryExpression )* }
|
||||||
Multiply = { "*" }
|
Multiply = { "*" }
|
||||||
Divide = { "/" }
|
Divide = { "/" }
|
||||||
Modulo = { "%" }
|
Modulo = { "%" }
|
||||||
|
|
||||||
|
UnaryExpression = { ( Not | Negative )* ~ PrimaryExpression ~ ( Call | ( PlusPlus | MinusMinus ) )* }
|
||||||
Not = { "!" }
|
Not = { "!" }
|
||||||
Negative = { "-" }
|
Negative = { "-" }
|
||||||
PlusPlus = { "++" }
|
PlusPlus = { "++" }
|
||||||
MinusMinus = { "--" }
|
MinusMinus = { "--" }
|
||||||
CallOp = { "()" }
|
|
||||||
Spread = { Ellipsis }
|
|
||||||
|
|
||||||
Operator = {
|
PrimaryExpression = { Literal | ObjectAccess | ParenthesizedExpression }
|
||||||
Or
|
ParenthesizedExpression = { "(" ~ Expression ~ ")" }
|
||||||
| And
|
|
||||||
| EqualTo
|
|
||||||
| NotEqualTo
|
|
||||||
| Greater
|
|
||||||
| Less
|
|
||||||
| GreaterEqual
|
|
||||||
| LessEqual
|
|
||||||
| Add
|
|
||||||
| Subtract
|
|
||||||
| Multiply
|
|
||||||
| Divide
|
|
||||||
| Modulo
|
|
||||||
| Not
|
|
||||||
| Negative
|
|
||||||
| PlusPlus
|
|
||||||
| MinusMinus
|
|
||||||
| CallOp
|
|
||||||
| Spread
|
|
||||||
}
|
|
||||||
|
|
||||||
// Commonly shared constructs
|
|
||||||
|
|
||||||
FullyQualifiedName = {
|
// Call
|
||||||
Identifier
|
CallExpression = { PrimaryExpression ~ Call+ }
|
||||||
~ ( "::" ~ Identifier )*
|
Call = { GenericArguments? ~ CallArguments }
|
||||||
}
|
ExpressionList = { Expression ~ ( "," ~ Expression )* }
|
||||||
|
CallArguments = {
|
||||||
Identifier = @{
|
( "(" ~ ExpressionList? ~ ")" )
|
||||||
( Keyword ~ IdentifierChar | !Keyword ~ IdentifierStartChar )
|
| ExpressionList
|
||||||
~ IdentifierChar*
|
|
||||||
}
|
|
||||||
|
|
||||||
IdentifierStartChar = {
|
|
||||||
'a'..'z'
|
|
||||||
| 'A'..'Z'
|
|
||||||
| "_"
|
|
||||||
}
|
|
||||||
|
|
||||||
IdentifierChar = {
|
|
||||||
'a'..'z'
|
|
||||||
| 'A'..'Z'
|
|
||||||
| '0'..'9'
|
|
||||||
| "_"
|
|
||||||
}
|
|
||||||
|
|
||||||
// In general:
|
|
||||||
// Arguments = usage
|
|
||||||
// Parameters = declaration
|
|
||||||
|
|
||||||
TypeUse = {
|
|
||||||
InterfaceOrClassTypeUse
|
|
||||||
| TupleTypeUse
|
|
||||||
| FunctionTypeUse
|
|
||||||
}
|
|
||||||
|
|
||||||
InterfaceOrClassTypeUse = {
|
|
||||||
FullyQualifiedName
|
|
||||||
~ GenericArguments?
|
|
||||||
}
|
|
||||||
|
|
||||||
TupleTypeUse = {
|
|
||||||
"("
|
|
||||||
~ (
|
|
||||||
TypeUse
|
|
||||||
~ ( "," ~ TypeUse )*
|
|
||||||
)?
|
|
||||||
~ ")"
|
|
||||||
}
|
|
||||||
|
|
||||||
FunctionTypeUse = {
|
|
||||||
FunctionTypeModifier?
|
|
||||||
~ Fn
|
|
||||||
~ GenericParameters?
|
|
||||||
~ TupleTypeUse
|
|
||||||
~ FunctionInputArguments?
|
|
||||||
~ ReturnType
|
|
||||||
}
|
|
||||||
|
|
||||||
FunctionTypeModifier = {
|
|
||||||
Cons
|
|
||||||
| Mut ~ Ref
|
|
||||||
| Mut
|
|
||||||
| Ref
|
|
||||||
}
|
|
||||||
|
|
||||||
GenericArguments = {
|
|
||||||
"<"
|
|
||||||
~ FullyQualifiedName
|
|
||||||
~ ( "," ~ FullyQualifiedName )*
|
|
||||||
~ ">"
|
|
||||||
}
|
|
||||||
|
|
||||||
InputArguments = {
|
|
||||||
"|"
|
|
||||||
~ (
|
|
||||||
InputArgument
|
|
||||||
~ ( "," ~ InputArgument )*
|
|
||||||
)?
|
|
||||||
~ "|"
|
|
||||||
}
|
|
||||||
|
|
||||||
InputArgument = {
|
|
||||||
Identifier
|
|
||||||
~ ( "=" ~ Identifier )
|
|
||||||
}
|
|
||||||
|
|
||||||
RefList = {
|
|
||||||
Ref
|
|
||||||
~ Identifier
|
|
||||||
~ ( "," ~ Identifier )*
|
|
||||||
}
|
|
||||||
|
|
||||||
FunctionInputArguments = {
|
|
||||||
"|"
|
|
||||||
~ (
|
|
||||||
FunctionInputArgument
|
|
||||||
~ ( "," ~ FunctionInputArgument )*
|
|
||||||
)?
|
|
||||||
~ "|"
|
|
||||||
}
|
|
||||||
|
|
||||||
FunctionInputArgument = {
|
|
||||||
( Delegate | Identifier )
|
|
||||||
~ ( "=" ~ Identifier )
|
|
||||||
}
|
|
||||||
|
|
||||||
// Generic Parameters
|
|
||||||
|
|
||||||
GenericParameters = {
|
|
||||||
"<"
|
|
||||||
~ Identifier
|
|
||||||
~ ( "," ~ Identifier )*
|
|
||||||
~ ">"
|
|
||||||
}
|
|
||||||
|
|
||||||
InputParameters = {
|
|
||||||
"|"
|
|
||||||
~ InputParameter
|
|
||||||
~ ( "," ~ InputParameter )*
|
|
||||||
~ "|"
|
|
||||||
}
|
|
||||||
|
|
||||||
InputParameter = {
|
|
||||||
Identifier
|
|
||||||
~ ":"
|
|
||||||
~ TypeUse
|
|
||||||
}
|
|
||||||
|
|
||||||
TupleGenericParameters = {
|
|
||||||
"("
|
|
||||||
~ (
|
|
||||||
Identifier
|
|
||||||
~ ( "," ~ Identifier )*
|
|
||||||
)?
|
|
||||||
~ ")"
|
|
||||||
}
|
|
||||||
|
|
||||||
FunctionGenericParameters = {
|
|
||||||
TupleGenericParameters
|
|
||||||
~ FunctionGenericParameterReturnType
|
|
||||||
}
|
|
||||||
|
|
||||||
FunctionGenericParameterReturnType = {
|
|
||||||
"->"
|
|
||||||
~ ( Void | Identifier )
|
|
||||||
~ RefList?
|
|
||||||
}
|
|
||||||
|
|
||||||
FunctionInputParameters = {
|
|
||||||
"|"
|
|
||||||
~ FunctionInputParameter
|
|
||||||
~ ( "," ~ FunctionInputParameter )*
|
|
||||||
~ "|"
|
|
||||||
}
|
|
||||||
|
|
||||||
FunctionInputParameter = {
|
|
||||||
( Delegate | Identifier )
|
|
||||||
~ ":"
|
|
||||||
~ TypeUse
|
|
||||||
}
|
|
||||||
|
|
||||||
ImplementsList = {
|
|
||||||
":"
|
|
||||||
~ TypeUse
|
|
||||||
~ ( "+" ~ TypeUse )
|
|
||||||
}
|
|
||||||
|
|
||||||
WhereGuards = {
|
|
||||||
Where
|
|
||||||
~ WhereGuard
|
|
||||||
~ ( "," ~ WhereGuard )*
|
|
||||||
}
|
|
||||||
|
|
||||||
WhereGuard = {
|
|
||||||
Identifier
|
|
||||||
~ ImplementsList
|
|
||||||
}
|
|
||||||
|
|
||||||
// Top-level constructs
|
|
||||||
|
|
||||||
CompilationUnit = {
|
|
||||||
SOI
|
|
||||||
~ Namespace?
|
|
||||||
~ ModuleLevelDeclaration*
|
|
||||||
~ EOI
|
|
||||||
}
|
|
||||||
|
|
||||||
Namespace = {
|
|
||||||
Ns
|
|
||||||
~ FullyQualifiedName
|
|
||||||
}
|
|
||||||
|
|
||||||
// Organizational declarations
|
|
||||||
|
|
||||||
ModuleLevelDeclaration = {
|
|
||||||
Type
|
|
||||||
| Module
|
|
||||||
| Interface
|
|
||||||
| Class
|
|
||||||
| FunctionDefinition
|
|
||||||
| PlatformFunction
|
|
||||||
}
|
|
||||||
|
|
||||||
InterfaceLevelDeclaration = {
|
|
||||||
Type
|
|
||||||
| Module
|
|
||||||
| Interface
|
|
||||||
| Class
|
|
||||||
| InterfaceFunction
|
|
||||||
| InterfaceDefaultFunction
|
|
||||||
| InterfaceOperatorFunction
|
|
||||||
| InterfaceDefaultOperatorFunction
|
|
||||||
}
|
|
||||||
|
|
||||||
ClassLevelDeclaration = {
|
|
||||||
Type
|
|
||||||
| Module
|
|
||||||
| Interface
|
|
||||||
| Class
|
|
||||||
| FunctionDefinition
|
|
||||||
| OperatorFunctionDefinition
|
|
||||||
| PlatformFunction
|
|
||||||
| Field
|
|
||||||
}
|
|
||||||
|
|
||||||
// Main organizational constructs
|
|
||||||
|
|
||||||
Type = {
|
|
||||||
Pub?
|
|
||||||
~ TypeKw
|
|
||||||
~ Identifier
|
|
||||||
~ GenericParameters?
|
|
||||||
~ TypeWhereGuards?
|
|
||||||
~ "="
|
|
||||||
~ TypeUse
|
|
||||||
}
|
|
||||||
|
|
||||||
Module = {
|
|
||||||
Pub?
|
|
||||||
~ Mod
|
|
||||||
~ Identifier
|
|
||||||
~ "{" ~ ModuleLevelDeclaration* ~ "}"
|
|
||||||
}
|
|
||||||
|
|
||||||
Interface = {
|
|
||||||
Pub?
|
|
||||||
~ Int
|
|
||||||
~ Identifier
|
|
||||||
~ InterfaceGenericParametersAndInputs?
|
|
||||||
~ ImplementsList?
|
|
||||||
~ WhereGuards?
|
|
||||||
~ ( "{" ~ InterfaceLevelDeclaration* ~ "}" )?
|
|
||||||
}
|
|
||||||
|
|
||||||
Class = {
|
|
||||||
Pub?
|
|
||||||
~ ClassKw
|
|
||||||
~ Identifier
|
|
||||||
~ GenericParameters?
|
|
||||||
~ ClassConstructor?
|
|
||||||
~ ImplementsList?
|
|
||||||
~ InputArguments?
|
|
||||||
~ WhereGuards?
|
|
||||||
~ ( "{" ~ ClassLevelDeclaration* ~ "}" )?
|
|
||||||
}
|
|
||||||
|
|
||||||
// Type
|
|
||||||
|
|
||||||
TypeWhereGuards = {
|
|
||||||
Where
|
|
||||||
~ TypeWhereGuard
|
|
||||||
~ ( "," ~ TypeWhereGuard )*
|
|
||||||
}
|
|
||||||
|
|
||||||
TypeWhereGuard = {
|
|
||||||
Identifier
|
|
||||||
~ ":"
|
|
||||||
~ TypeTypeUse
|
|
||||||
~ ( "+" ~ TypeTypeUse )*
|
|
||||||
}
|
|
||||||
|
|
||||||
TypeTypeUse = {
|
|
||||||
FullyQualifiedName
|
|
||||||
~ TypeTypeArguments?
|
|
||||||
}
|
|
||||||
|
|
||||||
TypeTypeArguments = {
|
|
||||||
TypeGenericArguments
|
|
||||||
| TypeGenericFunctionArguments
|
|
||||||
| TypeGenericTupleArguments
|
|
||||||
}
|
|
||||||
|
|
||||||
TypeGenericArguments = {
|
|
||||||
"<"
|
|
||||||
~ TypeGenericArgument
|
|
||||||
~ ( "," ~ TypeGenericArgument )*
|
|
||||||
~ ">"
|
|
||||||
}
|
|
||||||
|
|
||||||
TypeGenericArgument = {
|
|
||||||
Underscore
|
|
||||||
| FullyQualifiedName
|
|
||||||
| ( Infer ~ Identifier )
|
|
||||||
}
|
|
||||||
|
|
||||||
TypeGenericTupleArguments = {
|
|
||||||
"("
|
|
||||||
~ (
|
|
||||||
TypeGenericTupleArgument
|
|
||||||
~ ( "," ~ TypeGenericTupleArgument )*
|
|
||||||
)?
|
|
||||||
~ ")"
|
|
||||||
}
|
|
||||||
|
|
||||||
TypeGenericTupleArgument = {
|
|
||||||
Underscore
|
|
||||||
| FullyQualifiedName
|
|
||||||
| ( Infer ~ Identifier )
|
|
||||||
| ( Ellipsis ~ Underscore )
|
|
||||||
| ( Ellipsis ~ Infer ~ Identifier )
|
|
||||||
}
|
|
||||||
|
|
||||||
TypeGenericFunctionArguments = {
|
|
||||||
TypeGenericTupleArguments
|
|
||||||
~ TypeGenericArguments?
|
|
||||||
~ TypeFunctionReturnType
|
|
||||||
}
|
|
||||||
|
|
||||||
TypeFunctionReturnType = {
|
|
||||||
"->"
|
|
||||||
~ ( Void | FullyQualifiedName )
|
|
||||||
~ RefList?
|
|
||||||
}
|
|
||||||
|
|
||||||
// Interface
|
|
||||||
|
|
||||||
InterfaceGenericParametersAndInputs = {
|
|
||||||
GenericParameters ~ InputParameters?
|
|
||||||
| TupleGenericParameters
|
|
||||||
| FunctionGenericParameters ~ FunctionInputParameters?
|
|
||||||
| InputParameters
|
|
||||||
}
|
|
||||||
|
|
||||||
InterfaceFunction = {
|
|
||||||
(
|
|
||||||
Static
|
|
||||||
| Cons
|
|
||||||
| ( Mut ~ Ref? )
|
|
||||||
)?
|
|
||||||
~ Fn
|
|
||||||
~ GenericParameters?
|
|
||||||
~ Identifier
|
|
||||||
~ Parameters
|
|
||||||
~ ReturnType
|
|
||||||
~ WhereGuards?
|
|
||||||
}
|
|
||||||
|
|
||||||
InterfaceDefaultFunction = {
|
|
||||||
Def
|
|
||||||
~ (
|
|
||||||
Static
|
|
||||||
| Cons
|
|
||||||
| ( Mut ~ Ref? )
|
|
||||||
)?
|
|
||||||
~ Fn
|
|
||||||
~ GenericParameters?
|
|
||||||
~ Identifier
|
|
||||||
~ Parameters
|
|
||||||
~ ReturnType
|
|
||||||
~ WhereGuards?
|
|
||||||
~ FunctionBody
|
|
||||||
}
|
|
||||||
|
|
||||||
InterfaceOperatorFunction = {
|
|
||||||
(
|
|
||||||
Cons
|
|
||||||
| ( Mut ~ Ref? )
|
|
||||||
)?
|
|
||||||
~ Op
|
|
||||||
~ Operator
|
|
||||||
~ Parameters
|
|
||||||
~ ReturnType
|
|
||||||
~ RefList?
|
|
||||||
~ WhereGuards? // TODO: decide if we want this for interface op functions
|
|
||||||
}
|
|
||||||
|
|
||||||
InterfaceDefaultOperatorFunction = {
|
|
||||||
Def
|
|
||||||
~ (
|
|
||||||
Cons
|
|
||||||
| ( Mut ~ Ref? )
|
|
||||||
)?
|
|
||||||
~ Op
|
|
||||||
~ Operator
|
|
||||||
~ Parameters
|
|
||||||
~ ReturnType
|
|
||||||
~ RefList?
|
|
||||||
~ WhereGuards?
|
|
||||||
~ FunctionBody
|
|
||||||
}
|
|
||||||
|
|
||||||
// Class constructs
|
|
||||||
|
|
||||||
ClassConstructor = {
|
|
||||||
"("
|
|
||||||
~ DataMember
|
|
||||||
~ ( "," ~ DataMember )*
|
|
||||||
~ ")"
|
|
||||||
}
|
|
||||||
|
|
||||||
DataMember = {
|
|
||||||
Property
|
|
||||||
| Field
|
|
||||||
}
|
|
||||||
|
|
||||||
Property = {
|
|
||||||
Mut?
|
|
||||||
~ Identifier
|
|
||||||
~ ":"
|
|
||||||
~ TypeUse
|
|
||||||
}
|
|
||||||
|
|
||||||
Field = {
|
|
||||||
Mut?
|
|
||||||
~ Fld
|
|
||||||
~ Identifier
|
|
||||||
~ ":"
|
|
||||||
~ TypeUse
|
|
||||||
}
|
|
||||||
|
|
||||||
// Function constructs
|
|
||||||
FunctionModifier = {
|
|
||||||
Static
|
|
||||||
| Cons
|
|
||||||
| Mut? ~ Ref?
|
|
||||||
}
|
|
||||||
|
|
||||||
FunctionDefinition = {
|
|
||||||
Pub?
|
|
||||||
~ FunctionModifier
|
|
||||||
~ Fn
|
|
||||||
~ GenericParameters?
|
|
||||||
~ Identifier
|
|
||||||
~ Parameters
|
|
||||||
~ ReturnType?
|
|
||||||
~ FunctionBody
|
|
||||||
}
|
|
||||||
|
|
||||||
OperatorFunctionDefinition = {
|
|
||||||
Pub?
|
|
||||||
~ FunctionModifier
|
|
||||||
~ Op
|
|
||||||
~ Operator
|
|
||||||
~ Parameters
|
|
||||||
~ ReturnType?
|
|
||||||
~ FunctionBody
|
|
||||||
}
|
|
||||||
|
|
||||||
PlatformFunction = {
|
|
||||||
Pub?
|
|
||||||
~ FunctionModifier
|
|
||||||
~ Platform
|
|
||||||
~ Fn
|
|
||||||
~ GenericParameters
|
|
||||||
~ Identifier
|
|
||||||
~ Parameters
|
|
||||||
~ ReturnType
|
|
||||||
}
|
|
||||||
|
|
||||||
Parameters = {
|
|
||||||
"("
|
|
||||||
~ (
|
|
||||||
Parameter
|
|
||||||
~ ( "," ~ Parameter )*
|
|
||||||
)?
|
|
||||||
~ ")"
|
|
||||||
}
|
|
||||||
|
|
||||||
Parameter = {
|
|
||||||
Identifier
|
|
||||||
~ ":"
|
|
||||||
~ TypeUse
|
|
||||||
}
|
|
||||||
|
|
||||||
ReturnType = {
|
|
||||||
"->"
|
|
||||||
~ ( Void | TypeUse )
|
|
||||||
~ RefList?
|
|
||||||
}
|
|
||||||
|
|
||||||
FunctionBody = {
|
|
||||||
FunctionEqualsBody
|
|
||||||
| FunctionBlockBody
|
|
||||||
| FunctionAliasBody
|
|
||||||
}
|
|
||||||
|
|
||||||
FunctionEqualsBody = {
|
|
||||||
"="
|
|
||||||
~ Expression
|
|
||||||
}
|
|
||||||
|
|
||||||
FunctionBlockBody = {
|
|
||||||
"{"
|
|
||||||
~ Statement*
|
|
||||||
~ "}"
|
|
||||||
}
|
|
||||||
|
|
||||||
FunctionAliasBody = {
|
|
||||||
"alias"
|
|
||||||
~ Identifier
|
|
||||||
}
|
|
||||||
|
|
||||||
// Statements
|
|
||||||
|
|
||||||
BlockStatement = {
|
|
||||||
"{"
|
|
||||||
~ Statement*
|
|
||||||
~ "}"
|
|
||||||
}
|
|
||||||
|
|
||||||
Statement = {
|
|
||||||
BlockStatement
|
|
||||||
| VariableDeclaration
|
|
||||||
| AssignmentExpression
|
|
||||||
}
|
|
||||||
|
|
||||||
VariableDeclaration = {
|
|
||||||
Let
|
|
||||||
~ Mut?
|
|
||||||
~ Identifier
|
|
||||||
~ ( ":" ~ TypeUse )?
|
|
||||||
~ ( "=" ~ Expression )?
|
|
||||||
}
|
|
||||||
|
|
||||||
// Expressions
|
|
||||||
|
|
||||||
Expression = { OrExpression }
|
|
||||||
|
|
||||||
OrExpression = {
|
|
||||||
AndExpression
|
|
||||||
~ ( Or ~ Expression )*
|
|
||||||
}
|
|
||||||
|
|
||||||
AndExpression = {
|
|
||||||
EqualityExpression
|
|
||||||
~ ( And ~ Expression )*
|
|
||||||
}
|
|
||||||
|
|
||||||
EqualityExpression = {
|
|
||||||
ComparisonExpression
|
|
||||||
~ (
|
|
||||||
( EqualTo | NotEqualTo )
|
|
||||||
~ Expression
|
|
||||||
)*
|
|
||||||
}
|
|
||||||
|
|
||||||
ComparisonExpression = {
|
|
||||||
AdditiveExpression
|
|
||||||
~ (
|
|
||||||
( Greater | Less | GreaterEqual | LessEqual )
|
|
||||||
~ Expression
|
|
||||||
)*
|
|
||||||
}
|
|
||||||
|
|
||||||
AdditiveExpression = {
|
|
||||||
MultiplicativeExpression
|
|
||||||
~ (
|
|
||||||
( Add | Subtract )
|
|
||||||
~ Expression
|
|
||||||
)*
|
|
||||||
}
|
|
||||||
|
|
||||||
MultiplicativeExpression = {
|
|
||||||
SpreadExpression
|
|
||||||
~ (
|
|
||||||
( Multiply | Divide | Modulo )
|
|
||||||
~ Expression
|
|
||||||
)*
|
|
||||||
}
|
|
||||||
|
|
||||||
SpreadExpression = {
|
|
||||||
UnaryExpression
|
|
||||||
~ Spread
|
|
||||||
~ Expression
|
|
||||||
}
|
|
||||||
|
|
||||||
UnaryExpression = {
|
|
||||||
( Not | Negative )*
|
|
||||||
~ PrimaryExpression
|
|
||||||
~ ( ( NoParenthesesCall | ParenthesesCall )+ | ( PlusPlus | MinusMinus ) )?
|
|
||||||
}
|
|
||||||
|
|
||||||
PrimaryExpression = {
|
|
||||||
Literal
|
|
||||||
| ObjectAccess
|
|
||||||
| ParenthesizedExpression
|
|
||||||
}
|
|
||||||
|
|
||||||
ParenthesizedExpression = {
|
|
||||||
"("
|
|
||||||
~ Expression
|
|
||||||
~ ")"
|
|
||||||
}
|
|
||||||
|
|
||||||
// Calls
|
|
||||||
|
|
||||||
ParenthesesCall = {
|
|
||||||
TurboFish?
|
|
||||||
~ "("
|
|
||||||
~ ExpressionList?
|
|
||||||
~ ")"
|
|
||||||
}
|
|
||||||
|
|
||||||
NoParenthesesCall = {
|
|
||||||
TurboFish?
|
|
||||||
~ ExpressionList
|
|
||||||
}
|
|
||||||
|
|
||||||
TurboFish = {
|
|
||||||
"::"
|
|
||||||
~ GenericArguments
|
|
||||||
}
|
|
||||||
|
|
||||||
ExpressionList = {
|
|
||||||
Expression
|
|
||||||
~ ( "," ~ Expression )*
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Assignment
|
// Assignment
|
||||||
AssignmentExpression = {
|
AssignmentExpression = { ObjectAccess ~ "=" ~ Expression }
|
||||||
ObjectAccess
|
|
||||||
~ "="
|
|
||||||
~ Expression
|
|
||||||
}
|
|
||||||
|
|
||||||
// Object
|
// Object
|
||||||
ObjectAccess = {
|
ObjectAccess = { FullyQualifiedName ~ ( "." ~ Identifier )* }
|
||||||
FullyQualifiedName
|
|
||||||
~ ( "." ~ Identifier )*
|
|
||||||
}
|
|
||||||
|
|
||||||
// Literals
|
// Literals
|
||||||
Literal = {
|
Literal = { NumberLiteral | StringLiteral | BooleanLiteral | NullLiteral }
|
||||||
NumberLiteral
|
|
||||||
| StringLiteral
|
|
||||||
| BooleanLiteral
|
|
||||||
}
|
|
||||||
|
|
||||||
NumberLiteral = {
|
NumberLiteral = { LongLiteral | IntLiteral }
|
||||||
LongLiteral
|
|
||||||
| IntLiteral
|
|
||||||
| DoubleLiteral
|
|
||||||
}
|
|
||||||
|
|
||||||
IntLiteral = { NumberBase }
|
IntLiteral = { NumberBase }
|
||||||
|
|
||||||
LongLiteral = ${ NumberBase ~ "L" }
|
LongLiteral = ${ NumberBase ~ "L" }
|
||||||
|
|
||||||
DoubleLiteral = ${ DecimalBase ~ "." ~ Digit+ }
|
NumberBase = { DecimalBase | BinaryBase | HexadecimalBase }
|
||||||
|
|
||||||
NumberBase = {
|
|
||||||
DecimalBase
|
|
||||||
| BinaryBase
|
|
||||||
| HexadecimalBase
|
|
||||||
}
|
|
||||||
|
|
||||||
DecimalBase = @{ DecimalStartDigit ~ Digit* }
|
DecimalBase = @{ DecimalStartDigit ~ Digit* }
|
||||||
|
|
||||||
BinaryBase = @{ "0b" ~ Digit* }
|
BinaryBase = @{ "0b" ~ Digit* }
|
||||||
|
|
||||||
DecimalStartDigit = { '1'..'9' }
|
DecimalStartDigit = { '1'..'9' }
|
||||||
|
|
||||||
Digit = { '0'..'9'+ }
|
Digit = { '0'..'9'+ }
|
||||||
|
|
||||||
HexadecimalBase = @{ "0x" ~ HexadecimalDigit+ }
|
HexadecimalBase = @{ "0x" ~ HexadecimalDigit+ }
|
||||||
|
|
||||||
HexadecimalDigit = { '0'..'9' | 'a'..'f' }
|
HexadecimalDigit = { '0'..'9' | 'a'..'f' }
|
||||||
|
|
||||||
StringLiteral = ${ "\"" ~ StringInner ~ "\"" }
|
StringLiteral = ${ "\"" ~ StringInner ~ "\"" }
|
||||||
|
|
||||||
StringInner = @{ StringChar* }
|
StringInner = @{ StringChar* }
|
||||||
|
|
||||||
StringChar = {
|
StringChar = {
|
||||||
!( "\"" | "\\" ) ~ ANY
|
!( "\"" | "\\" ) ~ ANY
|
||||||
| "\\" ~ ( "\"" | "\\" | "/" | "b" | "f" | "n" | "r" | "t" )
|
| "\\" ~ ( "\"" | "\\" | "/" | "b" | "f" | "n" | "r" | "t" )
|
||||||
@ -783,4 +143,6 @@ StringChar = {
|
|||||||
|
|
||||||
BooleanLiteral = { "true" | "false" }
|
BooleanLiteral = { "true" | "false" }
|
||||||
|
|
||||||
|
NullLiteral = { "null" }
|
||||||
|
|
||||||
WHITESPACE = _{ " " | "\t" | "\n" | "\r" }
|
WHITESPACE = _{ " " | "\t" | "\n" | "\r" }
|
||||||
|
@ -51,10 +51,7 @@ mod deimos_parser_tests {
|
|||||||
}
|
}
|
||||||
|
|
||||||
fn parse(rule: Rule, input: &str) -> Pair<Rule> {
|
fn parse(rule: Rule, input: &str) -> Pair<Rule> {
|
||||||
let pair = DeimosParser::parse(rule, input)
|
let pair = DeimosParser::parse(rule, input).unwrap().next().unwrap();
|
||||||
.expect("Parsing failed.")
|
|
||||||
.next()
|
|
||||||
.unwrap();
|
|
||||||
dbg!(&pair);
|
dbg!(&pair);
|
||||||
pair
|
pair
|
||||||
}
|
}
|
||||||
@ -86,7 +83,7 @@ mod deimos_parser_tests {
|
|||||||
match_rule!(call; Rule::Call);
|
match_rule!(call; Rule::Call);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn identifier_call_as_call_expression() {
|
fn identifier_call_as_call_expression() {
|
||||||
let pair = parse(Rule::CallExpression, "foo()");
|
let pair = parse(Rule::CallExpression, "foo()");
|
||||||
@ -97,30 +94,4 @@ mod deimos_parser_tests {
|
|||||||
let call = call_expression_pairs.next().unwrap();
|
let call = call_expression_pairs.next().unwrap();
|
||||||
match_rule!(call; Rule::Call);
|
match_rule!(call; Rule::Call);
|
||||||
}
|
}
|
||||||
|
|
||||||
mod smoke_screen_tests {
|
|
||||||
use crate::parser::deimos_parser_tests::parse;
|
|
||||||
use crate::parser::Rule;
|
|
||||||
|
|
||||||
#[test]
|
|
||||||
fn simple_interface() {
|
|
||||||
parse(Rule::CompilationUnit, "pub int Simple { fn foo() -> Void }");
|
|
||||||
}
|
|
||||||
|
|
||||||
#[test]
|
|
||||||
fn interface_with_op() {
|
|
||||||
parse(
|
|
||||||
Rule::CompilationUnit,
|
|
||||||
"pub int Callable { op () () -> Void }",
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
#[test]
|
|
||||||
fn interface_with_alias() {
|
|
||||||
parse(
|
|
||||||
Rule::CompilationUnit,
|
|
||||||
"pub int Callable {\n fn call() -> Void\n op () () -> Void alias call\n}",
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user