Skip to content

Commit

Permalink
feat: Anon fns
Browse files Browse the repository at this point in the history
  • Loading branch information
can-keklik committed Nov 30, 2023
1 parent dd8427a commit 1238042
Show file tree
Hide file tree
Showing 11 changed files with 112 additions and 82 deletions.
2 changes: 1 addition & 1 deletion examples/fib.ly
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
fun fib($n) {
if ($n < 2) return $n;
return fib($n - 2) + fib($n - 1);
}
};

var $start_ly = clock();
print(fib(35) == 9227465);
Expand Down
2 changes: 1 addition & 1 deletion examples/fn.ly
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ fun helloWorld ($message) {
print("outer");
}
}
}
};

for (var $i = 0; $i < 10; $i = $i + 1) {
print(helloWorld("My name is Lykia."));
Expand Down
2 changes: 1 addition & 1 deletion examples/scan_err.ly
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,6 @@
fun fib($n) {
if ($n < 2) return $n;
return fib($n - 2) + fib($n - 1);
}
};

117E
9 changes: 6 additions & 3 deletions src/lang/ast/expr.rs
Original file line number Diff line number Diff line change
@@ -1,13 +1,16 @@
use std::rc::Rc;

use crate::{lang::token::Token, runtime::types::RV};

use super::sql::SqlSelect;
use super::{sql::SqlSelect, stmt::StmtId};

#[derive(Debug, Eq, PartialEq)]
pub enum Expr {
Select(SqlSelect),
Variable(Token),
Grouping(ExprId),
Literal(RV),
Function(Token, Vec<Token>, Rc<Vec<StmtId>>),
Binary {
left: ExprId,
token: Token,
Expand All @@ -32,5 +35,5 @@ pub enum Expr {
args: Vec<ExprId>,
},
}

pub type ExprId = usize;
#[derive(Debug, Clone, Copy, Eq, PartialEq)]
pub struct ExprId(pub usize);
8 changes: 4 additions & 4 deletions src/lang/ast/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -27,19 +27,19 @@ impl ParserArena {

pub fn expression(&mut self, expr: Expr) -> ExprId {
self.expressions.push(expr);
self.expressions.len() - 1
ExprId(self.expressions.len() - 1)
}

pub fn statement(&mut self, stmt: Stmt) -> StmtId {
self.statements.push(stmt);
self.statements.len() - 1
StmtId(self.statements.len() - 1)
}

pub fn get_expression(&self, idx: ExprId) -> &Expr {
&self.expressions[idx]
&self.expressions[idx.0]
}

pub fn get_statement(&self, idx: StmtId) -> &Stmt {
&self.statements[idx]
&self.statements[idx.0]
}
}
6 changes: 2 additions & 4 deletions src/lang/ast/stmt.rs
Original file line number Diff line number Diff line change
@@ -1,13 +1,10 @@
use std::rc::Rc;

use crate::lang::token::Token;

use super::expr::ExprId;

#[derive(Debug, Eq, PartialEq)]
pub enum Stmt {
Expression(ExprId),
Function(Token, Vec<Token>, Rc<Vec<StmtId>>),
Declaration(Token, ExprId),
Block(Vec<StmtId>),
If(ExprId, StmtId, Option<StmtId>),
Expand All @@ -17,4 +14,5 @@ pub enum Stmt {
Return(Token, Option<ExprId>),
}

pub type StmtId = usize;
#[derive(Debug, Clone, Copy, Eq, PartialEq)]
pub struct StmtId(pub usize);
28 changes: 14 additions & 14 deletions src/lang/parser.rs
Original file line number Diff line number Diff line change
Expand Up @@ -108,7 +108,6 @@ impl<'a> Parser<'a> {

fn declaration(&mut self) -> ParseResult<StmtId> {
match_next!(self, kw!(Var), var_declaration);
match_next!(self, kw!(Fun), fun_declaration);
self.statement()
}

Expand Down Expand Up @@ -236,7 +235,17 @@ impl<'a> Parser<'a> {
Ok(self.arena.statement(Stmt::Expression(expr)))
}

fn fun_declaration(&mut self) -> ParseResult<StmtId> {
fn var_declaration(&mut self) -> ParseResult<StmtId> {
let token = self.expected(Identifier { dollar: true })?.clone();
let expr = match self.match_next(sym!(Equal)) {
true => self.expression()?,
false => self.arena.expression(Expr::Literal(RV::Null)),
};
self.expected(sym!(Semicolon))?;
Ok(self.arena.statement(Stmt::Declaration(token, expr)))
}

fn fun_declaration(&mut self) -> ParseResult<ExprId> {
let token = self.expected(Identifier { dollar: false })?.clone();
self.expected(sym!(LeftParen))?;
let mut parameters: Vec<Token> = vec![];
Expand All @@ -254,27 +263,18 @@ impl<'a> Parser<'a> {

let block = self.arena.get_statement(bidx);

let body: Vec<usize> = match block {
let body: Vec<StmtId> = match block {
Stmt::Block(stmts) => stmts.clone(),
_ => vec![],
};

Ok(self
.arena
.statement(Stmt::Function(token, parameters, Rc::new(body))))
}

fn var_declaration(&mut self) -> ParseResult<StmtId> {
let token = self.expected(Identifier { dollar: true })?.clone();
let expr = match self.match_next(sym!(Equal)) {
true => self.expression()?,
false => self.arena.expression(Expr::Literal(RV::Null)),
};
self.expected(sym!(Semicolon))?;
Ok(self.arena.statement(Stmt::Declaration(token, expr)))
.expression(Expr::Function(token, parameters, Rc::new(body))))
}

fn expression(&mut self) -> ParseResult<ExprId> {
match_next!(self, kw!(Fun), fun_declaration);
self.assignment()
}

Expand Down
30 changes: 15 additions & 15 deletions src/lang/visualization.rs
Original file line number Diff line number Diff line change
Expand Up @@ -97,6 +97,21 @@ impl Parsed {
}
buf
}
Expr::Function(tok, args, body) => {
let mut buf = indent(
level,
&format!("FunctionDeclaration [{} (", tok.span.lexeme.as_ref()),
false,
);
for arg in args {
buf.push_str(&format!("{},", arg.span.lexeme.as_ref()));
}
buf.push_str(")]");
for stmt in body.as_ref() {
buf.push_str(&self.visit_stmt(stmt.clone(), level + 1)?);
}
buf
}
};

Ok(matched)
Expand Down Expand Up @@ -161,21 +176,6 @@ impl Parsed {
}
Ok(buf)
}
Stmt::Function(tok, args, body) => {
let mut buf = indent(
level,
&format!("FunctionDeclaration [{} (", tok.span.lexeme.as_ref()),
false,
);
for arg in args {
buf.push_str(&format!("{},", arg.span.lexeme.as_ref()));
}
buf.push_str(")]");
for expr in body.as_ref() {
buf.push_str(&self.visit_stmt(*expr, level + 1)?);
}
Ok(buf)
}
}
}

Expand Down
35 changes: 19 additions & 16 deletions src/runtime/interpreter.rs
Original file line number Diff line number Diff line change
Expand Up @@ -287,6 +287,25 @@ impl Visitor<RV, HaltReason> for Interpreter {
}))
}
}
Expr::Function(token, parameters, body) => {
let name = token.span.lexeme.as_ref().to_string();
let fun = Function::UserDefined {
name: name.clone(),
body: Rc::clone(body),
parameters: parameters
.iter()
.map(|x| x.span.lexeme.as_ref().to_string())
.collect(),
closure: self.env.clone(),
};

let callable = Callable(Some(parameters.len()), fun.into());

// TODO(vck): Callable shouldn't be cloned here
self.env.borrow_mut().declare(name, callable.clone());

return Ok(callable);
}
}
}

Expand Down Expand Up @@ -354,22 +373,6 @@ impl Visitor<RV, HaltReason> for Interpreter {
}
return Err(HaltReason::Return(RV::Undefined));
}
Stmt::Function(token, parameters, body) => {
let name = token.span.lexeme.as_ref().to_string();
let fun = Function::UserDefined {
name: name.clone(),
body: Rc::clone(body),
parameters: parameters
.iter()
.map(|x| x.span.lexeme.as_ref().to_string())
.collect(),
closure: self.env.clone(),
};

self.env
.borrow_mut()
.declare(name, Callable(Some(parameters.len()), fun.into()));
}
}
Ok(RV::Undefined)
}
Expand Down
26 changes: 13 additions & 13 deletions src/runtime/resolver.rs
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ impl Resolver {
}

pub fn get_distance(&self, eid: ExprId) -> Option<usize> {
self.locals.get(&eid).copied()
self.locals.get(&eid.0).copied()
}

pub fn begin_scope(&mut self) {
Expand Down Expand Up @@ -55,7 +55,7 @@ impl Resolver {
pub fn resolve_local(&mut self, expr: ExprId, name: &Token) {
for i in (0..self.scopes.len()).rev() {
if self.scopes[i].contains_key(&name.span.lexeme.as_ref().to_string()) {
self.locals.insert(expr, self.scopes.len() - 1 - i);
self.locals.insert(expr.0, self.scopes.len() - 1 - i);
return;
}
}
Expand Down Expand Up @@ -133,6 +133,17 @@ impl Visitor<RV, ResolveError> for Resolver {
self.resolve_expr(*argument);
}
}
Expr::Function(_token, parameters, body) => {
self.declare(_token);
self.define(_token);
self.begin_scope();
for param in parameters {
self.declare(param);
self.define(param);
}
self.resolve_stmts(body.as_ref());
self.end_scope();
}
Expr::Select(_) => (),
};
Ok(RV::Undefined)
Expand Down Expand Up @@ -175,17 +186,6 @@ impl Visitor<RV, ResolveError> for Resolver {
self.resolve_expr(expr.unwrap());
}
}
Stmt::Function(_token, parameters, body) => {
self.declare(_token);
self.define(_token);
self.begin_scope();
for param in parameters {
self.declare(param);
self.define(param);
}
self.resolve_stmts(body.as_ref());
self.end_scope();
}
}
Ok(RV::Undefined)
}
Expand Down
Loading

0 comments on commit 1238042

Please sign in to comment.