forked from AbleScript/ablescript
Generalised Spanned items
This commit is contained in:
parent
d890d7cfff
commit
db7fc4d592
|
@ -8,12 +8,48 @@
|
||||||
//! just plain subroutines and they do not return any value,
|
//! just plain subroutines and they do not return any value,
|
||||||
//! so their calls are statements.
|
//! so their calls are statements.
|
||||||
|
|
||||||
use std::hash::Hash;
|
use std::{fmt::Debug, hash::Hash};
|
||||||
|
|
||||||
use crate::variables::Value;
|
use crate::variables::Value;
|
||||||
|
|
||||||
type Span = std::ops::Range<usize>;
|
type Span = std::ops::Range<usize>;
|
||||||
|
|
||||||
|
#[derive(Clone)]
|
||||||
|
pub struct Spanned<T> {
|
||||||
|
pub item: T,
|
||||||
|
pub span: Span,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<T> Spanned<T> {
|
||||||
|
pub fn new(item: T, span: Span) -> Self {
|
||||||
|
Self { item, span }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<T: Debug> Debug for Spanned<T> {
|
||||||
|
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
|
||||||
|
if f.alternate() {
|
||||||
|
write!(f, "{:#?}", self.item)
|
||||||
|
} else {
|
||||||
|
write!(f, "{:?}", self.item)
|
||||||
|
}?;
|
||||||
|
|
||||||
|
write!(f, " @ {:?}", self.span)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<T: PartialEq> PartialEq for Spanned<T> {
|
||||||
|
fn eq(&self, other: &Self) -> bool {
|
||||||
|
self.item == other.item
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<T: Hash> Hash for Spanned<T> {
|
||||||
|
fn hash<H: std::hash::Hasher>(&self, state: &mut H) {
|
||||||
|
self.item.hash(state);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
#[derive(Debug, Clone)]
|
#[derive(Debug, Clone)]
|
||||||
pub struct Ident {
|
pub struct Ident {
|
||||||
pub ident: String,
|
pub ident: String,
|
||||||
|
@ -47,14 +83,14 @@ pub struct Assignable {
|
||||||
#[derive(Debug, PartialEq, Clone, Hash)]
|
#[derive(Debug, PartialEq, Clone, Hash)]
|
||||||
pub enum AssignableKind {
|
pub enum AssignableKind {
|
||||||
Variable,
|
Variable,
|
||||||
Index { indices: Vec<Expr> },
|
Index { indices: Vec<Spanned<ExprKind>> },
|
||||||
}
|
}
|
||||||
|
|
||||||
pub struct InvalidAssignable;
|
pub struct InvalidAssignable;
|
||||||
|
|
||||||
impl Assignable {
|
impl Assignable {
|
||||||
pub fn from_expr(expr: Expr) -> Result<Assignable, InvalidAssignable> {
|
pub fn from_expr(expr: Spanned<ExprKind>) -> Result<Assignable, InvalidAssignable> {
|
||||||
match expr.kind {
|
match expr.item {
|
||||||
ExprKind::Variable(ident) => Ok(Assignable {
|
ExprKind::Variable(ident) => Ok(Assignable {
|
||||||
ident: Ident::new(ident, expr.span),
|
ident: Ident::new(ident, expr.span),
|
||||||
kind: AssignableKind::Variable,
|
kind: AssignableKind::Variable,
|
||||||
|
@ -64,10 +100,10 @@ impl Assignable {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn from_index(mut buf: Expr, index: Expr) -> Result<Assignable, InvalidAssignable> {
|
fn from_index(mut buf: Spanned<ExprKind>, index: Spanned<ExprKind>) -> Result<Assignable, InvalidAssignable> {
|
||||||
let mut indices = vec![index];
|
let mut indices = vec![index];
|
||||||
let ident = loop {
|
let ident = loop {
|
||||||
match buf.kind {
|
match buf.item {
|
||||||
ExprKind::Variable(ident) => break ident,
|
ExprKind::Variable(ident) => break ident,
|
||||||
ExprKind::Index { expr, index } => {
|
ExprKind::Index { expr, index } => {
|
||||||
indices.push(*index);
|
indices.push(*index);
|
||||||
|
@ -87,33 +123,15 @@ impl Assignable {
|
||||||
|
|
||||||
#[derive(Debug, PartialEq, Clone, Hash)]
|
#[derive(Debug, PartialEq, Clone, Hash)]
|
||||||
pub struct Block {
|
pub struct Block {
|
||||||
pub block: Vec<Stmt>,
|
pub block: Vec<Spanned<StmtKind>>,
|
||||||
}
|
}
|
||||||
|
|
||||||
/// A syntactic unit expressing an effect.
|
/// A syntactic unit expressing an effect.
|
||||||
#[derive(Debug, Clone)]
|
|
||||||
pub struct Stmt {
|
|
||||||
pub kind: StmtKind,
|
|
||||||
pub span: Span,
|
|
||||||
}
|
|
||||||
|
|
||||||
impl PartialEq for Stmt {
|
|
||||||
fn eq(&self, other: &Self) -> bool {
|
|
||||||
self.kind == other.kind
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl Hash for Stmt {
|
|
||||||
fn hash<H: std::hash::Hasher>(&self, state: &mut H) {
|
|
||||||
self.kind.hash(state)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#[derive(Debug, PartialEq, Clone, Hash)]
|
#[derive(Debug, PartialEq, Clone, Hash)]
|
||||||
pub enum StmtKind {
|
pub enum StmtKind {
|
||||||
// Control flow
|
// Control flow
|
||||||
If {
|
If {
|
||||||
cond: Expr,
|
cond: Spanned<ExprKind>,
|
||||||
body: Block,
|
body: Block,
|
||||||
},
|
},
|
||||||
Loop {
|
Loop {
|
||||||
|
@ -124,11 +142,11 @@ pub enum StmtKind {
|
||||||
|
|
||||||
Var {
|
Var {
|
||||||
ident: Ident,
|
ident: Ident,
|
||||||
init: Option<Expr>,
|
init: Option<Spanned<ExprKind>>,
|
||||||
},
|
},
|
||||||
Assign {
|
Assign {
|
||||||
assignable: Assignable,
|
assignable: Assignable,
|
||||||
value: Expr,
|
value: Spanned<ExprKind>,
|
||||||
},
|
},
|
||||||
|
|
||||||
Functio {
|
Functio {
|
||||||
|
@ -138,70 +156,40 @@ pub enum StmtKind {
|
||||||
},
|
},
|
||||||
BfFunctio {
|
BfFunctio {
|
||||||
ident: Ident,
|
ident: Ident,
|
||||||
tape_len: Option<Expr>,
|
tape_len: Option<Spanned<ExprKind>>,
|
||||||
code: Vec<u8>,
|
code: Vec<u8>,
|
||||||
},
|
},
|
||||||
Call {
|
Call {
|
||||||
expr: Expr,
|
expr: Spanned<ExprKind>,
|
||||||
args: Vec<Expr>,
|
args: Vec<Spanned<ExprKind>>,
|
||||||
},
|
},
|
||||||
Print(Expr),
|
Print(Spanned<ExprKind>),
|
||||||
Read(Assignable),
|
Read(Assignable),
|
||||||
Melo(Ident),
|
Melo(Ident),
|
||||||
Rlyeh,
|
Rlyeh,
|
||||||
Rickroll,
|
Rickroll,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Stmt {
|
|
||||||
pub fn new(kind: StmtKind, span: Span) -> Self {
|
|
||||||
Self { kind, span }
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/// 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, Clone)]
|
|
||||||
pub struct Expr {
|
|
||||||
pub kind: ExprKind,
|
|
||||||
pub span: Span,
|
|
||||||
}
|
|
||||||
|
|
||||||
impl PartialEq for Expr {
|
|
||||||
fn eq(&self, other: &Self) -> bool {
|
|
||||||
self.kind == other.kind
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl Hash for Expr {
|
|
||||||
fn hash<H: std::hash::Hasher>(&self, state: &mut H) {
|
|
||||||
self.kind.hash(state)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#[derive(Debug, PartialEq, Clone, Hash)]
|
#[derive(Debug, PartialEq, Clone, Hash)]
|
||||||
pub enum ExprKind {
|
pub enum ExprKind {
|
||||||
BinOp {
|
BinOp {
|
||||||
lhs: Box<Expr>,
|
lhs: Box<Spanned<ExprKind>>,
|
||||||
rhs: Box<Expr>,
|
rhs: Box<Spanned<ExprKind>>,
|
||||||
kind: BinOpKind,
|
kind: BinOpKind,
|
||||||
},
|
},
|
||||||
Not(Box<Expr>),
|
Not(Box<Spanned<ExprKind>>),
|
||||||
Literal(Value),
|
Literal(Value),
|
||||||
Cart(Vec<(Expr, Expr)>),
|
Cart(Vec<(Spanned<ExprKind>, Spanned<ExprKind>)>),
|
||||||
Index {
|
Index {
|
||||||
expr: Box<Expr>,
|
expr: Box<Spanned<ExprKind>>,
|
||||||
index: Box<Expr>,
|
index: Box<Spanned<ExprKind>>,
|
||||||
},
|
},
|
||||||
Len(Box<Expr>),
|
Len(Box<Spanned<ExprKind>>),
|
||||||
Variable(String),
|
Variable(String),
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Expr {
|
|
||||||
pub fn new(kind: ExprKind, span: Span) -> Self {
|
|
||||||
Self { kind, span }
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#[derive(Debug, PartialEq, Clone, Hash)]
|
#[derive(Debug, PartialEq, Clone, Hash)]
|
||||||
pub enum BinOpKind {
|
pub enum BinOpKind {
|
||||||
Add,
|
Add,
|
||||||
|
|
|
@ -19,7 +19,7 @@ use std::{
|
||||||
use rand::random;
|
use rand::random;
|
||||||
|
|
||||||
use crate::{
|
use crate::{
|
||||||
ast::{Assignable, AssignableKind, Expr, ExprKind, Ident, Stmt, StmtKind},
|
ast::{Assignable, AssignableKind, ExprKind, Ident, Spanned, StmtKind},
|
||||||
base_55,
|
base_55,
|
||||||
consts::ablescript_consts,
|
consts::ablescript_consts,
|
||||||
error::{Error, ErrorKind},
|
error::{Error, ErrorKind},
|
||||||
|
@ -108,7 +108,7 @@ impl ExecEnv {
|
||||||
/// Execute a set of Statements in the root stack frame. Return an
|
/// Execute a set of Statements in the root stack frame. Return an
|
||||||
/// error if one or more of the Stmts failed to evaluate, or if a
|
/// error if one or more of the Stmts failed to evaluate, or if a
|
||||||
/// `break` or `hopback` statement occurred at the top level.
|
/// `break` or `hopback` statement occurred at the top level.
|
||||||
pub fn eval_stmts(&mut self, stmts: &[Stmt]) -> Result<(), Error> {
|
pub fn eval_stmts(&mut self, stmts: &[Spanned<StmtKind>]) -> Result<(), Error> {
|
||||||
match self.eval_stmts_hs(stmts, false)? {
|
match self.eval_stmts_hs(stmts, false)? {
|
||||||
HaltStatus::Finished => Ok(()),
|
HaltStatus::Finished => Ok(()),
|
||||||
HaltStatus::Break(span) | HaltStatus::Hopback(span) => Err(Error {
|
HaltStatus::Break(span) | HaltStatus::Hopback(span) => Err(Error {
|
||||||
|
@ -126,7 +126,11 @@ impl ExecEnv {
|
||||||
///
|
///
|
||||||
/// `interpret`-internal code should typically prefer this
|
/// `interpret`-internal code should typically prefer this
|
||||||
/// function over `eval_stmts`.
|
/// function over `eval_stmts`.
|
||||||
fn eval_stmts_hs(&mut self, stmts: &[Stmt], stackframe: bool) -> Result<HaltStatus, Error> {
|
fn eval_stmts_hs(
|
||||||
|
&mut self,
|
||||||
|
stmts: &[Spanned<StmtKind>],
|
||||||
|
stackframe: bool,
|
||||||
|
) -> Result<HaltStatus, Error> {
|
||||||
let init_depth = self.stack.len();
|
let init_depth = self.stack.len();
|
||||||
|
|
||||||
if stackframe {
|
if stackframe {
|
||||||
|
@ -151,11 +155,11 @@ impl ExecEnv {
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Evaluate an Expr, returning its value or an error.
|
/// Evaluate an Expr, returning its value or an error.
|
||||||
fn eval_expr(&self, expr: &Expr) -> Result<Value, Error> {
|
fn eval_expr(&self, expr: &Spanned<ExprKind>) -> Result<Value, Error> {
|
||||||
use crate::ast::BinOpKind::*;
|
use crate::ast::BinOpKind::*;
|
||||||
use crate::ast::ExprKind::*;
|
use crate::ast::ExprKind::*;
|
||||||
|
|
||||||
Ok(match &expr.kind {
|
Ok(match &expr.item {
|
||||||
BinOp { lhs, rhs, kind } => {
|
BinOp { lhs, rhs, kind } => {
|
||||||
let lhs = self.eval_expr(lhs)?;
|
let lhs = self.eval_expr(lhs)?;
|
||||||
let rhs = self.eval_expr(rhs)?;
|
let rhs = self.eval_expr(rhs)?;
|
||||||
|
@ -204,8 +208,8 @@ impl ExecEnv {
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Perform the action indicated by a statement.
|
/// Perform the action indicated by a statement.
|
||||||
fn eval_stmt(&mut self, stmt: &Stmt) -> Result<HaltStatus, Error> {
|
fn eval_stmt(&mut self, stmt: &Spanned<StmtKind>) -> Result<HaltStatus, Error> {
|
||||||
match &stmt.kind {
|
match &stmt.item {
|
||||||
StmtKind::Print(expr) => {
|
StmtKind::Print(expr) => {
|
||||||
println!("{}", self.eval_expr(expr)?);
|
println!("{}", self.eval_expr(expr)?);
|
||||||
}
|
}
|
||||||
|
@ -353,13 +357,18 @@ impl ExecEnv {
|
||||||
/// Call a function with the given arguments (i.e., actual
|
/// Call a function with the given arguments (i.e., actual
|
||||||
/// parameters). If the function invocation fails for some reason,
|
/// parameters). If the function invocation fails for some reason,
|
||||||
/// report the error at `span`.
|
/// report the error at `span`.
|
||||||
fn fn_call(&mut self, func: Functio, args: &[Expr], span: &Range<usize>) -> Result<(), Error> {
|
fn fn_call(
|
||||||
|
&mut self,
|
||||||
|
func: Functio,
|
||||||
|
args: &[Spanned<ExprKind>],
|
||||||
|
span: &Range<usize>,
|
||||||
|
) -> Result<(), Error> {
|
||||||
// Arguments that are ExprKind::Variable are pass by
|
// Arguments that are ExprKind::Variable are pass by
|
||||||
// reference; all other expressions are pass by value.
|
// reference; all other expressions are pass by value.
|
||||||
let args = args
|
let args = args
|
||||||
.iter()
|
.iter()
|
||||||
.map(|arg| {
|
.map(|arg| {
|
||||||
if let ExprKind::Variable(name) = &arg.kind {
|
if let ExprKind::Variable(name) = &arg.item {
|
||||||
self.get_var_rc(&Ident {
|
self.get_var_rc(&Ident {
|
||||||
ident: name.to_owned(),
|
ident: name.to_owned(),
|
||||||
span: arg.span.clone(),
|
span: arg.span.clone(),
|
||||||
|
|
|
@ -29,7 +29,7 @@ impl<'source> Parser<'source> {
|
||||||
/// Start parsing tokens
|
/// Start parsing tokens
|
||||||
///
|
///
|
||||||
/// Loops trough lexer, parses statements, returns AST
|
/// Loops trough lexer, parses statements, returns AST
|
||||||
pub fn init(&mut self) -> Result<Vec<Stmt>, Error> {
|
pub fn init(&mut self) -> Result<Vec<Spanned<StmtKind>>, Error> {
|
||||||
let mut ast = vec![];
|
let mut ast = vec![];
|
||||||
while let Some(token) = self.lexer.next() {
|
while let Some(token) = self.lexer.next() {
|
||||||
match token {
|
match token {
|
||||||
|
@ -64,32 +64,32 @@ impl<'source> Parser<'source> {
|
||||||
///
|
///
|
||||||
/// This function will route to corresponding flow functions
|
/// This function will route to corresponding flow functions
|
||||||
/// which may advance the lexer iterator
|
/// which may advance the lexer iterator
|
||||||
fn parse(&mut self, token: Token) -> Result<Stmt, Error> {
|
fn parse(&mut self, token: Token) -> Result<Spanned<StmtKind>, Error> {
|
||||||
let start = self.lexer.span().start;
|
let start = self.lexer.span().start;
|
||||||
|
|
||||||
match token {
|
match token {
|
||||||
Token::If => Ok(Stmt::new(self.if_flow()?, start..self.lexer.span().end)),
|
Token::If => Ok(Spanned::new(self.if_flow()?, start..self.lexer.span().end)),
|
||||||
Token::Functio => Ok(Stmt::new(
|
Token::Functio => Ok(Spanned::new(
|
||||||
self.functio_flow()?,
|
self.functio_flow()?,
|
||||||
start..self.lexer.span().end,
|
start..self.lexer.span().end,
|
||||||
)),
|
)),
|
||||||
Token::Bff => Ok(Stmt::new(self.bff_flow()?, start..self.lexer.span().end)),
|
Token::Bff => Ok(Spanned::new(self.bff_flow()?, start..self.lexer.span().end)),
|
||||||
Token::Var => Ok(Stmt::new(self.var_flow()?, start..self.lexer.span().end)),
|
Token::Var => Ok(Spanned::new(self.var_flow()?, start..self.lexer.span().end)),
|
||||||
Token::Melo => Ok(Stmt::new(self.melo_flow()?, start..self.lexer.span().end)),
|
Token::Melo => Ok(Spanned::new(self.melo_flow()?, start..self.lexer.span().end)),
|
||||||
Token::Loop => Ok(Stmt::new(self.loop_flow()?, start..self.lexer.span().end)),
|
Token::Loop => Ok(Spanned::new(self.loop_flow()?, start..self.lexer.span().end)),
|
||||||
Token::Break => Ok(Stmt::new(
|
Token::Break => Ok(Spanned::new(
|
||||||
self.semicolon_terminated(StmtKind::Break)?,
|
self.semicolon_terminated(StmtKind::Break)?,
|
||||||
start..self.lexer.span().end,
|
start..self.lexer.span().end,
|
||||||
)),
|
)),
|
||||||
Token::HopBack => Ok(Stmt::new(
|
Token::HopBack => Ok(Spanned::new(
|
||||||
self.semicolon_terminated(StmtKind::HopBack)?,
|
self.semicolon_terminated(StmtKind::HopBack)?,
|
||||||
start..self.lexer.span().end,
|
start..self.lexer.span().end,
|
||||||
)),
|
)),
|
||||||
Token::Rlyeh => Ok(Stmt::new(
|
Token::Rlyeh => Ok(Spanned::new(
|
||||||
self.semicolon_terminated(StmtKind::Rlyeh)?,
|
self.semicolon_terminated(StmtKind::Rlyeh)?,
|
||||||
start..self.lexer.span().end,
|
start..self.lexer.span().end,
|
||||||
)),
|
)),
|
||||||
Token::Rickroll => Ok(Stmt::new(
|
Token::Rickroll => Ok(Spanned::new(
|
||||||
self.semicolon_terminated(StmtKind::Rickroll)?,
|
self.semicolon_terminated(StmtKind::Rickroll)?,
|
||||||
start..self.lexer.span().end,
|
start..self.lexer.span().end,
|
||||||
)),
|
)),
|
||||||
|
@ -99,7 +99,7 @@ impl<'source> Parser<'source> {
|
||||||
| Token::Integer(_)
|
| Token::Integer(_)
|
||||||
| Token::Not
|
| Token::Not
|
||||||
| Token::LeftBracket
|
| Token::LeftBracket
|
||||||
| Token::LeftParen => Ok(Stmt::new(
|
| Token::LeftParen => Ok(Spanned::new(
|
||||||
self.value_flow(token)?,
|
self.value_flow(token)?,
|
||||||
start..self.lexer.span().end,
|
start..self.lexer.span().end,
|
||||||
)),
|
)),
|
||||||
|
@ -147,7 +147,7 @@ impl<'source> Parser<'source> {
|
||||||
/// AbleScript strongly separates expressions from statements.
|
/// AbleScript strongly separates expressions from statements.
|
||||||
/// Expressions do not have any side effects and the are
|
/// Expressions do not have any side effects and the are
|
||||||
/// only mathematial and logical operations or values.
|
/// only mathematial and logical operations or values.
|
||||||
fn parse_expr(&mut self, token: Token, buf: &mut Option<Expr>) -> Result<Expr, Error> {
|
fn parse_expr(&mut self, token: Token, buf: &mut Option<Spanned<ExprKind>>) -> Result<Spanned<ExprKind>, Error> {
|
||||||
let start = match buf {
|
let start = match buf {
|
||||||
Some(e) => e.span.start,
|
Some(e) => e.span.start,
|
||||||
None => self.lexer.span().start,
|
None => self.lexer.span().start,
|
||||||
|
@ -155,7 +155,7 @@ impl<'source> Parser<'source> {
|
||||||
|
|
||||||
match token {
|
match token {
|
||||||
// Values
|
// Values
|
||||||
Token::Identifier(i) => Ok(Expr::new(
|
Token::Identifier(i) => Ok(Spanned::new(
|
||||||
ExprKind::Variable(if self.tdark {
|
ExprKind::Variable(if self.tdark {
|
||||||
i.replace("lang", "script")
|
i.replace("lang", "script")
|
||||||
} else {
|
} else {
|
||||||
|
@ -163,11 +163,11 @@ impl<'source> Parser<'source> {
|
||||||
}),
|
}),
|
||||||
start..self.lexer.span().end,
|
start..self.lexer.span().end,
|
||||||
)),
|
)),
|
||||||
Token::Integer(i) => Ok(Expr::new(
|
Token::Integer(i) => Ok(Spanned::new(
|
||||||
ExprKind::Literal(Value::Int(i)),
|
ExprKind::Literal(Value::Int(i)),
|
||||||
start..self.lexer.span().end,
|
start..self.lexer.span().end,
|
||||||
)),
|
)),
|
||||||
Token::String(s) => Ok(Expr::new(
|
Token::String(s) => Ok(Spanned::new(
|
||||||
ExprKind::Literal(Value::Str(if self.tdark {
|
ExprKind::Literal(Value::Str(if self.tdark {
|
||||||
s.replace("lang", "script")
|
s.replace("lang", "script")
|
||||||
} else {
|
} else {
|
||||||
|
@ -177,11 +177,11 @@ impl<'source> Parser<'source> {
|
||||||
)),
|
)),
|
||||||
|
|
||||||
Token::LeftBracket => match buf.take() {
|
Token::LeftBracket => match buf.take() {
|
||||||
Some(buf) => Ok(Expr::new(
|
Some(buf) => Ok(Spanned::new(
|
||||||
self.index_flow(buf)?,
|
self.index_flow(buf)?,
|
||||||
start..self.lexer.span().end,
|
start..self.lexer.span().end,
|
||||||
)),
|
)),
|
||||||
None => Ok(Expr::new(self.cart_flow()?, start..self.lexer.span().end)),
|
None => Ok(Spanned::new(self.cart_flow()?, start..self.lexer.span().end)),
|
||||||
},
|
},
|
||||||
|
|
||||||
// Operations
|
// Operations
|
||||||
|
@ -192,7 +192,7 @@ impl<'source> Parser<'source> {
|
||||||
| Token::EqualEqual
|
| Token::EqualEqual
|
||||||
| Token::NotEqual
|
| Token::NotEqual
|
||||||
| Token::LessThan
|
| Token::LessThan
|
||||||
| Token::GreaterThan => Ok(Expr::new(
|
| Token::GreaterThan => Ok(Spanned::new(
|
||||||
self.binop_flow(
|
self.binop_flow(
|
||||||
BinOpKind::from_token(token).map_err(|e| Error::new(e, self.lexer.span()))?,
|
BinOpKind::from_token(token).map_err(|e| Error::new(e, self.lexer.span()))?,
|
||||||
buf,
|
buf,
|
||||||
|
@ -200,7 +200,7 @@ impl<'source> Parser<'source> {
|
||||||
start..self.lexer.span().end,
|
start..self.lexer.span().end,
|
||||||
)),
|
)),
|
||||||
|
|
||||||
Token::Not => Ok(Expr::new(
|
Token::Not => Ok(Spanned::new(
|
||||||
{
|
{
|
||||||
let next = self.checked_next()?;
|
let next = self.checked_next()?;
|
||||||
ExprKind::Not(Box::new(self.parse_expr(next, buf)?))
|
ExprKind::Not(Box::new(self.parse_expr(next, buf)?))
|
||||||
|
@ -262,7 +262,7 @@ impl<'source> Parser<'source> {
|
||||||
/// Flow for indexing operations
|
/// Flow for indexing operations
|
||||||
///
|
///
|
||||||
/// Indexing with empty index resolves to length of expression, else it indexes
|
/// Indexing with empty index resolves to length of expression, else it indexes
|
||||||
fn index_flow(&mut self, expr: Expr) -> Result<ExprKind, Error> {
|
fn index_flow(&mut self, expr: Spanned<ExprKind>) -> Result<ExprKind, Error> {
|
||||||
let mut buf = None;
|
let mut buf = None;
|
||||||
Ok(loop {
|
Ok(loop {
|
||||||
match self.checked_next()? {
|
match self.checked_next()? {
|
||||||
|
@ -285,7 +285,7 @@ impl<'source> Parser<'source> {
|
||||||
/// Generates operation from LHS buffer and next expression as RHS
|
/// Generates operation from LHS buffer and next expression as RHS
|
||||||
///
|
///
|
||||||
/// This is unaware of precedence, as AbleScript do not have it
|
/// This is unaware of precedence, as AbleScript do not have it
|
||||||
fn binop_flow(&mut self, kind: BinOpKind, lhs: &mut Option<Expr>) -> Result<ExprKind, Error> {
|
fn binop_flow(&mut self, kind: BinOpKind, lhs: &mut Option<Spanned<ExprKind>>) -> Result<ExprKind, Error> {
|
||||||
Ok(ExprKind::BinOp {
|
Ok(ExprKind::BinOp {
|
||||||
lhs: Box::new(
|
lhs: Box::new(
|
||||||
lhs.take()
|
lhs.take()
|
||||||
|
@ -303,7 +303,7 @@ impl<'source> Parser<'source> {
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Parse expressions until terminate token
|
/// Parse expressions until terminate token
|
||||||
fn expr_flow(&mut self, terminate: Token) -> Result<Expr, Error> {
|
fn expr_flow(&mut self, terminate: Token) -> Result<Spanned<ExprKind>, Error> {
|
||||||
let mut buf = None;
|
let mut buf = None;
|
||||||
Ok(loop {
|
Ok(loop {
|
||||||
match self.checked_next()? {
|
match self.checked_next()? {
|
||||||
|
@ -497,7 +497,7 @@ impl<'source> Parser<'source> {
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Parse functio call flow
|
/// Parse functio call flow
|
||||||
fn functio_call_flow(&mut self, expr: Expr) -> Result<StmtKind, Error> {
|
fn functio_call_flow(&mut self, expr: Spanned<ExprKind>) -> Result<StmtKind, Error> {
|
||||||
let mut args = vec![];
|
let mut args = vec![];
|
||||||
let mut buf = None;
|
let mut buf = None;
|
||||||
loop {
|
loop {
|
||||||
|
|
|
@ -12,7 +12,7 @@ use std::{
|
||||||
|
|
||||||
use rand::Rng;
|
use rand::Rng;
|
||||||
|
|
||||||
use crate::{ast::Stmt, brian::INSTRUCTION_MAPPINGS, consts};
|
use crate::{brian::INSTRUCTION_MAPPINGS, consts, ast::{Spanned, StmtKind}};
|
||||||
|
|
||||||
#[derive(Debug, Clone, Copy, PartialEq, PartialOrd)]
|
#[derive(Debug, Clone, Copy, PartialEq, PartialOrd)]
|
||||||
pub enum Abool {
|
pub enum Abool {
|
||||||
|
@ -58,7 +58,7 @@ pub enum Functio {
|
||||||
},
|
},
|
||||||
Able {
|
Able {
|
||||||
params: Vec<String>,
|
params: Vec<String>,
|
||||||
body: Vec<Stmt>,
|
body: Vec<Spanned<StmtKind>>,
|
||||||
},
|
},
|
||||||
Builtin(BuiltinFunctio),
|
Builtin(BuiltinFunctio),
|
||||||
Chain {
|
Chain {
|
||||||
|
|
Loading…
Reference in a new issue