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,10 +76,24 @@ 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) => {
|
||||||
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(
|
Token::DecimalValue(v) => Expression(
|
||||||
Kind::Literal(Literal::Number(*v)),
|
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)]
|
#[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