Skip to content

Commit bb68541

Browse files
committed
Added support for C return statements, and cleaned up some C translation code
1 parent cd3b1fa commit bb68541

File tree

13 files changed

+234
-193
lines changed

13 files changed

+234
-193
lines changed

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

+7-1
Original file line numberDiff line numberDiff line change
@@ -365,8 +365,14 @@ pub enum ExternalDeclaration {
365365
FunctionDefinition(FunctionDefinition),
366366
}
367367

368+
#[derive(Clone, Debug)]
369+
pub struct BlockItem {
370+
pub kind: BlockItemKind,
371+
pub source: Source,
372+
}
373+
368374
#[derive(Clone, Debug, From)]
369-
pub enum BlockItem {
375+
pub enum BlockItemKind {
370376
Declaration(Declaration),
371377
UnlabeledStatement(UnlabeledStatement),
372378
Label(Label),

Diff for: src/c/lexer/number.rs

+6-1
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,14 @@
11
use super::error::LexError;
22
use crate::c::token::{CTokenKind, Integer, IntegerSuffix};
33

4+
#[derive(Copy, Clone, Debug)]
45
enum Longness {
56
Regular,
67
Long,
78
ExtraLong,
89
}
910

11+
#[derive(Copy, Clone, Debug)]
1012
enum Sign {
1113
Regular,
1214
Unsigned,
@@ -17,16 +19,19 @@ pub fn lex_number(number: String) -> Result<CTokenKind, LexError> {
1719
let (number, radix) = lex_radix(&number);
1820
let (number, sign, longness) = lex_suffix(&number);
1921

22+
dbg!(&number, &sign, &longness);
23+
2024
use IntegerSuffix::*;
2125

2226
let requested = match (sign, longness) {
23-
(Sign::Regular, Longness::Regular) => Long,
27+
(Sign::Regular, Longness::Regular) => Int,
2428
(Sign::Regular, Longness::Long) => Long,
2529
(Sign::Regular, Longness::ExtraLong) => LongLong,
2630
(Sign::Unsigned, Longness::Regular) => UnsignedInt,
2731
(Sign::Unsigned, Longness::Long) => UnsignedLong,
2832
(Sign::Unsigned, Longness::ExtraLong) => UnsignedLongLong,
2933
};
34+
dbg!(&requested);
3035

3136
// The correct type for an integer literal is whichever of these fits it first
3237
// (Section 6.4.4.1 of the C standard)

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

+30-15
Original file line numberDiff line numberDiff line change
@@ -11,8 +11,8 @@ use super::{
1111
ast::{
1212
expr::{DesignatedInitializer, Designation},
1313
AbstractDeclarator, AbstractDeclaratorKind, Abstraction, AlignmentSpecifier,
14-
ArrayQualifier, Attribute, BracedInitializer, CTypedef, CommonDeclaration, Composite,
15-
CompositeKind, CompoundStatement, ConstExpr, Declaration, DeclarationSpecifier,
14+
ArrayQualifier, Attribute, BlockItem, BracedInitializer, CTypedef, CommonDeclaration,
15+
Composite, CompositeKind, CompoundStatement, ConstExpr, Declaration, DeclarationSpecifier,
1616
DeclarationSpecifierKind, DeclarationSpecifiers, Declarator, DeclaratorKind,
1717
EnumTypeSpecifier, Enumeration, EnumerationDefinition, EnumerationNamed, Enumerator,
1818
ExprStatement, ExternalDeclaration, FunctionDefinition, FunctionSpecifier, InitDeclarator,
@@ -24,7 +24,7 @@ use super::{
2424
},
2525
punctuator::Punctuator,
2626
token::{CToken, CTokenKind, Integer},
27-
translation::{declare_function, declare_named_declaration},
27+
translation::{declare_function, declare_named_declaration, TranslateCtx},
2828
};
2929
use crate::{
3030
ast::{AstFile, Type, TypeKind},
@@ -46,6 +46,10 @@ impl Parser<'_> {
4646
pub fn typedefs(&self) -> &HashMap<String, CTypedef> {
4747
&self.typedefs
4848
}
49+
50+
pub fn typedefs_mut(&mut self) -> &mut HashMap<String, CTypedef> {
51+
&mut self.typedefs
52+
}
4953
}
5054

5155
impl<'a> Parser<'a> {
@@ -86,6 +90,12 @@ impl<'a> Parser<'a> {
8690
while !self.input.peek().is_end_of_file() {
8791
let external_declaration = self.parse_external_declaration()?;
8892

93+
let mut ctx = TranslateCtx {
94+
ast_file: &mut ast_file,
95+
typedefs: &mut self.typedefs,
96+
diagnostics: self.diagnostics,
97+
};
98+
8999
match external_declaration {
90100
ExternalDeclaration::Declaration(declaration) => match declaration {
91101
Declaration::Common(declaration) => {
@@ -94,24 +104,20 @@ impl<'a> Parser<'a> {
94104
DeclaratorKind::Named(..)
95105
| DeclaratorKind::Pointer(..)
96106
| DeclaratorKind::Array(..) => declare_named_declaration(
97-
&mut ast_file,
107+
&mut ctx,
98108
&init_declarator.declarator,
99109
&declaration.attribute_specifiers[..],
100110
&declaration.declaration_specifiers,
101-
&mut self.typedefs,
102-
self.diagnostics,
103111
self.c_file_type,
104112
)?,
105113
DeclaratorKind::Function(declarator, parameter_type_list) => {
106114
declare_function(
107-
&mut self.typedefs,
108-
&mut ast_file,
115+
&mut ctx,
109116
&declaration.attribute_specifiers[..],
110117
&declaration.declaration_specifiers,
111118
declarator,
112119
parameter_type_list,
113120
None,
114-
self.diagnostics,
115121
self.c_file_type,
116122
)?;
117123
}
@@ -123,14 +129,12 @@ impl<'a> Parser<'a> {
123129
},
124130
ExternalDeclaration::FunctionDefinition(function_definition) => {
125131
declare_function(
126-
&mut self.typedefs,
127-
&mut ast_file,
132+
&mut ctx,
128133
&function_definition.attributes,
129134
&function_definition.declaration_specifiers,
130135
&function_definition.declarator,
131136
&function_definition.parameter_type_list,
132137
Some(function_definition.body),
133-
self.diagnostics,
134138
self.c_file_type,
135139
)?;
136140
}
@@ -1063,20 +1067,31 @@ impl<'a> Parser<'a> {
10631067
break;
10641068
}
10651069

1070+
let source = self.here();
1071+
10661072
if let Ok(declaration) = speculate!(self.input, self.parse_declaration()) {
1067-
statements.push(declaration.into());
1073+
statements.push(BlockItem {
1074+
kind: declaration.into(),
1075+
source,
1076+
});
10681077
continue;
10691078
}
10701079

10711080
if let Ok(unlabeled_statement) =
10721081
speculate!(self.input, self.parse_unlabeled_statement())
10731082
{
1074-
statements.push(unlabeled_statement.into());
1083+
statements.push(BlockItem {
1084+
kind: unlabeled_statement.into(),
1085+
source,
1086+
});
10751087
continue;
10761088
}
10771089

10781090
if let Ok(label) = speculate!(self.input, self.parse_label()) {
1079-
statements.push(label.into());
1091+
statements.push(BlockItem {
1092+
kind: label.into(),
1093+
source,
1094+
});
10801095
continue;
10811096
}
10821097

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

+6-12
Original file line numberDiff line numberDiff line change
@@ -1,20 +1,14 @@
1+
use super::TranslateCtx;
12
use crate::{
2-
ast::{self, AstFile},
3+
ast::{self},
34
c::{
4-
ast::{expr::Caster, CTypedef},
5+
ast::expr::Caster,
56
parser::ParseError,
67
translation::types::{build_type_specifier_qualifier, TypeBaseBuilder},
78
},
8-
diagnostics::Diagnostics,
99
};
10-
use std::collections::HashMap;
11-
12-
pub fn get_caster_type(
13-
ast_file: &mut AstFile,
14-
typedefs: &HashMap<String, CTypedef>,
15-
caster: &Caster,
16-
diagnostics: &Diagnostics,
17-
) -> Result<ast::Type, ParseError> {
10+
11+
pub fn get_caster_type(ctx: &mut TranslateCtx, caster: &Caster) -> Result<ast::Type, ParseError> {
1812
let mut builder = TypeBaseBuilder::new(caster.source);
1913

2014
if !caster.specializer_qualifiers.attributes.is_empty() {
@@ -26,7 +20,7 @@ pub fn get_caster_type(
2620
.type_specifier_qualifiers
2721
.iter()
2822
{
29-
build_type_specifier_qualifier(ast_file, &mut builder, typedefs, tsq, diagnostics)?;
23+
build_type_specifier_qualifier(ctx, &mut builder, tsq)?;
3024
}
3125

3226
if let Some(_abstract_declarator) = &caster.abstract_declarator {

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

+6-12
Original file line numberDiff line numberDiff line change
@@ -1,27 +1,21 @@
1+
use super::TranslateCtx;
12
use crate::{
2-
ast::{self, AstFile, FillBehavior, Language},
3+
ast::{self, FillBehavior, Language},
34
c::{
4-
ast::{
5-
expr::{CompoundLiteral, Initializer},
6-
CTypedef,
7-
},
5+
ast::expr::{CompoundLiteral, Initializer},
86
parser::ParseError,
97
translate_expr,
108
translation::expr::caster::get_caster_type,
119
},
12-
diagnostics::Diagnostics,
1310
source_files::Source,
1411
};
15-
use std::collections::HashMap;
1612

1713
pub fn translate_compound_literal(
18-
ast_file: &mut AstFile,
19-
typedefs: &HashMap<String, CTypedef>,
14+
ctx: &mut TranslateCtx,
2015
compound_literal: &CompoundLiteral,
2116
source: Source,
22-
diagnostics: &Diagnostics,
2317
) -> Result<ast::Expr, ParseError> {
24-
let ast_type = get_caster_type(ast_file, typedefs, &compound_literal.caster, diagnostics)?;
18+
let ast_type = get_caster_type(ctx, &compound_literal.caster)?;
2519
let mut fields = Vec::new();
2620

2721
for init in compound_literal
@@ -34,7 +28,7 @@ pub fn translate_compound_literal(
3428
}
3529

3630
let value = match &init.initializer {
37-
Initializer::Expression(expr) => translate_expr(ast_file, typedefs, expr, diagnostics)?,
31+
Initializer::Expression(expr) => translate_expr(ctx, expr)?,
3832
Initializer::BracedInitializer(_) => {
3933
todo!("nested brace initializer for translate_compound_literal")
4034
}

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

+14-27
Original file line numberDiff line numberDiff line change
@@ -7,25 +7,16 @@ use self::{
77
compound_literal::translate_compound_literal, integer::translate_expr_integer,
88
string::translate_expr_string,
99
};
10+
use super::TranslateCtx;
1011
use crate::{
11-
ast::{self, AstFile},
12+
ast,
1213
c::{
13-
ast::{
14-
expr::{BinaryOperator, Expr, ExprKind},
15-
CTypedef,
16-
},
14+
ast::expr::{BinaryOperator, Expr, ExprKind},
1715
parser::{error::ParseErrorKind, ParseError},
1816
},
19-
diagnostics::Diagnostics,
2017
};
21-
use std::collections::HashMap;
2218

23-
pub fn translate_expr(
24-
ast_file: &mut AstFile,
25-
typedefs: &HashMap<String, CTypedef>,
26-
expr: &Expr,
27-
diagnostics: &Diagnostics,
28-
) -> Result<ast::Expr, ParseError> {
19+
pub fn translate_expr(ctx: &mut TranslateCtx, expr: &Expr) -> Result<ast::Expr, ParseError> {
2920
Ok(match &expr.kind {
3021
ExprKind::Integer(integer) => translate_expr_integer(integer, expr.source)?,
3122
ExprKind::Float(_, _) => todo!(),
@@ -37,8 +28,8 @@ pub fn translate_expr(
3728
ExprKind::Character(_, _) => todo!(),
3829
ExprKind::Compound(_) => todo!(),
3930
ExprKind::BinaryOperation(operation) => {
40-
let left = translate_expr(ast_file, typedefs, &operation.left, diagnostics)?;
41-
let right = translate_expr(ast_file, typedefs, &operation.right, diagnostics)?;
31+
let left = translate_expr(ctx, &operation.left)?;
32+
let right = translate_expr(ctx, &operation.right)?;
4233

4334
let operator: ast::BinaryOperator = match operation.operator {
4435
BinaryOperator::LogicalOr => ast::ShortCircuitingBinaryOperator::Or.into(),
@@ -103,42 +94,38 @@ pub fn translate_expr(
10394
return Err(ParseErrorKind::UndefinedVariable(name.into()).at(expr.source));
10495
}
10596
ExprKind::EnumConstant(_, _) => todo!(),
106-
ExprKind::CompoundLiteral(compound_literal) => translate_compound_literal(
107-
ast_file,
108-
typedefs,
109-
compound_literal,
110-
expr.source,
111-
diagnostics,
112-
)?,
97+
ExprKind::CompoundLiteral(compound_literal) => {
98+
translate_compound_literal(ctx, compound_literal, expr.source)?
99+
}
113100
ExprKind::AddressOf(inner) => {
114101
ast::ExprKind::UnaryOperation(Box::new(ast::UnaryOperation {
115102
operator: ast::UnaryOperator::AddressOf,
116-
inner: translate_expr(ast_file, typedefs, inner, diagnostics)?,
103+
inner: translate_expr(ctx, inner)?,
117104
}))
118105
.at(expr.source)
119106
}
120107
ExprKind::Dereference(inner) => {
121108
ast::ExprKind::UnaryOperation(Box::new(ast::UnaryOperation {
122109
operator: ast::UnaryOperator::Dereference,
123-
inner: translate_expr(ast_file, typedefs, inner, diagnostics)?,
110+
inner: translate_expr(ctx, inner)?,
124111
}))
125112
.at(expr.source)
126113
}
127114
ExprKind::Negate(inner) => ast::ExprKind::UnaryOperation(Box::new(ast::UnaryOperation {
128115
operator: ast::UnaryOperator::Math(ast::UnaryMathOperator::Negate),
129-
inner: translate_expr(ast_file, typedefs, inner, diagnostics)?,
116+
inner: translate_expr(ctx, inner)?,
130117
}))
131118
.at(expr.source),
132119
ExprKind::BitComplement(inner) => {
133120
ast::ExprKind::UnaryOperation(Box::new(ast::UnaryOperation {
134121
operator: ast::UnaryOperator::Math(ast::UnaryMathOperator::BitComplement),
135-
inner: translate_expr(ast_file, typedefs, inner, diagnostics)?,
122+
inner: translate_expr(ctx, inner)?,
136123
}))
137124
.at(expr.source)
138125
}
139126
ExprKind::Not(inner) => ast::ExprKind::UnaryOperation(Box::new(ast::UnaryOperation {
140127
operator: ast::UnaryOperator::Math(ast::UnaryMathOperator::Not),
141-
inner: translate_expr(ast_file, typedefs, inner, diagnostics)?,
128+
inner: translate_expr(ctx, inner)?,
142129
}))
143130
.at(expr.source),
144131
ExprKind::Call(_target, _args) => todo!("translate C call expression"),

0 commit comments

Comments
 (0)