diff --git a/rust/src/compile/impls.rs b/rust/src/compile/impls.rs index 75391e6..766374d 100644 --- a/rust/src/compile/impls.rs +++ b/rust/src/compile/impls.rs @@ -51,18 +51,18 @@ impl Display for Type { if f.alternate() { s = format!("function returning < {:#} > with parameters: (", return_type); if let Some((first, remaining)) = param_list.split_first() { - write!(s, "{:#}", first)?; + write!(s, "{:#}", first.ctype)?; for p in remaining { - write!(s, ", {:#}", p)?; + write!(s, ", {:#}", p.ctype)?; } } s.push(')'); } else { s = "func (".to_string(); if let Some((first, remaining)) = param_list.split_first() { - write!(s, "{}", first)?; + write!(s, "{}", first.ctype)?; for p in remaining { - write!(s, ", {}", p)?; + write!(s, ", {}", p.ctype)?; } } write!(s, "): {}", return_type)?; @@ -73,12 +73,6 @@ impl Display for Type { } } -impl From> for DeclarationList { - fn from(l: Vec) -> Self { - DeclarationList { list: (l) } - } -} - impl Display for Declarator { fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { match self.value { @@ -115,8 +109,8 @@ impl Display for Statement { fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { match self { Self::Empty => writeln!(f, ";"), - // Self::ExprStmt(expr) => writeln!(f, "{};", expr), - // Self::ReturnStmt(expr) => writeln!(f, "return\n{};", expr), + Self::ExprStmt(expr) => writeln!(f, "{};", expr), + Self::ReturnStmt(expr) => writeln!(f, "return\n{};", expr), } } } diff --git a/rust/src/compile/parse.rs b/rust/src/compile/parse.rs index 05cea4b..daafaa0 100644 --- a/rust/src/compile/parse.rs +++ b/rust/src/compile/parse.rs @@ -9,7 +9,7 @@ use super::{ pub struct Parser { token_list: TokenList, index: usize, - globals: Option, + globals: Vec, } impl Parser { @@ -40,6 +40,8 @@ impl Parser { self.index += n; } + // pub fn reset(&mut self) { self.index = 0; } + #[inline] fn seek_to(&mut self, n: usize) { self.index = n; @@ -79,29 +81,21 @@ impl Parser { } impl Parser { - pub fn new(token_list: TokenList) -> Self { - Parser { token_list, index: 0, globals: None } + fn new(token_list: TokenList) -> Self { + Parser { token_list, index: 0, globals: vec![] } } pub fn from_str(input: &str) -> Result { input.parse().map_err(ParseError::LexError).map(Self::new) } - pub fn parse(&mut self) -> Result, ParseError> { - self.parse_expr(Precedence::P1Comma) + pub fn compile(&mut self) -> Result, ParseError> { + Ok(vec![]) } - pub fn declaration(&mut self) -> Result { + pub fn declaration(&mut self) -> Result { let base_type = self.declspec()?; - let result = self.declarator(base_type)?; - Ok(result) - } - - pub fn test(input: &str) -> Result { - match Self::from_str(input)?.parse()? { - Some(expr) => Ok(expr), - None => Err(ParseError::EndOfToken), - } + Ok(self.declarator(base_type)?) } pub fn show_parse_state(&self) { @@ -125,14 +119,24 @@ impl Parser { print!("\n"); } + fn enter_scope(&mut self) {} + + fn leave_scope(&mut self) {} + fn declspec(&mut self) -> Result { - match self.next()? { - Token::Keyword(Keyword::Void) => Ok(TYPE_VOID), - Token::Keyword(Keyword::Bool) => Ok(TYPE_BOOL), - Token::Keyword(Keyword::Char) => Ok(TYPE_CHAR), - Token::Keyword(Keyword::Int) => Ok(TYPE_INT), - _ => Err(ParseError::NotType), + while let Some(token) = self.peek_next() { + if token.is_type_keyword() { + self.advance(); + return match token { + Token::Keyword(Keyword::Void) => Ok(TYPE_VOID), + Token::Keyword(Keyword::Bool) => Ok(TYPE_BOOL), + Token::Keyword(Keyword::Char) => Ok(TYPE_CHAR), + Token::Keyword(Keyword::Int) => Ok(TYPE_INT), + _ => Err(ParseError::NotType), + }; + } } + Err(ParseError::NotType) } fn func_params(&mut self, base_type: Type) -> Result { @@ -185,7 +189,7 @@ impl Parser { } } - fn declarator(&mut self, mut base_type: Type) -> Result { + fn declarator(&mut self, mut base_type: Type) -> Result { while let Some(Token::Punct(Punct::Mul)) = self.peek_next() { self.advance(); base_type = base_type.into_pointer(); @@ -201,7 +205,7 @@ impl Parser { let pos2 = self.index; self.seek_to(pos1); - base_type = self.declarator(base_type)?; + let base_type = self.declarator(base_type)?; self.seek_to(pos2); Ok(base_type) @@ -212,7 +216,8 @@ impl Parser { } base_type = self.type_suffix(base_type)?; - Ok(base_type) + + Ok(TypeIdentifier::new(base_type, name)) } } else { Err(ParseError::EndOfToken) @@ -281,7 +286,7 @@ impl Parser { } } - fn parse_expr(&mut self, precedence: Precedence) -> Result, ParseError> { + pub fn parse_expr(&mut self, precedence: Precedence) -> Result, ParseError> { let mut first = match self.parse_leaf()? { Some(leaf) => leaf, None => return Ok(None), diff --git a/rust/src/compile/tests.rs b/rust/src/compile/tests.rs index 3339049..e42ac3e 100644 --- a/rust/src/compile/tests.rs +++ b/rust/src/compile/tests.rs @@ -7,12 +7,13 @@ fn test_declaration(input: &str) { p.show_parse_state(); r }) { - Ok(r) => println!("{}", r), + Ok(r) => println!("{}: {}", r.name.unwrap_or_default(), r.ctype), Err(e) => println!("\t[error]\t{}", e), } } #[test] +#[ignore = "done"] fn test_types() { test_declaration("int i, j"); test_declaration("int *i"); @@ -45,7 +46,7 @@ fn test_types() { fn test_expr(input: &str) { println!("------\n{}", input); match Parser::from_str(input).and_then(|mut x| { - let r = x.parse(); + let r = x.parse_expr(crate::compile::token::Precedence::P1Comma); x.show_parse_state(); r }) { @@ -96,3 +97,25 @@ fn test_expr_parse() { // 所有副作用在函数调用前完成 test_expr("(*pf[f1()]) (f2(), f3() + f4())"); } + +fn compile(input: &str) { + println!("\n------"); + match Parser::from_str(input).and_then(|mut p| { + let r = p.compile(); + p.show_parse_state(); + r + }) { + Ok(r) => { + for obj in r { + println!("{:?}", obj); + } + } + + Err(e) => println!("\t[error]\t{}", e), + } +} + +#[test] +fn test_compile() { + compile("int i;"); +} diff --git a/rust/src/compile/token_impl.rs b/rust/src/compile/token_impl.rs index 5be46ed..8df1e5f 100644 --- a/rust/src/compile/token_impl.rs +++ b/rust/src/compile/token_impl.rs @@ -283,6 +283,27 @@ impl Token { } } + pub fn is_type_keyword(&self) -> bool { + match self { + Token::Keyword(keyword) => matches!( + keyword, + Keyword::Void + | Keyword::Bool | Keyword::Char + | Keyword::Short | Keyword::Int + | Keyword::Long | Keyword::Signed + | Keyword::Unsigned | Keyword::Float + | Keyword::Double | Keyword::Struct + | Keyword::Union | Keyword::Enum + | Keyword::Auto | Keyword::Register + | Keyword::Const | Keyword::Volatile + | Keyword::Restrict | Keyword::Typedef + | Keyword::Inline | Keyword::Static + | Keyword::Extern + ), + _ => false, + } + } + pub fn precedence(&self) -> Precedence { match self { Token::Const(_) => Precedence::P0Min, diff --git a/rust/src/compile/types.rs b/rust/src/compile/types.rs index 32f6289..aa206ab 100644 --- a/rust/src/compile/types.rs +++ b/rust/src/compile/types.rs @@ -8,14 +8,21 @@ pub enum Object { #[derive(Debug, Clone, PartialEq, Eq)] pub struct Variable { - pub next: Option>, - pub name: Option, + pub name: String, pub ctype: Type, + + pub is_local: bool, + pub is_tentative: bool, } #[derive(Debug, Clone, PartialEq, Eq)] pub struct Function { - pub next: Option>, + pub name: String, + pub ctype: Func, + pub locals: Vec, + pub stmts: Vec, + pub stack_size: usize, + pub is_definition: bool, } #[derive(Debug, Clone, PartialEq, Eq)] @@ -23,17 +30,12 @@ pub enum Type { Void, Bool, Char, - // Short(Short), Int, - // Long(Long), - // Float(Float), - // Double(Double), Ptr(Ptr), Array(Array), - // Enum(Enum), - // Struct(Struct), - // Union(Union), Func(Func), + // Enum(Enum), // Struct(Struct), // Union(Union), + // Short(Short), // Long(Long), // Float(Float), // Double(Double), } pub const TYPE_VOID: Type = Type::Void; @@ -41,6 +43,34 @@ pub const TYPE_BOOL: Type = Type::Bool; pub const TYPE_CHAR: Type = Type::Char; pub const TYPE_INT: Type = Type::Int; +#[derive(Debug, Clone, PartialEq, Eq)] +pub struct TypeIdentifier { + pub name: Option, + pub ctype: Type, +} + +impl TypeIdentifier { + pub fn from_type(ctype: Type) -> Self { + TypeIdentifier { name: None, ctype } + } + + pub fn from_type_name(ctype: Type, name: String) -> Self { + TypeIdentifier { name: Some(name), ctype } + } + + pub fn new(ctype: Type, name: Option) -> Self { + TypeIdentifier { name, ctype } + } +} + +#[derive(Debug, Copy, Clone, PartialEq, Eq)] +pub struct VarAttr { + pub is_typedef: bool, + pub is_static: bool, + pub is_extern: bool, + pub is_inline: bool, +} + impl Type { pub fn into_pointer(self) -> Self { Type::Ptr(Ptr { base_type: Box::new(self) }) @@ -48,7 +78,7 @@ impl Type { pub fn into_array(self, expr: Option) -> Self { let length = match expr { - Some(Expr::Const(Const::Integer(ref i))) => i.parse().unwrap(), + Some(Expr::Const(Const::Integer(ref i))) => i.parse().unwrap_or_default(), _ => 0, }; Type::Array(Array { base_type: Box::new(self), length, size_expr: expr }) @@ -58,7 +88,7 @@ impl Type { Type::Func(Func { return_type: Box::new(self), param_list: vec![], is_variadic: false }) } - pub fn into_function_with_param(self, param_list: Vec) -> Self { + pub fn into_function_with_param(self, param_list: Vec) -> Self { Type::Func(Func { return_type: Box::new(self), param_list, is_variadic: false }) } } @@ -106,7 +136,7 @@ pub struct Array { #[derive(Debug, Clone, PartialEq, Eq)] pub struct Func { pub return_type: Box, - pub param_list: Vec, + pub param_list: Vec, pub is_variadic: bool, } @@ -143,6 +173,8 @@ pub struct Parameter { pub enum Statement { #[default] Empty, + ExprStmt(Expr), + ReturnStmt(Expr), } #[derive(Debug, Clone, PartialEq, Eq)] @@ -241,11 +273,3 @@ pub struct CommaExpr { pub left: Box, pub right: Box, } - -#[derive(Debug, Clone, PartialEq, Eq)] -pub enum Declaration {} - -#[derive(Debug, PartialEq, Eq)] -pub struct DeclarationList { - pub list: Vec, -} diff --git a/rust/src/main.rs b/rust/src/main.rs index 6a881cc..d9b3a89 100644 --- a/rust/src/main.rs +++ b/rust/src/main.rs @@ -118,12 +118,12 @@ fn main() -> Result<(), Box> { p.show_parse_state(); r })?; - println!("------\n{}", data); + println!("------\n{}: {}", data.name.unwrap_or_default(), data.ctype); } - match compile::parse::Parser::test(src.as_str()) { - Ok(expr) => println!("------\n{}", expr), - Err(e) => println!("\t[error]\n{}", e), + let objs = compile::parse::Parser::from_str(src.as_str()).and_then(|mut p| p.compile())?; + for obj in objs { + println!("------\n{:?}", obj); } }