Much work on grammar, AST building and unparsing.
This commit is contained in:
parent
e8aff842ed
commit
82af6b4dfb
530
src/ast/build.rs
530
src/ast/build.rs
@ -1,374 +1,208 @@
|
||||
use crate::ast::{
|
||||
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 crate::ast::{CompilationUnit, DelegateOrIdentifier, Fqn, FunctionModifier, FunctionTypeUse, GenericArgument, GenericArguments, GenericParameter, GenericParameters, Identifier, InputArgument, InputArguments, InterfaceOrClassTypeUse, Reference, References, ReturnType, TupleTypeUse, TypeUse, VoidOrTypeUse};
|
||||
use crate::parser::Rule;
|
||||
use pest::iterators::Pair;
|
||||
use pest::Parser;
|
||||
|
||||
fn build_field(field_pair: Pair<Rule>) -> Declaration {
|
||||
fn expect_and_use<T>(pair: Pair<Rule>, rule: Rule, f: fn(Pair<Rule>) -> T) -> T {
|
||||
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!()
|
||||
}
|
||||
|
||||
fn build_prop(prop_pair: Pair<Rule>) -> Declaration {
|
||||
todo!()
|
||||
}
|
||||
|
||||
fn build_generic_argument(generic_argument_pair: Pair<Rule>) -> GenericArgument {
|
||||
let fqn_pair = generic_argument_pair.into_inner().next().unwrap();
|
||||
GenericArgument {
|
||||
fqn: build_fqn(fqn_pair),
|
||||
}
|
||||
}
|
||||
|
||||
fn build_generic_arguments_declaration(
|
||||
generic_arguments_declaration_pair: Pair<Rule>,
|
||||
) -> Vec<GenericArgument> {
|
||||
let mut generic_arguments: Vec<GenericArgument> = vec![];
|
||||
for pair in generic_arguments_declaration_pair.into_inner() {
|
||||
match pair.as_rule() {
|
||||
Rule::GenericArguments => {
|
||||
generic_arguments.push(build_generic_argument(pair));
|
||||
}
|
||||
_ => 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!(),
|
||||
}
|
||||
}
|
||||
Parameter {
|
||||
identifier: identifier.unwrap(),
|
||||
declared_type,
|
||||
}
|
||||
}
|
||||
|
||||
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 => {
|
||||
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_identifier(identifier_pair: Pair<Rule>) -> Identifier {
|
||||
Identifier {
|
||||
name: identifier_pair.as_str().to_string(),
|
||||
}
|
||||
}
|
||||
|
||||
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 => {
|
||||
identifiers.push(build_identifier(pair));
|
||||
}
|
||||
_ => unreachable!(),
|
||||
}
|
||||
for identifier_pair in fqn_pair.into_inner() {
|
||||
identifiers.push(expect_and_use(
|
||||
identifier_pair,
|
||||
Rule::Identifier,
|
||||
build_identifier,
|
||||
));
|
||||
}
|
||||
Fqn { identifiers }
|
||||
}
|
||||
|
||||
fn build_compilation_unit(pair: Pair<Rule>) -> CompilationUnit {
|
||||
let mut namespace: Option<Fqn> = None;
|
||||
let mut declarations: Vec<Declaration> = vec![];
|
||||
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!(),
|
||||
}
|
||||
}
|
||||
|
||||
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));
|
||||
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::ModuleLevelDeclaration => {
|
||||
declarations.push(build_module_level_declaration(pair));
|
||||
Rule::Fn => {}
|
||||
Rule::GenericParameters => {
|
||||
generics = Some(build_generic_parameters(inner_pair));
|
||||
}
|
||||
Rule::EOI => {} // ignore
|
||||
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!(),
|
||||
}
|
||||
}
|
||||
|
||||
CompilationUnit {
|
||||
namespace,
|
||||
declarations,
|
||||
FunctionTypeUse {
|
||||
function_modifier,
|
||||
generics: generics.unwrap_or(GenericParameters(vec![])),
|
||||
parameters: parameters.unwrap(),
|
||||
inputs: inputs.unwrap_or(InputArguments(vec![])),
|
||||
return_type: return_type.unwrap(),
|
||||
}
|
||||
}
|
||||
|
||||
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."),
|
||||
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 {
|
||||
fqn: build_fqn(fqn_pair),
|
||||
}
|
||||
}
|
||||
|
||||
fn build_function_modifier(function_modifier_pair: Pair<Rule>) -> FunctionModifier {
|
||||
let mut inner = function_modifier_pair.into_inner();
|
||||
if inner.len() == 2 {
|
||||
FunctionModifier::MutRef
|
||||
} else {
|
||||
match inner.next().unwrap().as_rule() {
|
||||
Rule::Cons => FunctionModifier::Cons,
|
||||
Rule::Mut => FunctionModifier::Mut,
|
||||
Rule::Ref => FunctionModifier::Ref,
|
||||
_ => unreachable!(),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
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,
|
||||
references,
|
||||
}
|
||||
}
|
||||
|
||||
fn build_references(ref_list_pair: Pair<Rule>) -> References {
|
||||
let mut identifiers: Vec<Identifier> = vec![];
|
||||
for pair in ref_list_pair.into_inner() {
|
||||
match pair.as_rule() {
|
||||
Rule::Ref => {},
|
||||
Rule::Identifier => {
|
||||
identifiers.push(build_identifier(pair));
|
||||
},
|
||||
_ => unreachable!(),
|
||||
}
|
||||
}
|
||||
References(identifiers.into_iter().map(|identifier| Reference(identifier)).collect())
|
||||
}
|
||||
|
@ -64,9 +64,7 @@ impl GenericParameters {
|
||||
}
|
||||
|
||||
#[derive(Debug)]
|
||||
pub struct GenericParameter {
|
||||
identifier: Identifier,
|
||||
}
|
||||
pub struct GenericParameter(Identifier);
|
||||
|
||||
// Generic arguments
|
||||
|
||||
@ -86,10 +84,36 @@ pub struct GenericArgument {
|
||||
|
||||
// Type-use and components
|
||||
|
||||
// #[derive(Debug)]
|
||||
// pub struct TypeUse {
|
||||
// pub fqn: Fqn,
|
||||
// pub arguments: Option<TypeArguments>,
|
||||
// pub inputs: Option<InputArguments>,
|
||||
// }
|
||||
|
||||
#[derive(Debug)]
|
||||
pub struct TypeUse {
|
||||
pub enum TypeUse {
|
||||
InterfaceOrClass(InterfaceOrClassTypeUse),
|
||||
Tuple(TupleTypeUse),
|
||||
Function(FunctionTypeUse),
|
||||
}
|
||||
|
||||
#[derive(Debug)]
|
||||
pub struct InterfaceOrClassTypeUse {
|
||||
pub fqn: Fqn,
|
||||
pub arguments: Option<TypeArguments>,
|
||||
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)]
|
||||
@ -110,7 +134,7 @@ impl TupleArguments {
|
||||
|
||||
#[derive(Debug)]
|
||||
pub struct FunctionTypeArguments {
|
||||
pub parameters: Parameters,
|
||||
pub parameters: TupleParameters,
|
||||
pub return_type: Box<TypeUse>,
|
||||
}
|
||||
|
||||
@ -133,10 +157,16 @@ pub struct Parameter {
|
||||
|
||||
#[derive(Debug)]
|
||||
pub struct ReturnType {
|
||||
pub type_use: Box<TypeUse>,
|
||||
pub declared_type: VoidOrTypeUse,
|
||||
pub references: References,
|
||||
}
|
||||
|
||||
#[derive(Debug)]
|
||||
pub enum VoidOrTypeUse {
|
||||
Void,
|
||||
TypeUse(Box<TypeUse>),
|
||||
}
|
||||
|
||||
#[derive(Debug)]
|
||||
pub struct References(pub Vec<Reference>);
|
||||
|
||||
@ -147,9 +177,7 @@ impl References {
|
||||
}
|
||||
|
||||
#[derive(Debug)]
|
||||
pub struct Reference {
|
||||
pub identifier: Identifier,
|
||||
}
|
||||
pub struct Reference(pub Identifier);
|
||||
|
||||
// Inputs
|
||||
|
||||
@ -180,7 +208,7 @@ impl InputArguments {
|
||||
#[derive(Debug)]
|
||||
pub struct InputArgument {
|
||||
pub lhs: DelegateOrIdentifier,
|
||||
pub rhs: Identifier
|
||||
pub rhs: Identifier,
|
||||
}
|
||||
|
||||
// Where guards
|
||||
@ -197,7 +225,7 @@ impl WhereGuards {
|
||||
#[derive(Debug)]
|
||||
pub struct WhereGuard {
|
||||
pub identifier: Identifier,
|
||||
pub implements: ImplementsList
|
||||
pub implements: ImplementsList,
|
||||
}
|
||||
|
||||
// Implements
|
||||
@ -389,7 +417,7 @@ pub struct ClassConstructor(pub Vec<ClassConstructorParameter>);
|
||||
pub struct ClassConstructorParameter {
|
||||
pub is_field: bool,
|
||||
pub identifier: Identifier,
|
||||
pub declared_type: TypeUse
|
||||
pub declared_type: TypeUse,
|
||||
}
|
||||
|
||||
#[derive(Debug)]
|
||||
@ -469,7 +497,7 @@ pub enum Expression {
|
||||
Unary(UnaryExpression),
|
||||
Assignment(Box<AssignmentExpression>),
|
||||
Call(CallExpression),
|
||||
Literal(Literal)
|
||||
Literal(Literal),
|
||||
}
|
||||
|
||||
#[derive(Debug)]
|
||||
@ -494,7 +522,7 @@ pub struct AssignmentExpression {
|
||||
#[derive(Debug)]
|
||||
pub struct CallExpression {
|
||||
pub callee: Box<Expression>,
|
||||
pub arguments: CallArguments
|
||||
pub arguments: CallArguments,
|
||||
}
|
||||
|
||||
#[derive(Debug)]
|
||||
|
@ -1,3 +1,4 @@
|
||||
use std::fmt::write;
|
||||
use crate::ast::*;
|
||||
|
||||
macro_rules! to_unparse_vec {
|
||||
@ -161,7 +162,7 @@ impl ListUnparse for GenericParameters {
|
||||
|
||||
impl Unparse for GenericParameter {
|
||||
fn unparse(&self, buf: &mut dyn std::fmt::Write) -> std::fmt::Result {
|
||||
self.identifier.unparse(buf)
|
||||
self.0.unparse(buf)
|
||||
}
|
||||
}
|
||||
|
||||
@ -195,10 +196,58 @@ impl Unparse for GenericArgument {
|
||||
|
||||
impl Unparse for TypeUse {
|
||||
fn unparse(&self, buf: &mut dyn std::fmt::Write) -> std::fmt::Result {
|
||||
self.fqn.unparse(buf)?;
|
||||
if let Some(type_arguments) = &self.arguments {
|
||||
type_arguments.unparse(buf)?;
|
||||
use TypeUse::*;
|
||||
match self {
|
||||
InterfaceOrClass(interface_or_class_type_use) => interface_or_class_type_use.unparse(buf),
|
||||
Tuple(tuple_type_use) => tuple_type_use.unparse(buf),
|
||||
Function(function_type_use) => function_type_use.unparse(buf),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl Unparse for InterfaceOrClassTypeUse {
|
||||
fn unparse(&self, buf: &mut dyn std::fmt::Write) -> std::fmt::Result {
|
||||
self.fqn.unparse(buf)?;
|
||||
self.generics.unparse(buf)?;
|
||||
unparse_ok!()
|
||||
}
|
||||
}
|
||||
|
||||
impl ListUnparse for TupleTypeUse {
|
||||
fn prefix() -> &'static str {
|
||||
"("
|
||||
}
|
||||
|
||||
fn separator() -> &'static str {
|
||||
", "
|
||||
}
|
||||
|
||||
fn suffix() -> &'static str {
|
||||
")"
|
||||
}
|
||||
|
||||
fn inner(&self) -> Vec<&dyn Unparse> {
|
||||
to_unparse_vec!(self.0)
|
||||
}
|
||||
}
|
||||
|
||||
impl Unparse for FunctionTypeUse {
|
||||
fn unparse(&self, buf: &mut dyn std::fmt::Write) -> std::fmt::Result {
|
||||
if let Some(function_modifier) = &self.function_modifier {
|
||||
function_modifier.unparse(buf)?;
|
||||
}
|
||||
write!(buf, " fn ")?;
|
||||
if !self.generics.is_empty() {
|
||||
self.generics.unparse(buf)?;
|
||||
write!(buf, " ")?;
|
||||
}
|
||||
self.parameters.unparse(buf)?;
|
||||
write!(buf, " ")?;
|
||||
if !self.inputs.is_empty() {
|
||||
self.inputs.unparse(buf)?;
|
||||
write!(buf, " ")?;
|
||||
}
|
||||
self.return_type.unparse(buf)?;
|
||||
unparse_ok!()
|
||||
}
|
||||
}
|
||||
@ -273,7 +322,7 @@ impl Unparse for Parameter {
|
||||
impl Unparse for ReturnType {
|
||||
fn unparse(&self, buf: &mut dyn std::fmt::Write) -> std::fmt::Result {
|
||||
write!(buf, "-> ")?;
|
||||
self.type_use.unparse(buf)?;
|
||||
self.declared_type.unparse(buf)?;
|
||||
if !self.references.is_empty() {
|
||||
self.references.unparse(buf)?;
|
||||
}
|
||||
@ -281,6 +330,16 @@ impl Unparse for ReturnType {
|
||||
}
|
||||
}
|
||||
|
||||
impl Unparse for VoidOrTypeUse {
|
||||
fn unparse(&self, buf: &mut dyn std::fmt::Write) -> std::fmt::Result {
|
||||
use VoidOrTypeUse::*;
|
||||
match self {
|
||||
Void => write!(buf, "Void"),
|
||||
TypeUse(type_use) => type_use.unparse(buf),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl ListUnparse for References {
|
||||
fn prefix() -> &'static str {
|
||||
"ref "
|
||||
@ -297,7 +356,7 @@ impl ListUnparse for References {
|
||||
|
||||
impl Unparse for Reference {
|
||||
fn unparse(&self, buf: &mut dyn std::fmt::Write) -> std::fmt::Result {
|
||||
self.identifier.unparse(buf)
|
||||
self.0.unparse(buf)
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1,6 +1,6 @@
|
||||
use crate::ast::{
|
||||
AssignExpression, BlockStatement, CallExpression, CompilationUnit, Declaration, Expression,
|
||||
Fqn, FunctionDeclaration, Identifier, LValue, Statement,
|
||||
AssignExpression, BlockStatement, CallExpression, CompilationUnit, Expression, Fqn,
|
||||
FunctionDeclaration, Identifier, LValue, ModuleLevelDeclaration, Statement,
|
||||
};
|
||||
use crate::object_file::{DvmObjectFile, DvmPath};
|
||||
use crate::vm::function::DvmFunction;
|
||||
@ -153,7 +153,7 @@ pub fn convert(file_name: &str, ast: CompilationUnit) -> DvmObjectFile {
|
||||
|
||||
for declaration in ast.declarations() {
|
||||
match declaration {
|
||||
Declaration::Function(function_declaration) => {
|
||||
ModuleLevelDeclaration::Function(function_declaration) => {
|
||||
let function = convert_static_function(&state, &context, function_declaration);
|
||||
object_file.add_function(function);
|
||||
}
|
||||
|
@ -123,13 +123,39 @@ IdentifierChar = {
|
||||
// Parameters = declaration
|
||||
|
||||
TypeUse = {
|
||||
InterfaceOrClassTypeUse
|
||||
| TupleTypeUse
|
||||
| FunctionTypeUse
|
||||
}
|
||||
|
||||
InterfaceOrClassTypeUse = {
|
||||
FullyQualifiedName
|
||||
~ GenericArguments?
|
||||
}
|
||||
|
||||
TupleTypeUse = {
|
||||
"("
|
||||
~ (
|
||||
GenericArguments ~ InputArguments?
|
||||
| TupleGenericArguments
|
||||
| FunctionGenericArguments ~ FunctionInputArguments?
|
||||
| InputArguments
|
||||
TypeUse
|
||||
~ ( "," ~ TypeUse )*
|
||||
)?
|
||||
~ ")"
|
||||
}
|
||||
|
||||
FunctionTypeUse = {
|
||||
FunctionTypeModifier?
|
||||
~ Fn
|
||||
~ GenericParameters?
|
||||
~ TupleTypeUse
|
||||
~ FunctionInputArguments?
|
||||
~ ReturnType
|
||||
}
|
||||
|
||||
FunctionTypeModifier = {
|
||||
Cons
|
||||
| Mut ~ Ref
|
||||
| Mut
|
||||
| Ref
|
||||
}
|
||||
|
||||
GenericArguments = {
|
||||
@ -153,27 +179,6 @@ InputArgument = {
|
||||
~ ( "=" ~ Identifier )
|
||||
}
|
||||
|
||||
TupleGenericArguments = {
|
||||
"("
|
||||
~ (
|
||||
FullyQualifiedName
|
||||
~ ( "," ~ FullyQualifiedName )*
|
||||
)?
|
||||
~ ")"
|
||||
}
|
||||
|
||||
FunctionGenericArguments = {
|
||||
TupleGenericArguments
|
||||
~ ReturnTypeGenericArgument
|
||||
~ FunctionInputArguments?
|
||||
}
|
||||
|
||||
ReturnTypeGenericArgument = {
|
||||
"->"
|
||||
~ ( Void | FullyQualifiedName )
|
||||
~ RefList?
|
||||
}
|
||||
|
||||
RefList = {
|
||||
Ref
|
||||
~ Identifier
|
||||
@ -522,7 +527,7 @@ Field = {
|
||||
FunctionModifier = {
|
||||
Static
|
||||
| Cons
|
||||
| Mut? Ref?
|
||||
| Mut? ~ Ref?
|
||||
}
|
||||
|
||||
FunctionDefinition = {
|
||||
|
Loading…
Reference in New Issue
Block a user