From cff714c07e5e2c0f11c121504500a554d60c08cc Mon Sep 17 00:00:00 2001 From: Mel Date: Thu, 21 Oct 2021 23:46:01 +0200 Subject: Implement program walking. --- src/parse/ast/expression.rs | 38 ++++++-------- src/parse/ast/mod.rs | 2 +- src/parse/ast/nodes.rs | 118 ++++++++++++++++++++++++++++++++++++++++++++ src/parse/ast/statement.rs | 2 +- src/parse/ast/value.rs | 106 --------------------------------------- 5 files changed, 135 insertions(+), 131 deletions(-) create mode 100644 src/parse/ast/nodes.rs delete mode 100644 src/parse/ast/value.rs (limited to 'src/parse/ast') 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, @@ -16,15 +14,9 @@ pub enum Expression { right: Box, }, Group(Box), - Block(Box), - Fn { - header: FnHeader, - body: Box, - }, - If { - conditionals: Vec, - else_block: Option>, - }, + Block(Box), + Fn(Box), + If(Box), 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/nodes.rs b/src/parse/ast/nodes.rs new file mode 100644 index 0000000..2347d5b --- /dev/null +++ b/src/parse/ast/nodes.rs @@ -0,0 +1,118 @@ +use crate::lex::token::{Token, TokenVariant::*}; + +use super::{expression::Expression, statement::Statement}; + +#[derive(Debug, Clone, Copy)] +pub enum BinaryOperator { + Plus, + Minus, + Star, + Slash, + Eq, + Neq, + Gt, + Gte, + Lt, + Lte, + Assign, + ConstAssign, + Dot, +} + +impl BinaryOperator { + pub fn from_token(token: Token) -> Self { + match token.variant { + OpPlus => Self::Plus, + OpMinus => Self::Minus, + OpStar => Self::Star, + OpSlash => Self::Slash, + OpEq => Self::Eq, + OpNeq => Self::Neq, + OpLt => Self::Lt, + OpGt => Self::Gt, + OpLte => Self::Lte, + OpGte => Self::Gte, + Assign => Self::Assign, + ConstAssign => Self::ConstAssign, + Dot => Self::Dot, + _ => panic!("Can't create binary operator from '{:?}'.", token.variant), + } + } +} + +#[derive(Debug, Clone, Copy)] +pub enum UnaryOperator { + Plus, + Minus, + Not, +} + +impl UnaryOperator { + pub fn from_token(token: Token) -> Self { + match token.variant { + OpPlus => Self::Plus, + OpMinus => Self::Minus, + OpNot => Self::Not, + _ => panic!("Can't create unary operator from '{:?}'.", token.variant), + } + } +} + +#[derive(Debug, Clone)] +pub enum Literal { + Int(u32), + Float(f32), + Str(String), +} + +impl Literal { + pub fn from_token(token: Token) -> Self { + match token.variant { + Int(int) => Self::Int(int), + Float(float) => Self::Float(float), + Str(string) => Self::Str(string), + _ => panic!("Can't create literal from '{:?}'.", token.variant), + } + } +} + +pub type Identifier = String; + +// If the contraint is None the type will have to be inferred +// during analysis. +#[derive(Debug, Clone)] +pub struct TypedIdentifier { + pub identifier: Identifier, + pub type_constraint: Option, +} + +#[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, + pub return_type: Option, +} + +#[derive(Debug, Clone)] +pub struct IfNode { + pub conditionals: Vec, + pub else_block: Option, +} + +#[derive(Debug, Clone)] +pub struct BlockNode { + pub statements: Vec, + pub tail_expression: Option, +} + +#[derive(Debug, Clone)] +pub struct ConditionalBlock { + pub condition: Expression, + 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/ast/value.rs b/src/parse/ast/value.rs deleted file mode 100644 index 263cb58..0000000 --- a/src/parse/ast/value.rs +++ /dev/null @@ -1,106 +0,0 @@ -use crate::lex::token::{Token, TokenVariant::*}; - -use super::{expression::Expression, statement::Statement}; - -#[derive(Debug)] -pub enum BinaryOperator { - Plus, - Minus, - Star, - Slash, - Eq, - Neq, - Gt, - Gte, - Lt, - Lte, - Assign, - ConstAssign, - Dot, -} - -impl BinaryOperator { - pub fn from_token(token: Token) -> Self { - match token.variant { - OpPlus => Self::Plus, - OpMinus => Self::Minus, - OpStar => Self::Star, - OpSlash => Self::Slash, - OpEq => Self::Eq, - OpNeq => Self::Neq, - OpLt => Self::Lt, - OpGt => Self::Gt, - OpLte => Self::Lte, - OpGte => Self::Gte, - Assign => Self::Assign, - ConstAssign => Self::ConstAssign, - Dot => Self::Dot, - _ => panic!("Can't create binary operator from '{:?}'.", token.variant) - } - } -} - -#[derive(Debug)] -pub enum UnaryOperator { - Plus, - Minus, - Not, -} - -impl UnaryOperator { - pub fn from_token(token: Token) -> Self { - match token.variant { - OpPlus => Self::Plus, - OpMinus => Self::Minus, - OpNot => Self::Not, - _ => panic!("Can't create unary operator from '{:?}'.", token.variant) - } - } -} - -#[derive(Debug)] -pub enum Literal { - Int(u32), - Float(f32), - Str(String), -} - -impl Literal { - pub fn from_token(token: Token) -> Self { - match token.variant { - Int(int) => Self::Int(int), - Float(float) => Self::Float(float), - Str(string) => Self::Str(string), - _ => panic!("Can't create literal from '{:?}'.", token.variant) - } - } -} - -pub type Identifier = String; - -// If the contraint is None the type will have to be inferred -// during analysis. -#[derive(Debug)] -pub struct TypedIdentifier { - pub identifier: Identifier, - pub type_constraint: Option, -} - -#[derive(Debug)] -pub struct FnHeader { - pub has_self_receiver: bool, - pub parameters: Vec, - pub return_type: Option, -} - -#[derive(Debug)] -pub struct Block { - pub statements: Vec, - pub tail_expression: Option, -} - -#[derive(Debug)] -pub struct ConditionalBlock { - pub condition: Expression, - pub block: Block, -} -- cgit 1.4.1