-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
10 changed files
with
557 additions
and
333 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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); | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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>; | ||
} | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.