about summary refs log tree commit diff
path: root/src/parse
diff options
context:
space:
mode:
authorMel <einebeere@gmail.com>2021-12-14 00:08:13 +0100
committerMel <einebeere@gmail.com>2021-12-28 21:46:39 +0100
commite621f13a226d297d5368f4c294a8549a93843934 (patch)
tree4079d2bb1a9f08e8411395e4d0ba8c87f063980c /src/parse
parent9d331e92045ca9098ab5f2139c80ea33e89e8ca3 (diff)
downloadrabbithole-e621f13a226d297d5368f4c294a8549a93843934.tar.zst
rabbithole-e621f13a226d297d5368f4c294a8549a93843934.zip
AST restructure
Diffstat (limited to 'src/parse')
-rw-r--r--src/parse/ast/expression.rs117
-rw-r--r--src/parse/ast/nodes.rs176
-rw-r--r--src/parse/ast/statement.rs22
-rw-r--r--src/parse/parser.rs266
4 files changed, 377 insertions, 204 deletions
diff --git a/src/parse/ast/expression.rs b/src/parse/ast/expression.rs
index d119a71..e883aaa 100644
--- a/src/parse/ast/expression.rs
+++ b/src/parse/ast/expression.rs
@@ -1,34 +1,45 @@
 use std::fmt::{self, Display, Formatter};
 
-use crate::parse::ast::nodes::StrPart;
+use crate::lex::token::Location;
 
 use super::nodes::{
-    ArrayAccessNode, ArrayNode, BinaryOperator, BlockNode, CallNode, FnNode, Identifier, IfNode,
-    LoopNode, MemberAccessNode, SimpleLiteral, StrNode, UnaryOperator,
+    ArrayAccessExpression, ArrayExpression, BinaryOperatorNode, BlockExpression, CallExpression,
+    FnExpression, Identifier, IfExpression, LoopExpression, MemberAccessExpression,
+    SimpleLiteralNode, StrExpression, StrPartKind, UnaryOperatorNode,
 };
 
 #[derive(Debug, Clone)]
-pub enum Expression {
+pub struct Expression {
+    // TODO: Sometimes this location is duplicated for no reason,
+    // i.e. in the UnaryExpression, since the token for the UnaryOperatorNode
+    // will be the same as the location for the expression...
+    // Can we do something about it or is some duplication fine?
+    pub at: Location,
+    pub kind: ExpressionKind,
+}
+
+#[derive(Debug, Clone)]
+pub enum ExpressionKind {
     Binary {
         left: Box<Expression>,
-        op: BinaryOperator,
+        op: BinaryOperatorNode,
         right: Box<Expression>,
     },
     Unary {
-        op: UnaryOperator,
+        op: UnaryOperatorNode,
         right: Box<Expression>,
     },
-    Call(Box<CallNode>),
-    ArrayAccess(Box<ArrayAccessNode>),
-    MemberAccess(Box<MemberAccessNode>),
+    Call(Box<CallExpression>),
+    ArrayAccess(Box<ArrayAccessExpression>),
+    MemberAccess(Box<MemberAccessExpression>),
     Group(Box<Expression>),
-    Block(Box<BlockNode>),
-    If(Box<IfNode>),
-    Loop(Box<LoopNode>),
-    StrLiteral(Box<StrNode>),
-    FnLiteral(Box<FnNode>),
-    ArrayLiteral(ArrayNode),
-    SimpleLiteral(SimpleLiteral),
+    Block(Box<BlockExpression>),
+    If(Box<IfExpression>),
+    Loop(Box<LoopExpression>),
+    StrLiteral(Box<StrExpression>),
+    FnLiteral(Box<FnExpression>),
+    ArrayLiteral(ArrayExpression),
+    SimpleLiteral(SimpleLiteralNode),
     Identifier(Identifier),
 }
 
@@ -41,8 +52,8 @@ impl Display for Expression {
 impl Expression {
     pub(crate) fn nested_fmt(&self, f: &mut Formatter<'_>, depth: usize) -> fmt::Result {
         let pad = "  ".repeat(depth);
-        match self {
-            Expression::Binary { left, op, right } => {
+        match self.kind {
+            ExpressionKind::Binary { left, op, right } => {
                 writeln!(f, "{}Binary:", pad)?;
                 writeln!(f, "{}- Left:", pad)?;
                 left.nested_fmt(f, depth + 1)?;
@@ -50,63 +61,63 @@ impl Expression {
                 writeln!(f, "{}- Right:", pad)?;
                 right.nested_fmt(f, depth + 1)?;
             }
-            Expression::Unary { op, right } => {
+            ExpressionKind::Unary { op, right } => {
                 writeln!(f, "{}Unary:", pad)?;
                 writeln!(f, "{}- Operator: {:?}", pad, op)?;
                 writeln!(f, "{}- Right:", pad)?;
                 right.nested_fmt(f, depth + 1)?;
             }
-            Expression::Call(node) => {
+            ExpressionKind::Call(expr) => {
                 writeln!(f, "{}Function Call:", pad)?;
                 writeln!(f, "{}- Called:", pad)?;
-                node.called.nested_fmt(f, depth + 1)?;
-                for (i, e) in node.arguments.iter().enumerate() {
+                expr.called.nested_fmt(f, depth + 1)?;
+                for (i, e) in expr.arguments.iter().enumerate() {
                     writeln!(f, "{}- Argument {}:", pad, i)?;
                     e.nested_fmt(f, depth + 1)?;
                 }
             }
-            Expression::ArrayAccess(node) => {
+            ExpressionKind::ArrayAccess(expr) => {
                 writeln!(f, "{}Array Access:", pad)?;
                 writeln!(f, "{}- Array:", pad)?;
-                node.array.nested_fmt(f, depth + 1)?;
+                expr.array.nested_fmt(f, depth + 1)?;
                 writeln!(f, "{}- Index:", pad)?;
-                node.index.nested_fmt(f, depth + 1)?;
+                expr.index.nested_fmt(f, depth + 1)?;
             }
-            Expression::MemberAccess(node) => {
+            ExpressionKind::MemberAccess(expr) => {
                 writeln!(f, "{}Member Access:", pad)?;
                 writeln!(f, "{}- Object:", pad)?;
-                node.object.nested_fmt(f, depth + 1)?;
-                writeln!(f, "{}- Member Name: {}", pad, node.member_name)?;
+                expr.object.nested_fmt(f, depth + 1)?;
+                writeln!(f, "{}- Member Name: {}", pad, expr.member_name)?;
             }
-            Expression::Group(node) => {
+            ExpressionKind::Group(expr) => {
                 writeln!(f, "{}Group:", pad)?;
-                node.nested_fmt(f, depth + 1)?;
+                expr.nested_fmt(f, depth + 1)?;
             }
-            Expression::Block(block) => {
-                Self::block_fmt(f, block, depth + 1)?;
+            ExpressionKind::Block(expr) => {
+                Self::block_fmt(f, &expr, depth + 1)?;
             }
-            Expression::StrLiteral(node) => {
+            ExpressionKind::StrLiteral(expr) => {
                 writeln!(f, "{}Str:", pad)?;
-                for (i, statement) in node.parts.iter().enumerate() {
+                for (i, statement) in expr.parts.iter().enumerate() {
                     writeln!(f, "{}- {}:", pad, i)?;
-                    match statement {
-                        StrPart::Literal(literal) => {
+                    match statement.kind {
+                        StrPartKind::Literal(literal) => {
                             writeln!(f, "{}{}", "  ".repeat(depth + 1), literal.clone())
                         }
-                        StrPart::Embed(block) => block.nested_fmt(f, depth + 1),
+                        StrPartKind::Embed(block) => block.nested_fmt(f, depth + 1),
                     }?;
                 }
             }
-            Expression::FnLiteral(node) => {
+            ExpressionKind::FnLiteral(expr) => {
                 write!(f, "{}Fn (", pad)?;
 
                 // Write self receiver
-                if node.header.has_self_receiver {
+                if expr.header.has_self_receiver {
                     write!(f, "self, ")?;
                 }
 
                 // Write parameters
-                for p in node.header.parameters.iter() {
+                for p in expr.header.parameters.iter() {
                     write!(
                         f,
                         "{}: {}, ",
@@ -119,52 +130,52 @@ impl Expression {
                 writeln!(
                     f,
                     ") -> {}:",
-                    node.header.return_type.as_ref().unwrap_or(&"_".into())
+                    expr.header.return_type.as_ref().unwrap_or(&"_".into())
                 )?;
-                Self::block_fmt(f, &node.body, depth + 1)?;
+                Self::block_fmt(f, &expr.body, depth + 1)?;
             }
-            Expression::ArrayLiteral(node) => {
+            ExpressionKind::ArrayLiteral(expr) => {
                 writeln!(f, "{}Array Literal:", pad)?;
-                for (i, c) in node.elements.iter().enumerate() {
+                for (i, c) in expr.elements.iter().enumerate() {
                     writeln!(f, "{}- Element {}:", pad, i)?;
                     c.nested_fmt(f, depth + 1)?;
                 }
             }
-            Expression::SimpleLiteral(literal) => {
+            ExpressionKind::SimpleLiteral(literal) => {
                 writeln!(f, "{}Literal: {:?}", pad, literal)?;
             }
-            Expression::Identifier(identifier) => {
+            ExpressionKind::Identifier(identifier) => {
                 writeln!(f, "{}Identifier: {:?}", pad, identifier)?;
             }
-            Expression::If(node) => {
+            ExpressionKind::If(expr) => {
                 writeln!(f, "{}If:", pad)?;
-                for (i, c) in node.conditionals.iter().enumerate() {
+                for (i, c) in expr.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) = &node.else_block {
+                if let Some(e) = &expr.else_block {
                     writeln!(f, "{}- Else:", pad)?;
                     Self::block_fmt(f, e, depth + 1)?;
                 }
             }
-            Expression::Loop(node) => {
+            ExpressionKind::Loop(expr) => {
                 writeln!(f, "{}Loop:", pad)?;
-                if let Some(loop_condition) = &node.condition {
+                if let Some(loop_condition) = &expr.condition {
                     writeln!(f, "{}- Condition:", pad)?;
                     loop_condition.nested_fmt(f, depth + 1)?;
                 }
 
                 writeln!(f, "{}- Body:", pad)?;
-                Self::block_fmt(f, &node.body, depth + 1)?;
+                Self::block_fmt(f, &expr.body, depth + 1)?;
             }
         }
 
         Ok(())
     }
 
-    fn block_fmt(f: &mut Formatter<'_>, block: &BlockNode, depth: usize) -> fmt::Result {
+    fn block_fmt(f: &mut Formatter<'_>, block: &BlockExpression, 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/nodes.rs b/src/parse/ast/nodes.rs
index 16d0eaa..4eff251 100644
--- a/src/parse/ast/nodes.rs
+++ b/src/parse/ast/nodes.rs
@@ -1,9 +1,23 @@
-use crate::lex::token::{Token, TokenKind::*};
+//! Nodes are parts of an expression, but aren't expressions themselves.
+//! Example: A BinaryExpression is made out of two expressions and an operator node,
+//! because an operator can't be an expression by itself.
+//!
+//! Nodes can also contain nested expressions.
+//! This module also contains the actual expression structs for this reason,
+//! although this might be changed later?
+
+use crate::lex::token::{Location, Token, TokenKind::*};
 
 use super::{expression::Expression, statement::Statement};
 
+#[derive(Debug, Clone)]
+pub struct BinaryOperatorNode {
+    pub at: Location,
+    pub kind: BinaryOperatorKind,
+}
+
 #[derive(Debug, Clone, Copy)]
-pub enum BinaryOperator {
+pub enum BinaryOperatorKind {
     Plus,
     Minus,
     Star,
@@ -21,140 +35,196 @@ pub enum BinaryOperator {
     Dot,
 }
 
-impl BinaryOperator {
+impl BinaryOperatorNode {
     pub fn from_token(token: Token) -> Self {
-        match token.kind {
-            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,
-            OpAnd => Self::And,
-            OpOr => Self::Or,
-            Assign => Self::Assign,
-            ConstAssign => Self::ConstAssign,
-            Dot => Self::Dot,
+        use BinaryOperatorKind as Kind;
+
+        let kind = match token.kind {
+            OpPlus => Kind::Plus,
+            OpMinus => Kind::Minus,
+            OpStar => Kind::Star,
+            OpSlash => Kind::Slash,
+            OpEq => Kind::Eq,
+            OpNeq => Kind::Neq,
+            OpLt => Kind::Lt,
+            OpGt => Kind::Gt,
+            OpLte => Kind::Lte,
+            OpGte => Kind::Gte,
+            OpAnd => Kind::And,
+            OpOr => Kind::Or,
+            Assign => Kind::Assign,
+            ConstAssign => Kind::ConstAssign,
+            Dot => Kind::Dot,
             _ => panic!("Can't create binary operator from '{:?}'.", token.kind),
+        };
+
+        Self {
+            at: token.location,
+            kind,
         }
     }
 }
 
+#[derive(Debug, Clone)]
+pub struct UnaryOperatorNode {
+    pub at: Location,
+    pub kind: UnaryOperatorKind,
+}
+
 #[derive(Debug, Clone, Copy)]
-pub enum UnaryOperator {
+pub enum UnaryOperatorKind {
     Minus,
     Not,
 }
 
-impl UnaryOperator {
+impl UnaryOperatorNode {
     pub fn from_token(token: Token) -> Self {
-        match token.kind {
-            OpMinus => Self::Minus,
-            OpNot => Self::Not,
+        use UnaryOperatorKind as Kind;
+
+        let kind = match token.kind {
+            OpMinus => Kind::Minus,
+            OpNot => Kind::Not,
             _ => panic!("Can't create unary operator from '{:?}'.", token.kind),
+        };
+
+        Self {
+            at: token.location,
+            kind,
         }
     }
 }
 
 #[derive(Debug, Clone)]
-pub enum SimpleLiteral {
+pub struct SimpleLiteralNode {
+    pub at: Location,
+    pub kind: SimpleLiteralKind,
+}
+
+#[derive(Debug, Clone)]
+pub enum SimpleLiteralKind {
     Int(u32),
     Float(f32),
     Bool(bool),
 }
 
-impl SimpleLiteral {
+impl SimpleLiteralNode {
     pub fn from_token(token: Token) -> Self {
-        match token.kind {
-            Int(int) => Self::Int(int),
-            Float(float) => Self::Float(float),
-            KeywordTrue => Self::Bool(true),
-            KeywordFalse => Self::Bool(false),
+        use SimpleLiteralKind as Kind;
+
+        let kind = match token.kind {
+            Int(int) => Kind::Int(int),
+            Float(float) => Kind::Float(float),
+            KeywordTrue => Kind::Bool(true),
+            KeywordFalse => Kind::Bool(false),
             _ => panic!("Can't create literal from '{:?}'.", token.kind),
+        };
+
+        Self {
+            at: token.location,
+            kind,
         }
     }
 }
 
 pub type Identifier = String;
 
-// If the contraint is None the type will have to be inferred
+// If the constraint is None the type will have to be inferred
 // during analysis.
 #[derive(Debug, Clone)]
-pub struct TypedIdentifier {
+pub struct TypedIdentifierNode {
+    // TODO: Add locations to other parts, not just the start of the identifier.
+    // i.e. make an IdentifierNode or something like that.
+    pub at: Location,
     pub identifier: Identifier,
     pub type_constraint: Option<Identifier>,
 }
 
 #[derive(Debug, Clone)]
-pub struct CallNode {
+pub struct CallExpression {
+    // TODO: Ditto.
+    pub at: Location,
     pub called: Expression,
     pub arguments: Vec<Expression>,
 }
 
 #[derive(Debug, Clone)]
-pub struct ArrayAccessNode {
+pub struct ArrayAccessExpression {
+    pub at: Location,
     pub array: Expression,
     pub index: Expression,
 }
 
 #[derive(Debug, Clone)]
-pub struct MemberAccessNode {
+pub struct MemberAccessExpression {
+    // TODO: Ditto.
+    pub at: Location,
     pub object: Expression,
     pub member_name: Identifier,
 }
 
 #[derive(Debug, Clone)]
-pub struct StrNode {
-    pub parts: Vec<StrPart>,
+pub struct StrExpression {
+    pub at: Location,
+    pub parts: Vec<StrPartNode>,
+}
+
+#[derive(Debug, Clone)]
+pub struct StrPartNode {
+    pub at: Location,
+    pub kind: StrPartKind,
 }
 
 #[derive(Debug, Clone)]
-pub enum StrPart {
+pub enum StrPartKind {
     Literal(String),
     Embed(Expression),
 }
 
 #[derive(Debug, Clone)]
-pub struct FnNode {
-    pub header: FnHeader,
-    pub body: BlockNode,
+pub struct FnExpression {
+    pub at: Location,
+    pub header: FnHeaderNode,
+    pub body: BlockExpression,
 }
 
 #[derive(Debug, Clone)]
-pub struct FnHeader {
+pub struct FnHeaderNode {
+    // TODO: ditto...
+    pub at: Location,
     pub has_self_receiver: bool,
-    pub parameters: Vec<TypedIdentifier>,
+    pub parameters: Vec<TypedIdentifierNode>,
     pub return_type: Option<Identifier>,
 }
 
 #[derive(Debug, Clone)]
-pub struct ArrayNode {
+pub struct ArrayExpression {
+    pub at: Location,
     pub elements: Vec<Expression>,
 }
 #[derive(Debug, Clone)]
-pub struct IfNode {
-    pub conditionals: Vec<ConditionalBlock>,
-    pub else_block: Option<BlockNode>,
+pub struct IfExpression {
+    pub at: Location,
+    pub conditionals: Vec<ConditionalBlockNode>,
+    pub else_block: Option<BlockExpression>,
 }
 
 #[derive(Debug, Clone)]
-pub struct LoopNode {
+pub struct LoopExpression {
+    pub at: Location,
     pub condition: Option<Expression>,
-    pub body: BlockNode,
+    pub body: BlockExpression,
 }
 
 #[derive(Debug, Clone)]
-pub struct BlockNode {
+pub struct BlockExpression {
+    pub at: Location,
     pub statements: Vec<Statement>,
     pub tail_expression: Option<Expression>,
 }
 
 #[derive(Debug, Clone)]
-pub struct ConditionalBlock {
+pub struct ConditionalBlockNode {
+    pub at: Location,
     pub condition: Expression,
-    pub block: BlockNode,
+    pub block: BlockExpression,
 }
diff --git a/src/parse/ast/statement.rs b/src/parse/ast/statement.rs
index 99ee0e0..7eb9978 100644
--- a/src/parse/ast/statement.rs
+++ b/src/parse/ast/statement.rs
@@ -1,9 +1,17 @@
 use std::fmt::Display;
 
+use crate::lex::token::Location;
+
 use super::expression::Expression;
 
 #[derive(Debug, Clone)]
-pub enum Statement {
+pub struct Statement {
+    pub at: Location,
+    pub kind: StatementKind,
+}
+
+#[derive(Debug, Clone)]
+pub enum StatementKind {
     Expression(Expression),
     Print(Expression),
     Break(Option<Expression>),
@@ -24,17 +32,17 @@ impl Statement {
         depth: usize,
     ) -> std::fmt::Result {
         let pad = "  ".repeat(depth);
-        match self {
-            Statement::Expression(expression) => expression.nested_fmt(f, depth)?,
-            Statement::Print(expression) => {
+        match self.kind {
+            StatementKind::Expression(expression) => expression.nested_fmt(f, depth)?,
+            StatementKind::Print(expression) => {
                 writeln!(f, "{}Print:", pad)?;
                 expression.nested_fmt(f, depth + 1)?;
             }
-            Statement::Return(expression) => {
+            StatementKind::Return(expression) => {
                 writeln!(f, "{}Return:", pad)?;
                 expression.nested_fmt(f, depth + 1)?;
             }
-            Statement::Break(expression) => {
+            StatementKind::Break(expression) => {
                 if let Some(returned_on_break) = expression {
                     writeln!(f, "{}Break:", pad)?;
                     returned_on_break.nested_fmt(f, depth + 1)?;
@@ -42,7 +50,7 @@ impl Statement {
                     writeln!(f, "{}Break", pad)?;
                 }
             }
-            Statement::Continue => {
+            StatementKind::Continue => {
                 writeln!(f, "{}Continue", pad)?;
             }
         }
diff --git a/src/parse/parser.rs b/src/parse/parser.rs
index 76bbab7..4363bbb 100644
--- a/src/parse/parser.rs
+++ b/src/parse/parser.rs
@@ -1,15 +1,18 @@
 use thiserror::Error;
 
-use super::ast::expression::Expression;
-use super::ast::nodes::{ArrayNode, LoopNode, StrNode, UnaryOperator};
-use super::ast::statement::Statement;
+use super::ast::expression::{Expression, ExpressionKind};
+use super::ast::nodes::{
+    ArrayExpression, BinaryOperatorNode, FnHeaderNode, LoopExpression, SimpleLiteralNode,
+    StrExpression, StrPartKind, StrPartNode, TypedIdentifierNode, UnaryOperatorNode,
+};
+use super::ast::statement::{Statement, StatementKind};
 use super::ast::Program;
 use crate::error::{ErrorLocation, RHError, RHErrorKind};
 use crate::lex::lexer::Lexer;
 use crate::lex::token::TokenKind::{self, *};
 use crate::parse::ast::nodes::{
-    ArrayAccessNode, BinaryOperator, BlockNode, CallNode, ConditionalBlock, FnHeader, FnNode,
-    IfNode, MemberAccessNode, SimpleLiteral, StrPart, TypedIdentifier,
+    ArrayAccessExpression, BlockExpression, CallExpression, ConditionalBlockNode, FnExpression,
+    IfExpression, MemberAccessExpression,
 };
 use crate::{check, consume, consume_if, inner, lex::token::Token, merge_token_names};
 use std::iter::Peekable;
@@ -47,14 +50,17 @@ impl<T: Iterator<Item = Token>> Parser<T> {
     }
 
     fn return_statement(&mut self) -> Result<Statement, RHError> {
-        consume!(self, KeywordReturn)?;
+        let return_token = consume!(self, KeywordReturn)?;
         let expression = self.expression()?;
         consume!(self, SemiColon)?;
-        Ok(Statement::Return(expression))
+        Ok(Statement {
+            at: return_token.location,
+            kind: StatementKind::Return(expression),
+        })
     }
 
     fn break_statement(&mut self) -> Result<Statement, RHError> {
-        consume!(self, KeywordBreak)?;
+        let break_token = consume!(self, KeywordBreak)?;
         let returned_on_break = if consume_if!(self, SemiColon).is_none() {
             let expression = self.expression()?;
             consume!(self, SemiColon)?;
@@ -62,26 +68,38 @@ impl<T: Iterator<Item = Token>> Parser<T> {
         } else {
             None
         };
-        Ok(Statement::Break(returned_on_break))
+        Ok(Statement {
+            at: break_token.location,
+            kind: StatementKind::Break(returned_on_break),
+        })
     }
 
     fn continue_statement(&mut self) -> Result<Statement, RHError> {
-        consume!(self, KeywordContinue)?;
+        let continue_token = consume!(self, KeywordContinue)?;
         consume!(self, SemiColon)?;
-        Ok(Statement::Continue)
+        Ok(Statement {
+            at: continue_token.location,
+            kind: StatementKind::Continue,
+        })
     }
 
     fn print_statement(&mut self) -> Result<Statement, RHError> {
-        consume!(self, KeywordPrint)?;
+        let print_token = consume!(self, KeywordPrint)?;
         let expression = self.expression()?;
         consume!(self, SemiColon)?;
-        Ok(Statement::Print(expression))
+        Ok(Statement {
+            at: print_token.location,
+            kind: StatementKind::Print(expression),
+        })
     }
 
     fn expression_statement(&mut self) -> Result<Statement, RHError> {
         let expression = self.expression()?;
         consume!(self, SemiColon)?;
-        Ok(Statement::Expression(expression))
+        Ok(Statement {
+            at: expression.at,
+            kind: StatementKind::Expression(expression),
+        })
     }
 
     pub fn expression(&mut self) -> Result<Expression, RHError> {
@@ -95,10 +113,13 @@ impl<T: Iterator<Item = Token>> Parser<T> {
         if let Some(op) = consume_if!(self, Assign | ConstAssign) {
             let right = self.assignment_expression()?;
 
-            Ok(Expression::Binary {
-                left: Box::new(left),
-                op: BinaryOperator::from_token(op),
-                right: Box::new(right),
+            Ok(Expression {
+                at: left.at,
+                kind: ExpressionKind::Binary {
+                    left: Box::new(left),
+                    op: BinaryOperatorNode::from_token(op),
+                    right: Box::new(right),
+                },
             })
         } else {
             Ok(left)
@@ -111,10 +132,13 @@ impl<T: Iterator<Item = Token>> Parser<T> {
         while let Some(op) = consume_if!(self, OpAnd) {
             let right = self.and_expression()?;
 
-            left = Expression::Binary {
-                left: Box::new(left),
-                op: BinaryOperator::from_token(op),
-                right: Box::new(right),
+            left = Expression {
+                at: left.at,
+                kind: ExpressionKind::Binary {
+                    left: Box::new(left),
+                    op: BinaryOperatorNode::from_token(op),
+                    right: Box::new(right),
+                },
             };
         }
 
@@ -127,10 +151,13 @@ impl<T: Iterator<Item = Token>> Parser<T> {
         while let Some(op) = consume_if!(self, OpOr) {
             let right = self.equality_expression()?;
 
-            left = Expression::Binary {
-                left: Box::new(left),
-                op: BinaryOperator::from_token(op),
-                right: Box::new(right),
+            left = Expression {
+                at: left.at,
+                kind: ExpressionKind::Binary {
+                    left: Box::new(left),
+                    op: BinaryOperatorNode::from_token(op),
+                    right: Box::new(right),
+                },
             };
         }
 
@@ -143,10 +170,13 @@ impl<T: Iterator<Item = Token>> Parser<T> {
         while let Some(op) = consume_if!(self, OpEq | OpNeq) {
             let right = self.comparison_expression()?;
 
-            left = Expression::Binary {
-                left: Box::new(left),
-                op: BinaryOperator::from_token(op),
-                right: Box::new(right),
+            left = Expression {
+                at: left.at,
+                kind: ExpressionKind::Binary {
+                    left: Box::new(left),
+                    op: BinaryOperatorNode::from_token(op),
+                    right: Box::new(right),
+                },
             };
         }
 
@@ -159,10 +189,13 @@ impl<T: Iterator<Item = Token>> Parser<T> {
         while let Some(op) = consume_if!(self, OpGt | OpGte | OpLt | OpLte) {
             let right = self.term_expression()?;
 
-            left = Expression::Binary {
-                left: Box::new(left),
-                op: BinaryOperator::from_token(op),
-                right: Box::new(right),
+            left = Expression {
+                at: left.at,
+                kind: ExpressionKind::Binary {
+                    left: Box::new(left),
+                    op: BinaryOperatorNode::from_token(op),
+                    right: Box::new(right),
+                },
             };
         }
 
@@ -175,10 +208,13 @@ impl<T: Iterator<Item = Token>> Parser<T> {
         while let Some(op) = consume_if!(self, OpPlus | OpMinus) {
             let right = self.factor_expression()?;
 
-            left = Expression::Binary {
-                left: Box::new(left),
-                op: BinaryOperator::from_token(op),
-                right: Box::new(right),
+            left = Expression {
+                at: left.at,
+                kind: ExpressionKind::Binary {
+                    left: Box::new(left),
+                    op: BinaryOperatorNode::from_token(op),
+                    right: Box::new(right),
+                },
             };
         }
 
@@ -191,10 +227,13 @@ impl<T: Iterator<Item = Token>> Parser<T> {
         while let Some(op) = consume_if!(self, OpSlash | OpStar) {
             let right = self.unary_expression()?;
 
-            left = Expression::Binary {
-                left: Box::new(left),
-                op: BinaryOperator::from_token(op),
-                right: Box::new(right),
+            left = Expression {
+                at: left.at,
+                kind: ExpressionKind::Binary {
+                    left: Box::new(left),
+                    op: BinaryOperatorNode::from_token(op),
+                    right: Box::new(right),
+                },
             };
         }
 
@@ -203,9 +242,14 @@ impl<T: Iterator<Item = Token>> Parser<T> {
 
     fn unary_expression(&mut self) -> Result<Expression, RHError> {
         let expression = if check!(self, OpPlus | OpMinus | OpNot) {
-            Expression::Unary {
-                op: UnaryOperator::from_token(self.tokens.next().unwrap()),
-                right: Box::new(self.unary_expression()?),
+            let op_token = self.tokens.next().unwrap();
+
+            Expression {
+                at: op_token.location,
+                kind: ExpressionKind::Unary {
+                    op: UnaryOperatorNode::from_token(op_token),
+                    right: Box::new(self.unary_expression()?),
+                },
             }
         } else {
             self.postfix_expression()?
@@ -218,7 +262,7 @@ impl<T: Iterator<Item = Token>> Parser<T> {
         let mut left = self.unit_expression()?;
 
         while let Some(token) = consume_if!(self, GroupOpen | ArrayOpen | Dot) {
-            match token.kind {
+            let kind = match token.kind {
                 GroupOpen => {
                     let mut arguments = Vec::new();
 
@@ -231,27 +275,35 @@ impl<T: Iterator<Item = Token>> Parser<T> {
                         }
                     }
 
-                    left = Expression::Call(Box::new(CallNode {
+                    ExpressionKind::Call(Box::new(CallExpression {
+                        at: token.location,
                         called: left,
                         arguments,
-                    }));
+                    }))
                 }
                 ArrayOpen => {
                     let index = self.expression()?;
                     consume!(self, ArrayClose)?;
 
-                    left = Expression::ArrayAccess(Box::new(ArrayAccessNode { array: left, index }))
+                    ExpressionKind::ArrayAccess(Box::new(ArrayAccessExpression {
+                        at: token.location,
+                        array: left,
+                        index,
+                    }))
                 }
                 Dot => {
                     let member_name = inner!(consume!(self, Ident(_))?, Ident);
 
-                    left = Expression::MemberAccess(Box::new(MemberAccessNode {
+                    ExpressionKind::MemberAccess(Box::new(MemberAccessExpression {
+                        at: token.location,
                         object: left,
                         member_name,
                     }))
                 }
                 _ => unreachable!(),
-            }
+            };
+
+            left = Expression { at: left.at, kind };
         }
 
         Ok(left)
@@ -259,24 +311,24 @@ impl<T: Iterator<Item = Token>> Parser<T> {
 
     fn unit_expression(&mut self) -> Result<Expression, RHError> {
         if let Some(token) = self.tokens.peek() {
-            match token.kind {
+            let kind = match token.kind {
                 Int(_) | Float(_) | Str(_) | KeywordTrue | KeywordFalse => {
                     let literal = self.tokens.next().unwrap();
-                    Ok(Expression::SimpleLiteral(SimpleLiteral::from_token(
-                        literal,
-                    )))
+                    Ok(ExpressionKind::SimpleLiteral(
+                        SimpleLiteralNode::from_token(literal),
+                    ))
                 }
-                Ident(_) => Ok(Expression::Identifier(inner!(
+                Ident(_) => Ok(ExpressionKind::Identifier(inner!(
                     self.tokens.next().unwrap(),
                     Ident
                 ))),
-                StrOpen => Ok(Expression::StrLiteral(Box::new(self.str()?))),
-                GroupOpen => Ok(Expression::Group(Box::new(self.group()?))),
-                BlockOpen => Ok(Expression::Block(Box::new(self.generic_block()?))),
-                ArrayOpen => Ok(Expression::ArrayLiteral(self.array()?)),
-                KeywordFn => Ok(Expression::FnLiteral(Box::new(self.function()?))),
-                KeywordIf => Ok(Expression::If(Box::new(self.conditional()?))),
-                KeywordLoop => Ok(Expression::Loop(Box::new(self.repeating()?))),
+                StrOpen => Ok(ExpressionKind::StrLiteral(Box::new(self.str()?))),
+                GroupOpen => Ok(ExpressionKind::Group(Box::new(self.group()?))),
+                BlockOpen => Ok(ExpressionKind::Block(Box::new(self.generic_block()?))),
+                ArrayOpen => Ok(ExpressionKind::ArrayLiteral(self.array()?)),
+                KeywordFn => Ok(ExpressionKind::FnLiteral(Box::new(self.function()?))),
+                KeywordIf => Ok(ExpressionKind::If(Box::new(self.conditional()?))),
+                KeywordLoop => Ok(ExpressionKind::Loop(Box::new(self.repeating()?))),
                 _ => Err(parser_error(
                     ErrorLocation::Specific(token.location),
                     ParserError::UnexpectedToken {
@@ -298,7 +350,12 @@ impl<T: Iterator<Item = Token>> Parser<T> {
                         ),
                     },
                 )),
-            }
+            }?;
+
+            Ok(Expression {
+                at: token.location,
+                kind,
+            })
         } else {
             Err(parser_error(
                 ErrorLocation::Eof,
@@ -317,8 +374,8 @@ impl<T: Iterator<Item = Token>> Parser<T> {
         Ok(expression)
     }
 
-    fn array(&mut self) -> Result<ArrayNode, RHError> {
-        consume!(self, ArrayOpen)?;
+    fn array(&mut self) -> Result<ArrayExpression, RHError> {
+        let array_token = consume!(self, ArrayOpen)?;
         let mut elements = Vec::new();
 
         loop {
@@ -330,39 +387,48 @@ impl<T: Iterator<Item = Token>> Parser<T> {
         }
 
         consume!(self, ArrayClose)?;
-        Ok(ArrayNode { elements })
+        Ok(ArrayExpression {
+            at: array_token.location,
+            elements,
+        })
     }
 
-    fn str(&mut self) -> Result<StrNode, RHError> {
+    fn str(&mut self) -> Result<StrExpression, RHError> {
         let mut parts = Vec::new();
 
-        consume!(self, StrOpen)?;
+        let str_token = consume!(self, StrOpen)?;
 
         loop {
             let token = self.tokens.next().expect("Unclosed str.");
 
-            let part = match token.kind {
-                Str(literal) => StrPart::Literal(literal),
+            let part_kind = match token.kind {
+                Str(literal) => StrPartKind::Literal(literal),
                 StrEmbed(code) => {
                     let embed_lexer = Lexer::new(&code);
                     let mut embed_parser = Parser::new(embed_lexer);
 
                     let node = embed_parser.expression()?;
 
-                    StrPart::Embed(node)
+                    StrPartKind::Embed(node)
                 }
                 StrClose => break,
                 _ => unreachable!(),
             };
 
-            parts.push(part);
+            parts.push(StrPartNode {
+                at: token.location,
+                kind: part_kind,
+            });
         }
 
-        Ok(StrNode { parts })
+        Ok(StrExpression {
+            at: str_token.location,
+            parts,
+        })
     }
 
-    fn function(&mut self) -> Result<FnNode, RHError> {
-        consume!(self, KeywordFn)?;
+    fn function(&mut self) -> Result<FnExpression, RHError> {
+        let fn_token = consume!(self, KeywordFn)?;
 
         let header = {
             let has_self_receiver = if consume_if!(self, KeywordSelf).is_some() {
@@ -382,9 +448,10 @@ impl<T: Iterator<Item = Token>> Parser<T> {
                     None
                 };
 
-                parameters.push(TypedIdentifier {
+                parameters.push(TypedIdentifierNode {
                     identifier: parameter_name,
                     type_constraint,
+                    at: token.location,
                 });
 
                 if consume_if!(self, Comma).is_none() {
@@ -398,29 +465,36 @@ impl<T: Iterator<Item = Token>> Parser<T> {
                 None
             };
 
-            FnHeader {
+            FnHeaderNode {
                 has_self_receiver,
                 parameters,
                 return_type,
+                at: fn_token.location,
             }
         };
 
         let body = self.generic_block()?;
 
-        Ok(FnNode { header, body })
+        Ok(FnExpression {
+            header,
+            body,
+            // Duplicated ^
+            at: fn_token.location,
+        })
     }
 
-    fn conditional(&mut self) -> Result<IfNode, RHError> {
-        consume!(self, KeywordIf)?;
+    fn conditional(&mut self) -> Result<IfExpression, RHError> {
+        let if_token = consume!(self, KeywordIf)?;
 
         let mut conditionals = Vec::new();
 
         let if_condition = self.expression()?;
         let if_block = self.generic_block()?;
 
-        conditionals.push(ConditionalBlock {
+        conditionals.push(ConditionalBlockNode {
             condition: if_condition,
             block: if_block,
+            at: if_condition.at,
         });
 
         // Elifs
@@ -428,9 +502,10 @@ impl<T: Iterator<Item = Token>> Parser<T> {
             let elif_condition = self.expression()?;
             let elif_block = self.generic_block()?;
 
-            conditionals.push(ConditionalBlock {
+            conditionals.push(ConditionalBlockNode {
                 condition: elif_condition,
                 block: elif_block,
+                at: elif_condition.at,
             });
         }
 
@@ -440,14 +515,15 @@ impl<T: Iterator<Item = Token>> Parser<T> {
             None
         };
 
-        Ok(IfNode {
+        Ok(IfExpression {
             conditionals,
             else_block,
+            at: if_token.location,
         })
     }
 
-    fn repeating(&mut self) -> Result<LoopNode, RHError> {
-        consume!(self, KeywordLoop)?;
+    fn repeating(&mut self) -> Result<LoopExpression, RHError> {
+        let loop_token = consume!(self, KeywordLoop)?;
 
         let condition = if consume_if!(self, KeywordIf).is_some() {
             let expression = self.expression()?;
@@ -457,11 +533,15 @@ impl<T: Iterator<Item = Token>> Parser<T> {
         };
 
         let body = self.generic_block()?;
-        Ok(LoopNode { body, condition })
+        Ok(LoopExpression {
+            body,
+            condition,
+            at: loop_token.location,
+        })
     }
 
-    fn generic_block(&mut self) -> Result<BlockNode, RHError> {
-        consume!(self, BlockOpen)?;
+    fn generic_block(&mut self) -> Result<BlockExpression, RHError> {
+        let block_token = consume!(self, BlockOpen)?;
 
         let mut statements = Vec::new();
         let mut tail_expression = None;
@@ -478,7 +558,10 @@ impl<T: Iterator<Item = Token>> Parser<T> {
                 _ => {
                     let expression = self.expression()?;
                     if consume_if!(self, SemiColon).is_some() {
-                        statements.push(Statement::Expression(expression));
+                        statements.push(Statement {
+                            kind: StatementKind::Expression(expression),
+                            at: expression.at,
+                        });
                     } else {
                         tail_expression = Some(expression);
                         break;
@@ -489,9 +572,10 @@ impl<T: Iterator<Item = Token>> Parser<T> {
 
         consume!(self, BlockClose)?;
 
-        Ok(BlockNode {
+        Ok(BlockExpression {
             statements,
             tail_expression,
+            at: block_token.location,
         })
     }
 }