valkyrie-ast 0.0.1

Abstract Syntax Tree of valkyrie language
Documentation
use super::*;
use crate::ValkyrieOperator;

#[derive(Clone, Debug, Serialize, Deserialize)]
pub struct BinaryExpression {
    pub base: ValkyrieASTNode,
    pub terms: Vec<(ValkyrieOperator, ValkyrieASTNode)>,
}

impl BinaryExpression {
    pub fn new(lhs: ValkyrieASTNode, op: ValkyrieOperator, rhs: ValkyrieASTNode) -> Self {
        Self { base: lhs, terms: vec![(op, rhs)] }
    }
    pub fn extend(&mut self, op: ValkyrieOperator, rhs: ValkyrieASTNode) {
        self.terms.push((op, rhs));
    }
    pub fn combine(lhs: ValkyrieASTNode, op: ValkyrieOperator, rhs: ValkyrieASTNode) -> ValkyrieASTNode {
        let file = lhs.span.file;
        let head = lhs.span.head;
        let tail = rhs.span.tail;
        let binary = match (lhs.kind, rhs.kind) {
            (ValkyrieASTKind::Binary(mut a), ValkyrieASTKind::Binary(b)) => {
                a.extend(op, b.base);
                a.terms.extend(b.terms);
                a
            }
            (ValkyrieASTKind::Binary(mut a), b) => {
                a.extend(op, ValkyrieASTNode { kind: b, span: rhs.span });
                a
            }
            (a, ValkyrieASTKind::Binary(b)) => {
                let mut new = Self::new(ValkyrieASTNode { kind: a, span: lhs.span }, op, b.base);
                new.terms.extend(b.terms);
                box new
            }
            (a, b) => {
                box Self::new(ValkyrieASTNode { kind: a, span: lhs.span }, op, ValkyrieASTNode { kind: b, span: rhs.span })
            }
        };
        binary.to_node(file, &Range { start: head, end: tail })
    }

    pub fn to_node(self, file: FileID, range: &Range<usize>) -> ValkyrieASTNode {
        ValkyrieASTNode { kind: ValkyrieASTKind::Binary(box self), span: FileSpan { file, head: range.start, tail: range.end } }
    }
}