diff --git a/src/ast.rs b/src/ast.rs index e73fc3c7..69c25701 100644 --- a/src/ast.rs +++ b/src/ast.rs @@ -12,7 +12,7 @@ use crate::variables::Value; type Span = std::ops::Range; -#[derive(Debug)] +#[derive(Debug, PartialEq, Clone)] pub struct Iden { pub iden: String, pub span: Span, @@ -24,19 +24,19 @@ impl Iden { } } -#[derive(Debug)] +#[derive(Debug, PartialEq, Clone)] pub struct Block { pub block: Vec, } /// A syntactic unit expressing an effect. -#[derive(Debug)] +#[derive(Debug, PartialEq, Clone)] pub struct Stmt { pub kind: StmtKind, pub span: Span, } -#[derive(Debug)] +#[derive(Debug, PartialEq, Clone)] pub enum StmtKind { // Control flow If { @@ -76,13 +76,13 @@ impl Stmt { /// Expression is parse unit which do not cause any effect, /// like math and logical operations or values. -#[derive(Debug)] +#[derive(Debug, PartialEq, Clone)] pub struct Expr { pub kind: ExprKind, pub span: Span, } -#[derive(Debug)] +#[derive(Debug, PartialEq, Clone)] pub enum ExprKind { BinOp { lhs: Box, @@ -100,7 +100,7 @@ impl Expr { } } -#[derive(Debug)] +#[derive(Debug, PartialEq, Clone)] pub enum BinOpKind { Add, Subtract, diff --git a/src/interpret.rs b/src/interpret.rs index 0753d94f..3f16add0 100644 --- a/src/interpret.rs +++ b/src/interpret.rs @@ -72,7 +72,7 @@ impl ExecEnv { // It's an error to issue a `break` outside of a // `loop` statement. kind: ErrorKind::TopLevelBreak, - position: 0..0, + span: 0..0, }), } } @@ -150,7 +150,7 @@ impl ExecEnv { } .ok_or(Error { kind: ErrorKind::ArithmeticError, - position: 0..0, + span: 0..0, })?; Int(res) } @@ -246,7 +246,7 @@ impl ExecEnv { crate::brian::interpret_with_io(&body, &input as &[_], &mut output) .map_err(|e| Error { kind: ErrorKind::BfInterpretError(e), - position: 0..0, + span: 0..0, })?; // I guess Brainfuck functions write @@ -264,7 +264,7 @@ impl ExecEnv { _ => { return Err(Error { kind: ErrorKind::TypeError(iden.0.to_owned()), - position: 0..0, + span: 0..0, }) } } @@ -319,13 +319,13 @@ impl ExecEnv { kind: ErrorKind::MeloVariable(name.to_owned()), // TODO: figure out some way to avoid this // 0..0 dumbness - position: 0..0, + span: 0..0, }) } } None => Err(Error { kind: ErrorKind::UnknownVariable(name.to_owned()), - position: 0..0, + span: 0..0, }), } } @@ -347,13 +347,13 @@ impl ExecEnv { } else { Err(Error { kind: ErrorKind::MeloVariable(name.to_owned()), - position: 0..0, + span: 0..0, }) } } None => Err(Error { kind: ErrorKind::UnknownVariable(name.to_owned()), - position: 0..0, + span: 0..0, }), } } @@ -399,7 +399,7 @@ mod tests { })]), Err(Error { kind: ErrorKind::TypeError(_), - position: _, + span: _, }) )); } @@ -416,7 +416,7 @@ mod tests { })]), Err(Error { kind: ErrorKind::ArithmeticError, - position: _, + span: _, }) )); @@ -428,7 +428,7 @@ mod tests { })]), Err(Error { kind: ErrorKind::ArithmeticError, - position: _, + span: _, }) )); } diff --git a/src/parser.rs b/src/parser.rs index 96dced7f..a9c6a57d 100644 --- a/src/parser.rs +++ b/src/parser.rs @@ -14,6 +14,7 @@ use crate::variables::Value; /// Make one using [`Parser::new`] function pub struct Parser<'source> { lexer: Lexer<'source, Token>, + tdark: bool, } impl<'source> Parser<'source> { @@ -21,6 +22,7 @@ impl<'source> Parser<'source> { pub fn new(source: &'source str) -> Self { Self { lexer: Token::lexer(source), + tdark: false, } } @@ -30,7 +32,19 @@ impl<'source> Parser<'source> { pub fn init(&mut self) -> Result, Error> { let mut ast = vec![]; while let Some(token) = self.lexer.next() { - ast.push(self.parse(token)?); + match token { + // Ignore comments + Token::Comment => continue, + + // T-Dark block (replace `lang` with `script`) + Token::TDark => { + self.tdark = true; + let block = self.get_block()?; + ast.append(&mut block.block); + self.tdark = false; + } + token => ast.push(self.parse(token)?), + } } Ok(ast) } @@ -103,7 +117,11 @@ impl<'source> Parser<'source> { fn get_iden(&mut self) -> Result { match self.lexer.next().ok_or(Error::unexpected_eof())? { Token::Identifier(iden) => Ok(Iden { - iden, + iden: if self.tdark { + iden.replace("lang", "script") + } else { + iden + }, span: self.lexer.span(), }), t => Err(Error::new(ErrorKind::UnexpectedToken(t), self.lexer.span())), @@ -121,7 +139,11 @@ impl<'source> Parser<'source> { match token { // Values Token::Identifier(i) => Ok(Expr::new( - ExprKind::Variable(i), + ExprKind::Variable(if self.tdark { + i.replace("lang", "script") + } else { + i + }), start..self.lexer.span().end, )), Token::Abool(a) => Ok(Expr::new( @@ -137,7 +159,11 @@ impl<'source> Parser<'source> { start..self.lexer.span().end, )), Token::String(s) => Ok(Expr::new( - ExprKind::Literal(Value::Str(s)), + ExprKind::Literal(Value::Str(if self.tdark { + s.replace("lang", "script") + } else { + s + })), start..self.lexer.span().end, )), Token::Nul => Ok(Expr::new( diff --git a/src/variables.rs b/src/variables.rs index a6abee9e..8b47d541 100644 --- a/src/variables.rs +++ b/src/variables.rs @@ -2,11 +2,8 @@ use std::{convert::TryFrom, fmt::Display, io::Write}; use rand::Rng; -use crate::{ - error::{Error, ErrorKind}, - parser::item::Item, -}; - +use crate::ast::{Expr, Stmt}; +use crate::error::{Error, ErrorKind}; #[derive(Debug, Clone, PartialEq)] pub enum Abool { Never = -1, @@ -37,7 +34,7 @@ impl From for bool { #[derive(Debug, Clone, PartialEq)] pub enum Functio { BfFunctio(Vec), - AbleFunctio(Vec), + AbleFunctio(Vec), } #[derive(Debug, Clone, PartialEq)] @@ -147,7 +144,7 @@ impl TryFrom for i32 { // this `position` correctly, or re-write the // `error::Error` struct so we can omit the `position` // when using some error kinds. - position: 0..0, + span: 0..0, }), } }