arrow-parser 0.0.2

Parser for the Arrow programming language
Documentation
use super::operator::ExprOperatorName;
use super::source::SourceRange;
use crate::symbol::Scope;
use ordered_float::OrderedFloat;

pub trait Syntax {}

pub enum LiteralTemplatePart {
  Substitution(Node<Expression>),
  String(String),
}

pub enum Expression {
  Binary {
    left: Node<Expression>,
    right: Node<Expression>,
    operator: ExprOperatorName,
  },
  BindMethod {
    impl_: String,
    method: String,
    arguments: Vec<Node<Expression>>,
  },
  Block {
    statements: Vec<Node<Statement>>,
    result: Option<Node<Expression>>,
  },
  CallMethod {
    object: Node<Expression>,
    method: String,
    arguments: Vec<Node<Expression>>,
    optional: bool,
  },
  CallValue {
    callee: Node<Expression>,
    arguments: Vec<Node<Expression>>,
    optional: bool,
  },
  Cast {
    value: Node<Expression>,
    typ: String,
  },
  Closure {
    parameters: Vec<String>,
    body: Node<Expression>, // Always Expression::Block.
  },
  Field {
    object: Node<Expression>,
    field: String,
    optional: bool,
  },
  Index {
    object: Node<Expression>,
    index: Node<Expression>,
    optional: bool,
  },
  If {
    condition: Node<Expression>,
    consequent: Node<Expression>,        // Always Expression::Block.
    alternate: Option<Node<Expression>>, // Always Expression::Block or Expression::If if Some.
  },
  LiteralArray {
    entries: Vec<Node<Expression>>,
  },
  LiteralBoolean {
    value: bool,
  },
  LiteralFloat {
    value: OrderedFloat<f64>,
  },
  LiteralInt {
    value: i64,
  },
  LiteralNone {},
  LiteralObject {
    fields: Vec<(String, Node<Expression>)>,
  },
  LiteralTemplateExpr {
    parts: Vec<LiteralTemplatePart>,
  },
  Unary {
    operand: Node<Expression>,
    operator: ExprOperatorName,
  },
  Var {
    name: String,
  },
}

impl Syntax for Expression {}

// Statements never result in values.
pub enum Statement {
  Break,
  Continue,
  Expression {
    expression: Node<Expression>,
  },
  FieldAssign {
    object: Node<Expression>,
    field: String,
    value: Node<Expression>,
    optional: bool,
  },
  For {
    variable: String,
    iterable: Node<Expression>,
    body: Node<Expression>, // Always Expression::Block with None `result`.
  },
  IndexAssign {
    object: Node<Expression>,
    index: Node<Expression>,
    value: Node<Expression>,
    optional: bool,
  },
  Let {
    variable: String,
    value: Node<Expression>,
  },
  Loop {
    body: Node<Expression>, // Always Expression::Block with None `result`.
  },
  Return {
    value: Option<Node<Expression>>,
  },
  VarAssign {
    variable: String,
    value: Node<Expression>,
  },
}

impl Syntax for Statement {}

pub enum ModuleItem {
  Impl {
    name: String,
    methods: Vec<(String, Node<Expression>)>, // Always Expression::Closure.
  },
  Statement {
    statement: Node<Statement>,
  },
}

impl Syntax for ModuleItem {}

pub struct Node<S: Syntax> {
  pub loc: SourceRange,
  pub stx: Box<S>,
  // A new scope is introduced immediately at Expression::Block and Expression::Closure, not their immediate children. This makes it easier to get and identify new scopes from nodes.
  pub scope: Scope,
}

pub struct Module {
  pub items: Vec<Node<ModuleItem>>,
}