diff options
Diffstat (limited to 'src/parse/ast/nodes.rs')
| -rw-r--r-- | src/parse/ast/nodes.rs | 176 |
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, } |
