Skip to content

Commit

Permalink
💻 added resolver ( incomplete )
Browse files Browse the repository at this point in the history
  • Loading branch information
aym-n committed Jan 8, 2024
1 parent 40c3963 commit 8f10567
Show file tree
Hide file tree
Showing 10 changed files with 557 additions and 333 deletions.
102 changes: 67 additions & 35 deletions generate_ast/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -13,34 +13,35 @@ pub fn generate_ast(output_dir: &String) -> io::Result<()> {
output_dir,
&"Expr".to_string(),
&vec![
"Assign : Token name, Box<Expr> value".to_string(),
"Binary : Box<Expr> left, Token operator, Box<Expr> right".to_string(),
"Call : Box<Expr> callee, Token paren, Vec<Expr> arguments".to_string(),
"Grouping : Box<Expr> expression".to_string(),
"Assign : Token name, Rc<Expr> value".to_string(),
"Binary : Rc<Expr> left, Token operator, Rc<Expr> right".to_string(),
"Call : Rc<Expr> callee, Token paren, Vec<Rc<Expr>> arguments".to_string(),
"Grouping : Rc<Expr> expression".to_string(),
"Literal : Option<Object> value".to_string(),
"Logical : Box<Expr> left, Token operator, Box<Expr> right".to_string(),
"Unary : Token operator, Box<Expr> right".to_string(),
"Logical : Rc<Expr> left, Token operator, Rc<Expr> right".to_string(),
"Unary : Token operator, Rc<Expr> right".to_string(),
"Variable : Token name".to_string(),

],
&vec![
"crate::tokens::*".to_string(),
"crate::errors::*".to_string(),
"std::rc::Rc".to_string(),
],
)?;

define_ast(
output_dir,
&"Stmt".to_string(),
&vec![
"Block : Vec<Stmt> statements".to_string(),
"Expression : Expr expression".to_string(),
"Function : Token name, Rc<Vec<Token>> params, Rc<Vec<Stmt>> body".to_string(),
"If : Expr condition, Box<Stmt> then_branch, Option<Box<Stmt>> else_branch".to_string(),
"Print : Expr expression".to_string(),
"Var : Token name, Option<Expr> initializer".to_string(),
"While : Expr condition, Box<Stmt> body".to_string(),
"Return : Token keyword, Option<Expr> value".to_string(),
"Block : Rc<Vec<Rc<Stmt>>> statements".to_string(),
"Expression : Rc<Expr> expression".to_string(),
"Function : Token name, Rc<Vec<Token>> params, Rc<Vec<Rc<Stmt>>> body".to_string(),
"If : Rc<Expr> condition, Rc<Stmt> then_branch, Option<Rc<Stmt>> else_branch".to_string(),
"Print : Rc<Expr> expression".to_string(),
"Var : Token name, Option<Rc<Expr>> initializer".to_string(),
"While : Rc<Expr> condition, Rc<Stmt> body".to_string(),
"Return : Token keyword, Option<Rc<Expr>> value".to_string(),
],
&vec![
"crate::expr::Expr".to_string(),
Expand Down Expand Up @@ -84,19 +85,49 @@ fn define_ast(

write!(file, "\npub enum {base_name} {{\n")?;
for t in &tree_types {
write!(file, " {}({}),\n", t.base_class_name, t.class_name)?;
write!(file, " {}(Rc<{}>),\n", t.base_class_name, t.class_name)?;
}
write!(file, "}}\n\n")?;

writeln!(file, "impl PartialEq for {} {{", base_name)?;
writeln!(file, " fn eq(&self, other: &Self) -> bool {{")?;
writeln!(file, " match (self, other) {{")?;
for t in &tree_types {
writeln!(
file,
" ({0}::{1}(a), {0}::{1}(b)) => Rc::ptr_eq(a, b),",
base_name, t.base_class_name
)?;
}
writeln!(file, " _ => false,")?;
writeln!(file, " }}")?;
writeln!(file, " }}")?;
writeln!(file, "}}\n\nimpl Eq for {}{{}}\n", base_name)?;

writeln!(file, "use std::hash::{{Hash, Hasher}};")?;
writeln!(file, "impl Hash for {} {{", base_name)?;
writeln!(file, " fn hash<H>(&self, hasher: &mut H)")?;
writeln!(file, " where H: Hasher,")?;
writeln!(file, " {{ match self {{ ")?;
for t in &tree_types {
writeln!(
file,
" {}::{}(a) => {{ hasher.write_usize(Rc::as_ptr(a) as usize); }}",
base_name, t.base_class_name
)?;
}
writeln!(file, " }}\n }}\n}}\n")?;

write!(file, "impl {} {{\n", base_name)?;
write!(file, " pub fn accept<T>(&self, {}_visitor: &dyn {base_name}Visitor<T>) -> Result<T , Error> {{\n", base_name.to_lowercase())?;
write!(file, " pub fn accept<T>(&self, wrapper: &Rc<{}>, {}_visitor: &dyn {base_name}Visitor<T>) -> Result<T , Error> {{\n", base_name, base_name.to_lowercase())?;
write!(file, " match self {{\n")?;
for t in &tree_types {
write!(
file,
" {}::{}(v) => v.accept({}_visitor),\n",
" {0}::{1}(v) => {3}_visitor.visit_{2}_{3}(wrapper, &v),\n",
base_name,
t.base_class_name,
t.base_class_name.to_lowercase(),
base_name.to_lowercase()
)?;
}
Expand All @@ -116,29 +147,30 @@ fn define_ast(
for t in &tree_types {
write!(
file,
" fn visit_{}_{}(&self, expr: &{}) -> Result<T , Error>;\n",
" fn visit_{0}_{1}(&self, wrapper: &Rc<{3}>, {1}: &{2}) -> Result<T , Error>;\n",
t.base_class_name.to_lowercase(),
base_name.to_lowercase(),
t.class_name
t.class_name,
base_name,
)?;
}
write!(file, "}}\n\n")?;

for t in &tree_types {
write!(file, "impl {} {{\n", t.class_name)?;
write!(
file,
" pub fn accept<T>(&self, visitor: &dyn {}Visitor<T>) -> Result<T , Error> {{\n",
base_name
)?;
write!(
file,
" visitor.visit_{}_{}(self)\n",
t.base_class_name.to_lowercase(),
base_name.to_lowercase()
)?;
write!(file, " }}\n")?;
write!(file, "}}\n\n")?;
}
// for t in &tree_types {
// write!(file, "impl {} {{\n", t.class_name)?;
// write!(
// file,
// " pub fn accept<T>(&self, visitor: &dyn {}Visitor<T>) -> Result<T , Error> {{\n",
// base_name
// )?;
// write!(
// file,
// " visitor.visit_{}_{}(self)\n",
// t.base_class_name.to_lowercase(),
// base_name.to_lowercase()
// )?;
// write!(file, " }}\n")?;
// write!(file, "}}\n\n")?;
// }
Ok(())
}
14 changes: 7 additions & 7 deletions main.arc
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
var a = 0;
var temp;
fn fib(n) {
if (n <= 1) return n;
return fib(n - 2) + fib(n - 1);
}

for (var b = 1; a < 10000; b = temp + b) {
print a;
temp = a;
a = b;
}
for(var i = 0; i < 100; i = i + 1){
print fib(i);
}
2 changes: 1 addition & 1 deletion src/errors.rs
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,7 @@ impl Error {
err
}

fn report(&self, loc: &str) {
fn report(&self, _loc: &str) {
match self {
Error::ParseError { token, message }
| Error::RuntimeError { token, message } => {
Expand Down
152 changes: 70 additions & 82 deletions src/expr.rs
Original file line number Diff line number Diff line change
@@ -1,128 +1,116 @@
use crate::tokens::*;
use crate::errors::*;
use std::rc::Rc;

pub enum Expr {
Assign(AssignExpr),
Binary(BinaryExpr),
Call(CallExpr),
Grouping(GroupingExpr),
Literal(LiteralExpr),
Logical(LogicalExpr),
Unary(UnaryExpr),
Variable(VariableExpr),
Assign(Rc<AssignExpr>),
Binary(Rc<BinaryExpr>),
Call(Rc<CallExpr>),
Grouping(Rc<GroupingExpr>),
Literal(Rc<LiteralExpr>),
Logical(Rc<LogicalExpr>),
Unary(Rc<UnaryExpr>),
Variable(Rc<VariableExpr>),
}

impl PartialEq for Expr {
fn eq(&self, other: &Self) -> bool {
match (self, other) {
(Expr::Assign(a), Expr::Assign(b)) => Rc::ptr_eq(a, b),
(Expr::Binary(a), Expr::Binary(b)) => Rc::ptr_eq(a, b),
(Expr::Call(a), Expr::Call(b)) => Rc::ptr_eq(a, b),
(Expr::Grouping(a), Expr::Grouping(b)) => Rc::ptr_eq(a, b),
(Expr::Literal(a), Expr::Literal(b)) => Rc::ptr_eq(a, b),
(Expr::Logical(a), Expr::Logical(b)) => Rc::ptr_eq(a, b),
(Expr::Unary(a), Expr::Unary(b)) => Rc::ptr_eq(a, b),
(Expr::Variable(a), Expr::Variable(b)) => Rc::ptr_eq(a, b),
_ => false,
}
}
}

impl Eq for Expr{}

use std::hash::{Hash, Hasher};
impl Hash for Expr {
fn hash<H>(&self, hasher: &mut H)
where H: Hasher,
{ match self {
Expr::Assign(a) => { hasher.write_usize(Rc::as_ptr(a) as usize); }
Expr::Binary(a) => { hasher.write_usize(Rc::as_ptr(a) as usize); }
Expr::Call(a) => { hasher.write_usize(Rc::as_ptr(a) as usize); }
Expr::Grouping(a) => { hasher.write_usize(Rc::as_ptr(a) as usize); }
Expr::Literal(a) => { hasher.write_usize(Rc::as_ptr(a) as usize); }
Expr::Logical(a) => { hasher.write_usize(Rc::as_ptr(a) as usize); }
Expr::Unary(a) => { hasher.write_usize(Rc::as_ptr(a) as usize); }
Expr::Variable(a) => { hasher.write_usize(Rc::as_ptr(a) as usize); }
}
}
}

impl Expr {
pub fn accept<T>(&self, expr_visitor: &dyn ExprVisitor<T>) -> Result<T , Error> {
pub fn accept<T>(&self, wrapper: &Rc<Expr>, expr_visitor: &dyn ExprVisitor<T>) -> Result<T , Error> {
match self {
Expr::Assign(v) => v.accept(expr_visitor),
Expr::Binary(v) => v.accept(expr_visitor),
Expr::Call(v) => v.accept(expr_visitor),
Expr::Grouping(v) => v.accept(expr_visitor),
Expr::Literal(v) => v.accept(expr_visitor),
Expr::Logical(v) => v.accept(expr_visitor),
Expr::Unary(v) => v.accept(expr_visitor),
Expr::Variable(v) => v.accept(expr_visitor),
Expr::Assign(v) => expr_visitor.visit_assign_expr(wrapper, &v),
Expr::Binary(v) => expr_visitor.visit_binary_expr(wrapper, &v),
Expr::Call(v) => expr_visitor.visit_call_expr(wrapper, &v),
Expr::Grouping(v) => expr_visitor.visit_grouping_expr(wrapper, &v),
Expr::Literal(v) => expr_visitor.visit_literal_expr(wrapper, &v),
Expr::Logical(v) => expr_visitor.visit_logical_expr(wrapper, &v),
Expr::Unary(v) => expr_visitor.visit_unary_expr(wrapper, &v),
Expr::Variable(v) => expr_visitor.visit_variable_expr(wrapper, &v),
}
}
}

pub struct AssignExpr {
pub name: Token,
pub value: Box<Expr>,
pub value: Rc<Expr>,
}

pub struct BinaryExpr {
pub left: Box<Expr>,
pub left: Rc<Expr>,
pub operator: Token,
pub right: Box<Expr>,
pub right: Rc<Expr>,
}

pub struct CallExpr {
pub callee: Box<Expr>,
pub callee: Rc<Expr>,
pub paren: Token,
pub arguments: Vec<Expr>,
pub arguments: Vec<Rc<Expr>>,
}

pub struct GroupingExpr {
pub expression: Box<Expr>,
pub expression: Rc<Expr>,
}

pub struct LiteralExpr {
pub value: Option<Object>,
}

pub struct LogicalExpr {
pub left: Box<Expr>,
pub left: Rc<Expr>,
pub operator: Token,
pub right: Box<Expr>,
pub right: Rc<Expr>,
}

pub struct UnaryExpr {
pub operator: Token,
pub right: Box<Expr>,
pub right: Rc<Expr>,
}

pub struct VariableExpr {
pub name: Token,
}

pub trait ExprVisitor<T> {
fn visit_assign_expr(&self, expr: &AssignExpr) -> Result<T , Error>;
fn visit_binary_expr(&self, expr: &BinaryExpr) -> Result<T , Error>;
fn visit_call_expr(&self, expr: &CallExpr) -> Result<T , Error>;
fn visit_grouping_expr(&self, expr: &GroupingExpr) -> Result<T , Error>;
fn visit_literal_expr(&self, expr: &LiteralExpr) -> Result<T , Error>;
fn visit_logical_expr(&self, expr: &LogicalExpr) -> Result<T , Error>;
fn visit_unary_expr(&self, expr: &UnaryExpr) -> Result<T , Error>;
fn visit_variable_expr(&self, expr: &VariableExpr) -> Result<T , Error>;
}

impl AssignExpr {
pub fn accept<T>(&self, visitor: &dyn ExprVisitor<T>) -> Result<T , Error> {
visitor.visit_assign_expr(self)
}
}

impl BinaryExpr {
pub fn accept<T>(&self, visitor: &dyn ExprVisitor<T>) -> Result<T , Error> {
visitor.visit_binary_expr(self)
}
}

impl CallExpr {
pub fn accept<T>(&self, visitor: &dyn ExprVisitor<T>) -> Result<T , Error> {
visitor.visit_call_expr(self)
}
}

impl GroupingExpr {
pub fn accept<T>(&self, visitor: &dyn ExprVisitor<T>) -> Result<T , Error> {
visitor.visit_grouping_expr(self)
}
}

impl LiteralExpr {
pub fn accept<T>(&self, visitor: &dyn ExprVisitor<T>) -> Result<T , Error> {
visitor.visit_literal_expr(self)
}
}

impl LogicalExpr {
pub fn accept<T>(&self, visitor: &dyn ExprVisitor<T>) -> Result<T , Error> {
visitor.visit_logical_expr(self)
}
}

impl UnaryExpr {
pub fn accept<T>(&self, visitor: &dyn ExprVisitor<T>) -> Result<T , Error> {
visitor.visit_unary_expr(self)
}
}

impl VariableExpr {
pub fn accept<T>(&self, visitor: &dyn ExprVisitor<T>) -> Result<T , Error> {
visitor.visit_variable_expr(self)
}
fn visit_assign_expr(&self, wrapper: &Rc<Expr>, expr: &AssignExpr) -> Result<T , Error>;
fn visit_binary_expr(&self, wrapper: &Rc<Expr>, expr: &BinaryExpr) -> Result<T , Error>;
fn visit_call_expr(&self, wrapper: &Rc<Expr>, expr: &CallExpr) -> Result<T , Error>;
fn visit_grouping_expr(&self, wrapper: &Rc<Expr>, expr: &GroupingExpr) -> Result<T , Error>;
fn visit_literal_expr(&self, wrapper: &Rc<Expr>, expr: &LiteralExpr) -> Result<T , Error>;
fn visit_logical_expr(&self, wrapper: &Rc<Expr>, expr: &LogicalExpr) -> Result<T , Error>;
fn visit_unary_expr(&self, wrapper: &Rc<Expr>, expr: &UnaryExpr) -> Result<T , Error>;
fn visit_variable_expr(&self, wrapper: &Rc<Expr>, expr: &VariableExpr) -> Result<T , Error>;
}

2 changes: 1 addition & 1 deletion src/functions.rs
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ use crate::interpreter::Interpreter;
pub struct Function {
name : Token,
params : Rc<Vec<Token>>,
body : Rc<Vec<Stmt>>,
body : Rc<Vec<Rc<Stmt>>>,
closure: Rc<RefCell<Environment>>,
}

Expand Down
Loading

0 comments on commit 8f10567

Please sign in to comment.