aboutsummaryrefslogtreecommitdiff
path: root/src/parse
diff options
context:
space:
mode:
authorMel <einebeere@gmail.com>2021-10-21 23:46:01 +0200
committerMel <einebeere@gmail.com>2021-10-21 23:46:01 +0200
commitcff714c07e5e2c0f11c121504500a554d60c08cc (patch)
tree6c9e98696530b2661343942948b9f1a50a8665e7 /src/parse
parenta4980b8dbf1394c2b302f1de7c72d2264426b86e (diff)
downloadrabbithole-cff714c07e5e2c0f11c121504500a554d60c08cc.tar.zst
rabbithole-cff714c07e5e2c0f11c121504500a554d60c08cc.zip
Implement program walking.
Diffstat (limited to 'src/parse')
-rw-r--r--src/parse/ast/expression.rs38
-rw-r--r--src/parse/ast/mod.rs2
-rw-r--r--src/parse/ast/nodes.rs (renamed from src/parse/ast/value.rs)36
-rw-r--r--src/parse/ast/statement.rs2
-rw-r--r--src/parse/parser.rs33
5 files changed, 57 insertions, 54 deletions
diff --git a/src/parse/ast/expression.rs b/src/parse/ast/expression.rs
index 8563492..1749c40 100644
--- a/src/parse/ast/expression.rs
+++ b/src/parse/ast/expression.rs
@@ -1,10 +1,8 @@
use std::fmt::{self, Display, Formatter};
-use super::value::{
- BinaryOperator, Block, ConditionalBlock, FnHeader, Identifier, Literal, UnaryOperator,
-};
+use super::nodes::{BinaryOperator, BlockNode, FnNode, Identifier, IfNode, Literal, UnaryOperator};
-#[derive(Debug)]
+#[derive(Debug, Clone)]
pub enum Expression {
Binary {
left: Box<Expression>,
@@ -16,15 +14,9 @@ pub enum Expression {
right: Box<Expression>,
},
Group(Box<Expression>),
- Block(Box<Block>),
- Fn {
- header: FnHeader,
- body: Box<Block>,
- },
- If {
- conditionals: Vec<ConditionalBlock>,
- else_block: Option<Box<Block>>,
- },
+ Block(Box<BlockNode>),
+ Fn(Box<FnNode>),
+ If(Box<IfNode>),
Literal(Literal),
Identifier(Identifier),
}
@@ -60,16 +52,16 @@ impl Expression {
Expression::Block(block) => {
Self::block_fmt(f, block, depth + 1)?;
}
- Expression::Fn { header, body } => {
+ Expression::Fn(node) => {
write!(f, "{}Fn (", pad)?;
// Write self receiver
- if header.has_self_receiver {
+ if node.header.has_self_receiver {
write!(f, "self, ")?;
}
// Write parameters
- for p in header.parameters.iter() {
+ for p in node.header.parameters.iter() {
write!(
f,
"{}: {}, ",
@@ -82,9 +74,9 @@ impl Expression {
writeln!(
f,
") -> {}:",
- header.return_type.as_ref().unwrap_or(&"_".into())
+ node.header.return_type.as_ref().unwrap_or(&"_".into())
)?;
- Self::block_fmt(f, body, depth + 1)?;
+ Self::block_fmt(f, &node.body, depth + 1)?;
}
Expression::Literal(literal) => {
writeln!(f, "{}Literal: {:?}", pad, literal)?;
@@ -92,25 +84,25 @@ impl Expression {
Expression::Identifier(identifier) => {
writeln!(f, "{}Identifier: {:?}", pad, identifier)?;
}
- Expression::If { conditionals, else_block } => {
+ Expression::If(node) => {
writeln!(f, "{}If:", pad)?;
- for (i, c) in conditionals.iter().enumerate() {
+ for (i, c) in node.conditionals.iter().enumerate() {
writeln!(f, "{}- Condition {}:", pad, i)?;
c.condition.nested_fmt(f, depth + 1)?;
writeln!(f, "{}- Body {}:", pad, i)?;
Self::block_fmt(f, &c.block, depth + 1)?;
}
- if let Some(e) = else_block {
+ if let Some(e) = &node.else_block {
writeln!(f, "{}- Else:", pad)?;
Self::block_fmt(f, e, depth + 1)?;
}
- },
+ }
}
Ok(())
}
- fn block_fmt(f: &mut Formatter<'_>, block: &Block, depth: usize) -> fmt::Result {
+ fn block_fmt(f: &mut Formatter<'_>, block: &BlockNode, depth: usize) -> fmt::Result {
let pad = " ".repeat(depth);
writeln!(f, "{}Block:", pad)?;
for (i, statement) in block.statements.iter().enumerate() {
diff --git a/src/parse/ast/mod.rs b/src/parse/ast/mod.rs
index 257675f..93944b2 100644
--- a/src/parse/ast/mod.rs
+++ b/src/parse/ast/mod.rs
@@ -4,7 +4,7 @@ use self::statement::Statement;
pub mod expression;
pub mod statement;
-pub mod value;
+pub mod nodes;
#[derive(Debug)]
pub struct Program {
diff --git a/src/parse/ast/value.rs b/src/parse/ast/nodes.rs
index 263cb58..2347d5b 100644
--- a/src/parse/ast/value.rs
+++ b/src/parse/ast/nodes.rs
@@ -2,7 +2,7 @@ use crate::lex::token::{Token, TokenVariant::*};
use super::{expression::Expression, statement::Statement};
-#[derive(Debug)]
+#[derive(Debug, Clone, Copy)]
pub enum BinaryOperator {
Plus,
Minus,
@@ -35,12 +35,12 @@ impl BinaryOperator {
Assign => Self::Assign,
ConstAssign => Self::ConstAssign,
Dot => Self::Dot,
- _ => panic!("Can't create binary operator from '{:?}'.", token.variant)
+ _ => panic!("Can't create binary operator from '{:?}'.", token.variant),
}
}
}
-#[derive(Debug)]
+#[derive(Debug, Clone, Copy)]
pub enum UnaryOperator {
Plus,
Minus,
@@ -53,12 +53,12 @@ impl UnaryOperator {
OpPlus => Self::Plus,
OpMinus => Self::Minus,
OpNot => Self::Not,
- _ => panic!("Can't create unary operator from '{:?}'.", token.variant)
+ _ => panic!("Can't create unary operator from '{:?}'.", token.variant),
}
}
}
-#[derive(Debug)]
+#[derive(Debug, Clone)]
pub enum Literal {
Int(u32),
Float(f32),
@@ -71,7 +71,7 @@ impl Literal {
Int(int) => Self::Int(int),
Float(float) => Self::Float(float),
Str(string) => Self::Str(string),
- _ => panic!("Can't create literal from '{:?}'.", token.variant)
+ _ => panic!("Can't create literal from '{:?}'.", token.variant),
}
}
}
@@ -80,27 +80,39 @@ pub type Identifier = String;
// If the contraint is None the type will have to be inferred
// during analysis.
-#[derive(Debug)]
+#[derive(Debug, Clone)]
pub struct TypedIdentifier {
pub identifier: Identifier,
pub type_constraint: Option<Identifier>,
}
-#[derive(Debug)]
+#[derive(Debug, Clone)]
+pub struct FnNode {
+ pub header: FnHeader,
+ pub body: BlockNode,
+}
+
+#[derive(Debug, Clone)]
pub struct FnHeader {
pub has_self_receiver: bool,
pub parameters: Vec<TypedIdentifier>,
pub return_type: Option<Identifier>,
}
-#[derive(Debug)]
-pub struct Block {
+#[derive(Debug, Clone)]
+pub struct IfNode {
+ pub conditionals: Vec<ConditionalBlock>,
+ pub else_block: Option<BlockNode>,
+}
+
+#[derive(Debug, Clone)]
+pub struct BlockNode {
pub statements: Vec<Statement>,
pub tail_expression: Option<Expression>,
}
-#[derive(Debug)]
+#[derive(Debug, Clone)]
pub struct ConditionalBlock {
pub condition: Expression,
- pub block: Block,
+ pub block: BlockNode,
}
diff --git a/src/parse/ast/statement.rs b/src/parse/ast/statement.rs
index eec589e..b0e626d 100644
--- a/src/parse/ast/statement.rs
+++ b/src/parse/ast/statement.rs
@@ -2,7 +2,7 @@ use std::fmt::Display;
use super::expression::Expression;
-#[derive(Debug)]
+#[derive(Debug, Clone)]
pub enum Statement {
Expression(Expression),
Print(Expression),
diff --git a/src/parse/parser.rs b/src/parse/parser.rs
index 0316a35..0e865da 100644
--- a/src/parse/parser.rs
+++ b/src/parse/parser.rs
@@ -1,6 +1,6 @@
use super::ast::expression::Expression;
+use super::ast::nodes::UnaryOperator;
use super::ast::statement::Statement;
-use super::ast::value::UnaryOperator;
use super::ast::Program;
use crate::check;
use crate::consume;
@@ -8,12 +8,14 @@ use crate::consume_if;
use crate::inner;
use crate::lex::token::Token;
use crate::lex::token::TokenVariant::*;
-use crate::parse::ast::value::BinaryOperator;
-use crate::parse::ast::value::Block;
-use crate::parse::ast::value::ConditionalBlock;
-use crate::parse::ast::value::FnHeader;
-use crate::parse::ast::value::Literal;
-use crate::parse::ast::value::TypedIdentifier;
+use crate::parse::ast::nodes::BinaryOperator;
+use crate::parse::ast::nodes::BlockNode;
+use crate::parse::ast::nodes::ConditionalBlock;
+use crate::parse::ast::nodes::FnHeader;
+use crate::parse::ast::nodes::FnNode;
+use crate::parse::ast::nodes::IfNode;
+use crate::parse::ast::nodes::Literal;
+use crate::parse::ast::nodes::TypedIdentifier;
use anyhow::anyhow;
use anyhow::Result;
use std::iter::Peekable;
@@ -203,10 +205,7 @@ impl<T: Iterator<Item = Token>> Parser<T> {
let body = self.block()?;
- Ok(Expression::Fn {
- header,
- body: Box::new(body),
- })
+ Ok(Expression::Fn(Box::new(FnNode { header, body })))
}
KeywordIf => {
consume!(self, KeywordIf)?;
@@ -232,16 +231,16 @@ impl<T: Iterator<Item = Token>> Parser<T> {
});
}
- let else_conditional = if consume_if!(self, KeywordElse).is_some() {
+ let else_block = if consume_if!(self, KeywordElse).is_some() {
Some(self.block()?)
} else {
None
};
- Ok(Expression::If {
+ Ok(Expression::If(Box::new(IfNode {
conditionals,
- else_block: else_conditional.map(Box::new),
- })
+ else_block,
+ })))
}
_ => Err(anyhow!("Unexpected token: {:?}", token.variant)),
}
@@ -250,7 +249,7 @@ impl<T: Iterator<Item = Token>> Parser<T> {
}
}
- fn block(&mut self) -> Result<Block> {
+ fn block(&mut self) -> Result<BlockNode> {
consume!(self, BlockOpen)?;
let mut statements = Vec::new();
@@ -279,7 +278,7 @@ impl<T: Iterator<Item = Token>> Parser<T> {
consume!(self, BlockClose)?;
- Ok(Block {
+ Ok(BlockNode {
statements,
tail_expression,
})