Skip to content

Commit

Permalink
TMP - added
Browse files Browse the repository at this point in the history
  • Loading branch information
Cypher1 committed May 20, 2024
1 parent d3476ab commit 18b2ed1
Show file tree
Hide file tree
Showing 3 changed files with 25 additions and 42 deletions.
1 change: 0 additions & 1 deletion takolib/src/interpreter.rs
Original file line number Diff line number Diff line change
Expand Up @@ -243,7 +243,6 @@ impl<'a> Ctx<'a> {
Symbol::Dot => todo!(),
Symbol::Range => todo!(),
Symbol::Spread => todo!(),
Symbol::Comma => todo!(),
Symbol::Sequence => {
let Some(l) = op.args.first() else {
panic!("; expects a left and a right. Neither found");
Expand Down
51 changes: 19 additions & 32 deletions takolib/src/parser/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ use crate::ast::string_interner::Identifier;
use crate::ast::{Ast, Atom, Call, Contains, Definition, NodeData, NodeId, Op};
use crate::error::TError;
use better_std::include_strs;
use log::trace;
use log::{debug, trace};
use semantics::BindingMode;
use semantics::Literal;
use smallvec::{smallvec, SmallVec};
Expand Down Expand Up @@ -262,7 +262,7 @@ impl<'src, 'toks, T: Iterator<Item = &'toks Token>> ParseState<'src, 'toks, T> {
None
};
let implementation = if self.assignment_op(binding).is_ok() {
Some(self.expr(Symbol::Comma)?)
Some(self.any_expr()?)
} else {
None
};
Expand All @@ -282,7 +282,7 @@ impl<'src, 'toks, T: Iterator<Item = &'toks Token>> ParseState<'src, 'toks, T> {
}

fn binding_or_arg(&mut self, has_non_bind_args: &mut bool) -> Result<BindingOrValue, TError> {
let value = self.expr(Symbol::Comma)?;
let value = self.any_expr()?;
let node = &self.ast.get(value);
let location = node.location;
if let NodeData::Definition(binding) = node.id {
Expand Down Expand Up @@ -341,7 +341,7 @@ impl<'src, 'toks, T: Iterator<Item = &'toks Token>> ParseState<'src, 'toks, T> {
// Read args...
while self.operator_is(Symbol::CloseParen).is_err() {
bindings.push(self.binding_or_arg(&mut has_non_bind_args)?);
if self.require(TokenType::Op(Symbol::Comma)).is_err() {
if self.require(TokenType::Comma).is_err() {
self.require(TokenType::Op(Symbol::CloseParen))?;
break;
}
Expand All @@ -352,7 +352,7 @@ impl<'src, 'toks, T: Iterator<Item = &'toks Token>> ParseState<'src, 'toks, T> {
// Read args...
while self.operator_is(Symbol::CloseBracket).is_err() {
bindings.push(self.binding_or_arg(&mut has_non_bind_args)?);
if self.require(TokenType::Op(Symbol::Comma)).is_err() {
if self.require(TokenType::Comma).is_err() {
self.require(TokenType::Op(Symbol::CloseBracket))?;
break;
}
Expand Down Expand Up @@ -482,6 +482,7 @@ impl<'src, 'toks, T: Iterator<Item = &'toks Token>> ParseState<'src, 'toks, T> {
trace!("{indent}Expr: {token:?} (binding {binding:?})", indent=self.indent());
let mut left = if self.operator_is(Symbol::OpenBracket).is_ok() {
// Array, Tuple, List, Vector, Matrix, etc.
debug!("{indent}Got opener {:?}", Symbol::OpenBracket, indent=self.indent());
let args = self.repeated(Symbol::CloseBracket)?;
self.ast.add_op(
Op {
Expand All @@ -492,6 +493,7 @@ impl<'src, 'toks, T: Iterator<Item = &'toks Token>> ParseState<'src, 'toks, T> {
)
} else if self.operator_is(Symbol::OpenCurly).is_ok() {
// Block, set, dictionary, etc.
debug!("{indent}Got opener {:?}", Symbol::OpenCurly, indent=self.indent());
let args = self.repeated(Symbol::CloseCurly)?;
self.ast.add_op(
Op {
Expand All @@ -502,6 +504,7 @@ impl<'src, 'toks, T: Iterator<Item = &'toks Token>> ParseState<'src, 'toks, T> {
)
} else if self.operator_is(Symbol::OpenParen).is_ok() {
// Parenthesized expr... etc.
debug!("{indent}Got opener {:?}", Symbol::OpenParen, indent=self.indent());
let left = self.any_expr()?;
self.require(TokenType::Op(Symbol::CloseParen))?;
left
Expand Down Expand Up @@ -609,35 +612,19 @@ impl<'src, 'toks, T: Iterator<Item = &'toks Token>> ParseState<'src, 'toks, T> {

fn repeated(&mut self, closer: Symbol) -> Result<SmallVec<NodeId, 2>, TError> {
let mut args = smallvec![];
if self.operator_is(closer).is_err() {
let mut left = self.any_expr()?;
while self.operator_is(closer).is_err() {
let Ok(token) = self.peek().copied() else {
return Err(ParseError::UnexpectedEof.into());
};
let location = token.location();
let op = if self.require(TokenType::Op(Symbol::Comma)).is_ok() {
Symbol::Comma
} else if self.require(TokenType::Op(Symbol::Sequence)).is_ok() {
Symbol::Sequence // TODO: This isn't well supported
} else {
Symbol::Comma
};
if self.require(TokenType::Op(closer)).is_ok() {
break;
}

let right = self.any_expr()?;
left = self.ast.add_op(
Op {
op,
args: smallvec![left, right],
},
location,
);
while self.operator_is(closer).is_err() {
while self.require(TokenType::Comma).is_ok() {
// Eat extra commas
}
if self.require(TokenType::Op(closer)).is_ok() {
debug!("{indent}Got a closer {closer:?}", indent=self.indent());
break;
}
args.push(left);
debug!("{indent}Got no closer {closer:?} expecting another arg", indent=self.indent());
let arg = self.any_expr()?;
args.push(arg);
}
debug!("{indent}Got closer {closer:?}", indent=self.indent());
Ok(args)
}

Expand Down
15 changes: 6 additions & 9 deletions takolib/src/parser/tokens.rs
Original file line number Diff line number Diff line change
Expand Up @@ -84,9 +84,6 @@ pub enum Symbol {
Gt,
GtEqs,

// Groups
Comma,

// Maths
LeftShift,
RightShift,
Expand Down Expand Up @@ -151,8 +148,7 @@ lazy_static! {
Symbol::OpenParen => vec![Symbol::OpenCurly],
Symbol::OpenCurly => vec![Symbol::OpenBracket],
Symbol::OpenBracket => vec![Symbol::Sequence],
Symbol::Sequence => vec![Symbol::Comma],
Symbol::Comma => vec![
Symbol::Sequence => vec![
Symbol::Assign,
Symbol::AddAssign,
Symbol::SubAssign,
Expand Down Expand Up @@ -287,7 +283,7 @@ impl Symbol {
Self::OpenCurly => OpBinding::Open(Self::CloseCurly),
Self::OpenParen => OpBinding::Open(Self::CloseParen),
Self::OpenBracket => OpBinding::Open(Self::CloseParen),
Self::Sequence | Self::Comma => OpBinding::InfixOrPostfixBinOp,
Self::Sequence => OpBinding::InfixOrPostfixBinOp,
_ => OpBinding::InfixBinOp,
}
}
Expand Down Expand Up @@ -333,7 +329,6 @@ impl std::fmt::Display for Symbol {
Self::Dot => ".",
Self::Range => "..",
Self::Spread => "...",
Self::Comma => ",",
Self::Sequence => ";",
Self::Arrow => "->",
Self::DoubleArrow => "=>",
Expand Down Expand Up @@ -388,6 +383,7 @@ pub enum CharacterType {
#[derive(Copy, Clone, Debug, Eq, PartialEq, PartialOrd, Ord, Hash)]
pub enum TokenType {
Op(Symbol), // An operator (i.e. a known symbol used as a prefix or infix operator).
Comma, // A regular comma.
Ident, // A named value.
Atom, // A symbol starting with a '$', used differently to symbols which have values.
// Literals (i.e. tokens representing values):
Expand All @@ -408,6 +404,7 @@ impl fmt::Display for TokenType {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
match self {
Self::Op(sym) => write!(f, "a '{sym:?}' symbol"),
Self::Comma => write!(f, "a comma"),
Self::Ident => write!(f, "an identifier"),
Self::Atom => write!(f, "an atom"),
Self::NumberLit => write!(f, "a number"),
Expand Down Expand Up @@ -465,11 +462,12 @@ const _MULTI_COMMENT: &str = "/*";
#[inline]
fn classify_char(ch: char) -> CharacterType {
use CharacterType::{AtomHead, HexSym, PartialToken, Whitespace};
use TokenType::{Ident, NumberLit, Op, StringLit};
use TokenType::{Ident, Comma, NumberLit, Op, StringLit};
PartialToken(match ch {
'\n' | '\r' | '\t' | ' ' => return Whitespace,
'$' => return AtomHead,
'A'..='F' | 'a'..='f' => return HexSym,
',' => Comma,
'#' => Op(Symbol::Hash),
'~' => Op(Symbol::BitNot),
'!' => Op(Symbol::LogicalNot),
Expand All @@ -487,7 +485,6 @@ fn classify_char(ch: char) -> CharacterType {
'/' => Op(Symbol::Div),
'?' => Op(Symbol::Try),
'.' => Op(Symbol::Dot),
',' => Op(Symbol::Comma),
':' => Op(Symbol::HasType),
';' => Op(Symbol::Sequence),
'(' => Op(Symbol::OpenParen),
Expand Down

0 comments on commit 18b2ed1

Please sign in to comment.