Skip to content

Commit

Permalink
next: simple compile
Browse files Browse the repository at this point in the history
  • Loading branch information
davidxifeng committed Sep 10, 2022
1 parent 7552ffc commit baaa789
Show file tree
Hide file tree
Showing 6 changed files with 131 additions and 64 deletions.
18 changes: 6 additions & 12 deletions rust/src/compile/impls.rs
Expand Up @@ -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)?;
Expand All @@ -73,12 +73,6 @@ impl Display for Type {
}
}

impl From<Vec<Declaration>> for DeclarationList {
fn from(l: Vec<Declaration>) -> Self {
DeclarationList { list: (l) }
}
}

impl Display for Declarator {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
match self.value {
Expand Down Expand Up @@ -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),
}
}
}
Expand Down
55 changes: 30 additions & 25 deletions rust/src/compile/parse.rs
Expand Up @@ -9,7 +9,7 @@ use super::{
pub struct Parser {
token_list: TokenList,
index: usize,
globals: Option<Object>,
globals: Vec<Object>,
}

impl Parser {
Expand Down Expand Up @@ -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;
Expand Down Expand Up @@ -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<Self, ParseError> {
input.parse().map_err(ParseError::LexError).map(Self::new)
}

pub fn parse(&mut self) -> Result<Option<Expr>, ParseError> {
self.parse_expr(Precedence::P1Comma)
pub fn compile(&mut self) -> Result<Vec<Object>, ParseError> {
Ok(vec![])
}

pub fn declaration(&mut self) -> Result<Type, ParseError> {
pub fn declaration(&mut self) -> Result<TypeIdentifier, ParseError> {
let base_type = self.declspec()?;
let result = self.declarator(base_type)?;
Ok(result)
}

pub fn test(input: &str) -> Result<Expr, ParseError> {
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) {
Expand All @@ -125,14 +119,24 @@ impl Parser {
print!("\n");
}

fn enter_scope(&mut self) {}

fn leave_scope(&mut self) {}

fn declspec(&mut self) -> Result<Type, ParseError> {
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<Type, ParseError> {
Expand Down Expand Up @@ -185,7 +189,7 @@ impl Parser {
}
}

fn declarator(&mut self, mut base_type: Type) -> Result<Type, ParseError> {
fn declarator(&mut self, mut base_type: Type) -> Result<TypeIdentifier, ParseError> {
while let Some(Token::Punct(Punct::Mul)) = self.peek_next() {
self.advance();
base_type = base_type.into_pointer();
Expand All @@ -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)
Expand All @@ -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)
Expand Down Expand Up @@ -281,7 +286,7 @@ impl Parser {
}
}

fn parse_expr(&mut self, precedence: Precedence) -> Result<Option<Expr>, ParseError> {
pub fn parse_expr(&mut self, precedence: Precedence) -> Result<Option<Expr>, ParseError> {
let mut first = match self.parse_leaf()? {
Some(leaf) => leaf,
None => return Ok(None),
Expand Down
27 changes: 25 additions & 2 deletions rust/src/compile/tests.rs
Expand Up @@ -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");
Expand Down Expand Up @@ -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
}) {
Expand Down Expand Up @@ -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;");
}
21 changes: 21 additions & 0 deletions rust/src/compile/token_impl.rs
Expand Up @@ -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,
Expand Down
66 changes: 45 additions & 21 deletions rust/src/compile/types.rs
Expand Up @@ -8,47 +8,77 @@ pub enum Object {

#[derive(Debug, Clone, PartialEq, Eq)]
pub struct Variable {
pub next: Option<Box<Object>>,
pub name: Option<String>,
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<Box<Object>>,
pub name: String,
pub ctype: Func,
pub locals: Vec<Object>,
pub stmts: Vec<Statement>,
pub stack_size: usize,
pub is_definition: bool,
}

#[derive(Debug, Clone, PartialEq, Eq)]
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;
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<String>,
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<String>) -> 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) })
}

pub fn into_array(self, expr: Option<Expr>) -> 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 })
Expand All @@ -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<Type>) -> Self {
pub fn into_function_with_param(self, param_list: Vec<TypeIdentifier>) -> Self {
Type::Func(Func { return_type: Box::new(self), param_list, is_variadic: false })
}
}
Expand Down Expand Up @@ -106,7 +136,7 @@ pub struct Array {
#[derive(Debug, Clone, PartialEq, Eq)]
pub struct Func {
pub return_type: Box<Type>,
pub param_list: Vec<Type>,
pub param_list: Vec<TypeIdentifier>,
pub is_variadic: bool,
}

Expand Down Expand Up @@ -143,6 +173,8 @@ pub struct Parameter {
pub enum Statement {
#[default]
Empty,
ExprStmt(Expr),
ReturnStmt(Expr),
}

#[derive(Debug, Clone, PartialEq, Eq)]
Expand Down Expand Up @@ -241,11 +273,3 @@ pub struct CommaExpr {
pub left: Box<Expr>,
pub right: Box<Expr>,
}

#[derive(Debug, Clone, PartialEq, Eq)]
pub enum Declaration {}

#[derive(Debug, PartialEq, Eq)]
pub struct DeclarationList {
pub list: Vec<Declaration>,
}
8 changes: 4 additions & 4 deletions rust/src/main.rs
Expand Up @@ -118,12 +118,12 @@ fn main() -> Result<(), Box<dyn Error>> {
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);
}
}

Expand Down

0 comments on commit baaa789

Please sign in to comment.