Skip to content

Commit a7eec5f

Browse files
committed
Started working on parsing for C sizeof expressions
1 parent a9379d9 commit a7eec5f

File tree

4 files changed

+110
-19
lines changed

4 files changed

+110
-19
lines changed

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

+6
Original file line numberDiff line numberDiff line change
@@ -550,3 +550,9 @@ pub struct EnumerationNamed {
550550
pub enum_type_specifier: Option<EnumTypeSpecifier>,
551551
pub source: Source,
552552
}
553+
554+
#[derive(Clone, Debug)]
555+
pub struct TypeName {
556+
pub specifier_qualifiers: SpecifierQualifierList,
557+
pub abstract_declarator: Option<AbstractDeclarator>,
558+
}

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

+4-2
Original file line numberDiff line numberDiff line change
@@ -46,7 +46,8 @@ pub enum ParseErrorKind {
4646
DuplicateEnumMember(String),
4747
MustBeConstantInteger,
4848
EnumMemberNameConflictsWithExistingSymbol { name: String },
49-
UndefinedVariable(String),
49+
UndeclaredVariable(String),
50+
UndeclaredType(String),
5051
CannotContainNulInNullTerminatedString,
5152
Misc(&'static str),
5253
}
@@ -79,7 +80,8 @@ impl Display for ParseErrorKind {
7980
"Enum member name conflicts with existing symbol '{name}'",
8081
)
8182
}
82-
ParseErrorKind::UndefinedVariable(name) => write!(f, "Undefined variable '{name}'"),
83+
ParseErrorKind::UndeclaredVariable(name) => write!(f, "Undeclared variable '{name}'"),
84+
ParseErrorKind::UndeclaredType(name) => write!(f, "Undeclared type '{name}'"),
8385
ParseErrorKind::CannotContainNulInNullTerminatedString => {
8486
write!(f, "Cannot contain NUL byte in C-String'")
8587
}

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

+37-6
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@ use crate::{
33
c::{
44
ast::{
55
BinaryOperation, BinaryOperator, Caster, CompoundLiteral, Expr, ExprKind, Field,
6-
Subscript, Ternary,
6+
Subscript, Ternary, TypeName,
77
},
88
parser::speculate::speculate,
99
punctuator::Punctuator,
@@ -257,10 +257,17 @@ impl<'a> Parser<'a> {
257257
let inner = self.parse_expr_primary()?;
258258
return Ok(ExprKind::Not(Box::new(inner)).at(source));
259259
}
260-
CTokenKind::Punctuator(Punctuator::Increment) => todo!(),
261-
CTokenKind::Punctuator(Punctuator::Decrement) => todo!(),
262-
CTokenKind::SizeofKeyword => todo!(),
263-
CTokenKind::AlignofKeyword => todo!(),
260+
CTokenKind::Punctuator(Punctuator::Increment) => todo!("parse increment expression"),
261+
CTokenKind::Punctuator(Punctuator::Decrement) => todo!("parse decrement expression"),
262+
CTokenKind::SizeofKeyword => {
263+
if let Ok(_ty) = speculate!(self.input, self.parse_type_in_parens()) {
264+
return todo!("handle parsed sizeof(type)");
265+
}
266+
267+
let _inner = self.parse_expr_primary_base()?;
268+
todo!("parse sizeof expression")
269+
}
270+
CTokenKind::AlignofKeyword => todo!("parse alignof expression"),
264271
_ => (),
265272
}
266273

@@ -283,12 +290,36 @@ impl<'a> Parser<'a> {
283290
}
284291

285292
// Cast
286-
return todo!("cast");
293+
return todo!("parse cast expression");
287294
}
288295

289296
self.parse_expr_atom()
290297
}
291298

299+
fn parse_type_in_parens(&mut self) -> Result<TypeName, ParseError> {
300+
if !self.eat_open_paren() {
301+
return Err(self.error("Expected '(' to begin type in parentheses"));
302+
}
303+
304+
let type_name = self.parse_type_name()?;
305+
306+
if !self.eat_open_paren() {
307+
return Err(self.error("Expected ')' after type in parentheses"));
308+
}
309+
310+
return Ok(type_name);
311+
}
312+
313+
pub fn parse_type_name(&mut self) -> Result<TypeName, ParseError> {
314+
let specifier_qualifiers = self.parse_specifier_qualifier_list()?;
315+
let abstract_declarator = self.parse_abstract_declarator().ok();
316+
317+
Ok(TypeName {
318+
specifier_qualifiers,
319+
abstract_declarator,
320+
})
321+
}
322+
292323
fn parse_operator_expr(&mut self, precedence: usize, expr: Expr) -> Result<Expr, ParseError> {
293324
let mut lhs = expr;
294325

Diff for: src/c/translate/types/mod.rs

+63-11
Original file line numberDiff line numberDiff line change
@@ -14,9 +14,10 @@ use crate::{
1414
ast::{CInteger, FloatSize, IntegerSign, Param, Type, TypeKind},
1515
c::{
1616
ast::{
17-
AlignmentSpecifierKind, DeclarationSpecifiers, Declarator, DeclaratorKind, Decorator,
18-
Decorators, FunctionQualifier, FunctionSpecifier, ParameterDeclarationCore,
19-
StorageClassSpecifier, TypeQualifierKind, TypeSpecifierKind, TypeSpecifierQualifier,
17+
AbstractDeclarator, AbstractDeclaratorKind, AlignmentSpecifierKind,
18+
DeclarationSpecifiers, Declarator, DeclaratorKind, Decorator, Decorators,
19+
FunctionQualifier, FunctionSpecifier, ParameterDeclarationCore, StorageClassSpecifier,
20+
TypeQualifierKind, TypeSpecifierKind, TypeSpecifierQualifier,
2021
},
2122
parser::{error::ParseErrorKind, ParseError},
2223
},
@@ -169,14 +170,12 @@ pub fn build_type_specifier_qualifier(
169170
builder.concrete(make_anonymous_enum(ctx.ast_file, enumeration)?, ts.source)?
170171
}
171172
TypeSpecifierKind::TypedefName(typedef_name) => {
172-
let ast_type = ctx
173-
.typedefs
174-
.get(&typedef_name.name)
175-
.expect("typedef exists")
176-
.ast_type
177-
.clone();
178-
179-
builder.concrete(ast_type.kind, typedef_name.source)?
173+
let Some(typedef) = ctx.typedefs.get(&typedef_name.name) else {
174+
return Err(ParseErrorKind::UndeclaredType(typedef_name.name.clone())
175+
.at(typedef_name.source));
176+
};
177+
178+
builder.concrete(typedef.ast_type.kind.clone(), typedef_name.source)?
180179
}
181180
},
182181
TypeSpecifierQualifier::TypeQualifier(tq) => match &tq.kind {
@@ -286,3 +285,56 @@ fn get_name_and_decorators(
286285
}
287286
}
288287
}
288+
289+
fn get_decorators(
290+
ctx: &mut TranslateCtx,
291+
abstract_declarator: &AbstractDeclarator,
292+
) -> Result<Decorators, ParseError> {
293+
match &abstract_declarator.kind {
294+
AbstractDeclaratorKind::Nothing => Ok(Decorators::default()),
295+
AbstractDeclaratorKind::Pointer(inner, pointer) => {
296+
let mut decorators = get_decorators(ctx, inner)?;
297+
decorators.then_pointer(pointer.clone());
298+
Ok(decorators)
299+
}
300+
AbstractDeclaratorKind::Function(inner, parameter_type_list) => {
301+
let mut decorators = get_decorators(ctx, inner)?;
302+
let mut params = Vec::with_capacity(parameter_type_list.parameter_declarations.len());
303+
304+
if has_parameters(parameter_type_list) {
305+
for parameter in parameter_type_list.parameter_declarations.iter() {
306+
let (param_name, param_type) = match &parameter.core {
307+
ParameterDeclarationCore::Declarator(declarator) => {
308+
let declarator_info = get_name_and_type(
309+
ctx,
310+
declarator,
311+
&parameter.declaration_specifiers,
312+
true,
313+
)?;
314+
(declarator_info.name, declarator_info.ast_type)
315+
}
316+
ParameterDeclarationCore::AbstractDeclarator(_) => todo!(),
317+
ParameterDeclarationCore::Nothing => {
318+
todo!()
319+
}
320+
};
321+
322+
params.push(Param::named(param_name, param_type));
323+
}
324+
}
325+
326+
decorators.then_function(FunctionQualifier {
327+
params,
328+
source: abstract_declarator.source,
329+
is_cstyle_variadic: parameter_type_list.is_variadic,
330+
});
331+
332+
Ok(decorators)
333+
}
334+
AbstractDeclaratorKind::Array(inner, array_qualifier) => {
335+
let mut decorators = get_decorators(ctx, inner)?;
336+
decorators.then_array(array_qualifier.clone());
337+
Ok(decorators)
338+
}
339+
}
340+
}

0 commit comments

Comments
 (0)