phoenix-lang 1.5.3

A simple, fast programming language
Documentation
use serde::{Deserialize, Serialize};

use crate::scanner::TokenType;

#[derive(Debug, PartialEq, PartialOrd, Serialize, Deserialize)]
pub enum Precedence {
    None,
    Assignment,
    Or,
    And,
    Equality,
    Comparison,
    Term,
    Factor,
    Increment,
    Unary,
    Call,
    Primary,
}

#[derive(Serialize, Deserialize, Debug)]
pub enum ParseFn {
    None,
    Unary,
    Increment,
    Grouping,
    Number,
    Binary,
    Literal,
    String,
    Variable,
    List,
    HashMap,
    And,
    Or,
    Call,
    Dot,
    This,
    Super,
}

#[derive(Serialize, Deserialize, Debug)]
pub struct ParseRule {
    pub prefix: ParseFn,
    pub infix: ParseFn,
    pub precedence: Precedence,
}

impl ParseRule {
    pub fn next_precedence(&self) -> Precedence {
        match self.precedence {
            Precedence::None => Precedence::Assignment,
            Precedence::Assignment => Precedence::Or,
            Precedence::Or => Precedence::And,
            Precedence::And => Precedence::Equality,
            Precedence::Equality => Precedence::Comparison,
            Precedence::Comparison => Precedence::Term,
            Precedence::Term => Precedence::Factor,
            Precedence::Factor => Precedence::Unary,
            Precedence::Unary => Precedence::Increment,
            Precedence::Increment => Precedence::Call,
            Precedence::Call => Precedence::Primary,
            Precedence::Primary => Precedence::Primary,
        }
    }
}

const PARSE_RULE_NONE: ParseRule = ParseRule {
    prefix: ParseFn::None,
    infix: ParseFn::None,
    precedence: Precedence::None,
};

const PARSE_RULE_LP: ParseRule = ParseRule {
    prefix: ParseFn::Grouping,
    infix: ParseFn::Call,
    precedence: Precedence::Call,
};

const PARSE_RULE_MINUS: ParseRule = ParseRule {
    prefix: ParseFn::Unary,
    infix: ParseFn::Binary,
    precedence: Precedence::Term,
};

const PARSE_RULE_MINUS_ASSIGN: ParseRule = ParseRule {
    prefix: ParseFn::None,
    infix: ParseFn::Variable,
    precedence: Precedence::Assignment,
};

const PARSE_RULE_MINUS_MINUS: ParseRule = ParseRule {
    prefix: ParseFn::Grouping,
    infix: ParseFn::Increment,
    precedence: Precedence::Increment,
};

const PARSE_RULE_PLUS: ParseRule = ParseRule {
    prefix: ParseFn::None,
    infix: ParseFn::Binary,
    precedence: Precedence::Term,
};

const PARSE_RULE_PLUS_ASSIGN: ParseRule = ParseRule {
    prefix: ParseFn::None,
    infix: ParseFn::Binary,
    precedence: Precedence::Assignment,
};

const PARSE_RULE_PLUS_PLUS: ParseRule = ParseRule {
    prefix: ParseFn::Grouping,
    infix: ParseFn::Increment,
    precedence: Precedence::Increment,
};

const PARSE_RULE_SLASH: ParseRule = ParseRule {
    prefix: ParseFn::None,
    infix: ParseFn::Binary,
    precedence: Precedence::Factor,
};

const PARSE_RULE_SLASH_ASSIGN: ParseRule = ParseRule {
    prefix: ParseFn::None,
    infix: ParseFn::Binary,
    precedence: Precedence::Assignment,
};

const PARSE_RULE_STAR: ParseRule = ParseRule {
    prefix: ParseFn::None,
    infix: ParseFn::Binary,
    precedence: Precedence::Factor,
};

const PARSE_RULE_STAR_ASSIGN: ParseRule = ParseRule {
    prefix: ParseFn::None,
    infix: ParseFn::Binary,
    precedence: Precedence::Assignment,
};

const PARSE_RULE_NUM: ParseRule = ParseRule {
    prefix: ParseFn::Number,
    infix: ParseFn::None,
    precedence: Precedence::None,
};

const PARSE_RULE_TRUE: ParseRule = ParseRule {
    prefix: ParseFn::Literal,
    infix: ParseFn::None,
    precedence: Precedence::None,
};

const PARSE_RULE_FALSE: ParseRule = ParseRule {
    prefix: ParseFn::Literal,
    infix: ParseFn::None,
    precedence: Precedence::None,
};

const PARSE_RULE_NIL: ParseRule = ParseRule {
    prefix: ParseFn::Literal,
    infix: ParseFn::None,
    precedence: Precedence::None,
};

const PARSE_RULE_BANG: ParseRule = ParseRule {
    prefix: ParseFn::Unary,
    infix: ParseFn::None,
    precedence: Precedence::None,
};

const PARSE_RULE_BE: ParseRule = ParseRule {
    prefix: ParseFn::None,
    infix: ParseFn::Binary,
    precedence: Precedence::Equality,
};

const PARSE_RULE_EE: ParseRule = ParseRule {
    prefix: ParseFn::None,
    infix: ParseFn::Binary,
    precedence: Precedence::Equality,
};

const PARSE_RULE_G: ParseRule = ParseRule {
    prefix: ParseFn::None,
    infix: ParseFn::Binary,
    precedence: Precedence::Comparison,
};

const PARSE_RULE_GE: ParseRule = ParseRule {
    prefix: ParseFn::None,
    infix: ParseFn::Binary,
    precedence: Precedence::Comparison,
};
const PARSE_RULE_L: ParseRule = ParseRule {
    prefix: ParseFn::None,
    infix: ParseFn::Binary,
    precedence: Precedence::Comparison,
};
const PARSE_RULE_LE: ParseRule = ParseRule {
    prefix: ParseFn::None,
    infix: ParseFn::Binary,
    precedence: Precedence::Comparison,
};
const PARSE_RULE_STR: ParseRule = ParseRule {
    prefix: ParseFn::String,
    infix: ParseFn::None,
    precedence: Precedence::None,
};
const PARSE_RULE_ID: ParseRule = ParseRule {
    prefix: ParseFn::Variable,
    infix: ParseFn::None,
    precedence: Precedence::None,
};
const PARSE_RULE_AND: ParseRule = ParseRule {
    prefix: ParseFn::None,
    infix: ParseFn::And,
    precedence: Precedence::And,
};
const PARSE_RULE_OR: ParseRule = ParseRule {
    prefix: ParseFn::None,
    infix: ParseFn::Or,
    precedence: Precedence::Or,
};
const PARSE_RULE_DOT: ParseRule = ParseRule {
    prefix: ParseFn::None,
    infix: ParseFn::Dot,
    precedence: Precedence::Call,
};
const PARSE_RULE_THIS: ParseRule = ParseRule {
    prefix: ParseFn::This,
    infix: ParseFn::None,
    precedence: Precedence::None,
};
const PARSE_RULE_SUPER: ParseRule = ParseRule {
    prefix: ParseFn::Super,
    infix: ParseFn::None,
    precedence: Precedence::None,
};
const PARSE_RULE_LBRACKET: ParseRule = ParseRule {
    prefix: ParseFn::List,
    infix: ParseFn::None,
    precedence: Precedence::None,
};

const PARSE_RULE_LBRACE: ParseRule = ParseRule {
    prefix: ParseFn::HashMap,
    infix: ParseFn::None,
    precedence: Precedence::None,
};

pub fn get_rule(operator: TokenType) -> ParseRule {
    match operator {
        TokenType::LeftParen => PARSE_RULE_LP,
        TokenType::LeftBracket => PARSE_RULE_LBRACKET,
        TokenType::LeftBrace => PARSE_RULE_LBRACE,
        TokenType::Minus => PARSE_RULE_MINUS,
        TokenType::MinusMinus => PARSE_RULE_MINUS_MINUS,
        TokenType::MinusAssign => PARSE_RULE_MINUS_ASSIGN,
        TokenType::Plus => PARSE_RULE_PLUS,
        TokenType::PlusPlus => PARSE_RULE_PLUS_PLUS,
        TokenType::PlusAssign => PARSE_RULE_PLUS_ASSIGN,
        TokenType::Slash => PARSE_RULE_SLASH,
        TokenType::SlashAssign => PARSE_RULE_SLASH_ASSIGN,
        TokenType::Star => PARSE_RULE_STAR,
        TokenType::StarAssign => PARSE_RULE_STAR_ASSIGN,
        TokenType::Number => PARSE_RULE_NUM,
        TokenType::True => PARSE_RULE_TRUE,
        TokenType::False => PARSE_RULE_FALSE,
        TokenType::Nil => PARSE_RULE_NIL,
        TokenType::Bang => PARSE_RULE_BANG,
        TokenType::BangEqual => PARSE_RULE_BE,
        TokenType::EqualEqual => PARSE_RULE_EE,
        TokenType::Greater => PARSE_RULE_G,
        TokenType::GreaterEqual => PARSE_RULE_GE,
        TokenType::Less => PARSE_RULE_L,
        TokenType::LessEqual => PARSE_RULE_LE,
        TokenType::String => PARSE_RULE_STR,
        TokenType::Identifier => PARSE_RULE_ID,
        TokenType::And => PARSE_RULE_AND,
        TokenType::Or => PARSE_RULE_OR,
        TokenType::Dot => PARSE_RULE_DOT,
        TokenType::This => PARSE_RULE_THIS,
        TokenType::Super => PARSE_RULE_SUPER,
        _ => PARSE_RULE_NONE,
    }
}