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_lib::compile::CompileOutput;
|
||||
|
@ -49,6 +49,7 @@ pub enum ExpressionKind {
|
||||
FunctionCall(Box<FunctionCallExpression>),
|
||||
BlockExpr(Box<Block>),
|
||||
IfExpr(Box<IfExpression>),
|
||||
StructInit(StructInit),
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, Copy)]
|
||||
@ -130,6 +131,12 @@ pub enum ReturnType {
|
||||
Hard,
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone)]
|
||||
pub struct StructInit {
|
||||
name: String,
|
||||
fields: Vec<(String, Expression)>,
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone)]
|
||||
pub struct Block(
|
||||
pub Vec<BlockLevelStatement>,
|
||||
@ -160,18 +167,18 @@ pub enum BlockLevelStatement {
|
||||
|
||||
#[derive(Debug)]
|
||||
pub struct TypeDefinition {
|
||||
range: TokenRange,
|
||||
name: String,
|
||||
kind: TypeDefinitionKind,
|
||||
range: TokenRange,
|
||||
}
|
||||
|
||||
#[derive(Debug)]
|
||||
pub enum TypeDefinitionKind {
|
||||
Struct(Vec<StructField>),
|
||||
Struct(Vec<StructDefinitionField>),
|
||||
}
|
||||
|
||||
#[derive(Debug)]
|
||||
pub struct StructField {
|
||||
pub struct StructDefinitionField {
|
||||
name: String,
|
||||
ty: Type,
|
||||
range: TokenRange,
|
||||
|
@ -76,10 +76,24 @@ impl Parse for PrimaryExpression {
|
||||
)
|
||||
} else if let Ok(ifexpr) = stream.parse() {
|
||||
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() {
|
||||
match &token {
|
||||
Token::Identifier(v) => {
|
||||
Expression(Kind::VariableName(v.clone()), stream.get_range().unwrap())
|
||||
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())
|
||||
}
|
||||
}
|
||||
Token::DecimalValue(v) => Expression(
|
||||
Kind::Literal(Literal::Number(*v)),
|
||||
@ -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)]
|
||||
pub struct ValueIndex(u64);
|
||||
|
||||
@ -476,9 +541,30 @@ impl Parse for SetStatement {
|
||||
}
|
||||
}
|
||||
|
||||
impl Parse for TypeDefinition {
|
||||
fn parse(stream: TokenStream) -> Result<Self, Error> {
|
||||
todo!()
|
||||
#[derive(Debug)]
|
||||
pub struct StructDefinition(String, Vec<StructDefinitionField>, TokenRange);
|
||||
|
||||
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) => {
|
||||
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")?)?,
|
||||
})
|
||||
}
|
||||
|
@ -199,6 +199,7 @@ impl ast::Expression {
|
||||
mir::TypeKind::Vague(mir::VagueType::Unknown),
|
||||
*idx,
|
||||
),
|
||||
ast::ExpressionKind::StructInit(struct_init) => todo!("implement struct init process"),
|
||||
};
|
||||
|
||||
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
|
||||
/// tokens are consumed, otherwise token stream does not advance.
|
||||
///
|
||||
|
Loading…
Reference in New Issue
Block a user