Skip to content

Commit

Permalink
refactor parser
Browse files Browse the repository at this point in the history
  • Loading branch information
maxmindlin committed Jun 25, 2024
1 parent 5cb6b63 commit 35cbd67
Show file tree
Hide file tree
Showing 6 changed files with 347 additions and 162 deletions.
50 changes: 46 additions & 4 deletions scout-interpreter/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ pub mod object;
pub type EvalResult = Result<Arc<Object>, EvalError>;
pub type ScrapeResultsPtr = Arc<Mutex<ScrapeResults>>;

const MAX_DEPTH: usize = 2;
const MAX_DEPTH: usize = 10;

/// Evaluates the block and early returns if the stmt evaluates
/// to a Return
Expand Down Expand Up @@ -310,8 +310,13 @@ fn eval_crawl<'a>(
let mut scope = Env::default();
scope.add_outer(env.clone()).await;

if let Some(bind) = &lit.binding {
scope.set(bind, Arc::new(Object::Str(link.clone()))).await;
if let Some(bindings) = &lit.bindings {
scope
.set(&bindings.link, Arc::new(Object::Str(link.clone())))
.await;
scope
.set(&bindings.depth, Arc::new(Object::Number(depth as f64)))
.await;
}

let new_env = Arc::new(Mutex::new(scope));
Expand Down Expand Up @@ -570,7 +575,6 @@ fn eval_expression<'a>(
Ok(prev.unwrap())
}
ExprKind::Infix(lhs, op, rhs) => {
// TODO: precedence....
let l_obj = eval_expression(lhs, crawler, env.clone(), results.clone()).await?;
let r_obj = eval_expression(rhs, crawler, env.clone(), results.clone()).await?;
let res = eval_op(l_obj.clone(), op, r_obj.clone())?;
Expand Down Expand Up @@ -606,6 +610,16 @@ fn eval_op(lhs: Arc<Object>, op: &TokenKind, rhs: Arc<Object>) -> EvalResult {
TokenKind::Asterisk => eval_asterisk_op(lhs, rhs),
TokenKind::Slash => eval_slash_op(lhs, rhs),
TokenKind::LBracket => eval_index(lhs, rhs),
TokenKind::GT => eval_gt_op(lhs, rhs),
TokenKind::LT => eval_lt_op(lhs, rhs),
TokenKind::GTE => eval_gte_op(lhs, rhs),
TokenKind::LTE => eval_lte_op(lhs, rhs),
TokenKind::And => Ok(Arc::new(Object::Boolean(
lhs.is_truthy() && rhs.is_truthy(),
))),
TokenKind::Or => Ok(Arc::new(Object::Boolean(
lhs.is_truthy() || rhs.is_truthy(),
))),
_ => Err(EvalError::UnknownInfixOp),
}
}
Expand All @@ -627,6 +641,34 @@ fn eval_index(lhs: Arc<Object>, idx: Arc<Object>) -> EvalResult {
}
}

fn eval_gt_op(lhs: Arc<Object>, rhs: Arc<Object>) -> EvalResult {
match (&*lhs, &*rhs) {
(Object::Number(a), Object::Number(b)) => Ok(Arc::new(Object::Boolean(a > b))),
_ => Err(EvalError::UnknownInfixOp),
}
}

fn eval_gte_op(lhs: Arc<Object>, rhs: Arc<Object>) -> EvalResult {
match (&*lhs, &*rhs) {
(Object::Number(a), Object::Number(b)) => Ok(Arc::new(Object::Boolean(a >= b))),
_ => Err(EvalError::UnknownInfixOp),
}
}

fn eval_lt_op(lhs: Arc<Object>, rhs: Arc<Object>) -> EvalResult {
match (&*lhs, &*rhs) {
(Object::Number(a), Object::Number(b)) => Ok(Arc::new(Object::Boolean(a < b))),
_ => Err(EvalError::UnknownInfixOp),
}
}

fn eval_lte_op(lhs: Arc<Object>, rhs: Arc<Object>) -> EvalResult {
match (&*lhs, &*rhs) {
(Object::Number(a), Object::Number(b)) => Ok(Arc::new(Object::Boolean(a <= b))),
_ => Err(EvalError::UnknownInfixOp),
}
}

fn eval_plus_op(lhs: Arc<Object>, rhs: Arc<Object>) -> EvalResult {
match (&*lhs, &*rhs) {
(Object::Str(a), Object::Str(b)) => {
Expand Down
16 changes: 14 additions & 2 deletions scout-lexer/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -32,8 +32,20 @@ impl Lexer {
'+' => Token::new(Plus, c.to_string()),
'-' => Token::new(Minus, c.to_string()),
'*' => Token::new(Asterisk, c.to_string()),
'<' => Token::new(LT, c.to_string()),
'>' => Token::new(GT, c.to_string()),
'<' => match self.peek() {
Some('=') => {
self.next();
Token::new(LTE, "<=".to_string())
}
_ => Token::new(LT, '<'.to_string()),
},
'>' => match self.peek() {
Some('=') => {
self.next();
Token::new(GTE, "<=".to_string())
}
_ => Token::new(GT, '>'.to_string()),
},
'=' => match self.peek() {
Some('=') => {
self.next();
Expand Down
11 changes: 10 additions & 1 deletion scout-lexer/src/token.rs
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,8 @@ pub enum TokenKind {
Slash,
GT,
LT,
GTE,
LTE,
Bang,

// Keywords
Expand All @@ -51,6 +53,8 @@ pub enum TokenKind {
Throw,
Crawl,
Where,
And,
Or,
}

impl TokenKind {
Expand Down Expand Up @@ -78,13 +82,18 @@ impl TokenKind {
"catch" => Some(Catch),
"crawl" => Some(Crawl),
"throw" => Some(Throw),
"and" => Some(And),
"or" => Some(Or),
_ => None,
}
}

pub fn is_infix(&self) -> bool {
use TokenKind::*;
matches!(self, EQ | NEQ | Plus | Minus | Asterisk | Slash | GT | LT)
matches!(
self,
EQ | NEQ | Plus | Minus | Asterisk | Slash | GT | LT | And | Or
)
}

pub fn is_prefix(&self) -> bool {
Expand Down
File renamed without changes.
12 changes: 9 additions & 3 deletions scout-parser/src/ast.rs
Original file line number Diff line number Diff line change
Expand Up @@ -53,15 +53,21 @@ pub enum ExprKind {

#[derive(Debug, PartialEq, Clone)]
pub struct CrawlLiteral {
pub binding: Option<Identifier>,
pub bindings: Option<CrawlBindings>,
pub filter: Option<ExprKind>,
pub body: Block,
}

#[derive(Debug, PartialEq, Clone)]
pub struct CrawlBindings {
pub link: Identifier,
pub depth: Identifier,
}

impl CrawlLiteral {
pub fn new(binding: Option<Identifier>, filter: Option<ExprKind>, body: Block) -> Self {
pub fn new(bindings: Option<CrawlBindings>, filter: Option<ExprKind>, body: Block) -> Self {
Self {
binding,
bindings,
filter,
body,
}
Expand Down
Loading

0 comments on commit 35cbd67

Please sign in to comment.