|
7 | 7 | // SPDX-License-Identifier: MIT |
8 | 8 | // |
9 | 9 | // Parser for pcc C99 compiler |
10 | | -// Based on sparse's expression.c recursive descent design |
| 10 | +// Recursive descent parser with Pratt-style precedence climbing |
11 | 11 | // |
12 | 12 |
|
13 | 13 | use super::ast::{ |
@@ -181,15 +181,15 @@ impl fmt::Display for AttributeList { |
181 | 181 |
|
182 | 182 | /// C expression parser using recursive descent with precedence climbing |
183 | 183 | /// |
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. |
187 | 187 | pub struct Parser<'a> { |
188 | 188 | /// Token stream |
189 | 189 | tokens: &'a [Token], |
190 | 190 | /// Identifier table for looking up names |
191 | 191 | idents: &'a IdentTable, |
192 | | - /// Symbol table for binding declarations (like sparse's bind_symbol) |
| 192 | + /// Symbol table for binding declarations |
193 | 193 | symbols: &'a mut SymbolTable, |
194 | 194 | /// Type table for interning types |
195 | 195 | types: &'a mut TypeTable, |
@@ -1576,26 +1576,20 @@ impl<'a> Parser<'a> { |
1576 | 1576 | // Now expect parameter list |
1577 | 1577 | if self.is_special(b'(') { |
1578 | 1578 | 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; |
1590 | 1583 | } |
| 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); |
1591 | 1592 | } |
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); |
1599 | 1593 | } |
1600 | 1594 | } |
1601 | 1595 | } |
@@ -2921,9 +2915,9 @@ impl Parser<'_> { |
2921 | 2915 |
|
2922 | 2916 | /// Parse a compound statement (block) with its own scope |
2923 | 2917 | /// |
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. |
2927 | 2921 | fn parse_block_stmt(&mut self) -> ParseResult<Stmt> { |
2928 | 2922 | self.expect_special(b'{')?; |
2929 | 2923 |
|
@@ -3066,8 +3060,8 @@ impl Parser<'_> { |
3066 | 3060 |
|
3067 | 3061 | /// Parse a declaration and bind variables to symbol table |
3068 | 3062 | /// |
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. |
3071 | 3065 | fn parse_declaration_and_bind(&mut self) -> ParseResult<Declaration> { |
3072 | 3066 | // Parse type specifiers |
3073 | 3067 | let base_type = self.parse_type_specifier()?; |
@@ -3117,7 +3111,7 @@ impl Parser<'_> { |
3117 | 3111 | } |
3118 | 3112 | } |
3119 | 3113 |
|
3120 | | - // Bind to symbol table (like sparse's bind_symbol) |
| 3114 | + // Bind to symbol table |
3121 | 3115 | // Note: StringId is Copy, check for empty by comparing to empty string |
3122 | 3116 | let name_str = self.str(name); |
3123 | 3117 | if !name_str.is_empty() { |
@@ -3945,9 +3939,9 @@ impl Parser<'_> { |
3945 | 3939 |
|
3946 | 3940 | /// Parse a function definition |
3947 | 3941 | /// |
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. |
3951 | 3945 | #[cfg(test)] |
3952 | 3946 | fn parse_function_def(&mut self) -> ParseResult<FunctionDef> { |
3953 | 3947 | let func_pos = self.current_pos(); |
@@ -4010,7 +4004,6 @@ impl Parser<'_> { |
4010 | 4004 | let func_type_id = self.types.intern(func_type); |
4011 | 4005 |
|
4012 | 4006 | // Bind function to symbol table at current (global) scope |
4013 | | - // Like sparse's bind_symbol() in parse.c |
4014 | 4007 | let func_sym = Symbol::function(name, func_type_id, self.symbols.depth()); |
4015 | 4008 | let _ = self.symbols.declare(func_sym); // Ignore redefinition errors for now |
4016 | 4009 |
|
|
0 commit comments