Skip to content

Commit 13dda5e

Browse files
authored
Merge pull request #464 from rustcoreutils/updates
Updates
2 parents 5fe46d8 + d6abc1c commit 13dda5e

36 files changed

+2188
-4388
lines changed

cc/arch/codegen.rs

Lines changed: 3 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -44,27 +44,17 @@ pub const PCC_VERSION: &str = env!("CARGO_PKG_VERSION");
4444
pub fn generate_header_comments(target: &Target) -> Vec<String> {
4545
let mut comments = Vec::new();
4646

47-
// Compiler identification
48-
comments.push(format!("Generated by pcc {}", PCC_VERSION));
49-
5047
// Target triple (normalized format)
5148
let os_triple = match target.os {
5249
crate::target::Os::Linux => "unknown-linux-gnu",
5350
crate::target::Os::MacOS => "apple-darwin",
5451
crate::target::Os::FreeBSD => "unknown-freebsd",
5552
};
56-
comments.push(format!("Target: {}-{}", target.arch, os_triple));
5753

58-
// ABI info
54+
// Compiler identification with target
5955
comments.push(format!(
60-
"ABI: LP64, pointer={}bit, long={}bit, char={}",
61-
target.pointer_width,
62-
target.long_width,
63-
if target.char_signed {
64-
"signed"
65-
} else {
66-
"unsigned"
67-
}
56+
"Generated by pcc {} ({}-{})",
57+
PCC_VERSION, target.arch, os_triple
6858
));
6959

7060
comments

cc/diag.rs

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -18,10 +18,10 @@ use std::sync::atomic::{AtomicU32, Ordering};
1818
// Source Position
1919
// ============================================================================
2020

21-
/// Source position tracking (mirrors sparse's struct position)
21+
/// Source position tracking for tokens and diagnostics.
2222
///
23-
/// This is a compact structure that gets attached to every token.
24-
/// Following sparse's design where position fields are bit-packed.
23+
/// A compact structure attached to every token, tracking file, line,
24+
/// column, and preprocessor state (whitespace, newline flags).
2525
#[derive(Debug, Clone, Copy, Default, PartialEq, Eq)]
2626
pub struct Position {
2727
/// Stream/file index (which file this is in)
@@ -92,7 +92,7 @@ impl fmt::Display for Position {
9292
// Stream (Input Source)
9393
// ============================================================================
9494

95-
/// Input stream information (following sparse's struct stream)
95+
/// Input stream information for tracking source files and includes.
9696
#[derive(Debug, Clone)]
9797
pub struct Stream {
9898
/// Filename

cc/doc/TODO.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -413,7 +413,7 @@ _Noreturn void exit(int status);
413413
414414
### Overview
415415
416-
The compiler uses a sparse-style SSA IR, which is well-suited for classical optimizations. Passes are run iteratively until a fixed point is reached.
416+
The compiler uses an SSA-form IR, which is well-suited for classical optimizations. Passes are run iteratively until a fixed point is reached.
417417
418418
### Pass 1: SCCP - Sparse Conditional Constant Propagation
419419

cc/ir/dominate.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@
88
//
99
// Dominator tree computation for pcc C99 compiler
1010
//
11-
// Based on sparse's flowgraph.c and dominate.c:
11+
// Algorithms used:
1212
// - Dominator tree: "A simple, fast dominance algorithm" by Cooper, Harvey, Kennedy
1313
// - IDF computation: "A Linear Time Algorithm for Placing phi-nodes" by Sreedhar and Gao
1414
//
@@ -39,7 +39,7 @@ fn compute_postorder(func: &mut Function) -> Vec<BasicBlockId> {
3939
visited.insert(bb_id);
4040

4141
if let Some(bb) = func.get_block(bb_id) {
42-
// Visit children in reverse order (like sparse)
42+
// Visit children in reverse order for consistent numbering
4343
for &child in bb.children.iter().rev() {
4444
dfs(func, child, visited, postorder);
4545
}

cc/ir/linearize.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@
77
// SPDX-License-Identifier: MIT
88
//
99
// Linearizer for pcc C99 compiler
10-
// Converts AST to SSA-style IR following sparse's design
10+
// Converts AST to SSA-form IR with basic blocks and typed pseudo-registers
1111
//
1212

1313
use super::ssa::ssa_convert;
@@ -2143,7 +2143,7 @@ impl<'a> Linearizer<'a> {
21432143

21442144
/// Get the type of an expression.
21452145
/// PANICS if expression has no type - type evaluation pass must run first.
2146-
/// Following sparse's design: the IR should ALWAYS receive fully typed input.
2146+
/// The IR requires fully typed input from the type evaluation pass.
21472147
fn expr_type(&self, expr: &Expr) -> TypeId {
21482148
expr.typ.expect(
21492149
"BUG: expression has no type. Type evaluation pass must run before linearization.",

cc/ir/mod.rs

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@
77
// SPDX-License-Identifier: MIT
88
//
99
// Intermediate Representation (IR) for pcc C99 compiler
10-
// Based on sparse's linearize.c SSA-style IR
10+
// SSA-form IR with basic blocks and typed pseudo-registers
1111
//
1212
// The IR uses Single Static Assignment (SSA) form where each variable
1313
// is assigned exactly once. This simplifies dataflow analysis and
@@ -45,10 +45,10 @@ impl InsnRef {
4545
}
4646

4747
// ============================================================================
48-
// Opcodes - Following sparse's opcode.def
48+
// Opcodes
4949
// ============================================================================
5050

51-
/// IR opcodes following sparse's design
51+
/// IR opcodes for the intermediate representation
5252
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
5353
pub enum Opcode {
5454
// Function entry

cc/ir/ssa.rs

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -8,8 +8,7 @@
88
//
99
// SSA Conversion for pcc C99 compiler
1010
//
11-
// Based on sparse's ssa.c:
12-
// - Converts memory-based local variables to SSA form
11+
// Converts memory-based local variables to SSA form:
1312
// - Inserts phi nodes at dominance frontiers
1413
// - Renames variables to complete SSA construction
1514
//

cc/main.rs

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -421,6 +421,13 @@ fn main() -> Result<(), Box<dyn std::error::Error>> {
421421
let source_files: Vec<&String> = args.files.iter().filter(|f| is_source_file(f)).collect();
422422
let object_files: Vec<&String> = args.files.iter().filter(|f| is_object_file(f)).collect();
423423

424+
// Warn about unrecognized file types
425+
for file in &args.files {
426+
if !is_source_file(file) && !is_object_file(file) {
427+
eprintln!("pcc: warning: unrecognized file type: {}", file);
428+
}
429+
}
430+
424431
// If we only have object files and an output is specified, just link them
425432
if source_files.is_empty() && !object_files.is_empty() && args.output.is_some() {
426433
let exe_file = args.output.clone().unwrap();

cc/parse/ast.rs

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@
77
// SPDX-License-Identifier: MIT
88
//
99
// Abstract Syntax Tree for pcc C99 compiler
10-
// Based on sparse's AST representation
10+
// Type-annotated AST for C99 with expressions, statements, and declarations
1111
//
1212

1313
use crate::diag::Position;
@@ -108,15 +108,15 @@ pub enum AssignOp {
108108
// Expressions
109109
// ============================================================================
110110

111-
/// An expression with type annotation (like sparse's expr->ctype)
111+
/// An expression with type annotation
112112
///
113-
/// Following sparse's design, every expression carries its computed type.
114-
/// The type is filled in during type evaluation (after parsing, before linearization).
113+
/// Every expression carries its computed type, filled in during type evaluation
114+
/// (after parsing, before linearization).
115115
#[derive(Debug, Clone)]
116116
pub struct Expr {
117117
/// The expression kind/variant
118118
pub kind: ExprKind,
119-
/// The computed type of this expression (like sparse's expr->ctype)
119+
/// The computed type of this expression
120120
/// None before type evaluation, Some after (interned TypeId)
121121
pub typ: Option<TypeId>,
122122
/// Source position for debug info

cc/parse/parser.rs

Lines changed: 26 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@
77
// SPDX-License-Identifier: MIT
88
//
99
// Parser for pcc C99 compiler
10-
// Based on sparse's expression.c recursive descent design
10+
// Recursive descent parser with Pratt-style precedence climbing
1111
//
1212

1313
use super::ast::{
@@ -181,15 +181,15 @@ impl fmt::Display for AttributeList {
181181

182182
/// C expression parser using recursive descent with precedence climbing
183183
///
184-
/// Following sparse's design, the parser binds symbols to the symbol table
185-
/// during parsing. This means that by the time parsing is complete, all
186-
/// declared symbols are in the table with their types.
184+
/// The parser binds symbols to the symbol table during parsing. This means
185+
/// that by the time parsing is complete, all declared symbols are in the
186+
/// table with their types.
187187
pub struct Parser<'a> {
188188
/// Token stream
189189
tokens: &'a [Token],
190190
/// Identifier table for looking up names
191191
idents: &'a IdentTable,
192-
/// Symbol table for binding declarations (like sparse's bind_symbol)
192+
/// Symbol table for binding declarations
193193
symbols: &'a mut SymbolTable,
194194
/// Type table for interning types
195195
types: &'a mut TypeTable,
@@ -1576,26 +1576,20 @@ impl<'a> Parser<'a> {
15761576
// Now expect parameter list
15771577
if self.is_special(b'(') {
15781578
self.advance(); // consume '('
1579-
// Parse parameter types (simplified - just skip them for now)
1580-
// Full implementation would build proper function type
1581-
let mut param_depth = 1;
1582-
while param_depth > 0 && !self.is_eof() {
1583-
if self.is_special(b'(') {
1584-
param_depth += 1;
1585-
} else if self.is_special(b')') {
1586-
param_depth -= 1;
1587-
}
1588-
if param_depth > 0 {
1589-
self.advance();
1579+
// Parse parameter types properly
1580+
if let Ok((params, variadic)) = self.parse_parameter_list() {
1581+
if !self.is_special(b')') {
1582+
return None;
15901583
}
1584+
self.advance(); // consume final ')'
1585+
// Create function pointer type with actual parameter types
1586+
let param_type_ids: Vec<TypeId> =
1587+
params.iter().map(|p| p.typ).collect();
1588+
let fn_type = Type::function(result_id, param_type_ids, variadic);
1589+
let fn_type_id = self.types.intern(fn_type);
1590+
result_id = self.types.intern(Type::pointer(fn_type_id));
1591+
return Some(result_id);
15911592
}
1592-
self.advance(); // consume final ')'
1593-
// Create function pointer type: pointer to function returning result_id
1594-
// For now, create a generic function pointer (void -> result_id)
1595-
let fn_type = Type::function(result_id, vec![], false);
1596-
let fn_type_id = self.types.intern(fn_type);
1597-
result_id = self.types.intern(Type::pointer(fn_type_id));
1598-
return Some(result_id);
15991593
}
16001594
}
16011595
}
@@ -2921,9 +2915,9 @@ impl Parser<'_> {
29212915

29222916
/// Parse a compound statement (block) with its own scope
29232917
///
2924-
/// Like sparse, blocks create their own scope for local declarations.
2925-
/// This enters a new scope, parses the block, binds any declarations,
2926-
/// then leaves the scope.
2918+
/// Blocks create their own scope for local declarations. This enters a
2919+
/// new scope, parses the block, binds any declarations, then leaves
2920+
/// the scope.
29272921
fn parse_block_stmt(&mut self) -> ParseResult<Stmt> {
29282922
self.expect_special(b'{')?;
29292923

@@ -3066,8 +3060,8 @@ impl Parser<'_> {
30663060

30673061
/// Parse a declaration and bind variables to symbol table
30683062
///
3069-
/// Following sparse's design, this binds each declared variable to the
3070-
/// symbol table immediately during parsing. Like sparse's bind_symbol().
3063+
/// Binds each declared variable to the symbol table immediately during
3064+
/// parsing, so the symbol is available for subsequent references.
30713065
fn parse_declaration_and_bind(&mut self) -> ParseResult<Declaration> {
30723066
// Parse type specifiers
30733067
let base_type = self.parse_type_specifier()?;
@@ -3117,7 +3111,7 @@ impl Parser<'_> {
31173111
}
31183112
}
31193113

3120-
// Bind to symbol table (like sparse's bind_symbol)
3114+
// Bind to symbol table
31213115
// Note: StringId is Copy, check for empty by comparing to empty string
31223116
let name_str = self.str(name);
31233117
if !name_str.is_empty() {
@@ -3945,9 +3939,9 @@ impl Parser<'_> {
39453939

39463940
/// Parse a function definition
39473941
///
3948-
/// Following sparse's design, this binds the function to the symbol table
3949-
/// at global scope, then enters a new scope for the function body and
3950-
/// binds all parameters in that scope.
3942+
/// Binds the function to the symbol table at global scope, then enters
3943+
/// a new scope for the function body and binds all parameters in that
3944+
/// scope.
39513945
#[cfg(test)]
39523946
fn parse_function_def(&mut self) -> ParseResult<FunctionDef> {
39533947
let func_pos = self.current_pos();
@@ -4010,7 +4004,6 @@ impl Parser<'_> {
40104004
let func_type_id = self.types.intern(func_type);
40114005

40124006
// Bind function to symbol table at current (global) scope
4013-
// Like sparse's bind_symbol() in parse.c
40144007
let func_sym = Symbol::function(name, func_type_id, self.symbols.depth());
40154008
let _ = self.symbols.declare(func_sym); // Ignore redefinition errors for now
40164009

0 commit comments

Comments
 (0)