mirror of
https://github.com/Noratrieb/dilaria.git
synced 2026-01-17 02:45:02 +01:00
more primaries
This commit is contained in:
parent
a89c5f91f9
commit
d848818824
4 changed files with 112 additions and 4 deletions
|
|
@ -1,3 +1,6 @@
|
||||||
|
//!
|
||||||
|
//! The AST module contains all structs and enums for the abstract syntax tree generated by the parser
|
||||||
|
|
||||||
#![allow(dead_code)]
|
#![allow(dead_code)]
|
||||||
|
|
||||||
/// imagine interning or something here
|
/// imagine interning or something here
|
||||||
|
|
|
||||||
|
|
@ -1,3 +1,6 @@
|
||||||
|
//!
|
||||||
|
//! This modules handles error reporting in the interpreter
|
||||||
|
|
||||||
use std::fmt::Debug;
|
use std::fmt::Debug;
|
||||||
|
|
||||||
#[derive(Debug, Copy, Clone, PartialOrd, PartialEq, Ord, Eq, Hash)]
|
#[derive(Debug, Copy, Clone, PartialOrd, PartialEq, Ord, Eq, Hash)]
|
||||||
|
|
@ -18,6 +21,10 @@ impl Span {
|
||||||
pub fn single(start: usize) -> Self {
|
pub fn single(start: usize) -> Self {
|
||||||
Self { start, len: 1 }
|
Self { start, len: 1 }
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn dummy() -> Self {
|
||||||
|
Self { start: 0, len: 0 }
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub trait CompilerError {
|
pub trait CompilerError {
|
||||||
|
|
|
||||||
|
|
@ -1,3 +1,6 @@
|
||||||
|
//!
|
||||||
|
//! The lex module lexes the source code into Tokens
|
||||||
|
|
||||||
use crate::errors::{CompilerError, Span};
|
use crate::errors::{CompilerError, Span};
|
||||||
use std::iter::Peekable;
|
use std::iter::Peekable;
|
||||||
use std::str::CharIndices;
|
use std::str::CharIndices;
|
||||||
|
|
|
||||||
103
src/parse.rs
103
src/parse.rs
|
|
@ -43,7 +43,7 @@ impl<'code> Parser<'code> {
|
||||||
|
|
||||||
fn statement(&mut self) -> ParseResult<'code, Stmt> {
|
fn statement(&mut self) -> ParseResult<'code, Stmt> {
|
||||||
let expr = self.expression()?;
|
let expr = self.expression()?;
|
||||||
self.expect(TokenType::Semi);
|
self.expect(TokenType::Semi)?;
|
||||||
Ok(Stmt::Expr(expr))
|
Ok(Stmt::Expr(expr))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -96,7 +96,11 @@ impl<'code> Parser<'code> {
|
||||||
}
|
}
|
||||||
|
|
||||||
fn unary(&mut self) -> ParseResult<'code, Expr> {
|
fn unary(&mut self) -> ParseResult<'code, Expr> {
|
||||||
todo!()
|
match self.next().ok_or(ParseErr::EOF)?.kind {
|
||||||
|
TokenType::Not => todo!(),
|
||||||
|
TokenType::Minus => todo!(),
|
||||||
|
_ => todo!(),
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn primary(&mut self) -> ParseResult<'code, Expr> {
|
fn primary(&mut self) -> ParseResult<'code, Expr> {
|
||||||
|
|
@ -106,8 +110,20 @@ impl<'code> Parser<'code> {
|
||||||
TokenType::False => Ok(Expr::Literal(Literal::Boolean(false))),
|
TokenType::False => Ok(Expr::Literal(Literal::Boolean(false))),
|
||||||
TokenType::True => Ok(Expr::Literal(Literal::Boolean(true))),
|
TokenType::True => Ok(Expr::Literal(Literal::Boolean(true))),
|
||||||
TokenType::Null => Ok(Expr::Literal(Literal::Null)),
|
TokenType::Null => Ok(Expr::Literal(Literal::Null)),
|
||||||
TokenType::BraceO => todo!(),
|
TokenType::BraceO => {
|
||||||
TokenType::BracketO => todo!(),
|
self.expect(TokenType::BraceC)?;
|
||||||
|
Ok(Expr::Literal(Literal::Object))
|
||||||
|
}
|
||||||
|
TokenType::BracketO => {
|
||||||
|
let mut elements = Vec::new();
|
||||||
|
while self.peek().ok_or(ParseErr::EOF)?.kind != TokenType::BracketC {
|
||||||
|
let expr = self.expression()?;
|
||||||
|
elements.push(expr);
|
||||||
|
self.expect(TokenType::Comma)?;
|
||||||
|
}
|
||||||
|
self.expect(TokenType::BracketC);
|
||||||
|
Ok(Expr::Literal(Literal::Array(elements)))
|
||||||
|
}
|
||||||
TokenType::ParenO => todo!(),
|
TokenType::ParenO => todo!(),
|
||||||
_ => todo!(),
|
_ => todo!(),
|
||||||
}
|
}
|
||||||
|
|
@ -165,3 +181,82 @@ impl CompilerError for ParseErr<'_> {
|
||||||
todo!()
|
todo!()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[cfg(test)]
|
||||||
|
mod test {
|
||||||
|
use crate::lex::{Token, TokenType};
|
||||||
|
use crate::parse::Parser;
|
||||||
|
|
||||||
|
fn token(kind: TokenType) -> Token {
|
||||||
|
Token {
|
||||||
|
span: crate::errors::Span::dummy(),
|
||||||
|
kind,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn parser<'a, T: Into<Vec<Token<'a>>>>(tokens: T) -> Parser<'a> {
|
||||||
|
Parser {
|
||||||
|
tokens: tokens.into().into_iter().peekable(),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
mod primary {
|
||||||
|
use crate::ast::{Expr, Literal};
|
||||||
|
use crate::lex::{Token, TokenType};
|
||||||
|
use crate::parse::test::{parser, token};
|
||||||
|
|
||||||
|
fn parse_primary<'a, T: Into<Vec<Token<'a>>>>(tokens: T) -> Expr {
|
||||||
|
let mut parser = parser(tokens);
|
||||||
|
parser.primary().unwrap()
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn string() {
|
||||||
|
let tokens = [TokenType::Number(10.0)].map(token);
|
||||||
|
let literal = parse_primary(tokens);
|
||||||
|
assert_eq!(Expr::Literal(Literal::Number(10.0)), literal);
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn number() {
|
||||||
|
let tokens = [TokenType::String("uwu".to_string())].map(token);
|
||||||
|
let literal = parse_primary(tokens);
|
||||||
|
assert_eq!(Expr::Literal(Literal::String("uwu".to_string())), literal);
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn empty_object() {
|
||||||
|
let tokens = [TokenType::BraceO, TokenType::BraceC].map(token);
|
||||||
|
let literal = parse_primary(tokens);
|
||||||
|
assert_eq!(Expr::Literal(Literal::Object), literal);
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn empty_array() {
|
||||||
|
let tokens = [TokenType::BracketO, TokenType::BracketC].map(token);
|
||||||
|
let literal = parse_primary(tokens);
|
||||||
|
assert_eq!(Expr::Literal(Literal::Array(Vec::new())), literal);
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn r#false() {
|
||||||
|
let tokens = [TokenType::False].map(token);
|
||||||
|
let literal = parse_primary(tokens);
|
||||||
|
assert_eq!(Expr::Literal(Literal::Boolean(false)), literal);
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn r#true() {
|
||||||
|
let tokens = [TokenType::True].map(token);
|
||||||
|
let literal = parse_primary(tokens);
|
||||||
|
assert_eq!(Expr::Literal(Literal::Boolean(true)), literal);
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn null() {
|
||||||
|
let tokens = [TokenType::Null].map(token);
|
||||||
|
let literal = parse_primary(tokens);
|
||||||
|
assert_eq!(Expr::Literal(Literal::Null), literal);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue