Compare commits
2 Commits
9f5e27b289
...
8c802f2a15
Author | SHA1 | Date | |
---|---|---|---|
![]() |
8c802f2a15 | ||
![]() |
6f727e1cdf |
22
sketching/july_2025/closure.dm
Normal file
22
sketching/july_2025/closure.dm
Normal file
@ -0,0 +1,22 @@
|
|||||||
|
fn main()
|
||||||
|
var x = 42
|
||||||
|
let cl = { i: Int ->
|
||||||
|
let result = x + i
|
||||||
|
x += 1
|
||||||
|
result
|
||||||
|
}
|
||||||
|
println cl(0) // 42
|
||||||
|
println cl(0) // 43
|
||||||
|
println cl(0) // 44
|
||||||
|
end
|
||||||
|
|
||||||
|
fn main()
|
||||||
|
var x = 42
|
||||||
|
fn cl(i: Int): Int
|
||||||
|
let result = x + 1
|
||||||
|
x += 1
|
||||||
|
result
|
||||||
|
end
|
||||||
|
println cl(0) // 42
|
||||||
|
println cl(1) // 42
|
||||||
|
end
|
32
sketching/july_2025/hkt.dm
Normal file
32
sketching/july_2025/hkt.dm
Normal file
@ -0,0 +1,32 @@
|
|||||||
|
pub hkt Functor[Self<T>]
|
||||||
|
fn <U> map(f: fn (t: T) -> U) -> Self<U>
|
||||||
|
end
|
||||||
|
|
||||||
|
pub int Iterable<T>
|
||||||
|
fn iter() -> Iterator<T>
|
||||||
|
end
|
||||||
|
|
||||||
|
pub int Iterator<T> = () -> Option<T>
|
||||||
|
|
||||||
|
pub enum Option<T> : Functor[Self<T>]
|
||||||
|
Some(T),
|
||||||
|
None;
|
||||||
|
|
||||||
|
fn unwrap() -> T
|
||||||
|
self is Some(t) ? t : throw Exception('Empty Option')
|
||||||
|
end
|
||||||
|
|
||||||
|
fn expect(msg: String) -> T
|
||||||
|
self is Some(t) ? t : throw Exception(msg)
|
||||||
|
end
|
||||||
|
|
||||||
|
impl Functor
|
||||||
|
fn <U> map(f: fn (t: T) -> U) -> Self<U>
|
||||||
|
self is Some(t) ? Some(f(t)) : None
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
static fn lift(t: T) -> Self<T>
|
||||||
|
Some(t)
|
||||||
|
end
|
||||||
|
end
|
14
sketching/july_2025/int.dm
Normal file
14
sketching/july_2025/int.dm
Normal file
@ -0,0 +1,14 @@
|
|||||||
|
int Greeter
|
||||||
|
fn greet(): Void
|
||||||
|
end
|
||||||
|
|
||||||
|
class MyGreeter(greeting: String) : Greeter
|
||||||
|
impl fn greet()
|
||||||
|
println greeting
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
fn main()
|
||||||
|
let g: Greeter = MyGreeter("Hello, World!")
|
||||||
|
g.greet()
|
||||||
|
end
|
39
sketching/july_2025/name_one.dm
Normal file
39
sketching/july_2025/name_one.dm
Normal file
@ -0,0 +1,39 @@
|
|||||||
|
fn main(args: Array<String>)
|
||||||
|
if args[0] == 'greet' then
|
||||||
|
println 'Hello!'
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
fn main(args: Array<String>)
|
||||||
|
args.each { println it }
|
||||||
|
end
|
||||||
|
|
||||||
|
fn main(args: Array<String>)
|
||||||
|
if args.find { it == 'greet' } then
|
||||||
|
println 'There was a greet arg'
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
// longer
|
||||||
|
fn main(args: Array<String>)
|
||||||
|
let findIndexResult: Option<Int> = args.findIndex { it == 'greet' }
|
||||||
|
if findIndexResult.isSome() then
|
||||||
|
let index: Int = findIndex.unwrap()
|
||||||
|
println "greet arg was index ${index}"
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
// shorter with destructuring
|
||||||
|
fn main(args: Array<String>)
|
||||||
|
if let Some(greetIndex) = args.findIndex { it == 'greet' } then
|
||||||
|
println "greet arg was index ${greetIndex}"
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
fn main(args: Array<String>)
|
||||||
|
let parsed: CliArgs = std::cli::parse(args)
|
||||||
|
let greetingCount = parsed.get::<Int>('--count', '-c').orElse(1)
|
||||||
|
if let Some(greeting) = parsed.get('greeting', 'g') then
|
||||||
|
greetingCount.times { println greeting }
|
||||||
|
end
|
||||||
|
end
|
105
sketching/july_2025/string.dm
Normal file
105
sketching/july_2025/string.dm
Normal file
@ -0,0 +1,105 @@
|
|||||||
|
pub int Display
|
||||||
|
fn toString() -> String
|
||||||
|
end
|
||||||
|
|
||||||
|
pub int LazyDisplay
|
||||||
|
fn toLazyString() -> DString
|
||||||
|
end
|
||||||
|
|
||||||
|
pub int DString : Display
|
||||||
|
parts: Array<DStringPart>
|
||||||
|
end
|
||||||
|
|
||||||
|
pub enum DStringPart
|
||||||
|
Constant(String),
|
||||||
|
Display(Display),
|
||||||
|
Lazy(Fn<Display>)
|
||||||
|
end
|
||||||
|
|
||||||
|
#internal
|
||||||
|
class DStringImpl(parts) : DString
|
||||||
|
cachedEval: Option<String>
|
||||||
|
canCache: Option<Boolean>
|
||||||
|
|
||||||
|
fn getCanCache() -> Boolean
|
||||||
|
for part in parts do
|
||||||
|
if part is Lazy then return false end
|
||||||
|
end
|
||||||
|
true
|
||||||
|
end
|
||||||
|
|
||||||
|
impl Display
|
||||||
|
pub fn toString() -> String
|
||||||
|
if cachedEval is Some(s) then
|
||||||
|
return s
|
||||||
|
end
|
||||||
|
if canCache is None then
|
||||||
|
canCache = Some(getCanCache())
|
||||||
|
end
|
||||||
|
// Note the groovy-like property getter
|
||||||
|
if canCache.truthy then
|
||||||
|
cachedEval = Some(
|
||||||
|
parts.reduce('') { acc, part ->
|
||||||
|
let partAsString = match part as
|
||||||
|
Constant(s) => s,
|
||||||
|
Display(d) => d.toString(),
|
||||||
|
Lazy(f) => throw DumbProgrammerException(
|
||||||
|
'Cannot cache when parts contains a Lazy.'
|
||||||
|
)
|
||||||
|
end
|
||||||
|
acc + partAsString
|
||||||
|
}
|
||||||
|
)
|
||||||
|
cachedEval.unwrap()
|
||||||
|
else
|
||||||
|
parts.reduce('') { acc, part ->
|
||||||
|
let partAsString = match part as
|
||||||
|
Constant(s) => s,
|
||||||
|
Display(d) => d.toString(),
|
||||||
|
Lazy(f) => f().toString()
|
||||||
|
end
|
||||||
|
acc + partAsString
|
||||||
|
}
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
// Special "extension" implementation of Option for all T where T : Boolean
|
||||||
|
pub int HasTruth
|
||||||
|
fn isTruthy() -> Boolean
|
||||||
|
end
|
||||||
|
|
||||||
|
impl HasTruth for Option<T> where T is Boolean
|
||||||
|
pub fn isTruthy() -> Boolean
|
||||||
|
self is Some(b) ? b : false
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
// some other file
|
||||||
|
use std::extensions::HasTruth[Option<Boolean>]
|
||||||
|
|
||||||
|
fn maybeSomeOrNone -> Option<Boolean>
|
||||||
|
Some(true)
|
||||||
|
end
|
||||||
|
|
||||||
|
fn main()
|
||||||
|
let o = maybeSomeOrNone()
|
||||||
|
if o.truthy then
|
||||||
|
println "It's truthy!"
|
||||||
|
else
|
||||||
|
println "It's falsy..."
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
fn stringDemo() -> Void
|
||||||
|
let plain = 'Hello, World!'
|
||||||
|
let x = 42
|
||||||
|
let withDisplay = "Hello! x is $x"
|
||||||
|
let withLazy = "Hello! x is ${ x + 42 }"
|
||||||
|
println plain // Hello, World!
|
||||||
|
println withDisplay // Hello! x is 42
|
||||||
|
println withLazy // Hello! x is 84
|
||||||
|
x += 42
|
||||||
|
println withLazy // Hello! x is 126
|
||||||
|
end
|
41
sketching/july_2025/trait.dm
Normal file
41
sketching/july_2025/trait.dm
Normal file
@ -0,0 +1,41 @@
|
|||||||
|
pub trait HasTruth
|
||||||
|
fn isTruthy() -> Boolean
|
||||||
|
|
||||||
|
def fn isFalsy() -> Boolean = !self.truthy
|
||||||
|
end
|
||||||
|
|
||||||
|
pub trait Functor[Self<T>]
|
||||||
|
fn <U> map(f: fn (t: T) -> U) -> Self<U>
|
||||||
|
end
|
||||||
|
|
||||||
|
pub trait Lift[Self<T>]
|
||||||
|
static fn lift(t: T) -> Self<T>
|
||||||
|
end
|
||||||
|
|
||||||
|
pub trait Applicative[Self<T>, U, V] : Functor[Self] + Lift[Self] where T is fn (u: U) -> V
|
||||||
|
fn apply(us: Self<U>) -> Self<V>
|
||||||
|
end
|
||||||
|
|
||||||
|
pub trait Monad[Self<T>] : Functor[Self] + Lift[Self]
|
||||||
|
fn <U> flatMap(f: fn (t: T) -> Self<U>) -> Self<U>
|
||||||
|
end
|
||||||
|
|
||||||
|
// Traits as higher-kinded types
|
||||||
|
// - Cannot be used as concrete types, casted, etc.
|
||||||
|
// - Cannot be constructed/instantiated
|
||||||
|
// - Imports are different:
|
||||||
|
// ```
|
||||||
|
// use std::core::Option
|
||||||
|
// use std::trait::Monad[Option<*>] // bring in Monad for all Option<*>
|
||||||
|
// ```
|
||||||
|
// - Once imported, fns are in scope
|
||||||
|
// - Can also be looked-up 'dictionary' style:
|
||||||
|
// ```
|
||||||
|
// use std::trait::HasTruth[Option<Boolean>]
|
||||||
|
//
|
||||||
|
// fn main()
|
||||||
|
// let maybeTruthy: Option<Boolean> = someOtherApiCall()
|
||||||
|
// if HasTruth[maybeTruthy].isTruthy() then
|
||||||
|
// println "It's truthy."
|
||||||
|
// end
|
||||||
|
// ```
|
@ -427,29 +427,37 @@ fn build_namespace(file_id: usize, namespace_pair: Pair<Rule>) -> FullyQualified
|
|||||||
|
|
||||||
fn build_use_statement(file_id: usize, use_statement_pair: Pair<Rule>) -> UseStatement {
|
fn build_use_statement(file_id: usize, use_statement_pair: Pair<Rule>) -> UseStatement {
|
||||||
let as_span = use_statement_pair.as_span();
|
let as_span = use_statement_pair.as_span();
|
||||||
|
let range = Range {
|
||||||
|
start: as_span.start(),
|
||||||
|
end: as_span.end(),
|
||||||
|
};
|
||||||
|
|
||||||
let mut inner = use_statement_pair.into_inner();
|
let mut inner = use_statement_pair.into_inner();
|
||||||
let inner_length = inner.len();
|
let inner_length = inner.len();
|
||||||
|
|
||||||
inner.next().unwrap(); // use
|
inner.next().unwrap(); // use
|
||||||
|
|
||||||
let mut identifiers = vec![];
|
let mut prefixes = vec![];
|
||||||
let mut last = None;
|
let mut built: Option<UseStatement> = None;
|
||||||
|
|
||||||
for (i, inner_pair) in inner.into_iter().enumerate() {
|
for (i, inner_pair) in inner.into_iter().enumerate() {
|
||||||
if i != inner_length - 2 {
|
if i != inner_length - 2 {
|
||||||
identifiers.push(Box::new(expect_and_use(
|
prefixes.push(inner_pair.as_str());
|
||||||
file_id,
|
|
||||||
inner_pair,
|
|
||||||
Rule::Identifier,
|
|
||||||
build_identifier,
|
|
||||||
)));
|
|
||||||
} else {
|
} else {
|
||||||
last = Some(Box::new(match inner_pair.as_rule() {
|
built = Some(match inner_pair.as_rule() {
|
||||||
Rule::Identifier => {
|
Rule::Identifier => UseStatement::Concrete(ConcreteUseStatement::new(
|
||||||
UseStatementLast::Identifier(Box::new(build_identifier(file_id, inner_pair)))
|
prefixes.iter().map(|s| s.to_string()).collect(),
|
||||||
}
|
vec![Box::new(expect_and_use(
|
||||||
Rule::Star => UseStatementLast::Star,
|
file_id,
|
||||||
Rule::UseList => UseStatementLast::Identifiers(
|
inner_pair,
|
||||||
|
Rule::Identifier,
|
||||||
|
build_identifier,
|
||||||
|
))],
|
||||||
|
file_id,
|
||||||
|
range,
|
||||||
|
)),
|
||||||
|
Rule::UseList => UseStatement::Concrete(ConcreteUseStatement::new(
|
||||||
|
prefixes.iter().map(|s| s.to_string()).collect(),
|
||||||
inner_pair
|
inner_pair
|
||||||
.into_inner()
|
.into_inner()
|
||||||
.map(|identifier_pair| {
|
.map(|identifier_pair| {
|
||||||
@ -461,21 +469,20 @@ fn build_use_statement(file_id: usize, use_statement_pair: Pair<Rule>) -> UseSta
|
|||||||
))
|
))
|
||||||
})
|
})
|
||||||
.collect(),
|
.collect(),
|
||||||
),
|
file_id,
|
||||||
|
range,
|
||||||
|
)),
|
||||||
|
Rule::Star => UseStatement::Star(StarUseStatement::new(
|
||||||
|
prefixes.iter().map(|s| s.to_string()).collect(),
|
||||||
|
file_id,
|
||||||
|
range,
|
||||||
|
)),
|
||||||
_ => unreachable!(),
|
_ => unreachable!(),
|
||||||
}));
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
UseStatement::new(
|
built.unwrap()
|
||||||
identifiers,
|
|
||||||
last.unwrap(),
|
|
||||||
file_id,
|
|
||||||
Range {
|
|
||||||
start: as_span.start(),
|
|
||||||
end: as_span.end(),
|
|
||||||
},
|
|
||||||
)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fn build_module_level_declaration(file_id: usize, pair: Pair<Rule>) -> ModuleLevelDeclaration {
|
fn build_module_level_declaration(file_id: usize, pair: Pair<Rule>) -> ModuleLevelDeclaration {
|
||||||
|
@ -88,7 +88,7 @@ pub enum NodeRef<'a> {
|
|||||||
|
|
||||||
pub trait NodeInner {
|
pub trait NodeInner {
|
||||||
fn children(&self) -> Vec<NodeRef>;
|
fn children(&self) -> Vec<NodeRef>;
|
||||||
|
|
||||||
fn as_node_ref(&self) -> NodeRef;
|
fn as_node_ref(&self) -> NodeRef;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -96,7 +96,7 @@ impl NodeInner for Identifier {
|
|||||||
fn children(&self) -> Vec<NodeRef> {
|
fn children(&self) -> Vec<NodeRef> {
|
||||||
vec![]
|
vec![]
|
||||||
}
|
}
|
||||||
|
|
||||||
fn as_node_ref(&self) -> NodeRef {
|
fn as_node_ref(&self) -> NodeRef {
|
||||||
NodeRef::Identifier(self)
|
NodeRef::Identifier(self)
|
||||||
}
|
}
|
||||||
@ -109,7 +109,7 @@ impl NodeInner for FullyQualifiedName {
|
|||||||
.map(|id| NodeRef::Identifier(*id))
|
.map(|id| NodeRef::Identifier(*id))
|
||||||
.collect()
|
.collect()
|
||||||
}
|
}
|
||||||
|
|
||||||
fn as_node_ref(&self) -> NodeRef {
|
fn as_node_ref(&self) -> NodeRef {
|
||||||
NodeRef::FullyQualifiedName(self)
|
NodeRef::FullyQualifiedName(self)
|
||||||
}
|
}
|
||||||
@ -126,7 +126,7 @@ impl NodeInner for TypeUse {
|
|||||||
TypeUse::Function(function_type_use) => function_type_use.children(),
|
TypeUse::Function(function_type_use) => function_type_use.children(),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn as_node_ref(&self) -> NodeRef {
|
fn as_node_ref(&self) -> NodeRef {
|
||||||
NodeRef::TypeUse(self)
|
NodeRef::TypeUse(self)
|
||||||
}
|
}
|
||||||
@ -145,7 +145,7 @@ impl NodeInner for PrimitiveTypeUse {
|
|||||||
_ => vec![],
|
_ => vec![],
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn as_node_ref(&self) -> NodeRef {
|
fn as_node_ref(&self) -> NodeRef {
|
||||||
NodeRef::PrimitiveTypeUse(self)
|
NodeRef::PrimitiveTypeUse(self)
|
||||||
}
|
}
|
||||||
@ -158,7 +158,7 @@ impl NodeInner for InterfaceOrClassTypeUse {
|
|||||||
children.push(NodeRef::GenericArguments(self.generics()));
|
children.push(NodeRef::GenericArguments(self.generics()));
|
||||||
children
|
children
|
||||||
}
|
}
|
||||||
|
|
||||||
fn as_node_ref(&self) -> NodeRef {
|
fn as_node_ref(&self) -> NodeRef {
|
||||||
NodeRef::InterfaceOrClassTypeUse(self)
|
NodeRef::InterfaceOrClassTypeUse(self)
|
||||||
}
|
}
|
||||||
@ -168,7 +168,7 @@ impl NodeInner for TupleTypeUse {
|
|||||||
fn children(&self) -> Vec<NodeRef> {
|
fn children(&self) -> Vec<NodeRef> {
|
||||||
vec![NodeRef::TupleArguments(self.arguments())]
|
vec![NodeRef::TupleArguments(self.arguments())]
|
||||||
}
|
}
|
||||||
|
|
||||||
fn as_node_ref(&self) -> NodeRef {
|
fn as_node_ref(&self) -> NodeRef {
|
||||||
NodeRef::TupleTypeUse(self)
|
NodeRef::TupleTypeUse(self)
|
||||||
}
|
}
|
||||||
@ -182,7 +182,7 @@ impl NodeInner for FunctionTypeUse {
|
|||||||
NodeRef::ReturnType(self.return_type()),
|
NodeRef::ReturnType(self.return_type()),
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
|
|
||||||
fn as_node_ref(&self) -> NodeRef {
|
fn as_node_ref(&self) -> NodeRef {
|
||||||
NodeRef::FunctionTypeUse(self)
|
NodeRef::FunctionTypeUse(self)
|
||||||
}
|
}
|
||||||
@ -195,7 +195,7 @@ impl NodeInner for GenericArguments {
|
|||||||
.map(|type_use| NodeRef::TypeUse(*type_use))
|
.map(|type_use| NodeRef::TypeUse(*type_use))
|
||||||
.collect()
|
.collect()
|
||||||
}
|
}
|
||||||
|
|
||||||
fn as_node_ref(&self) -> NodeRef {
|
fn as_node_ref(&self) -> NodeRef {
|
||||||
NodeRef::GenericArguments(self)
|
NodeRef::GenericArguments(self)
|
||||||
}
|
}
|
||||||
@ -208,7 +208,7 @@ impl NodeInner for GenericParameters {
|
|||||||
.map(|id| NodeRef::Identifier(*id))
|
.map(|id| NodeRef::Identifier(*id))
|
||||||
.collect()
|
.collect()
|
||||||
}
|
}
|
||||||
|
|
||||||
fn as_node_ref(&self) -> NodeRef {
|
fn as_node_ref(&self) -> NodeRef {
|
||||||
NodeRef::GenericParameters(self)
|
NodeRef::GenericParameters(self)
|
||||||
}
|
}
|
||||||
@ -221,7 +221,7 @@ impl NodeInner for TupleArguments {
|
|||||||
.map(|type_use| NodeRef::TypeUse(*type_use))
|
.map(|type_use| NodeRef::TypeUse(*type_use))
|
||||||
.collect()
|
.collect()
|
||||||
}
|
}
|
||||||
|
|
||||||
fn as_node_ref(&self) -> NodeRef {
|
fn as_node_ref(&self) -> NodeRef {
|
||||||
NodeRef::TupleArguments(self)
|
NodeRef::TupleArguments(self)
|
||||||
}
|
}
|
||||||
@ -234,7 +234,7 @@ impl NodeInner for ImplementsList {
|
|||||||
.map(|type_use| NodeRef::TypeUse(*type_use))
|
.map(|type_use| NodeRef::TypeUse(*type_use))
|
||||||
.collect()
|
.collect()
|
||||||
}
|
}
|
||||||
|
|
||||||
fn as_node_ref(&self) -> NodeRef {
|
fn as_node_ref(&self) -> NodeRef {
|
||||||
NodeRef::ImplementsList(self)
|
NodeRef::ImplementsList(self)
|
||||||
}
|
}
|
||||||
@ -247,7 +247,7 @@ impl NodeInner for Parameters {
|
|||||||
.map(|parameter| NodeRef::Parameter(*parameter))
|
.map(|parameter| NodeRef::Parameter(*parameter))
|
||||||
.collect()
|
.collect()
|
||||||
}
|
}
|
||||||
|
|
||||||
fn as_node_ref(&self) -> NodeRef {
|
fn as_node_ref(&self) -> NodeRef {
|
||||||
NodeRef::Parameters(self)
|
NodeRef::Parameters(self)
|
||||||
}
|
}
|
||||||
@ -260,7 +260,7 @@ impl NodeInner for Parameter {
|
|||||||
NodeRef::TypeUse(self.type_use()),
|
NodeRef::TypeUse(self.type_use()),
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
|
|
||||||
fn as_node_ref(&self) -> NodeRef {
|
fn as_node_ref(&self) -> NodeRef {
|
||||||
NodeRef::Parameter(self)
|
NodeRef::Parameter(self)
|
||||||
}
|
}
|
||||||
@ -273,7 +273,7 @@ impl NodeInner for ReturnType {
|
|||||||
NodeRef::References(self.references()),
|
NodeRef::References(self.references()),
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
|
|
||||||
fn as_node_ref(&self) -> NodeRef {
|
fn as_node_ref(&self) -> NodeRef {
|
||||||
NodeRef::ReturnType(self)
|
NodeRef::ReturnType(self)
|
||||||
}
|
}
|
||||||
@ -286,7 +286,7 @@ impl NodeInner for References {
|
|||||||
.map(|identifier| NodeRef::Identifier(*identifier))
|
.map(|identifier| NodeRef::Identifier(*identifier))
|
||||||
.collect()
|
.collect()
|
||||||
}
|
}
|
||||||
|
|
||||||
fn as_node_ref(&self) -> NodeRef {
|
fn as_node_ref(&self) -> NodeRef {
|
||||||
NodeRef::References(self)
|
NodeRef::References(self)
|
||||||
}
|
}
|
||||||
@ -310,7 +310,7 @@ impl NodeInner for CompilationUnit {
|
|||||||
);
|
);
|
||||||
children
|
children
|
||||||
}
|
}
|
||||||
|
|
||||||
fn as_node_ref(&self) -> NodeRef {
|
fn as_node_ref(&self) -> NodeRef {
|
||||||
NodeRef::CompilationUnit(self)
|
NodeRef::CompilationUnit(self)
|
||||||
}
|
}
|
||||||
@ -319,25 +319,18 @@ impl NodeInner for CompilationUnit {
|
|||||||
impl NodeInner for UseStatement {
|
impl NodeInner for UseStatement {
|
||||||
fn children(&self) -> Vec<NodeRef> {
|
fn children(&self) -> Vec<NodeRef> {
|
||||||
let mut children = vec![];
|
let mut children = vec![];
|
||||||
children.extend(
|
match self {
|
||||||
self.identifiers()
|
UseStatement::Concrete(concrete_use_statement) => children.extend(
|
||||||
.iter()
|
concrete_use_statement
|
||||||
.map(|identifier| NodeRef::Identifier(*identifier)),
|
.identifiers()
|
||||||
);
|
|
||||||
match self.last() {
|
|
||||||
UseStatementLast::Identifier(identifier) => {
|
|
||||||
children.push(NodeRef::Identifier(identifier))
|
|
||||||
}
|
|
||||||
UseStatementLast::Identifiers(identifiers) => children.extend(
|
|
||||||
identifiers
|
|
||||||
.iter()
|
.iter()
|
||||||
.map(|identifier| NodeRef::Identifier(identifier.clone())),
|
.map(|identifier| NodeRef::Identifier(*identifier))
|
||||||
),
|
),
|
||||||
UseStatementLast::Star => {}
|
UseStatement::Star(_) => {}
|
||||||
}
|
}
|
||||||
children
|
children
|
||||||
}
|
}
|
||||||
|
|
||||||
fn as_node_ref(&self) -> NodeRef {
|
fn as_node_ref(&self) -> NodeRef {
|
||||||
NodeRef::UseStatement(self)
|
NodeRef::UseStatement(self)
|
||||||
}
|
}
|
||||||
@ -356,7 +349,7 @@ impl NodeInner for ModuleLevelDeclaration {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn as_node_ref(&self) -> NodeRef {
|
fn as_node_ref(&self) -> NodeRef {
|
||||||
NodeRef::ModuleLevelDeclaration(self)
|
NodeRef::ModuleLevelDeclaration(self)
|
||||||
}
|
}
|
||||||
@ -375,7 +368,7 @@ impl NodeInner for InterfaceLevelDeclaration {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn as_node_ref(&self) -> NodeRef {
|
fn as_node_ref(&self) -> NodeRef {
|
||||||
NodeRef::InterfaceLevelDeclaration(self)
|
NodeRef::InterfaceLevelDeclaration(self)
|
||||||
}
|
}
|
||||||
@ -399,7 +392,7 @@ impl NodeInner for ClassLevelDeclaration {
|
|||||||
Field(field_declaration) => field_declaration.children(),
|
Field(field_declaration) => field_declaration.children(),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn as_node_ref(&self) -> NodeRef {
|
fn as_node_ref(&self) -> NodeRef {
|
||||||
NodeRef::ClassLevelDeclaration(self)
|
NodeRef::ClassLevelDeclaration(self)
|
||||||
}
|
}
|
||||||
@ -416,7 +409,7 @@ impl NodeInner for ModuleDeclaration {
|
|||||||
);
|
);
|
||||||
children
|
children
|
||||||
}
|
}
|
||||||
|
|
||||||
fn as_node_ref(&self) -> NodeRef {
|
fn as_node_ref(&self) -> NodeRef {
|
||||||
NodeRef::ModuleDeclaration(self)
|
NodeRef::ModuleDeclaration(self)
|
||||||
}
|
}
|
||||||
@ -435,7 +428,7 @@ impl NodeInner for InterfaceDeclaration {
|
|||||||
);
|
);
|
||||||
children
|
children
|
||||||
}
|
}
|
||||||
|
|
||||||
fn as_node_ref(&self) -> NodeRef {
|
fn as_node_ref(&self) -> NodeRef {
|
||||||
NodeRef::InterfaceDeclaration(self)
|
NodeRef::InterfaceDeclaration(self)
|
||||||
}
|
}
|
||||||
@ -457,7 +450,7 @@ impl NodeInner for ClassDeclaration {
|
|||||||
);
|
);
|
||||||
children
|
children
|
||||||
}
|
}
|
||||||
|
|
||||||
fn as_node_ref(&self) -> NodeRef {
|
fn as_node_ref(&self) -> NodeRef {
|
||||||
NodeRef::ClassDeclaration(self)
|
NodeRef::ClassDeclaration(self)
|
||||||
}
|
}
|
||||||
@ -473,7 +466,7 @@ impl NodeInner for FunctionDefinition {
|
|||||||
NodeRef::FunctionBody(self.body()),
|
NodeRef::FunctionBody(self.body()),
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
|
|
||||||
fn as_node_ref(&self) -> NodeRef {
|
fn as_node_ref(&self) -> NodeRef {
|
||||||
NodeRef::FunctionDefinition(self)
|
NodeRef::FunctionDefinition(self)
|
||||||
}
|
}
|
||||||
@ -488,7 +481,7 @@ impl NodeInner for OperatorFunctionDefinition {
|
|||||||
NodeRef::FunctionBody(self.body()),
|
NodeRef::FunctionBody(self.body()),
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
|
|
||||||
fn as_node_ref(&self) -> NodeRef {
|
fn as_node_ref(&self) -> NodeRef {
|
||||||
NodeRef::OperatorFunctionDefinition(self)
|
NodeRef::OperatorFunctionDefinition(self)
|
||||||
}
|
}
|
||||||
@ -503,7 +496,7 @@ impl NodeInner for PlatformFunctionDeclaration {
|
|||||||
NodeRef::ReturnType(self.return_type()),
|
NodeRef::ReturnType(self.return_type()),
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
|
|
||||||
fn as_node_ref(&self) -> NodeRef {
|
fn as_node_ref(&self) -> NodeRef {
|
||||||
NodeRef::PlatformFunctionDeclaration(self)
|
NodeRef::PlatformFunctionDeclaration(self)
|
||||||
}
|
}
|
||||||
@ -522,7 +515,7 @@ impl NodeInner for InterfaceFunctionDeclaration {
|
|||||||
}
|
}
|
||||||
children
|
children
|
||||||
}
|
}
|
||||||
|
|
||||||
fn as_node_ref(&self) -> NodeRef {
|
fn as_node_ref(&self) -> NodeRef {
|
||||||
NodeRef::InterfaceFunctionDeclaration(self)
|
NodeRef::InterfaceFunctionDeclaration(self)
|
||||||
}
|
}
|
||||||
@ -540,7 +533,7 @@ impl NodeInner for InterfaceOperatorFunctionDeclaration {
|
|||||||
}
|
}
|
||||||
children
|
children
|
||||||
}
|
}
|
||||||
|
|
||||||
fn as_node_ref(&self) -> NodeRef {
|
fn as_node_ref(&self) -> NodeRef {
|
||||||
NodeRef::InterfaceOperatorFunctionDeclaration(self)
|
NodeRef::InterfaceOperatorFunctionDeclaration(self)
|
||||||
}
|
}
|
||||||
@ -554,7 +547,7 @@ impl NodeInner for FunctionBody {
|
|||||||
Self::Alias(identifier) => vec![NodeRef::Identifier(identifier.as_ref())],
|
Self::Alias(identifier) => vec![NodeRef::Identifier(identifier.as_ref())],
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn as_node_ref(&self) -> NodeRef {
|
fn as_node_ref(&self) -> NodeRef {
|
||||||
NodeRef::FunctionBody(self)
|
NodeRef::FunctionBody(self)
|
||||||
}
|
}
|
||||||
@ -567,7 +560,7 @@ impl NodeInner for ClassConstructor {
|
|||||||
.map(|parameter| NodeRef::ClassConstructorParameter(*parameter))
|
.map(|parameter| NodeRef::ClassConstructorParameter(*parameter))
|
||||||
.collect()
|
.collect()
|
||||||
}
|
}
|
||||||
|
|
||||||
fn as_node_ref(&self) -> NodeRef {
|
fn as_node_ref(&self) -> NodeRef {
|
||||||
NodeRef::ClassConstructor(self)
|
NodeRef::ClassConstructor(self)
|
||||||
}
|
}
|
||||||
@ -580,7 +573,7 @@ impl NodeInner for ClassConstructorParameter {
|
|||||||
Self::Field(field_declaration) => field_declaration.children(),
|
Self::Field(field_declaration) => field_declaration.children(),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn as_node_ref(&self) -> NodeRef {
|
fn as_node_ref(&self) -> NodeRef {
|
||||||
NodeRef::ClassConstructorParameter(self)
|
NodeRef::ClassConstructorParameter(self)
|
||||||
}
|
}
|
||||||
@ -593,7 +586,7 @@ impl NodeInner for PropertyDeclaration {
|
|||||||
NodeRef::TypeUse(self.declared_type()),
|
NodeRef::TypeUse(self.declared_type()),
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
|
|
||||||
fn as_node_ref(&self) -> NodeRef {
|
fn as_node_ref(&self) -> NodeRef {
|
||||||
NodeRef::PropertyDeclaration(self)
|
NodeRef::PropertyDeclaration(self)
|
||||||
}
|
}
|
||||||
@ -606,7 +599,7 @@ impl NodeInner for FieldDeclaration {
|
|||||||
NodeRef::TypeUse(self.declared_type()),
|
NodeRef::TypeUse(self.declared_type()),
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
|
|
||||||
fn as_node_ref(&self) -> NodeRef {
|
fn as_node_ref(&self) -> NodeRef {
|
||||||
NodeRef::FieldDeclaration(self)
|
NodeRef::FieldDeclaration(self)
|
||||||
}
|
}
|
||||||
@ -625,7 +618,7 @@ impl NodeInner for BlockStatement {
|
|||||||
}
|
}
|
||||||
children
|
children
|
||||||
}
|
}
|
||||||
|
|
||||||
fn as_node_ref(&self) -> NodeRef {
|
fn as_node_ref(&self) -> NodeRef {
|
||||||
NodeRef::BlockStatement(self)
|
NodeRef::BlockStatement(self)
|
||||||
}
|
}
|
||||||
@ -648,7 +641,7 @@ impl NodeInner for Statement {
|
|||||||
ForStatement(for_statement) => for_statement.children(),
|
ForStatement(for_statement) => for_statement.children(),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn as_node_ref(&self) -> NodeRef {
|
fn as_node_ref(&self) -> NodeRef {
|
||||||
NodeRef::Statement(self)
|
NodeRef::Statement(self)
|
||||||
}
|
}
|
||||||
@ -666,7 +659,7 @@ impl NodeInner for VariableDeclarationStatement {
|
|||||||
}
|
}
|
||||||
children
|
children
|
||||||
}
|
}
|
||||||
|
|
||||||
fn as_node_ref(&self) -> NodeRef {
|
fn as_node_ref(&self) -> NodeRef {
|
||||||
NodeRef::VariableDeclarationStatement(self)
|
NodeRef::VariableDeclarationStatement(self)
|
||||||
}
|
}
|
||||||
@ -679,7 +672,7 @@ impl NodeInner for AssignStatement {
|
|||||||
NodeRef::Expression(self.rhs()),
|
NodeRef::Expression(self.rhs()),
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
|
|
||||||
fn as_node_ref(&self) -> NodeRef {
|
fn as_node_ref(&self) -> NodeRef {
|
||||||
NodeRef::AssignStatement(self)
|
NodeRef::AssignStatement(self)
|
||||||
}
|
}
|
||||||
@ -689,7 +682,7 @@ impl NodeInner for CallStatement {
|
|||||||
fn children(&self) -> Vec<NodeRef> {
|
fn children(&self) -> Vec<NodeRef> {
|
||||||
vec![NodeRef::Expression(self.expression())]
|
vec![NodeRef::Expression(self.expression())]
|
||||||
}
|
}
|
||||||
|
|
||||||
fn as_node_ref(&self) -> NodeRef {
|
fn as_node_ref(&self) -> NodeRef {
|
||||||
NodeRef::CallStatement(self)
|
NodeRef::CallStatement(self)
|
||||||
}
|
}
|
||||||
@ -703,7 +696,7 @@ impl NodeInner for ReturnStatement {
|
|||||||
vec![]
|
vec![]
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn as_node_ref(&self) -> NodeRef {
|
fn as_node_ref(&self) -> NodeRef {
|
||||||
NodeRef::ReturnStatement(self)
|
NodeRef::ReturnStatement(self)
|
||||||
}
|
}
|
||||||
@ -716,7 +709,7 @@ impl NodeInner for IfStatement {
|
|||||||
NodeRef::BlockStatement(self.then_block()),
|
NodeRef::BlockStatement(self.then_block()),
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
|
|
||||||
fn as_node_ref(&self) -> NodeRef {
|
fn as_node_ref(&self) -> NodeRef {
|
||||||
NodeRef::IfStatement(self)
|
NodeRef::IfStatement(self)
|
||||||
}
|
}
|
||||||
@ -732,7 +725,7 @@ impl NodeInner for IfElseStatement {
|
|||||||
}
|
}
|
||||||
children
|
children
|
||||||
}
|
}
|
||||||
|
|
||||||
fn as_node_ref(&self) -> NodeRef {
|
fn as_node_ref(&self) -> NodeRef {
|
||||||
NodeRef::IfElseStatement(self)
|
NodeRef::IfElseStatement(self)
|
||||||
}
|
}
|
||||||
@ -745,7 +738,7 @@ impl NodeInner for ElseIfs {
|
|||||||
.map(|statement| NodeRef::IfStatement(statement))
|
.map(|statement| NodeRef::IfStatement(statement))
|
||||||
.collect()
|
.collect()
|
||||||
}
|
}
|
||||||
|
|
||||||
fn as_node_ref(&self) -> NodeRef {
|
fn as_node_ref(&self) -> NodeRef {
|
||||||
NodeRef::ElseIfs(self)
|
NodeRef::ElseIfs(self)
|
||||||
}
|
}
|
||||||
@ -755,7 +748,7 @@ impl NodeInner for ElseBlock {
|
|||||||
fn children(&self) -> Vec<NodeRef> {
|
fn children(&self) -> Vec<NodeRef> {
|
||||||
vec![NodeRef::BlockStatement(self.block_statement())]
|
vec![NodeRef::BlockStatement(self.block_statement())]
|
||||||
}
|
}
|
||||||
|
|
||||||
fn as_node_ref(&self) -> NodeRef {
|
fn as_node_ref(&self) -> NodeRef {
|
||||||
NodeRef::ElseBlock(self)
|
NodeRef::ElseBlock(self)
|
||||||
}
|
}
|
||||||
@ -768,7 +761,7 @@ impl NodeInner for WhileStatement {
|
|||||||
NodeRef::BlockStatement(self.body()),
|
NodeRef::BlockStatement(self.body()),
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
|
|
||||||
fn as_node_ref(&self) -> NodeRef {
|
fn as_node_ref(&self) -> NodeRef {
|
||||||
NodeRef::WhileStatement(self)
|
NodeRef::WhileStatement(self)
|
||||||
}
|
}
|
||||||
@ -782,7 +775,7 @@ impl NodeInner for ForStatement {
|
|||||||
NodeRef::BlockStatement(self.body()),
|
NodeRef::BlockStatement(self.body()),
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
|
|
||||||
fn as_node_ref(&self) -> NodeRef {
|
fn as_node_ref(&self) -> NodeRef {
|
||||||
NodeRef::ForStatement(self)
|
NodeRef::ForStatement(self)
|
||||||
}
|
}
|
||||||
@ -803,7 +796,7 @@ impl NodeInner for Expression {
|
|||||||
Closure(closure) => closure.children(),
|
Closure(closure) => closure.children(),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn as_node_ref(&self) -> NodeRef {
|
fn as_node_ref(&self) -> NodeRef {
|
||||||
NodeRef::Expression(self)
|
NodeRef::Expression(self)
|
||||||
}
|
}
|
||||||
@ -817,7 +810,7 @@ impl NodeInner for TernaryExpression {
|
|||||||
NodeRef::Expression(self.false_expression()),
|
NodeRef::Expression(self.false_expression()),
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
|
|
||||||
fn as_node_ref(&self) -> NodeRef {
|
fn as_node_ref(&self) -> NodeRef {
|
||||||
NodeRef::TernaryExpression(self)
|
NodeRef::TernaryExpression(self)
|
||||||
}
|
}
|
||||||
@ -830,7 +823,7 @@ impl NodeInner for BinaryExpression {
|
|||||||
NodeRef::Expression(self.right()),
|
NodeRef::Expression(self.right()),
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
|
|
||||||
fn as_node_ref(&self) -> NodeRef {
|
fn as_node_ref(&self) -> NodeRef {
|
||||||
NodeRef::BinaryExpression(self)
|
NodeRef::BinaryExpression(self)
|
||||||
}
|
}
|
||||||
@ -840,7 +833,7 @@ impl NodeInner for PrefixExpression {
|
|||||||
fn children(&self) -> Vec<NodeRef> {
|
fn children(&self) -> Vec<NodeRef> {
|
||||||
vec![NodeRef::Expression(self.expression())]
|
vec![NodeRef::Expression(self.expression())]
|
||||||
}
|
}
|
||||||
|
|
||||||
fn as_node_ref(&self) -> NodeRef {
|
fn as_node_ref(&self) -> NodeRef {
|
||||||
NodeRef::PrefixExpression(self)
|
NodeRef::PrefixExpression(self)
|
||||||
}
|
}
|
||||||
@ -850,7 +843,7 @@ impl NodeInner for SuffixExpression {
|
|||||||
fn children(&self) -> Vec<NodeRef> {
|
fn children(&self) -> Vec<NodeRef> {
|
||||||
vec![NodeRef::Expression(self.expression())]
|
vec![NodeRef::Expression(self.expression())]
|
||||||
}
|
}
|
||||||
|
|
||||||
fn as_node_ref(&self) -> NodeRef {
|
fn as_node_ref(&self) -> NodeRef {
|
||||||
NodeRef::SuffixExpression(self)
|
NodeRef::SuffixExpression(self)
|
||||||
}
|
}
|
||||||
@ -866,7 +859,7 @@ impl NodeInner for CallExpression {
|
|||||||
children.push(NodeRef::CallArguments(self.arguments()));
|
children.push(NodeRef::CallArguments(self.arguments()));
|
||||||
children
|
children
|
||||||
}
|
}
|
||||||
|
|
||||||
fn as_node_ref(&self) -> NodeRef {
|
fn as_node_ref(&self) -> NodeRef {
|
||||||
NodeRef::CallExpression(self)
|
NodeRef::CallExpression(self)
|
||||||
}
|
}
|
||||||
@ -876,7 +869,7 @@ impl NodeInner for TurboFish {
|
|||||||
fn children(&self) -> Vec<NodeRef> {
|
fn children(&self) -> Vec<NodeRef> {
|
||||||
vec![NodeRef::GenericArguments(self.generics())]
|
vec![NodeRef::GenericArguments(self.generics())]
|
||||||
}
|
}
|
||||||
|
|
||||||
fn as_node_ref(&self) -> NodeRef {
|
fn as_node_ref(&self) -> NodeRef {
|
||||||
NodeRef::TurboFish(self)
|
NodeRef::TurboFish(self)
|
||||||
}
|
}
|
||||||
@ -889,7 +882,7 @@ impl NodeInner for CallArguments {
|
|||||||
.map(|argument| NodeRef::CallArgument(*argument))
|
.map(|argument| NodeRef::CallArgument(*argument))
|
||||||
.collect()
|
.collect()
|
||||||
}
|
}
|
||||||
|
|
||||||
fn as_node_ref(&self) -> NodeRef {
|
fn as_node_ref(&self) -> NodeRef {
|
||||||
NodeRef::CallArguments(self)
|
NodeRef::CallArguments(self)
|
||||||
}
|
}
|
||||||
@ -899,7 +892,7 @@ impl NodeInner for CallArgument {
|
|||||||
fn children(&self) -> Vec<NodeRef> {
|
fn children(&self) -> Vec<NodeRef> {
|
||||||
vec![NodeRef::Expression(self.expression())]
|
vec![NodeRef::Expression(self.expression())]
|
||||||
}
|
}
|
||||||
|
|
||||||
fn as_node_ref(&self) -> NodeRef {
|
fn as_node_ref(&self) -> NodeRef {
|
||||||
NodeRef::CallArgument(self)
|
NodeRef::CallArgument(self)
|
||||||
}
|
}
|
||||||
@ -920,7 +913,7 @@ impl NodeInner for Closure {
|
|||||||
}
|
}
|
||||||
children
|
children
|
||||||
}
|
}
|
||||||
|
|
||||||
fn as_node_ref(&self) -> NodeRef {
|
fn as_node_ref(&self) -> NodeRef {
|
||||||
NodeRef::Closure(self)
|
NodeRef::Closure(self)
|
||||||
}
|
}
|
||||||
@ -933,7 +926,7 @@ impl NodeInner for ClosureCaptures {
|
|||||||
.map(|capture| NodeRef::ClosureCapture(*capture))
|
.map(|capture| NodeRef::ClosureCapture(*capture))
|
||||||
.collect()
|
.collect()
|
||||||
}
|
}
|
||||||
|
|
||||||
fn as_node_ref(&self) -> NodeRef {
|
fn as_node_ref(&self) -> NodeRef {
|
||||||
NodeRef::ClosureCaptures(self)
|
NodeRef::ClosureCaptures(self)
|
||||||
}
|
}
|
||||||
@ -943,7 +936,7 @@ impl NodeInner for ClosureCapture {
|
|||||||
fn children(&self) -> Vec<NodeRef> {
|
fn children(&self) -> Vec<NodeRef> {
|
||||||
vec![NodeRef::Identifier(self.identifier())]
|
vec![NodeRef::Identifier(self.identifier())]
|
||||||
}
|
}
|
||||||
|
|
||||||
fn as_node_ref(&self) -> NodeRef {
|
fn as_node_ref(&self) -> NodeRef {
|
||||||
NodeRef::ClosureCapture(self)
|
NodeRef::ClosureCapture(self)
|
||||||
}
|
}
|
||||||
@ -956,7 +949,7 @@ impl NodeInner for ClosureParameters {
|
|||||||
.map(|parameter| NodeRef::ClosureParameter(*parameter))
|
.map(|parameter| NodeRef::ClosureParameter(*parameter))
|
||||||
.collect()
|
.collect()
|
||||||
}
|
}
|
||||||
|
|
||||||
fn as_node_ref(&self) -> NodeRef {
|
fn as_node_ref(&self) -> NodeRef {
|
||||||
NodeRef::ClosureParameters(self)
|
NodeRef::ClosureParameters(self)
|
||||||
}
|
}
|
||||||
@ -971,7 +964,7 @@ impl NodeInner for ClosureParameter {
|
|||||||
}
|
}
|
||||||
children
|
children
|
||||||
}
|
}
|
||||||
|
|
||||||
fn as_node_ref(&self) -> NodeRef {
|
fn as_node_ref(&self) -> NodeRef {
|
||||||
NodeRef::ClosureParameter(self)
|
NodeRef::ClosureParameter(self)
|
||||||
}
|
}
|
||||||
@ -984,7 +977,7 @@ impl NodeInner for ObjectAccess {
|
|||||||
NodeRef::ObjectNavigations(self.navigations()),
|
NodeRef::ObjectNavigations(self.navigations()),
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
|
|
||||||
fn as_node_ref(&self) -> NodeRef {
|
fn as_node_ref(&self) -> NodeRef {
|
||||||
NodeRef::ObjectAccess(self)
|
NodeRef::ObjectAccess(self)
|
||||||
}
|
}
|
||||||
@ -997,7 +990,7 @@ impl NodeInner for ObjectNavigations {
|
|||||||
.map(|navigation| NodeRef::ObjectNavigation(*navigation))
|
.map(|navigation| NodeRef::ObjectNavigation(*navigation))
|
||||||
.collect()
|
.collect()
|
||||||
}
|
}
|
||||||
|
|
||||||
fn as_node_ref(&self) -> NodeRef {
|
fn as_node_ref(&self) -> NodeRef {
|
||||||
NodeRef::ObjectNavigations(self)
|
NodeRef::ObjectNavigations(self)
|
||||||
}
|
}
|
||||||
@ -1010,7 +1003,7 @@ impl NodeInner for ObjectNavigation {
|
|||||||
ObjectNavigation::Index(index_expression) => NodeRef::Expression(index_expression),
|
ObjectNavigation::Index(index_expression) => NodeRef::Expression(index_expression),
|
||||||
}]
|
}]
|
||||||
}
|
}
|
||||||
|
|
||||||
fn as_node_ref(&self) -> NodeRef {
|
fn as_node_ref(&self) -> NodeRef {
|
||||||
NodeRef::ObjectNavigation(self)
|
NodeRef::ObjectNavigation(self)
|
||||||
}
|
}
|
||||||
@ -1024,7 +1017,7 @@ impl NodeInner for Literal {
|
|||||||
_ => vec![],
|
_ => vec![],
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn as_node_ref(&self) -> NodeRef {
|
fn as_node_ref(&self) -> NodeRef {
|
||||||
NodeRef::Literal(self)
|
NodeRef::Literal(self)
|
||||||
}
|
}
|
||||||
@ -1037,7 +1030,7 @@ impl NodeInner for DString {
|
|||||||
.map(|part| NodeRef::DStringPart(*part))
|
.map(|part| NodeRef::DStringPart(*part))
|
||||||
.collect()
|
.collect()
|
||||||
}
|
}
|
||||||
|
|
||||||
fn as_node_ref(&self) -> NodeRef {
|
fn as_node_ref(&self) -> NodeRef {
|
||||||
NodeRef::DString(self)
|
NodeRef::DString(self)
|
||||||
}
|
}
|
||||||
@ -1050,7 +1043,7 @@ impl NodeInner for DStringPart {
|
|||||||
_ => vec![],
|
_ => vec![],
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn as_node_ref(&self) -> NodeRef {
|
fn as_node_ref(&self) -> NodeRef {
|
||||||
NodeRef::DStringPart(self)
|
NodeRef::DStringPart(self)
|
||||||
}
|
}
|
||||||
|
@ -1,75 +1,48 @@
|
|||||||
use crate::ast::node::named::Named;
|
use crate::ast::node::named::Named;
|
||||||
use crate::ast::node::names::Identifier;
|
use crate::ast::node::names::Identifier;
|
||||||
use std::borrow::Cow;
|
|
||||||
use std::range::Range;
|
use std::range::Range;
|
||||||
|
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
pub struct UseStatement {
|
pub enum UseStatement {
|
||||||
|
Concrete(ConcreteUseStatement),
|
||||||
|
Star(StarUseStatement),
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Debug)]
|
||||||
|
pub struct ConcreteUseStatement {
|
||||||
|
prefixes: Vec<String>,
|
||||||
identifiers: Vec<Box<Identifier>>,
|
identifiers: Vec<Box<Identifier>>,
|
||||||
last: Box<UseStatementLast>,
|
|
||||||
file_id: usize,
|
file_id: usize,
|
||||||
range: Range<usize>,
|
range: Range<usize>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl UseStatement {
|
impl ConcreteUseStatement {
|
||||||
pub fn new(
|
pub fn new(
|
||||||
|
prefixes: Vec<String>,
|
||||||
identifiers: Vec<Box<Identifier>>,
|
identifiers: Vec<Box<Identifier>>,
|
||||||
last: Box<UseStatementLast>,
|
|
||||||
file_id: usize,
|
file_id: usize,
|
||||||
range: Range<usize>,
|
range: Range<usize>,
|
||||||
) -> Self {
|
) -> Self {
|
||||||
UseStatement {
|
ConcreteUseStatement {
|
||||||
|
prefixes,
|
||||||
identifiers,
|
identifiers,
|
||||||
last,
|
|
||||||
file_id,
|
file_id,
|
||||||
range,
|
range,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn base_name(&self) -> Cow<'_, str> {
|
pub fn prefixes(&self) -> &Vec<String> {
|
||||||
use UseStatementLast::*;
|
&self.prefixes
|
||||||
if self.identifiers.is_empty() {
|
|
||||||
match self.last.as_ref() {
|
|
||||||
Identifier(_) => Cow::from(""),
|
|
||||||
Star | Identifiers(_) => panic!(), // should never get here because of grammar
|
|
||||||
}
|
|
||||||
} else if self.identifiers.len() == 1 {
|
|
||||||
self.identifiers[0].name()
|
|
||||||
} else {
|
|
||||||
let mut acc = String::new();
|
|
||||||
for (i, identifier) in self.identifiers.iter().enumerate() {
|
|
||||||
acc.push_str(&identifier.name());
|
|
||||||
if i != self.identifiers.len() - 1 {
|
|
||||||
acc.push_str("::");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
Cow::from(acc)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn is_star(&self) -> bool {
|
pub fn join_prefixes(&self) -> String {
|
||||||
match self.last.as_ref() {
|
self.prefixes.join("::")
|
||||||
UseStatementLast::Star => true,
|
|
||||||
_ => false,
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn identifiers(&self) -> Vec<&Identifier> {
|
pub fn identifiers(&self) -> Vec<&Identifier> {
|
||||||
self.identifiers.iter().map(Box::as_ref).collect()
|
self.identifiers.iter().map(Box::as_ref).collect()
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn identifiers_mut(&mut self) -> Vec<&mut Identifier> {
|
|
||||||
self.identifiers.iter_mut().map(Box::as_mut).collect()
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn last(&self) -> &UseStatementLast {
|
|
||||||
&self.last
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn last_mut(&mut self) -> &mut UseStatementLast {
|
|
||||||
&mut self.last
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn file_id(&self) -> usize {
|
pub fn file_id(&self) -> usize {
|
||||||
self.file_id
|
self.file_id
|
||||||
}
|
}
|
||||||
@ -80,8 +53,34 @@ impl UseStatement {
|
|||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
pub enum UseStatementLast {
|
pub struct StarUseStatement {
|
||||||
Identifier(Box<Identifier>),
|
prefixes: Vec<String>,
|
||||||
Identifiers(Vec<Box<Identifier>>),
|
file_id: usize,
|
||||||
Star,
|
range: Range<usize>,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl StarUseStatement {
|
||||||
|
pub fn new(prefixes: Vec<String>, file_id: usize, range: Range<usize>) -> Self {
|
||||||
|
Self {
|
||||||
|
prefixes,
|
||||||
|
file_id,
|
||||||
|
range,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn prefixes(&self) -> &Vec<String> {
|
||||||
|
&self.prefixes
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn join_prefixes(&self) -> String {
|
||||||
|
self.prefixes.join("::")
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn file_id(&self) -> usize {
|
||||||
|
self.file_id
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn range(&self) -> Range<usize> {
|
||||||
|
self.range
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -320,6 +320,28 @@ impl PrettyPrint for CompilationUnit {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl PrettyPrint for UseStatement {
|
||||||
|
fn pretty_print(&self, writer: &mut IndentWriter) -> std::io::Result<()> {
|
||||||
|
writer.writeln_indented("UseStatement")?;
|
||||||
|
writer.increase_indent();
|
||||||
|
match self {
|
||||||
|
UseStatement::Concrete(concrete_use_statement) => {
|
||||||
|
writer.writeln_indented(&format!("ConcreteUseStatement(prefixes = {})", concrete_use_statement.join_prefixes()))?;
|
||||||
|
writer.increase_indent();
|
||||||
|
for identifier in concrete_use_statement.identifiers() {
|
||||||
|
identifier.pretty_print(writer)?;
|
||||||
|
}
|
||||||
|
writer.decrease_indent();
|
||||||
|
}
|
||||||
|
UseStatement::Star(star_use_statement) => {
|
||||||
|
writer.writeln_indented(&format!("StarUseStatement(prefixes = {})", star_use_statement.join_prefixes()))?;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
writer.decrease_indent();
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
impl PrettyPrint for ModuleLevelDeclaration {
|
impl PrettyPrint for ModuleLevelDeclaration {
|
||||||
fn pretty_print(&self, writer: &mut IndentWriter) -> std::io::Result<()> {
|
fn pretty_print(&self, writer: &mut IndentWriter) -> std::io::Result<()> {
|
||||||
use crate::ast::node::level::ModuleLevelDeclaration::*;
|
use crate::ast::node::level::ModuleLevelDeclaration::*;
|
||||||
@ -618,39 +640,6 @@ impl PrettyPrint for FieldDeclaration {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl PrettyPrint for UseStatement {
|
|
||||||
fn pretty_print(&self, writer: &mut IndentWriter) -> std::io::Result<()> {
|
|
||||||
writer.writeln_indented("UseStatement")?;
|
|
||||||
writer.increase_indent();
|
|
||||||
for identifier in self.identifiers() {
|
|
||||||
identifier.pretty_print(writer)?;
|
|
||||||
}
|
|
||||||
self.last().pretty_print(writer)?;
|
|
||||||
writer.decrease_indent();
|
|
||||||
Ok(())
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl PrettyPrint for UseStatementLast {
|
|
||||||
fn pretty_print(&self, writer: &mut IndentWriter) -> std::io::Result<()> {
|
|
||||||
writer.writeln_indented("UseStatementLast")?;
|
|
||||||
writer.increase_indent();
|
|
||||||
match self {
|
|
||||||
UseStatementLast::Identifier(i) => i.pretty_print(writer)?,
|
|
||||||
UseStatementLast::Identifiers(is) => {
|
|
||||||
for i in is {
|
|
||||||
i.pretty_print(writer)?;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
UseStatementLast::Star => {
|
|
||||||
writer.writeln_indented("Star")?;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
writer.decrease_indent();
|
|
||||||
Ok(())
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl PrettyPrint for BlockStatement {
|
impl PrettyPrint for BlockStatement {
|
||||||
fn pretty_print(&self, writer: &mut IndentWriter) -> std::io::Result<()> {
|
fn pretty_print(&self, writer: &mut IndentWriter) -> std::io::Result<()> {
|
||||||
writer.writeln_indented("BlockStatement")?;
|
writer.writeln_indented("BlockStatement")?;
|
||||||
|
@ -410,35 +410,28 @@ impl Unparse for CompilationUnit {
|
|||||||
impl Unparse for UseStatement {
|
impl Unparse for UseStatement {
|
||||||
fn unparse(&self, writer: &mut IndentWriter) -> std::io::Result<()> {
|
fn unparse(&self, writer: &mut IndentWriter) -> std::io::Result<()> {
|
||||||
writer.write_indented("use ")?;
|
writer.write_indented("use ")?;
|
||||||
for (i, identifier) in self.identifiers().iter().enumerate() {
|
|
||||||
identifier.unparse(writer)?;
|
|
||||||
if i != self.identifiers().len() - 2 {
|
|
||||||
// 2 because of use
|
|
||||||
writer.write("::")?;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
self.last().unparse(writer)?;
|
|
||||||
Ok(())
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl Unparse for UseStatementLast {
|
|
||||||
fn unparse(&self, writer: &mut IndentWriter) -> std::io::Result<()> {
|
|
||||||
match self {
|
match self {
|
||||||
UseStatementLast::Star => writer.write("*"),
|
UseStatement::Concrete(concrete_use_statement) => {
|
||||||
UseStatementLast::Identifiers(identifiers) => {
|
writer.write(&format!("{}::", concrete_use_statement.join_prefixes()))?;
|
||||||
writer.write("{")?;
|
let identifiers = concrete_use_statement.identifiers();
|
||||||
for (i, identifier) in identifiers.iter().enumerate() {
|
if identifiers.len() == 1 {
|
||||||
identifier.unparse(writer)?;
|
identifiers[0].unparse(writer)?;
|
||||||
if i != identifiers.len() - 1 {
|
} else {
|
||||||
writer.write(", ")?;
|
writer.write("{")?;
|
||||||
|
for (i, identifier) in identifiers.iter().enumerate() {
|
||||||
|
identifier.unparse(writer)?;
|
||||||
|
if i != identifiers.len() - 1 {
|
||||||
|
writer.write(", ")?;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
writer.write("}")?;
|
||||||
}
|
}
|
||||||
writer.write("}")?;
|
},
|
||||||
Ok(())
|
UseStatement::Star(star_use_statement) => {
|
||||||
|
writer.write(&format!("{}::*", star_use_statement.join_prefixes()))?;
|
||||||
}
|
}
|
||||||
UseStatementLast::Identifier(i) => i.unparse(writer),
|
|
||||||
}
|
}
|
||||||
|
Ok(())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -364,21 +364,7 @@ fn gather_use_statement(
|
|||||||
fqn_context: &mut FqnContext,
|
fqn_context: &mut FqnContext,
|
||||||
diagnostics: &mut Vec<DmDiagnostic>,
|
diagnostics: &mut Vec<DmDiagnostic>,
|
||||||
) {
|
) {
|
||||||
if use_statement.is_star() {
|
todo!()
|
||||||
todo!()
|
|
||||||
}
|
|
||||||
let base_name = use_statement.base_name().to_string();
|
|
||||||
match use_statement.last_mut() {
|
|
||||||
UseStatementLast::Identifier(identifier) => {
|
|
||||||
handle_use_statement_import(symbol_table, &base_name, identifier, diagnostics)
|
|
||||||
}
|
|
||||||
UseStatementLast::Identifiers(identifiers) => {
|
|
||||||
for identifier in identifiers {
|
|
||||||
handle_use_statement_import(symbol_table, &base_name, identifier, diagnostics)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
UseStatementLast::Star => panic!(),
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Declarations allowed in each level */
|
/* Declarations allowed in each level */
|
||||||
|
@ -56,7 +56,6 @@ mod tests {
|
|||||||
use super::*;
|
use super::*;
|
||||||
use crate::ast::build::build_ast;
|
use crate::ast::build::build_ast;
|
||||||
use crate::ast::children::NodeRef;
|
use crate::ast::children::NodeRef;
|
||||||
use crate::ast::node::use_statement::UseStatementLast;
|
|
||||||
use crate::ast::walk::walk_depth_first;
|
use crate::ast::walk::walk_depth_first;
|
||||||
use crate::parser::{DeimosParser, Rule};
|
use crate::parser::{DeimosParser, Rule};
|
||||||
use crate::std_core::add_std_core_symbols;
|
use crate::std_core::add_std_core_symbols;
|
||||||
@ -126,25 +125,7 @@ mod tests {
|
|||||||
panic!("{:?} does not have a saved symbol.", fqn)
|
panic!("{:?} does not have a saved symbol.", fqn)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
NodeRef::UseStatement(use_statement) => match use_statement.last() {
|
NodeRef::UseStatement(use_statement) => match use_statement {
|
||||||
UseStatementLast::Identifier(identifier) => {
|
|
||||||
if identifier.saved_symbol().is_none() {
|
|
||||||
panic!(
|
|
||||||
"UseStatement {:?} does not have a saved symbol.",
|
|
||||||
identifier
|
|
||||||
)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
UseStatementLast::Identifiers(identifiers) => {
|
|
||||||
for identifier in identifiers {
|
|
||||||
if identifier.saved_symbol().is_none() {
|
|
||||||
panic!(
|
|
||||||
"UseStatement {:?} does not have a saved symbol.",
|
|
||||||
identifier
|
|
||||||
)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
_ => todo!(),
|
_ => todo!(),
|
||||||
},
|
},
|
||||||
_ => {}
|
_ => {}
|
||||||
@ -153,35 +134,7 @@ mod tests {
|
|||||||
|
|
||||||
fn assert_resolved_symbols(compilation_unit: &CompilationUnit) {
|
fn assert_resolved_symbols(compilation_unit: &CompilationUnit) {
|
||||||
walk_depth_first(compilation_unit, &mut |node_ref| match node_ref {
|
walk_depth_first(compilation_unit, &mut |node_ref| match node_ref {
|
||||||
NodeRef::UseStatement(use_statement) => match use_statement.last() {
|
NodeRef::UseStatement(use_statement) => match use_statement {
|
||||||
UseStatementLast::Identifier(identifier) => {
|
|
||||||
let use_statement_symbol = identifier
|
|
||||||
.saved_symbol()
|
|
||||||
.unwrap()
|
|
||||||
.unwrap_use_statement_symbol();
|
|
||||||
let borrowed = use_statement_symbol.borrow();
|
|
||||||
if borrowed.referenced_symbol().is_none() {
|
|
||||||
panic!(
|
|
||||||
"{:?} does not have a referenced symbol.",
|
|
||||||
use_statement_symbol
|
|
||||||
)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
UseStatementLast::Identifiers(identifiers) => {
|
|
||||||
for identifier in identifiers {
|
|
||||||
let use_statement_symbol = identifier
|
|
||||||
.saved_symbol()
|
|
||||||
.unwrap()
|
|
||||||
.unwrap_use_statement_symbol();
|
|
||||||
let borrowed = use_statement_symbol.borrow();
|
|
||||||
if borrowed.referenced_symbol().is_none() {
|
|
||||||
panic!(
|
|
||||||
"{:?} does not have a referenced symbol.",
|
|
||||||
use_statement_symbol
|
|
||||||
)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
_ => todo!(),
|
_ => todo!(),
|
||||||
},
|
},
|
||||||
_ => {}
|
_ => {}
|
||||||
|
@ -260,36 +260,7 @@ fn resolve_use_statement(
|
|||||||
symbol_table: &mut SymbolTable,
|
symbol_table: &mut SymbolTable,
|
||||||
diagnostics: &mut Vec<DmDiagnostic>,
|
diagnostics: &mut Vec<DmDiagnostic>,
|
||||||
) {
|
) {
|
||||||
let file_id = use_statement.file_id();
|
todo!()
|
||||||
let use_statement_range = use_statement.range();
|
|
||||||
let base_name = use_statement.base_name().to_string();
|
|
||||||
|
|
||||||
match use_statement.last_mut() {
|
|
||||||
UseStatementLast::Identifier(identifier) => {
|
|
||||||
handle_use_statement_identifier(
|
|
||||||
identifier.deref_mut(),
|
|
||||||
&base_name,
|
|
||||||
symbol_table,
|
|
||||||
diagnostics,
|
|
||||||
file_id,
|
|
||||||
use_statement_range,
|
|
||||||
);
|
|
||||||
}
|
|
||||||
UseStatementLast::Identifiers(identifiers) => {
|
|
||||||
for identifier in identifiers {
|
|
||||||
let identifier_range = identifier.range();
|
|
||||||
handle_use_statement_identifier(
|
|
||||||
identifier.deref_mut(),
|
|
||||||
&base_name,
|
|
||||||
symbol_table,
|
|
||||||
diagnostics,
|
|
||||||
file_id,
|
|
||||||
identifier_range,
|
|
||||||
)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
UseStatementLast::Star => todo!("star imports"),
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Declarations allowed in each level */
|
/* Declarations allowed in each level */
|
||||||
|
@ -28,15 +28,7 @@ impl SourceDefinition {
|
|||||||
range: borrowed.range(),
|
range: borrowed.range(),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[deprecated(note = "Use identifier instead.")]
|
|
||||||
pub fn from_use_statement(use_statement: &UseStatement) -> Self {
|
|
||||||
SourceDefinition {
|
|
||||||
file_id: use_statement.file_id(),
|
|
||||||
range: use_statement.range(),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn file_id(&self) -> usize {
|
pub fn file_id(&self) -> usize {
|
||||||
self.file_id
|
self.file_id
|
||||||
}
|
}
|
||||||
|
@ -333,6 +333,20 @@ Namespace = {
|
|||||||
~ FullyQualifiedName
|
~ FullyQualifiedName
|
||||||
}
|
}
|
||||||
|
|
||||||
|
UseStatement = {
|
||||||
|
Use
|
||||||
|
~ Identifier
|
||||||
|
~ ( "::" ~ Identifier )*
|
||||||
|
~ ( "::" ~ ( Star | UseList ) )?
|
||||||
|
}
|
||||||
|
|
||||||
|
UseList = {
|
||||||
|
"{"
|
||||||
|
~ Identifier
|
||||||
|
~ ( "," ~ Identifier )*
|
||||||
|
~ "}"
|
||||||
|
}
|
||||||
|
|
||||||
// Organizational declarations
|
// Organizational declarations
|
||||||
|
|
||||||
ModuleLevelDeclaration = {
|
ModuleLevelDeclaration = {
|
||||||
@ -523,20 +537,6 @@ Field = {
|
|||||||
|
|
||||||
// Statements
|
// Statements
|
||||||
|
|
||||||
UseStatement = {
|
|
||||||
Use
|
|
||||||
~ Identifier
|
|
||||||
~ ( "::" ~ Identifier )*
|
|
||||||
~ ( "::" ~ ( Star | UseList ) )?
|
|
||||||
}
|
|
||||||
|
|
||||||
UseList = {
|
|
||||||
"{"
|
|
||||||
~ Identifier
|
|
||||||
~ ( "," ~ Identifier )*
|
|
||||||
~ "}"
|
|
||||||
}
|
|
||||||
|
|
||||||
BlockStatement = {
|
BlockStatement = {
|
||||||
"{"
|
"{"
|
||||||
~ Statement*
|
~ Statement*
|
||||||
|
Loading…
Reference in New Issue
Block a user