forked from AbleScript/ablescript
Unified span terminology
- Add more derivations, because it's required by another parts of project
This commit is contained in:
parent
f893e24aed
commit
902d8b914c
14
src/ast.rs
14
src/ast.rs
|
@ -12,7 +12,7 @@ use crate::variables::Value;
|
||||||
|
|
||||||
type Span = std::ops::Range<usize>;
|
type Span = std::ops::Range<usize>;
|
||||||
|
|
||||||
#[derive(Debug)]
|
#[derive(Debug, PartialEq, Clone)]
|
||||||
pub struct Iden {
|
pub struct Iden {
|
||||||
pub iden: String,
|
pub iden: String,
|
||||||
pub span: Span,
|
pub span: Span,
|
||||||
|
@ -24,19 +24,19 @@ impl Iden {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug)]
|
#[derive(Debug, PartialEq, Clone)]
|
||||||
pub struct Block {
|
pub struct Block {
|
||||||
pub block: Vec<Stmt>,
|
pub block: Vec<Stmt>,
|
||||||
}
|
}
|
||||||
|
|
||||||
/// A syntactic unit expressing an effect.
|
/// A syntactic unit expressing an effect.
|
||||||
#[derive(Debug)]
|
#[derive(Debug, PartialEq, Clone)]
|
||||||
pub struct Stmt {
|
pub struct Stmt {
|
||||||
pub kind: StmtKind,
|
pub kind: StmtKind,
|
||||||
pub span: Span,
|
pub span: Span,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug)]
|
#[derive(Debug, PartialEq, Clone)]
|
||||||
pub enum StmtKind {
|
pub enum StmtKind {
|
||||||
// Control flow
|
// Control flow
|
||||||
If {
|
If {
|
||||||
|
@ -76,13 +76,13 @@ impl Stmt {
|
||||||
|
|
||||||
/// Expression is parse unit which do not cause any effect,
|
/// Expression is parse unit which do not cause any effect,
|
||||||
/// like math and logical operations or values.
|
/// like math and logical operations or values.
|
||||||
#[derive(Debug)]
|
#[derive(Debug, PartialEq, Clone)]
|
||||||
pub struct Expr {
|
pub struct Expr {
|
||||||
pub kind: ExprKind,
|
pub kind: ExprKind,
|
||||||
pub span: Span,
|
pub span: Span,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug)]
|
#[derive(Debug, PartialEq, Clone)]
|
||||||
pub enum ExprKind {
|
pub enum ExprKind {
|
||||||
BinOp {
|
BinOp {
|
||||||
lhs: Box<Expr>,
|
lhs: Box<Expr>,
|
||||||
|
@ -100,7 +100,7 @@ impl Expr {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug)]
|
#[derive(Debug, PartialEq, Clone)]
|
||||||
pub enum BinOpKind {
|
pub enum BinOpKind {
|
||||||
Add,
|
Add,
|
||||||
Subtract,
|
Subtract,
|
||||||
|
|
|
@ -72,7 +72,7 @@ impl ExecEnv {
|
||||||
// It's an error to issue a `break` outside of a
|
// It's an error to issue a `break` outside of a
|
||||||
// `loop` statement.
|
// `loop` statement.
|
||||||
kind: ErrorKind::TopLevelBreak,
|
kind: ErrorKind::TopLevelBreak,
|
||||||
position: 0..0,
|
span: 0..0,
|
||||||
}),
|
}),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -150,7 +150,7 @@ impl ExecEnv {
|
||||||
}
|
}
|
||||||
.ok_or(Error {
|
.ok_or(Error {
|
||||||
kind: ErrorKind::ArithmeticError,
|
kind: ErrorKind::ArithmeticError,
|
||||||
position: 0..0,
|
span: 0..0,
|
||||||
})?;
|
})?;
|
||||||
Int(res)
|
Int(res)
|
||||||
}
|
}
|
||||||
|
@ -246,7 +246,7 @@ impl ExecEnv {
|
||||||
crate::brian::interpret_with_io(&body, &input as &[_], &mut output)
|
crate::brian::interpret_with_io(&body, &input as &[_], &mut output)
|
||||||
.map_err(|e| Error {
|
.map_err(|e| Error {
|
||||||
kind: ErrorKind::BfInterpretError(e),
|
kind: ErrorKind::BfInterpretError(e),
|
||||||
position: 0..0,
|
span: 0..0,
|
||||||
})?;
|
})?;
|
||||||
|
|
||||||
// I guess Brainfuck functions write
|
// I guess Brainfuck functions write
|
||||||
|
@ -264,7 +264,7 @@ impl ExecEnv {
|
||||||
_ => {
|
_ => {
|
||||||
return Err(Error {
|
return Err(Error {
|
||||||
kind: ErrorKind::TypeError(iden.0.to_owned()),
|
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()),
|
kind: ErrorKind::MeloVariable(name.to_owned()),
|
||||||
// TODO: figure out some way to avoid this
|
// TODO: figure out some way to avoid this
|
||||||
// 0..0 dumbness
|
// 0..0 dumbness
|
||||||
position: 0..0,
|
span: 0..0,
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
None => Err(Error {
|
None => Err(Error {
|
||||||
kind: ErrorKind::UnknownVariable(name.to_owned()),
|
kind: ErrorKind::UnknownVariable(name.to_owned()),
|
||||||
position: 0..0,
|
span: 0..0,
|
||||||
}),
|
}),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -347,13 +347,13 @@ impl ExecEnv {
|
||||||
} else {
|
} else {
|
||||||
Err(Error {
|
Err(Error {
|
||||||
kind: ErrorKind::MeloVariable(name.to_owned()),
|
kind: ErrorKind::MeloVariable(name.to_owned()),
|
||||||
position: 0..0,
|
span: 0..0,
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
None => Err(Error {
|
None => Err(Error {
|
||||||
kind: ErrorKind::UnknownVariable(name.to_owned()),
|
kind: ErrorKind::UnknownVariable(name.to_owned()),
|
||||||
position: 0..0,
|
span: 0..0,
|
||||||
}),
|
}),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -399,7 +399,7 @@ mod tests {
|
||||||
})]),
|
})]),
|
||||||
Err(Error {
|
Err(Error {
|
||||||
kind: ErrorKind::TypeError(_),
|
kind: ErrorKind::TypeError(_),
|
||||||
position: _,
|
span: _,
|
||||||
})
|
})
|
||||||
));
|
));
|
||||||
}
|
}
|
||||||
|
@ -416,7 +416,7 @@ mod tests {
|
||||||
})]),
|
})]),
|
||||||
Err(Error {
|
Err(Error {
|
||||||
kind: ErrorKind::ArithmeticError,
|
kind: ErrorKind::ArithmeticError,
|
||||||
position: _,
|
span: _,
|
||||||
})
|
})
|
||||||
));
|
));
|
||||||
|
|
||||||
|
@ -428,7 +428,7 @@ mod tests {
|
||||||
})]),
|
})]),
|
||||||
Err(Error {
|
Err(Error {
|
||||||
kind: ErrorKind::ArithmeticError,
|
kind: ErrorKind::ArithmeticError,
|
||||||
position: _,
|
span: _,
|
||||||
})
|
})
|
||||||
));
|
));
|
||||||
}
|
}
|
||||||
|
|
|
@ -14,6 +14,7 @@ use crate::variables::Value;
|
||||||
/// Make one using [`Parser::new`] function
|
/// Make one using [`Parser::new`] function
|
||||||
pub struct Parser<'source> {
|
pub struct Parser<'source> {
|
||||||
lexer: Lexer<'source, Token>,
|
lexer: Lexer<'source, Token>,
|
||||||
|
tdark: bool,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'source> Parser<'source> {
|
impl<'source> Parser<'source> {
|
||||||
|
@ -21,6 +22,7 @@ impl<'source> Parser<'source> {
|
||||||
pub fn new(source: &'source str) -> Self {
|
pub fn new(source: &'source str) -> Self {
|
||||||
Self {
|
Self {
|
||||||
lexer: Token::lexer(source),
|
lexer: Token::lexer(source),
|
||||||
|
tdark: false,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -30,7 +32,19 @@ impl<'source> Parser<'source> {
|
||||||
pub fn init(&mut self) -> Result<Vec<Stmt>, Error> {
|
pub fn init(&mut self) -> Result<Vec<Stmt>, Error> {
|
||||||
let mut ast = vec![];
|
let mut ast = vec![];
|
||||||
while let Some(token) = self.lexer.next() {
|
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)
|
Ok(ast)
|
||||||
}
|
}
|
||||||
|
@ -103,7 +117,11 @@ impl<'source> Parser<'source> {
|
||||||
fn get_iden(&mut self) -> Result<Iden, Error> {
|
fn get_iden(&mut self) -> Result<Iden, Error> {
|
||||||
match self.lexer.next().ok_or(Error::unexpected_eof())? {
|
match self.lexer.next().ok_or(Error::unexpected_eof())? {
|
||||||
Token::Identifier(iden) => Ok(Iden {
|
Token::Identifier(iden) => Ok(Iden {
|
||||||
iden,
|
iden: if self.tdark {
|
||||||
|
iden.replace("lang", "script")
|
||||||
|
} else {
|
||||||
|
iden
|
||||||
|
},
|
||||||
span: self.lexer.span(),
|
span: self.lexer.span(),
|
||||||
}),
|
}),
|
||||||
t => Err(Error::new(ErrorKind::UnexpectedToken(t), self.lexer.span())),
|
t => Err(Error::new(ErrorKind::UnexpectedToken(t), self.lexer.span())),
|
||||||
|
@ -121,7 +139,11 @@ impl<'source> Parser<'source> {
|
||||||
match token {
|
match token {
|
||||||
// Values
|
// Values
|
||||||
Token::Identifier(i) => Ok(Expr::new(
|
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,
|
start..self.lexer.span().end,
|
||||||
)),
|
)),
|
||||||
Token::Abool(a) => Ok(Expr::new(
|
Token::Abool(a) => Ok(Expr::new(
|
||||||
|
@ -137,7 +159,11 @@ impl<'source> Parser<'source> {
|
||||||
start..self.lexer.span().end,
|
start..self.lexer.span().end,
|
||||||
)),
|
)),
|
||||||
Token::String(s) => Ok(Expr::new(
|
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,
|
start..self.lexer.span().end,
|
||||||
)),
|
)),
|
||||||
Token::Nul => Ok(Expr::new(
|
Token::Nul => Ok(Expr::new(
|
||||||
|
|
|
@ -2,11 +2,8 @@ use std::{convert::TryFrom, fmt::Display, io::Write};
|
||||||
|
|
||||||
use rand::Rng;
|
use rand::Rng;
|
||||||
|
|
||||||
use crate::{
|
use crate::ast::{Expr, Stmt};
|
||||||
error::{Error, ErrorKind},
|
use crate::error::{Error, ErrorKind};
|
||||||
parser::item::Item,
|
|
||||||
};
|
|
||||||
|
|
||||||
#[derive(Debug, Clone, PartialEq)]
|
#[derive(Debug, Clone, PartialEq)]
|
||||||
pub enum Abool {
|
pub enum Abool {
|
||||||
Never = -1,
|
Never = -1,
|
||||||
|
@ -37,7 +34,7 @@ impl From<Abool> for bool {
|
||||||
#[derive(Debug, Clone, PartialEq)]
|
#[derive(Debug, Clone, PartialEq)]
|
||||||
pub enum Functio {
|
pub enum Functio {
|
||||||
BfFunctio(Vec<u8>),
|
BfFunctio(Vec<u8>),
|
||||||
AbleFunctio(Vec<Item>),
|
AbleFunctio(Vec<Stmt>),
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug, Clone, PartialEq)]
|
#[derive(Debug, Clone, PartialEq)]
|
||||||
|
@ -147,7 +144,7 @@ impl TryFrom<Value> for i32 {
|
||||||
// this `position` correctly, or re-write the
|
// this `position` correctly, or re-write the
|
||||||
// `error::Error` struct so we can omit the `position`
|
// `error::Error` struct so we can omit the `position`
|
||||||
// when using some error kinds.
|
// when using some error kinds.
|
||||||
position: 0..0,
|
span: 0..0,
|
||||||
}),
|
}),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue