Skip to content

Commit d0a380f

Browse files
committed
Added AST and ASG support for unnamed function parameters
1 parent 3534f49 commit d0a380f

File tree

13 files changed

+109
-95
lines changed

13 files changed

+109
-95
lines changed

Diff for: src/asg/func.rs

+6-2
Original file line numberDiff line numberDiff line change
@@ -46,13 +46,17 @@ impl Display for Params {
4646

4747
#[derive(Clone, Debug, Hash, Eq)]
4848
pub struct Param {
49-
pub name: String,
49+
pub name: Option<String>,
5050
pub ty: Type,
5151
}
5252

5353
impl Display for Param {
5454
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
55-
write!(f, "{} {}", self.name, self.ty)
55+
if let Some(name) = &self.name {
56+
write!(f, "{} {}", name, self.ty)
57+
} else {
58+
write!(f, "{}", self.ty)
59+
}
5660
}
5761
}
5862

Diff for: src/ast/func/params.rs

+9-2
Original file line numberDiff line numberDiff line change
@@ -17,12 +17,19 @@ impl Params {
1717

1818
#[derive(Clone, Debug)]
1919
pub struct Param {
20-
pub name: String,
20+
pub name: Option<String>,
2121
pub ast_type: Type,
2222
}
2323

2424
impl Param {
25-
pub fn new(name: String, ast_type: Type) -> Self {
25+
pub fn new(name: Option<String>, ast_type: Type) -> Self {
2626
Self { name, ast_type }
2727
}
28+
29+
pub fn named(name: String, ast_type: Type) -> Self {
30+
Self {
31+
name: Some(name),
32+
ast_type,
33+
}
34+
}
2835
}

Diff for: src/c/parser/mod.rs

+2-2
Original file line numberDiff line numberDiff line change
@@ -169,7 +169,7 @@ pub struct ArrayQualifier {
169169

170170
#[derive(Clone, Debug)]
171171
pub struct FunctionQualifier {
172-
pub parameters: Vec<Param>,
172+
pub params: Vec<Param>,
173173
pub is_cstyle_variadic: bool,
174174
pub source: Source,
175175
}
@@ -1552,7 +1552,7 @@ impl<'a> Parser<'a> {
15521552
));
15531553
}
15541554

1555-
todo!();
1555+
todo!("parse compound statement");
15561556

15571557
if !self.eat_punctuator(Punctuator::CloseCurly) {
15581558
return Err(ParseError::new(

Diff for: src/c/translation/expr/caster.rs

+2-2
Original file line numberDiff line numberDiff line change
@@ -34,14 +34,14 @@ pub fn get_caster_type(
3434

3535
let base = builder.build()?;
3636

37-
if base.storage_class.is_some() {
37+
if base.specifiers.storage_class.is_some() {
3838
return Err(ParseError::message(
3939
"Storage class specifier cannot be used on cast",
4040
caster.source,
4141
));
4242
}
4343

44-
if base.function_specifier.is_some() {
44+
if base.specifiers.function_specifier.is_some() {
4545
return Err(ParseError::message(
4646
"Storage class specifier cannot be used on cast",
4747
caster.source,

Diff for: src/c/translation/function.rs

+18-19
Original file line numberDiff line numberDiff line change
@@ -22,24 +22,23 @@ pub fn declare_function(
2222
c_file_type: CFileType,
2323
) -> Result<(), ParseError> {
2424
let source = declarator.source;
25-
let (name, return_type, storage_class, function_specifier, _is_thread_local) =
26-
get_name_and_type(
27-
ast_file,
28-
typedefs,
29-
declarator,
30-
declaration_specifiers,
31-
false,
32-
diagnostics,
33-
)?;
25+
let func_info = get_name_and_type(
26+
ast_file,
27+
typedefs,
28+
declarator,
29+
declaration_specifiers,
30+
false,
31+
diagnostics,
32+
)?;
3433
let mut required = vec![];
3534

36-
if function_specifier.is_some() {
35+
if func_info.specifiers.function_specifier.is_some() {
3736
return Err(ParseErrorKind::Misc("Function specifiers are not supported yet").at(source));
3837
}
3938

4039
if has_parameters(parameter_type_list) {
4140
for param in parameter_type_list.parameter_declarations.iter() {
42-
let (name, ast_type, storage_class, function_specifier, _) = match &param.core {
41+
let param_info = match &param.core {
4342
ParameterDeclarationCore::Declarator(declarator) => get_name_and_type(
4443
ast_file,
4544
typedefs,
@@ -52,33 +51,33 @@ pub fn declare_function(
5251
ParameterDeclarationCore::Nothing => todo!(),
5352
};
5453

55-
if storage_class.is_some() {
54+
if param_info.specifiers.storage_class.is_some() {
5655
return Err(
5756
ParseErrorKind::Misc("Storage classes not support on typedef").at(param.source),
5857
);
5958
}
6059

61-
if function_specifier.is_some() {
60+
if param_info.specifiers.function_specifier.is_some() {
6261
return Err(
6362
ParseErrorKind::Misc("Function specifiers cannot be used on typedef")
6463
.at(source),
6564
);
6665
}
6766

68-
required.push(Param { name, ast_type });
67+
required.push(Param::new(Some(param_info.name), param_info.ast_type));
6968
}
7069
}
7170

72-
match storage_class {
71+
match func_info.specifiers.storage_class {
7372
Some(StorageClassSpecifier::Typedef) => {
7473
let ast_type = ast::TypeKind::FuncPtr(ast::FuncPtr {
7574
parameters: required,
76-
return_type: Box::new(return_type),
75+
return_type: Box::new(func_info.ast_type),
7776
is_cstyle_variadic: parameter_type_list.is_variadic,
7877
})
7978
.at(declarator.source);
8079

81-
typedefs.insert(name, CTypedef { ast_type });
80+
typedefs.insert(func_info.name, CTypedef { ast_type });
8281
return Ok(());
8382
}
8483
Some(_) => {
@@ -90,14 +89,14 @@ pub fn declare_function(
9089
}
9190

9291
let head = FuncHead {
93-
name,
92+
name: func_info.name,
9493
type_params: TypeParams::default(),
9594
givens: vec![],
9695
params: Params {
9796
required,
9897
is_cstyle_vararg: parameter_type_list.is_variadic,
9998
},
100-
return_type,
99+
return_type: func_info.ast_type,
101100
is_foreign: true,
102101
source,
103102
abide_abi: true,

Diff for: src/c/translation/mod.rs

+17-12
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,7 @@ pub fn declare_named_declaration(
2424
diagnostics: &Diagnostics,
2525
c_file_type: CFileType,
2626
) -> Result<(), ParseError> {
27-
let (name, ast_type, storage_class, function_specifier, is_thread_local) = get_name_and_type(
27+
let decl_info = get_name_and_type(
2828
ast_file,
2929
typedefs,
3030
declarator,
@@ -33,8 +33,8 @@ pub fn declare_named_declaration(
3333
diagnostics,
3434
)?;
3535

36-
if let Some(StorageClassSpecifier::Typedef) = storage_class {
37-
if let Some(function_specifier) = function_specifier {
36+
if let Some(StorageClassSpecifier::Typedef) = decl_info.specifiers.storage_class {
37+
if let Some(function_specifier) = decl_info.specifiers.function_specifier {
3838
diagnostics.push(WarningDiagnostic::new(
3939
format!(
4040
"Function specifier '{}' does nothing on typedef",
@@ -45,21 +45,26 @@ pub fn declare_named_declaration(
4545
}
4646

4747
ast_file.type_aliases.push(ast::TypeAlias {
48-
name: name.clone(),
48+
name: decl_info.name.clone(),
4949
params: TypeParams::default(),
50-
value: ast_type.clone(),
50+
value: decl_info.ast_type.clone(),
5151
source: declarator.source,
5252
privacy: c_file_type.privacy(),
5353
});
5454

55-
typedefs.insert(name, CTypedef { ast_type });
55+
typedefs.insert(
56+
decl_info.name,
57+
CTypedef {
58+
ast_type: decl_info.ast_type,
59+
},
60+
);
5661
return Ok(());
5762
}
5863

59-
if let None | Some(StorageClassSpecifier::Extern) = storage_class {
60-
let is_foreign = storage_class.is_some();
64+
if let None | Some(StorageClassSpecifier::Extern) = decl_info.specifiers.storage_class {
65+
let is_foreign = decl_info.specifiers.storage_class.is_some();
6166

62-
if let Some(function_specifier) = function_specifier {
67+
if let Some(function_specifier) = decl_info.specifiers.function_specifier {
6368
diagnostics.push(WarningDiagnostic::new(
6469
format!(
6570
"Function specifier '{}' on functions is not respected yet",
@@ -70,11 +75,11 @@ pub fn declare_named_declaration(
7075
}
7176

7277
ast_file.global_variables.push(ast::GlobalVar {
73-
name,
74-
ast_type,
78+
name: decl_info.name,
79+
ast_type: decl_info.ast_type,
7580
source: declarator.source,
7681
is_foreign,
77-
is_thread_local,
82+
is_thread_local: decl_info.specifiers.is_thread_local,
7883
privacy: c_file_type.privacy(),
7984
exposure: ast::Exposure::Exposed,
8085
});

Diff for: src/c/translation/types/composite.rs

+12-15
Original file line numberDiff line numberDiff line change
@@ -54,36 +54,33 @@ pub fn make_composite(
5454
for member_declarator in member.member_declarators.iter() {
5555
match member_declarator {
5656
MemberDeclarator::Declarator(declarator) => {
57-
let (name, ast_type, storage_class, function_specifier, _) =
58-
get_name_and_type(
59-
ast_file,
60-
typedefs,
61-
declarator,
62-
&DeclarationSpecifiers::from(
63-
&member.specifier_qualifiers,
64-
),
65-
false,
66-
diagnostics,
67-
)?;
57+
let member_info = get_name_and_type(
58+
ast_file,
59+
typedefs,
60+
declarator,
61+
&DeclarationSpecifiers::from(&member.specifier_qualifiers),
62+
false,
63+
diagnostics,
64+
)?;
6865

69-
if storage_class.is_some() {
66+
if member_info.specifiers.storage_class.is_some() {
7067
return Err(ParseErrorKind::Misc(
7168
"Storage classes not supported here",
7269
)
7370
.at(declarator.source));
7471
}
7572

76-
if function_specifier.is_some() {
73+
if member_info.specifiers.function_specifier.is_some() {
7774
return Err(ParseErrorKind::Misc(
7875
"Function specifiers cannot be used here",
7976
)
8077
.at(declarator.source));
8178
}
8279

8380
fields.insert(
84-
name.clone(),
81+
member_info.name.clone(),
8582
Field {
86-
ast_type,
83+
ast_type: member_info.ast_type.clone(),
8784
privacy: Privacy::Public,
8885
source: declarator.source,
8986
},

Diff for: src/c/translation/types/decorate.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -70,7 +70,7 @@ pub fn decorate_function(
7070
source: Source,
7171
) -> Result<Type, ParseError> {
7272
Ok(TypeKind::FuncPtr(FuncPtr {
73-
parameters: function.parameters.clone(),
73+
parameters: function.params.clone(),
7474
return_type: Box::new(ast_type),
7575
is_cstyle_variadic: function.is_cstyle_variadic,
7676
})

0 commit comments

Comments
 (0)