about summary refs log tree commit diff
path: root/src/parse/ast/nodes.rs
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/ast/nodes.rs
parent9d331e92045ca9098ab5f2139c80ea33e89e8ca3 (diff)
downloadrabbithole-e621f13a226d297d5368f4c294a8549a93843934.tar.zst
rabbithole-e621f13a226d297d5368f4c294a8549a93843934.zip
AST restructure
Diffstat (limited to 'src/parse/ast/nodes.rs')
-rw-r--r--src/parse/ast/nodes.rs176
1 files changed, 123 insertions, 53 deletions
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,
 }