@@ -41,19 +41,23 @@ std::shared_ptr<object::Object> Evaluator::eval(
4141 if (typeid (*node) == typeid (ast::Program)) {
4242 auto n = node->cast <ast::Program>();
4343 return eval_program (n->statments (), env);
44+
4445 } else if (typeid (*node) == typeid (ast::ExpressionStatment)) {
4546 auto n = node->cast <ast::ExpressionStatment>();
4647 return eval (n->expression (), env);
48+
4749 } else if (typeid (*node) == typeid (ast::BlockStatment)) {
4850 auto n = node->cast <ast::BlockStatment>();
4951 return eval_statments (n->statments (), env);
52+
5053 } else if (typeid (*node) == typeid (ast::ReturnStatment)) {
5154 auto n = node->cast <ast::ReturnStatment>();
5255 auto return_val = eval (n->expression (), env);
5356 if (is_error (return_val.get ())) {
5457 return return_val;
5558 }
5659 return std::make_shared<object::ReturnValue>(return_val);
60+
5761 } else if (typeid (*node) == typeid (ast::LetStatment)) {
5862 auto n = node->cast <ast::LetStatment>();
5963 auto val = eval (n->expression (), env);
@@ -62,65 +66,117 @@ std::shared_ptr<object::Object> Evaluator::eval(
6266 }
6367
6468 env->set (n->identifier ()->value (), val);
69+
6570 } else if (typeid (*node) == typeid (ast::IntegerLiteral)) {
6671 auto n = node->cast <ast::IntegerLiteral>();
6772 return std::shared_ptr<object::Integer>(
6873 new object::Integer (n->value ()));
74+
6975 } else if (typeid (*node) == typeid (ast::BooleanLiteral)) {
7076 auto n = node->cast <ast::BooleanLiteral>();
7177 return n->value () ? _true : _false;
78+
7279 } else if (typeid (*node) == typeid (ast::StringLiteral)) {
7380 auto n = node->cast <ast::StringLiteral>();
7481 return std::make_shared<object::String>(n->value ());
82+
7583 } else if (typeid (*node) == typeid (ast::ArrayLiteral)) {
7684 auto n = node->cast <ast::ArrayLiteral>();
7785 auto elems = eval_expressions (n->elements (), env);
7886 if (!elems.empty () && is_error (elems[0 ].get ())) {
7987 return elems[0 ];
8088 }
8189 return std::make_shared<object::Array>(elems);
90+
8291 } else if (typeid (*node) == typeid (ast::PrefixExpression)) {
8392 auto n = node->cast <ast::PrefixExpression>();
8493 auto right = eval (n->right (), env);
8594 if (is_error (right.get ())) {
8695 return right;
8796 }
8897 return eval_prefix_expression (n->op (), right.get (), env);
98+
8999 } else if (typeid (*node) == typeid (ast::InfixExpression)) {
90100 auto n = node->cast <ast::InfixExpression>();
91101 auto left = eval (n->left (), env);
92102 if (is_error (left.get ())) {
93103 return left;
94104 }
105+
95106 auto right = eval (n->right (), env);
96107 if (is_error (right.get ())) {
97108 return right;
98109 }
110+
99111 return eval_infix_expression (n->op (), left.get (), right.get (), env);
112+
100113 } else if (typeid (*node) == typeid (ast::IfExpression)) {
101114 return eval_if_expression (node->cast <ast::IfExpression>(), env);
115+
102116 } else if (typeid (*node) == typeid (ast::Identifier)) {
103117 return eval_identifier (node->cast <ast::Identifier>(), env);
118+
104119 } else if (typeid (*node) == typeid (ast::FunctionLiteral)) {
105120 auto n = node->cast <ast::FunctionLiteral>();
106121 return std::make_shared<object::Function>(
107122 n->parameters (), n->body (), env);
123+
108124 } else if (typeid (*node) == typeid (ast::CallExpression)) {
109125 auto n = node->cast <ast::CallExpression>();
110126 auto function = eval (n->function (), env);
111127 if (is_error (function.get ())) {
112128 return function;
113129 }
130+
114131 auto args = eval_expressions (n->arguments (), env);
115132 if (!args.empty () && is_error (args[0 ].get ())) {
116133 return args[0 ];
117134 }
135+
118136 return apply_function (function.get (), args);
137+
138+ } else if (typeid (*node) == typeid (ast::IndexExpression)) {
139+ auto n = node->cast <ast::IndexExpression>();
140+ auto array = eval (n->left (), env);
141+ if (is_error (array.get ())) {
142+ return array;
143+ }
144+
145+ auto index = eval (n->index (), env);
146+ if (is_error (index.get ())) {
147+ return index;
148+ }
149+
150+ return eval_index_expression (array.get (), index.get ());
151+
119152 }
120153
121154 return nullptr ;
122155}
123156
157+ std::shared_ptr<object::Object> Evaluator::eval_index_expression (
158+ const object::Object* array,
159+ const object::Object* index) const {
160+ if (typeid (*array) == typeid (object::Array)
161+ && typeid (*index) == typeid (object::Integer)) {
162+ auto a = array->cast <object::Array>();
163+ auto i = index->cast <object::Integer>();
164+
165+ auto & elems = a->elements ();
166+ auto idx = i->value ();
167+
168+ if (idx < 0 ) {
169+ idx += elems.size ();
170+ }
171+
172+ if (idx < 0 || idx >= elems.size ()) {
173+ return _null;
174+ }
175+
176+ return elems[idx];
177+ }
178+ return new_error (" index operator not supported: `{}`" , array->type ());
179+ }
124180
125181std::shared_ptr<object::Object> Evaluator::apply_function (
126182 const object::Object* fn,
0 commit comments