Skip to content

Commit 758ac75

Browse files
authored
Merge pull request #372 from Pivot-Studio/griffin/improve/add-comments
improve: add some comments for AST nodes
2 parents 7d0888a + 0fe6a45 commit 758ac75

32 files changed

+352
-168
lines changed

internal_macro/src/node_macro/src/lib.rs

Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,50 @@
11
use proc_macro::TokenStream;
22
use quote::quote;
33
use syn::{parse_macro_input, DeriveInput};
4+
/// node is a macro to embed new fields, add some macros and implement
5+
/// crate::ast::node::FmtTrait and crate::ast::node::RangeTrait
6+
/// traits for the structure.
7+
/// currently, it supports arguemnts as 'comment' and 'copy':
8+
///
9+
/// The node without any argument embeds a new field 'range' into a structure
10+
/// ```rust
11+
/// #[node]
12+
/// pub struct demo {
13+
/// pub filed: i32,
14+
/// pub field2: String,
15+
/// }
16+
/// ```
17+
/// The embedded structure looks like:
18+
/// ```rust
19+
/// #[derive(Clone, PartialEq, Eq, derivative::Derivative)]
20+
/// #[derivative(Debug)]
21+
/// pub struct demo {
22+
/// pub filed: i32,
23+
/// pub field2: String,
24+
/// pub range: crate::ast::range::Range,
25+
/// }
26+
/// ```
27+
///
28+
/// If we pass the argument `comment`:
29+
/// ```rust
30+
/// #[node(comment)]
31+
/// pub struct demo {
32+
/// pub filed: i32,
33+
/// pub field2: String,
34+
/// }
35+
/// ```
36+
///
37+
/// The embedded structure looks like:
38+
/// ```rust
39+
/// #[derive(Clone, PartialEq, Eq, derivative::Derivative)]
40+
/// #[derivative(Debug)]
41+
/// pub struct demo {
42+
/// pub filed: i32,
43+
/// pub field2: String,
44+
/// pub comments: Vec<Vec<Box<crate::ast::node::NodeEnum>>>,
45+
/// pub range: crate::ast::range::Range,
46+
/// }
47+
/// ```
448
#[proc_macro_attribute]
549
pub fn node(args: TokenStream, input: TokenStream) -> TokenStream {
650
let mut ast = parse_macro_input!(input as DeriveInput);

src/ast/fmt.rs

Lines changed: 13 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -144,9 +144,9 @@ impl FmtBuilder {
144144
pub fn parse_use_node(&mut self, node: &UseNode) {
145145
self.token("use");
146146
self.space();
147-
for (i, id) in node.ids.iter().enumerate() {
147+
for (i, id) in node.namespace.iter().enumerate() {
148148
id.format(self);
149-
if i != node.ids.len() - 1 {
149+
if i != node.namespace.len() - 1 {
150150
self.dbcolon();
151151
}
152152
}
@@ -158,9 +158,9 @@ impl FmtBuilder {
158158
self.enter();
159159
}
160160
pub fn parse_extern_id_node(&mut self, node: &ExternIdNode) {
161-
for (i, id) in node.ns.iter().enumerate() {
161+
for (i, id) in node.namespace.iter().enumerate() {
162162
id.format(self);
163-
if i != node.ns.len() {
163+
if i != node.namespace.len() {
164164
self.dbcolon();
165165
}
166166
}
@@ -192,7 +192,7 @@ impl FmtBuilder {
192192
}
193193
}
194194
pub fn parse_struct_def_node(&mut self, node: &StructDefNode) {
195-
for c in node.pre_comments.iter() {
195+
for c in node.docs.iter() {
196196
c.format(self);
197197
}
198198
self.prefix();
@@ -303,12 +303,12 @@ impl FmtBuilder {
303303
self.token("let");
304304
self.space();
305305
node.var.format(self);
306-
if let Some(tp) = &node.tp {
306+
if let Some(tp) = &node.variable_type {
307307
self.colon();
308308
self.space();
309309
tp.format(self);
310310
}
311-
if let Some(exp) = &node.exp {
311+
if let Some(exp) = &node.value_expression {
312312
self.space();
313313
self.equal();
314314
self.space();
@@ -350,7 +350,7 @@ impl FmtBuilder {
350350
}
351351
}
352352
pub fn parse_ret_node(&mut self, node: &RetNode) {
353-
if let Some((t, _)) = node.yiel {
353+
if let Some((t, _)) = node.yield_identifier {
354354
self.token(t.get_str());
355355
self.space();
356356
}
@@ -713,7 +713,7 @@ impl FmtBuilder {
713713
self.r_paren();
714714
}
715715
pub fn parse_trait_bound_node(&mut self, node: &TraitBoundNode) {
716-
node.generic.format(self);
716+
node.identifier.format(self);
717717
if let Some(impl_trait) = &node.impl_trait {
718718
impl_trait.format(self);
719719
}
@@ -756,7 +756,7 @@ impl FmtBuilder {
756756
self.space();
757757
self.token("as");
758758
self.space();
759-
node.ty.format(self);
759+
node.target_type.format(self);
760760
if let Some((t, _)) = node.tail {
761761
if t == TokenType::QUESTION {
762762
self.token("?");
@@ -770,7 +770,7 @@ impl FmtBuilder {
770770
self.space();
771771
self.token("is");
772772
self.space();
773-
node.ty.format(self);
773+
node.target_type.format(self);
774774
}
775775
pub fn parse_tuple_init_node(&mut self, node: &TupleInitNode) {
776776
self.l_paren();
@@ -788,7 +788,7 @@ impl FmtBuilder {
788788
}
789789
pub fn parse_tuple_type_node(&mut self, node: &TupleTypeNode) {
790790
self.l_paren();
791-
for (i, ty) in node.tps.iter().enumerate() {
791+
for (i, ty) in node.types.iter().enumerate() {
792792
if i > 0 {
793793
self.comma();
794794
self.space();
@@ -844,7 +844,7 @@ impl FmtBuilder {
844844
pub fn parse_global_const_node(&mut self, node: &GlobalConstNode) {
845845
self.token("const");
846846
self.space();
847-
node.var.format(self);
847+
node.constant.format(self);
848848
self.semicolon();
849849
// 顶层节点加空格
850850
self.enter();

src/ast/node/cast.rs

Lines changed: 24 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -25,8 +25,14 @@ use crate::ast::node::RangeTrait;
2525

2626
#[node]
2727
pub struct AsNode {
28+
/// expr is the expression which calculates a value as output
2829
pub expr: Box<NodeEnum>,
29-
pub ty: Box<TypeNodeEnum>,
30+
31+
/// target_type refers the desired type for the expr
32+
pub target_type: Box<TypeNodeEnum>,
33+
34+
/// tail is the question or exclaimation mark following an 'as' statement
35+
/// it will be None if no marks exist
3036
pub tail: Option<(TokenType, Range)>,
3137
}
3238

@@ -37,10 +43,10 @@ impl Node for AsNode {
3743
builder: &'b BuilderEnum<'a, '_>,
3844
) -> NodeResult {
3945
let re = self.expr.emit(ctx, builder);
40-
self.ty.emit_highlight(ctx);
46+
self.target_type.emit_highlight(ctx);
4147
let v = re?.get_value();
4248
let v = v.unwrap();
43-
let target_tp = self.ty.get_type(ctx, builder, true)?;
49+
let target_tp = self.target_type.get_type(ctx, builder, true)?;
4450
let (val, target_tp) = ctx.force_cast_safe(
4551
v.get_value(),
4652
&v.get_ty().borrow(),
@@ -58,7 +64,7 @@ impl PrintTrait for AsNode {
5864
tab(tabs, line.clone(), end);
5965
println!("AsNode");
6066
self.expr.print(tabs + 1, false, line.clone());
61-
self.ty.print(tabs + 1, true, line.clone());
67+
self.target_type.print(tabs + 1, true, line.clone());
6268
}
6369
}
6470

@@ -88,14 +94,14 @@ impl<'a, 'ctx> Ctx<'a> {
8894
}
8995
(PLType::Union(union), target_ty) => {
9096
if node.tail.is_none() {
91-
let pos = node.ty.range().end;
97+
let pos = node.target_type.range().end;
9298
let end_range = Range {
9399
start: pos,
94100
end: pos,
95101
};
96102
return Err(node.range.new_err(ErrorCode::INVALID_DIRECT_UNION_CAST)
97103
.add_label(node.expr.range(), self.get_file(), format_label!("type of the expression is `{}`", &union.name))
98-
.add_label(node.ty.range(), self.get_file(), format_label!("target type is `{}`", target_ty.get_name()))
104+
.add_label(node.target_type.range(), self.get_file(), format_label!("target type is `{}`", target_ty.get_name()))
99105
.add_label(end_range, self.get_file(), format_label!("add `{}` or `{}` to make it legal", "?", "!"))
100106
.add_help("cast a union to its member type directly is not allowed, use `?` or `!` after the cast expression")
101107
.add_to_ctx(self));
@@ -124,7 +130,7 @@ impl<'a, 'ctx> Ctx<'a> {
124130
format_label!("type of the expression is `{}`", &union.name),
125131
)
126132
.add_label(
127-
node.ty.range(),
133+
node.target_type.range(),
128134
self.get_file(),
129135
format_label!("target type is `{}`", target_ty.get_name()),
130136
)
@@ -137,14 +143,14 @@ impl<'a, 'ctx> Ctx<'a> {
137143
}
138144
(PLType::Trait(t), target_ty) => {
139145
if node.tail.is_none() {
140-
let pos = node.ty.range().end;
146+
let pos = node.target_type.range().end;
141147
let end_range = Range {
142148
start: pos,
143149
end: pos,
144150
};
145151
return Err(node.range.new_err(ErrorCode::INVALID_DIRECT_TRAIT_CAST)
146152
.add_label(node.expr.range(), self.get_file(), format_label!("type of the expression is `{}`", &t.name))
147-
.add_label(node.ty.range(), self.get_file(), format_label!("target type is `{}`", target_ty.get_name()))
153+
.add_label(node.target_type.range(), self.get_file(), format_label!("target type is `{}`", target_ty.get_name()))
148154
.add_label(end_range, self.get_file(), format_label!("add `{}` or `{}` to make it legal", "?", "!"))
149155
.add_help("cast a trait to specific type directly is not allowed, use `?` or `!` after the cast expression")
150156
.add_to_ctx(self));
@@ -161,7 +167,7 @@ impl<'a, 'ctx> Ctx<'a> {
161167
.up_cast(
162168
target_ty.clone(),
163169
Arc::new(RefCell::new(ty.clone())),
164-
node.ty.range(),
170+
node.target_type.range(),
165171
node.expr.range(),
166172
val,
167173
builder,
@@ -175,7 +181,7 @@ impl<'a, 'ctx> Ctx<'a> {
175181
format_label!("type of the expression is `{}`", ty.get_name()),
176182
)
177183
.add_label(
178-
node.ty.range(),
184+
node.target_type.range(),
179185
self.get_file(),
180186
format_label!("target type is `{}`", target_ty.borrow().get_name()),
181187
)
@@ -486,8 +492,10 @@ pub fn get_option_type<'a, 'b>(
486492

487493
#[node]
488494
pub struct IsNode {
495+
/// expr is the expression which calculates a value as output
489496
pub expr: Box<NodeEnum>,
490-
pub ty: Box<TypeNodeEnum>,
497+
/// target_type refers the desired type for the expr
498+
pub target_type: Box<TypeNodeEnum>,
491499
}
492500

493501
impl Node for IsNode {
@@ -497,9 +505,9 @@ impl Node for IsNode {
497505
builder: &'b BuilderEnum<'a, '_>,
498506
) -> NodeResult {
499507
let re = self.expr.emit(ctx, builder);
500-
self.ty.emit_highlight(ctx);
508+
self.target_type.emit_highlight(ctx);
501509
let v = re?.get_value().unwrap();
502-
let target_tp = self.ty.get_type(ctx, builder, true)?;
510+
let target_tp = self.target_type.get_type(ctx, builder, true)?;
503511
let val = v.get_value();
504512
let binding = v.get_ty();
505513
let tp = &*binding.borrow();
@@ -528,7 +536,7 @@ impl Node for IsNode {
528536
.to_result()
529537
} else {
530538
Err(self
531-
.ty
539+
.target_type
532540
.range()
533541
.new_err(ErrorCode::UNION_DOES_NOT_CONTAIN_TYPE)
534542
.add_to_ctx(ctx))
@@ -570,6 +578,6 @@ impl PrintTrait for IsNode {
570578
tab(tabs, line.clone(), end);
571579
println!("IsNode");
572580
self.expr.print(tabs + 1, false, line.clone());
573-
self.ty.print(tabs + 1, true, line.clone());
581+
self.target_type.print(tabs + 1, true, line.clone());
574582
}
575583
}

src/ast/node/control.rs

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,9 +7,16 @@ use crate::ast::pltype::PriType;
77
use internal_macro::node;
88

99
#[node(comment)]
10+
/// IfNode is consisted by a 'if' clause and a 'else' clause.
11+
/// the 'else' clause is allowed to embed another IfNode
1012
pub struct IfNode {
13+
/// condition is the bool expression for the if keyword
14+
/// there is no type check in the AST stage, but we did check it when lowering ast
1115
pub cond: Box<NodeEnum>,
16+
/// then is the logic to be executed if the cond is true
1217
pub then: Box<StatementsNode>,
18+
/// els stands for the left part of the condition clause
19+
/// it might be another IfNode or a statement
1320
pub els: Option<Box<NodeEnum>>,
1421
}
1522

@@ -159,6 +166,20 @@ impl Node for WhileNode {
159166
}
160167

161168
#[node(comment)]
169+
/// ForNode is consisted by four parts: pre,cond, opt and body in the format of `for pre;cond;opt body`.
170+
///
171+
/// The pre and opt are optional, but the semi-colons are compulsory.
172+
///
173+
/// For example:
174+
/// ```pi
175+
/// for let i = 0; i < 5; i = i + 1{
176+
/// // ^pre ^cond ^opt
177+
///
178+
/// println!(i)
179+
/// // ^body
180+
/// }
181+
///
182+
/// ```
162183
pub struct ForNode {
163184
pub pre: Option<Box<NodeEnum>>,
164185
pub cond: Box<NodeEnum>,

src/ast/node/function.rs

Lines changed: 10 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -452,14 +452,21 @@ fn handle_ret<'a, 'b>(
452452
}
453453
#[node]
454454
pub struct FuncDefNode {
455+
/// id is the function identifier
455456
pub id: Box<VarNode>,
457+
/// paralist is the parameter lists
456458
pub paralist: Vec<Box<TypedIdentifierNode>>,
459+
/// ret is the return type of the function
457460
pub ret: Box<TypeNodeEnum>,
461+
/// docs is the documentation of the structure started with `///`
458462
pub doc: Vec<Box<NodeEnum>>,
463+
/// pre_comments is the comments above a structure
459464
pub pre_comments: Vec<Box<NodeEnum>>,
460-
pub declare: bool,
465+
/// is_declaration_only refers whether this function is a declaration only, which means it has no body
466+
pub is_declaration_only: bool,
461467
pub generics: Option<Box<GenericDefNode>>,
462468
pub body: Option<StatementsNode>,
469+
/// modifier indicates whether the trait is decorated by a keyword `pub`
463470
pub modifier: Option<(TokenType, Range)>,
464471
pub generics_size: usize, // the size of generics except the generics from impl node
465472
pub trait_bounds: Option<Vec<Box<TraitBoundNode>>>,
@@ -531,7 +538,7 @@ impl TypeNode for FuncDefNode {
531538
param_names: param_name,
532539
range: self.id.range(),
533540
doc: self.doc.clone(),
534-
llvmname: if self.declare {
541+
llvmname: if self.is_declaration_only {
535542
if self.id.name.starts_with('|') {
536543
return Err(self
537544
.range
@@ -562,7 +569,7 @@ impl TypeNode for FuncDefNode {
562569
node: Some(Box::new(self.clone())),
563570
body_range: self.range,
564571
in_trait: self.in_trait_def,
565-
is_declare: self.declare,
572+
is_declare: self.is_declaration_only,
566573
};
567574
if self.generics.is_none() {
568575
builder.get_or_insert_fn_handle(&fnvalue, child);

0 commit comments

Comments
 (0)