Add struct type and expression parsing
This commit is contained in:
		
							parent
							
								
									5fca72a3f9
								
							
						
					
					
						commit
						c83d53ae53
					
				@ -1,4 +1,4 @@
 | 
				
			|||||||
use std::{env, fs, path::PathBuf};
 | 
					use std::{env, error::Error, fs, path::PathBuf};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
use reid::compile;
 | 
					use reid::compile;
 | 
				
			||||||
use reid_lib::compile::CompileOutput;
 | 
					use reid_lib::compile::CompileOutput;
 | 
				
			||||||
 | 
				
			|||||||
@ -49,6 +49,7 @@ pub enum ExpressionKind {
 | 
				
			|||||||
    FunctionCall(Box<FunctionCallExpression>),
 | 
					    FunctionCall(Box<FunctionCallExpression>),
 | 
				
			||||||
    BlockExpr(Box<Block>),
 | 
					    BlockExpr(Box<Block>),
 | 
				
			||||||
    IfExpr(Box<IfExpression>),
 | 
					    IfExpr(Box<IfExpression>),
 | 
				
			||||||
 | 
					    StructInit(StructInit),
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#[derive(Debug, Clone, Copy)]
 | 
					#[derive(Debug, Clone, Copy)]
 | 
				
			||||||
@ -130,6 +131,12 @@ pub enum ReturnType {
 | 
				
			|||||||
    Hard,
 | 
					    Hard,
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#[derive(Debug, Clone)]
 | 
				
			||||||
 | 
					pub struct StructInit {
 | 
				
			||||||
 | 
					    name: String,
 | 
				
			||||||
 | 
					    fields: Vec<(String, Expression)>,
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#[derive(Debug, Clone)]
 | 
					#[derive(Debug, Clone)]
 | 
				
			||||||
pub struct Block(
 | 
					pub struct Block(
 | 
				
			||||||
    pub Vec<BlockLevelStatement>,
 | 
					    pub Vec<BlockLevelStatement>,
 | 
				
			||||||
@ -160,18 +167,18 @@ pub enum BlockLevelStatement {
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
#[derive(Debug)]
 | 
					#[derive(Debug)]
 | 
				
			||||||
pub struct TypeDefinition {
 | 
					pub struct TypeDefinition {
 | 
				
			||||||
    range: TokenRange,
 | 
					 | 
				
			||||||
    name: String,
 | 
					    name: String,
 | 
				
			||||||
    kind: TypeDefinitionKind,
 | 
					    kind: TypeDefinitionKind,
 | 
				
			||||||
 | 
					    range: TokenRange,
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#[derive(Debug)]
 | 
					#[derive(Debug)]
 | 
				
			||||||
pub enum TypeDefinitionKind {
 | 
					pub enum TypeDefinitionKind {
 | 
				
			||||||
    Struct(Vec<StructField>),
 | 
					    Struct(Vec<StructDefinitionField>),
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#[derive(Debug)]
 | 
					#[derive(Debug)]
 | 
				
			||||||
pub struct StructField {
 | 
					pub struct StructDefinitionField {
 | 
				
			||||||
    name: String,
 | 
					    name: String,
 | 
				
			||||||
    ty: Type,
 | 
					    ty: Type,
 | 
				
			||||||
    range: TokenRange,
 | 
					    range: TokenRange,
 | 
				
			||||||
 | 
				
			|||||||
@ -76,11 +76,25 @@ impl Parse for PrimaryExpression {
 | 
				
			|||||||
            )
 | 
					            )
 | 
				
			||||||
        } else if let Ok(ifexpr) = stream.parse() {
 | 
					        } else if let Ok(ifexpr) = stream.parse() {
 | 
				
			||||||
            Expression(Kind::IfExpr(Box::new(ifexpr)), stream.get_range().unwrap())
 | 
					            Expression(Kind::IfExpr(Box::new(ifexpr)), stream.get_range().unwrap())
 | 
				
			||||||
 | 
					        } else if let (Some(Token::Identifier(_)), Some(Token::BraceOpen)) =
 | 
				
			||||||
 | 
					            (stream.peek(), stream.peek2())
 | 
				
			||||||
 | 
					        {
 | 
				
			||||||
 | 
					            Expression(
 | 
				
			||||||
 | 
					                Kind::StructInit(stream.parse()?),
 | 
				
			||||||
 | 
					                stream.get_range().unwrap(),
 | 
				
			||||||
 | 
					            )
 | 
				
			||||||
        } else if let Some(token) = stream.next() {
 | 
					        } else if let Some(token) = stream.next() {
 | 
				
			||||||
            match &token {
 | 
					            match &token {
 | 
				
			||||||
                Token::Identifier(v) => {
 | 
					                Token::Identifier(v) => {
 | 
				
			||||||
 | 
					                    if let Some(Token::BraceOpen) = stream.peek() {
 | 
				
			||||||
 | 
					                        Expression(
 | 
				
			||||||
 | 
					                            Kind::StructInit(stream.parse()?),
 | 
				
			||||||
 | 
					                            stream.get_range().unwrap(),
 | 
				
			||||||
 | 
					                        )
 | 
				
			||||||
 | 
					                    } else {
 | 
				
			||||||
                        Expression(Kind::VariableName(v.clone()), stream.get_range().unwrap())
 | 
					                        Expression(Kind::VariableName(v.clone()), stream.get_range().unwrap())
 | 
				
			||||||
                    }
 | 
					                    }
 | 
				
			||||||
 | 
					                }
 | 
				
			||||||
                Token::DecimalValue(v) => Expression(
 | 
					                Token::DecimalValue(v) => Expression(
 | 
				
			||||||
                    Kind::Literal(Literal::Number(*v)),
 | 
					                    Kind::Literal(Literal::Number(*v)),
 | 
				
			||||||
                    stream.get_range().unwrap(),
 | 
					                    stream.get_range().unwrap(),
 | 
				
			||||||
@ -415,6 +429,57 @@ impl Parse for VariableReference {
 | 
				
			|||||||
    }
 | 
					    }
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					impl Parse for StructInit {
 | 
				
			||||||
 | 
					    fn parse(mut stream: TokenStream) -> Result<Self, Error> {
 | 
				
			||||||
 | 
					        let Some(Token::Identifier(name)) = stream.next() else {
 | 
				
			||||||
 | 
					            return Err(stream.expected_err("struct identifier")?);
 | 
				
			||||||
 | 
					        };
 | 
				
			||||||
 | 
					        stream.expect(Token::BraceOpen)?;
 | 
				
			||||||
 | 
					        let named_list = stream.parse::<NamedFieldList<Expression>>()?;
 | 
				
			||||||
 | 
					        let fields = named_list.0.into_iter().map(|f| (f.0, f.1)).collect();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        stream.expect(Token::BraceClose)?;
 | 
				
			||||||
 | 
					        stream.expect(Token::Semi)?;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        Ok(StructInit { name, fields })
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#[derive(Debug)]
 | 
				
			||||||
 | 
					pub struct NamedFieldList<T: Parse + std::fmt::Debug>(Vec<NamedField<T>>);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					impl<T: Parse + std::fmt::Debug> Parse for NamedFieldList<T> {
 | 
				
			||||||
 | 
					    fn parse(mut stream: TokenStream) -> Result<Self, Error> {
 | 
				
			||||||
 | 
					        let mut fields = Vec::new();
 | 
				
			||||||
 | 
					        while let Ok(field) = stream.parse() {
 | 
				
			||||||
 | 
					            fields.push(field);
 | 
				
			||||||
 | 
					            match stream.peek() {
 | 
				
			||||||
 | 
					                Some(Token::Comma) => {
 | 
				
			||||||
 | 
					                    stream.next();
 | 
				
			||||||
 | 
					                } // Consume comma
 | 
				
			||||||
 | 
					                Some(Token::BraceClose) => break,
 | 
				
			||||||
 | 
					                Some(_) | None => Err(stream.expected_err("another field or closing brace")?)?,
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					        Ok(NamedFieldList(fields))
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#[derive(Debug)]
 | 
				
			||||||
 | 
					pub struct NamedField<T: Parse + std::fmt::Debug>(String, T, TokenRange);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					impl<T: Parse + std::fmt::Debug> Parse for NamedField<T> {
 | 
				
			||||||
 | 
					    fn parse(mut stream: TokenStream) -> Result<Self, Error> {
 | 
				
			||||||
 | 
					        let Some(Token::Identifier(field_name)) = stream.next() else {
 | 
				
			||||||
 | 
					            return Err(stream.expected_err("type name")?);
 | 
				
			||||||
 | 
					        };
 | 
				
			||||||
 | 
					        stream.expect(Token::Colon)?;
 | 
				
			||||||
 | 
					        let value = stream.parse()?;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        Ok(NamedField(field_name, value, stream.get_range().unwrap()))
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#[derive(Debug, Clone, Copy)]
 | 
					#[derive(Debug, Clone, Copy)]
 | 
				
			||||||
pub struct ValueIndex(u64);
 | 
					pub struct ValueIndex(u64);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@ -476,9 +541,30 @@ impl Parse for SetStatement {
 | 
				
			|||||||
    }
 | 
					    }
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
impl Parse for TypeDefinition {
 | 
					#[derive(Debug)]
 | 
				
			||||||
    fn parse(stream: TokenStream) -> Result<Self, Error> {
 | 
					pub struct StructDefinition(String, Vec<StructDefinitionField>, TokenRange);
 | 
				
			||||||
        todo!()
 | 
					
 | 
				
			||||||
 | 
					impl Parse for StructDefinition {
 | 
				
			||||||
 | 
					    fn parse(mut stream: TokenStream) -> Result<Self, Error> {
 | 
				
			||||||
 | 
					        stream.expect(Token::Struct)?;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        let Some(Token::Identifier(name)) = stream.next() else {
 | 
				
			||||||
 | 
					            return Err(stream.expected_err("identifier")?);
 | 
				
			||||||
 | 
					        };
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        stream.expect(Token::BraceOpen)?;
 | 
				
			||||||
 | 
					        let named_fields = stream.parse::<NamedFieldList<Type>>()?;
 | 
				
			||||||
 | 
					        let fields = named_fields
 | 
				
			||||||
 | 
					            .0
 | 
				
			||||||
 | 
					            .into_iter()
 | 
				
			||||||
 | 
					            .map(|f| StructDefinitionField {
 | 
				
			||||||
 | 
					                name: f.0,
 | 
				
			||||||
 | 
					                ty: f.1,
 | 
				
			||||||
 | 
					                range: f.2,
 | 
				
			||||||
 | 
					            })
 | 
				
			||||||
 | 
					            .collect();
 | 
				
			||||||
 | 
					        stream.expect(Token::BraceClose)?;
 | 
				
			||||||
 | 
					        Ok(StructDefinition(name, fields, stream.get_range().unwrap()))
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@ -497,6 +583,14 @@ impl Parse for TopLevelStatement {
 | 
				
			|||||||
            Some(Token::FnKeyword) | Some(Token::PubKeyword) => {
 | 
					            Some(Token::FnKeyword) | Some(Token::PubKeyword) => {
 | 
				
			||||||
                Stmt::FunctionDefinition(stream.parse()?)
 | 
					                Stmt::FunctionDefinition(stream.parse()?)
 | 
				
			||||||
            }
 | 
					            }
 | 
				
			||||||
 | 
					            Some(Token::Struct) => {
 | 
				
			||||||
 | 
					                let StructDefinition(name, fields, range) = stream.parse::<StructDefinition>()?;
 | 
				
			||||||
 | 
					                Stmt::TypeDefinition(TypeDefinition {
 | 
				
			||||||
 | 
					                    name,
 | 
				
			||||||
 | 
					                    kind: TypeDefinitionKind::Struct(fields),
 | 
				
			||||||
 | 
					                    range,
 | 
				
			||||||
 | 
					                })
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
            _ => Err(stream.expected_err("import or fn")?)?,
 | 
					            _ => Err(stream.expected_err("import or fn")?)?,
 | 
				
			||||||
        })
 | 
					        })
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
				
			|||||||
@ -199,6 +199,7 @@ impl ast::Expression {
 | 
				
			|||||||
                mir::TypeKind::Vague(mir::VagueType::Unknown),
 | 
					                mir::TypeKind::Vague(mir::VagueType::Unknown),
 | 
				
			||||||
                *idx,
 | 
					                *idx,
 | 
				
			||||||
            ),
 | 
					            ),
 | 
				
			||||||
 | 
					            ast::ExpressionKind::StructInit(struct_init) => todo!("implement struct init process"),
 | 
				
			||||||
        };
 | 
					        };
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        mir::Expression(kind, self.1.into())
 | 
					        mir::Expression(kind, self.1.into())
 | 
				
			||||||
 | 
				
			|||||||
@ -63,6 +63,14 @@ impl<'a, 'b> TokenStream<'a, 'b> {
 | 
				
			|||||||
        }
 | 
					        }
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    pub fn peek2(&mut self) -> Option<Token> {
 | 
				
			||||||
 | 
					        if self.tokens.len() < (self.position + 1) {
 | 
				
			||||||
 | 
					            None
 | 
				
			||||||
 | 
					        } else {
 | 
				
			||||||
 | 
					            Some(self.tokens[self.position + 1].token.clone())
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    /// Parse the next value of trait Parse. If the parse succeeded, the related
 | 
					    /// Parse the next value of trait Parse. If the parse succeeded, the related
 | 
				
			||||||
    /// tokens are consumed, otherwise token stream does not advance.
 | 
					    /// tokens are consumed, otherwise token stream does not advance.
 | 
				
			||||||
    ///
 | 
					    ///
 | 
				
			||||||
 | 
				
			|||||||
		Loading…
	
		Reference in New Issue
	
	Block a user