~starkingdoms/starkingdoms

fdb3bfb1e0bf0eea64a9aad0f81d305728daedc2 — ghostlyzsh 1 year, 4 months ago bc4391c
functions added
3 files changed, 70 insertions(+), 129 deletions(-)

M kabel/grammar.ebnf
M kabel/src/macros.rs
M kabel/src/parser.rs
M kabel/grammar.ebnf => kabel/grammar.ebnf +0 -1
@@ 4,7 4,6 @@ statement = function | loop | while | if | expression_statement ;

function = "function" , identifier , "(" , { identifier , "," , } ")" , block

(* implemented *)
loop = "loop" , block ;

while = "while" , "(" , expression , ")" , block ;

M kabel/src/macros.rs => kabel/src/macros.rs +16 -0
@@ 24,3 24,19 @@ macro_rules! lit {
        }
    };
}

#[macro_export]
macro_rules! unexpected_token {
    ($self:expr, $message:expr, $token:expr) => {
        $crate::error::KabelError::new(
            $crate::error::ErrorKind::UnexpectedToken,
            format!(
                $message,
                $self.text[$token.start..$token.end].to_string()
            ),
            $token.line,
            $token.column,
            $self.text[$token.line_start..$token.end].to_string(),
        )
    };
}

M kabel/src/parser.rs => kabel/src/parser.rs +54 -128
@@ 1,7 1,7 @@
use crate::{
    error::{ErrorKind, KabelError},
    lexer::{Token, TokenType},
    lit,
    lit, unexpected_token,
};

pub struct Parser {


@@ 48,6 48,7 @@ impl Parser {
    pub fn statement(&mut self) -> Result<AST, KabelError> {
        match self.peek()?.token_type {
            TokenType::Ident(ident) => match ident.as_str() {
                "function" => self.function_statement(),
                "loop" => self.loop_statement(),
                "while" => self.while_statement(),
                "if" => self.if_statement(),


@@ 57,6 58,40 @@ impl Parser {
        }
    }

    pub fn function_statement(&mut self) -> Result<AST, KabelError> {
        let function_ident = self.read_token()?;
        let ident = self.read_token()?;
        if let TokenType::Ident(name) = ident.token_type {
            let left_paren = self.read_token()?;
            if let TokenType::LeftParen = left_paren.token_type {
                let mut expressions = Vec::new();
                while self.peek()?.token_type != TokenType::RightParen {
                    expressions.push(self.expression()?);
                    if let TokenType::Comma = self.peek()?.token_type {
                        self.read_token()?;
                    }
                }
                let right_paren = self.read_token()?;
                if let TokenType::RightParen = right_paren.token_type {
                    let block = self.block()?;
                    return Ok(AST {
                        ast_type: ASTType::Function(Box::new(lit!(Ident, name, ident)), expressions, Box::new(block.clone())),
                        start: function_ident.start,
                        end: block.end,
                        line: function_ident.line,
                        column: function_ident.column,
                    });
                } else {
                    return Err(unexpected_token!(self, "Expected ) found {}", right_paren));
                }
            } else {
                return Err(unexpected_token!(self, "Expected ( found {}", left_paren));
            }
        } else {
            return Err(unexpected_token!(self, "Expected identifier found {}", ident));
        }
    }

    pub fn loop_statement(&mut self) -> Result<AST, KabelError> {
        let loop_ident = self.read_token()?;
        let block = self.block()?;


@@ 85,28 120,10 @@ impl Parser {
                    column: while_ident.column,
                });
            } else {
                return Err(KabelError::new(
                    ErrorKind::UnexpectedToken,
                    format!(
                        "Expected ) found {}",
                        self.text[right_paren.start..right_paren.end].to_string()
                    ),
                    right_paren.line,
                    right_paren.column,
                    self.text[right_paren.line_start..right_paren.end].to_string(),
                ));
                return Err(unexpected_token!(self, "Expected ) found {}", right_paren));
            }
        } else {
            return Err(KabelError::new(
                ErrorKind::UnexpectedToken,
                format!(
                    "Expected ( found {}",
                    self.text[left_paren.start..left_paren.end].to_string()
                ),
                left_paren.line,
                left_paren.column,
                self.text[left_paren.line_start..left_paren.end].to_string(),
            ));
            return Err(unexpected_token!(self, "Expected ( found {}", left_paren));
        }
    }



@@ 152,30 169,10 @@ impl Parser {
                                        column: if_ident.column,
                                    });
                                } else {
                                    return Err(KabelError::new(
                                        ErrorKind::UnexpectedToken,
                                        format!(
                                            "Expected if found {}",
                                            self.text[else_if_ident.start..else_if_ident.end]
                                                .to_string()
                                        ),
                                        else_if_ident.line,
                                        else_if_ident.column,
                                        self.text[else_if_ident.line_start..else_if_ident.end]
                                            .to_string(),
                                    ));
                                    return Err(unexpected_token!(self, "Expected if found {}", else_if_ident));
                                }
                            }
                            return Err(KabelError::new(
                                ErrorKind::UnexpectedToken,
                                format!(
                                    "Unexpected token {}",
                                    self.text[else_ident.start..else_ident.end].to_string()
                                ),
                                else_ident.line,
                                else_ident.column,
                                self.text[else_ident.line_start..else_ident.end].to_string(),
                            ));
                            return Err(unexpected_token!(self, "Unexpected token {}", else_ident));
                        } else {
                            self.current -= 1;
                        }


@@ 189,28 186,10 @@ impl Parser {
                    column: if_ident.column,
                });
            } else {
                return Err(KabelError::new(
                    ErrorKind::UnexpectedToken,
                    format!(
                        "Expected ) found {}",
                        self.text[right_paren.start..right_paren.end].to_string()
                    ),
                    right_paren.line,
                    right_paren.column,
                    self.text[right_paren.line_start..right_paren.end].to_string(),
                ));
                return Err(unexpected_token!(self, "Expected ) found {}", right_paren));
            }
        } else {
            return Err(KabelError::new(
                ErrorKind::UnexpectedToken,
                format!(
                    "Expected ( found {}",
                    self.text[left_paren.start..left_paren.end].to_string()
                ),
                left_paren.line,
                left_paren.column,
                self.text[left_paren.line_start..left_paren.end].to_string(),
            ));
            return Err(unexpected_token!(self, "Expected ( found {}", left_paren));
        }
    }



@@ 230,16 209,7 @@ impl Parser {
                column: left_brace.column,
            });
        } else {
            return Err(KabelError::new(
                ErrorKind::UnexpectedToken,
                format!(
                    "Expected {{ found {}",
                    self.text[left_brace.start..left_brace.end].to_string()
                ),
                left_brace.line,
                left_brace.column,
                self.text[left_brace.line_start..left_brace.end].to_string(),
            ));
            return Err(unexpected_token!(self, "Expected {{ found {}", left_brace));
        }
    }



@@ 260,16 230,7 @@ impl Parser {
            return Ok(expression);
        } else {
            self.current -= 1;
            return Err(KabelError::new(
                ErrorKind::UnexpectedToken,
                format!(
                    "Expected ; found {}",
                    self.text[semicolon.start..semicolon.end].to_string()
                ),
                semicolon.line,
                semicolon.column,
                self.text[semicolon.line_start..semicolon.end].to_string(),
            ));
            return Err(unexpected_token!(self, "Expected ; found {}", semicolon));
        }
    }



@@ 301,28 262,10 @@ impl Parser {
                    column: var.column,
                });
            } else {
                return Err(KabelError::new(
                    ErrorKind::UnexpectedToken,
                    format!(
                        "Expected equals, found {}",
                        self.text[equal.start..equal.end].to_string()
                    ),
                    equal.line,
                    equal.column,
                    self.text[equal.line_start..equal.end].to_string(),
                ));
                return Err(unexpected_token!(self, "Expected = found {}", equal));
            }
        } else {
            return Err(KabelError::new(
                ErrorKind::UnexpectedToken,
                format!(
                    "Expected identifier, found {}",
                    self.text[ident.start..ident.end].to_string()
                ),
                ident.line,
                ident.column,
                self.text[ident.line_start..ident.end].to_string(),
            ));
            return Err(unexpected_token!(self, "Expected identifier found {}", ident));
        }
    }



@@ 645,16 588,7 @@ impl Parser {
                return Ok(self.group(token)?);
            }
            _ => {
                return Err(KabelError::new(
                    ErrorKind::UnexpectedToken,
                    format!(
                        "Unexpected token {}",
                        self.text[token.start..token.end].to_string()
                    ),
                    token.line,
                    token.column,
                    self.text[token.line_start..token.end].to_string(),
                ));
                return Err(unexpected_token!(self, "Unexpected token {}", token));
            }
        }
    }


@@ 696,16 630,7 @@ impl Parser {
                        column: expr.column,
                    };
                } else {
                    return Err(KabelError::new(
                        ErrorKind::UnexpectedToken,
                        format!(
                            "Unexpected token {}",
                            self.text[child.start..child.end].to_string()
                        ),
                        child.line,
                        child.column,
                        self.text[child.line_start..child.end].to_string(),
                    ));
                    return Err(unexpected_token!(self, "Unexpected token {}", child));
                }
                if self.current >= self.input.len() {
                    break;


@@ 815,12 740,13 @@ pub struct AST {
pub enum ASTType {
    Program(Vec<AST>),

    Loop(Box<AST>),
    While(Box<AST>, Box<AST>),
    If(Box<AST>, Box<AST>, Option<Box<AST>>),
    Block(Vec<AST>),
    Function(Box<AST>, Vec<AST>, Box<AST>), // name, args, block
    Loop(Box<AST>), // block
    While(Box<AST>, Box<AST>), // condition, block
    If(Box<AST>, Box<AST>, Option<Box<AST>>), // condition, block, else/else if
    Block(Vec<AST>), // statements

    Decl(Box<AST>, Box<AST>),
    Decl(Box<AST>, Box<AST>), // identifier, expression
    Binary(Box<AST>, BinOp, Box<AST>),
    Unary(UnOp, Box<AST>),